Prefer function to COPY_STRING macro
* src/sparse.c (struct block_ptr): New type, to allow a functional style. (dump_str_nl, floorlog10): New static functions. (COPY_STRING): Remove. All uses replaced by dump_str_nl. (pax_dump_header_1): Use floorlog10 instead of creating a string. Simplify size calculation.
This commit is contained in:
106
src/sparse.c
106
src/sparse.c
@@ -1159,48 +1159,65 @@ pax_dump_header_0 (struct tar_sparse_file *file)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* An output block BLOCK, and a pointer PTR into it. */
|
||||
struct block_ptr
|
||||
{
|
||||
union block *block;
|
||||
char *ptr;
|
||||
};
|
||||
|
||||
/* Append to BP the contents of the string SRC, followed by a newline.
|
||||
If the string doesn’t fit, put any overflow into the succeeding blocks.
|
||||
Return the updated BP. */
|
||||
static struct block_ptr
|
||||
dump_str_nl (struct block_ptr bp, char const *str)
|
||||
{
|
||||
char *endp = bp.block->buffer + BLOCKSIZE;
|
||||
char c;
|
||||
do
|
||||
{
|
||||
c = *str++;
|
||||
if (bp.ptr == endp)
|
||||
{
|
||||
set_next_block_after (bp.block);
|
||||
bp.block = find_next_block ();
|
||||
bp.ptr = bp.block->buffer;
|
||||
endp = bp.block->buffer + BLOCKSIZE;
|
||||
}
|
||||
*bp.ptr++ = c ? c : '\n';
|
||||
}
|
||||
while (c);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
/* Return the floor of the log base 10 of N. If N is 0, return 0. */
|
||||
static int
|
||||
floorlog10 (uintmax_t n)
|
||||
{
|
||||
for (int f = 0; ; f++)
|
||||
if ((n /= 10) == 0)
|
||||
return f;
|
||||
}
|
||||
|
||||
static bool
|
||||
pax_dump_header_1 (struct tar_sparse_file *file)
|
||||
{
|
||||
off_t block_ordinal = current_block_ordinal ();
|
||||
union block *blk;
|
||||
char *p, *q;
|
||||
size_t i;
|
||||
char nbuf[UINTMAX_STRSIZE_BOUND];
|
||||
off_t size = 0;
|
||||
struct sp_array *map = file->stat_info->sparse_map;
|
||||
char *save_file_name = file->stat_info->file_name;
|
||||
|
||||
#define COPY_STRING(b,dst,src) do \
|
||||
{ \
|
||||
char *endp = b->buffer + BLOCKSIZE; \
|
||||
char const *srcp = src; \
|
||||
while (*srcp) \
|
||||
{ \
|
||||
if (dst == endp) \
|
||||
{ \
|
||||
set_next_block_after (b); \
|
||||
b = find_next_block (); \
|
||||
dst = b->buffer; \
|
||||
endp = b->buffer + BLOCKSIZE; \
|
||||
} \
|
||||
*dst++ = *srcp++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Compute stored file size */
|
||||
p = umaxtostr (file->stat_info->sparse_map_avail, nbuf);
|
||||
size += strlen (p) + 1;
|
||||
for (i = 0; i < file->stat_info->sparse_map_avail; i++)
|
||||
off_t size = floorlog10 (file->stat_info->sparse_map_avail) + 2;
|
||||
for (idx_t i = 0; i < file->stat_info->sparse_map_avail; i++)
|
||||
{
|
||||
p = umaxtostr (map[i].offset, nbuf);
|
||||
size += strlen (p) + 1;
|
||||
p = umaxtostr (map[i].numbytes, nbuf);
|
||||
size += strlen (p) + 1;
|
||||
size += floorlog10 (map[i].offset) + 2;
|
||||
size += floorlog10 (map[i].numbytes) + 2;
|
||||
}
|
||||
size = (size + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
file->stat_info->archive_file_size += size * BLOCKSIZE;
|
||||
file->dumped_size += size * BLOCKSIZE;
|
||||
size = (size + BLOCKSIZE - 1) / BLOCKSIZE * BLOCKSIZE;
|
||||
file->stat_info->archive_file_size += size;
|
||||
file->dumped_size += size;
|
||||
|
||||
/* Store sparse file identification */
|
||||
xheader_store ("GNU.sparse.major", file->stat_info, NULL);
|
||||
@@ -1214,27 +1231,22 @@ pax_dump_header_1 (struct tar_sparse_file *file)
|
||||
if (strlen (file->stat_info->file_name) > NAME_FIELD_SIZE)
|
||||
file->stat_info->file_name[NAME_FIELD_SIZE] = 0;
|
||||
|
||||
blk = pax_start_header (file->stat_info);
|
||||
finish_header (file->stat_info, blk, block_ordinal);
|
||||
struct block_ptr bp;
|
||||
bp.block = pax_start_header (file->stat_info);
|
||||
finish_header (file->stat_info, bp.block, block_ordinal);
|
||||
free (file->stat_info->file_name);
|
||||
file->stat_info->file_name = save_file_name;
|
||||
|
||||
blk = find_next_block ();
|
||||
q = blk->buffer;
|
||||
p = umaxtostr (file->stat_info->sparse_map_avail, nbuf);
|
||||
COPY_STRING (blk, q, p);
|
||||
COPY_STRING (blk, q, "\n");
|
||||
for (i = 0; i < file->stat_info->sparse_map_avail; i++)
|
||||
bp.block = find_next_block ();
|
||||
bp.ptr = bp.block->buffer;
|
||||
bp = dump_str_nl (bp, umaxtostr (file->stat_info->sparse_map_avail, nbuf));
|
||||
for (idx_t i = 0; i < file->stat_info->sparse_map_avail; i++)
|
||||
{
|
||||
p = umaxtostr (map[i].offset, nbuf);
|
||||
COPY_STRING (blk, q, p);
|
||||
COPY_STRING (blk, q, "\n");
|
||||
p = umaxtostr (map[i].numbytes, nbuf);
|
||||
COPY_STRING (blk, q, p);
|
||||
COPY_STRING (blk, q, "\n");
|
||||
bp = dump_str_nl (bp, umaxtostr (map[i].offset, nbuf));
|
||||
bp = dump_str_nl (bp, umaxtostr (map[i].numbytes, nbuf));
|
||||
}
|
||||
memset (q, 0, BLOCKSIZE - (q - blk->buffer));
|
||||
set_next_block_after (blk);
|
||||
memset (bp.ptr, 0, BLOCKSIZE - (bp.ptr - bp.block->buffer));
|
||||
set_next_block_after (bp.block);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user