cut: terminate cut_list[] so that we don't need "size of the array" variable

function                                             old     new   delta
cut_main                                            1410    1404      -6

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2024-12-16 00:32:57 +01:00
parent ba9651b803
commit 0bd84c9472

View file

@ -84,19 +84,22 @@
#define opt_REGEX (option_mask32 & OPT_REGEX) #define opt_REGEX (option_mask32 & OPT_REGEX)
struct cut_list { struct cut_range {
unsigned startpos; unsigned startpos;
unsigned endpos; unsigned endpos;
}; };
static int cmpfunc(const void *a, const void *b) static int cmpfunc(const void *a, const void *b)
{ {
return (((struct cut_list *) a)->startpos - return (((struct cut_range *) a)->startpos -
((struct cut_list *) b)->startpos); ((struct cut_range *) b)->startpos);
} }
#define END_OF_LIST(list_elem) ((list_elem).startpos == UINT_MAX)
#define NOT_END_OF_LIST(list_elem) ((list_elem).startpos != UINT_MAX)
static void cut_file(FILE *file, const char *delim, const char *odelim, static void cut_file(FILE *file, const char *delim, const char *odelim,
const struct cut_list *cut_list, unsigned nlists) const struct cut_range *cut_list)
{ {
char *line; char *line;
unsigned linenum = 0; /* keep these zero-based to be consistent */ unsigned linenum = 0; /* keep these zero-based to be consistent */
@ -115,7 +118,7 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
int need_odelim = 0; int need_odelim = 0;
/* print the chars specified in each cut list */ /* print the chars specified in each cut list */
for (; cl_pos < nlists; cl_pos++) { for (; NOT_END_OF_LIST(cut_list[cl_pos]); cl_pos++) {
unsigned spos; unsigned spos;
for (spos = cut_list[cl_pos].startpos; spos < linelen;) { for (spos = cut_list[cl_pos].startpos; spos < linelen;) {
if (!printed[spos]) { if (!printed[spos]) {
@ -137,9 +140,9 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
} else if (!opt_REGEX && *delim == '\n') { } else if (!opt_REGEX && *delim == '\n') {
unsigned spos = cut_list[cl_pos].startpos; unsigned spos = cut_list[cl_pos].startpos;
/* get out if we have no more lists to process or if the lines /* get out if we have no more ranges to process or if the lines
* are lower than what we're interested in */ * are lower than what we're interested in */
if ((linenum < spos) || (cl_pos >= nlists)) if ((linenum < spos) || END_OF_LIST(cut_list[cl_pos]))
goto next_line; goto next_line;
/* if the line we're looking for is lower than the one we were /* if the line we're looking for is lower than the one we were
@ -149,8 +152,8 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
/* go to the next list if we're at the end of this one */ /* go to the next list if we're at the end of this one */
if (spos > cut_list[cl_pos].endpos) { if (spos > cut_list[cl_pos].endpos) {
cl_pos++; cl_pos++;
/* get out if there's no more lists to process */ /* get out if there's no more ranges to process */
if (cl_pos >= nlists) if (END_OF_LIST(cut_list[cl_pos]))
goto next_line; goto next_line;
spos = cut_list[cl_pos].startpos; spos = cut_list[cl_pos].startpos;
/* get out if the current line is lower than the one /* get out if the current line is lower than the one
@ -188,7 +191,8 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
/* End of current range? */ /* End of current range? */
if (end == linelen || dcount > cut_list[cl_pos].endpos) { if (end == linelen || dcount > cut_list[cl_pos].endpos) {
end_of_range: end_of_range:
if (++cl_pos >= nlists) cl_pos++;
if (END_OF_LIST(cut_list[cl_pos]))
break; break;
if (option_mask32 & OPT_NOSORT) if (option_mask32 & OPT_NOSORT)
start = dcount = next = 0; start = dcount = next = 0;
@ -284,9 +288,9 @@ static void cut_file(FILE *file, const char *delim, const char *odelim,
int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int cut_main(int argc UNUSED_PARAM, char **argv) int cut_main(int argc UNUSED_PARAM, char **argv)
{ {
/* growable array holding a series of lists */ /* growable array holding a series of ranges */
struct cut_list *cut_list = NULL; struct cut_range *cut_list = NULL;
unsigned nlists = 0; /* number of elements in above list */ unsigned nranges = 0; /* number of elements in above list */
char *LIST, *ltok; char *LIST, *ltok;
const char *delim = NULL; const char *delim = NULL;
const char *odelim = NULL; const char *odelim = NULL;
@ -383,15 +387,16 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
bb_error_msg_and_die("invalid range %s-%s", ntok, ltok ?: ntok); bb_error_msg_and_die("invalid range %s-%s", ntok, ltok ?: ntok);
/* add the new range */ /* add the new range */
cut_list = xrealloc_vector(cut_list, 4, nlists); cut_list = xrealloc_vector(cut_list, 4, nranges);
/* NB: s is always >= 0 */ /* NB: s is always >= 0 */
cut_list[nlists].startpos = s; cut_list[nranges].startpos = s;
cut_list[nlists].endpos = e; cut_list[nranges].endpos = e;
nlists++; nranges++;
} }
cut_list[nranges].startpos = UINT_MAX; /* end indicator */
/* make sure we got some cut positions out of all that */ /* make sure we got some cut positions out of all that */
//if (nlists == 0) //if (nranges == 0)
// bb_simple_error_msg_and_die("missing list of positions"); // bb_simple_error_msg_and_die("missing list of positions");
//^^^ this is impossible since one of -bcfF is required, //^^^ this is impossible since one of -bcfF is required,
// they populate LIST with non-empty string and when it is parsed, // they populate LIST with non-empty string and when it is parsed,
@ -401,7 +406,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
* easier on us when it comes time to print the chars / fields / lines * easier on us when it comes time to print the chars / fields / lines
*/ */
if (!(opt & OPT_NOSORT)) if (!(opt & OPT_NOSORT))
qsort(cut_list, nlists, sizeof(cut_list[0]), cmpfunc); qsort(cut_list, nranges, sizeof(cut_list[0]), cmpfunc);
#if ENABLE_FEATURE_CUT_REGEX #if ENABLE_FEATURE_CUT_REGEX
if (opt & OPT_REGEX) { if (opt & OPT_REGEX) {
@ -422,7 +427,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
retval = EXIT_FAILURE; retval = EXIT_FAILURE;
continue; continue;
} }
cut_file(file, delim, odelim, cut_list, nlists); cut_file(file, delim, odelim, cut_list);
fclose_if_not_stdin(file); fclose_if_not_stdin(file);
} while (*++argv); } while (*++argv);