From: Paul Eggert Date: Sun, 18 Aug 2024 16:44:25 +0000 (-0700) Subject: Prefer function to COPY_STRING macro X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=f25dd56e83dfb5b442a4bc8601a29c43631206ca;p=thirdparty%2Ftar.git 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. --- diff --git a/src/sparse.c b/src/sparse.c index 80a1ff59..c79e6997 100644 --- a/src/sparse.c +++ b/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; }