Changeset 3321 in kBuild
- Timestamp:
- Apr 16, 2020 10:21:15 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/function.c
r3319 r3321 3638 3638 } 3639 3639 3640 /* Note that negative start isand length are used for referencing from the3640 /* Note that negative start and length are used for referencing from the 3641 3641 end of the string. */ 3642 3642 if (pad == NULL) … … 5801 5801 /* Helper for performer GNU make style quoting of one filename. */ 5802 5802 5803 static char *helper_quote_make (char *o, const char *name, int is_dep, int is_tgt, 5804 int quote_trailing_slashes, const char *funcname) 5805 { 5806 unsigned const map_flags = MAP_NUL 5807 | MAP_BLANK 5803 static char * 5804 helper_quote_make (char *o, const char *name, size_t len, int is_dep, 5805 int is_tgt, int quote_trailing_slashes, 5806 const char *funcname) 5807 { 5808 unsigned const map_flags = MAP_BLANK 5808 5809 | MAP_NEWLINE 5809 5810 | MAP_COMMENT … … 5814 5815 is_tgt ? MAP_COLON : 0); 5815 5816 const char *cur = name; 5816 if (*cur) 5817 { 5817 assert (memchr (name, '\0', len) == NULL); 5818 if (len > 0) 5819 { 5820 const char * const end = &name[len]; 5818 5821 unsigned long len_out = 0; 5819 5822 const char *prev = cur; 5820 for (;;)5823 do 5821 5824 { 5822 5825 char ch = *cur; … … 5833 5836 } 5834 5837 5835 if (flags & MAP_NUL)5836 break;5837 5838 5838 /* Dollar is quoted by duplicating the dollar: */ 5839 5839 if (flags & MAP_VARIABLE) 5840 5840 { 5841 o = variable_buffer_output (o, "$", 1); 5841 5842 prev = cur++; 5842 o = variable_buffer_output (o, "$", 1);5843 5843 } 5844 5844 /* The rest is quoted by '\': */ … … 5859 5859 } 5860 5860 } 5861 while ((uintptr_t)cur < (uintptr_t)end); 5862 5863 /* Flush pending output. */ 5864 if (prev != cur) 5865 { 5866 o = variable_buffer_output (o, prev, cur - prev); 5867 len_out += cur - prev; 5868 } 5861 5869 5862 5870 /* Escape trailing slashes when needed. */ … … 5941 5949 /* Output the quoted argument: */ 5942 5950 if (quote_trailing_slashes) 5943 o = helper_quote_make (o, arg, is_dep, is_tgt,5951 o = helper_quote_make (o, arg, strlen (arg), is_dep, is_tgt, 5944 5952 quote_trailing_slashes, funcname); 5945 5953 else … … 5948 5956 int qts = end != arg && end[-1] == '\\' 5949 5957 && func_quote_make_has_more_non_empty_args (&argv[i + 1]); 5950 o = helper_quote_make (o, arg, is_dep, is_tgt, qts, funcname); 5958 o = helper_quote_make (o, arg, strlen (arg), is_dep, is_tgt, 5959 qts, funcname); 5951 5960 } 5952 5961 } … … 6122 6131 } 6123 6132 6124 6133 /* Decoded style options for the $(q* ) and $(*file* ) functions. */ 6125 6134 #define Q_RET_MASK 0x000f 6126 #define Q_RET_ UNQUOTED0x00006127 #define Q_RET_QUOTED 6128 #define Q_RET_QUOTED_DEP 6129 #define Q_RET_QUOTED_ DEP_END0x00036130 #define Q_RET_QUOTED_TGT 6131 #define Q_RET_ QUOTED_TGT_END0x00056135 #define Q_RET_QUOTED 0x0000 6136 #define Q_RET_QUOTED_DEP 0x0001 6137 #define Q_RET_QUOTED_DEP_END 0x0002 6138 #define Q_RET_QUOTED_TGT 0x0003 6139 #define Q_RET_QUOTED_TGT_END 0x0004 6140 #define Q_RET_UNQUOTED 0x0005 6132 6141 #define Q_RET_SHELL 0x0006 6133 6142 #define Q_RET_SHELL_IN_DQ 0x0007 … … 6149 6158 #define Q_SEP_COMMA 0x0400 /* for VMS, output only */ 6150 6159 6151 #define Q_QDEFAULT 0x00006160 #define Q_QDEFAULT (Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE) 6152 6161 #ifndef VMS 6153 6162 # define Q_QDEFAULT_VMS_TRICKS Q_QDEFAULT … … 6162 6171 style, but can also pick the input and space styles (just because we can). */ 6163 6172 6164 static unsigned int helper_file_ return_style (char *style, unsigned int intstyle)6173 static unsigned int helper_file_quoting_style (char *style, unsigned int intstyle) 6165 6174 { 6166 6175 if (style != NULL) … … 6272 6281 unsigned int style, int is_last) 6273 6282 { 6274 assert ( file[len] == '\0');6283 assert (memchr (file, '\0', len) == NULL); 6275 6284 switch (style & Q_RET_MASK) 6276 6285 { … … 6279 6288 break; 6280 6289 case Q_RET_QUOTED: 6281 o = helper_quote_make (o, file, 0 /*is_dep*/, 0 /*is_tgt*/,6290 o = helper_quote_make (o, file, len, 0 /*is_dep*/, 0 /*is_tgt*/, 6282 6291 !is_last /*quote_trailing_slashes*/, NULL); 6283 6292 break; 6284 6293 case Q_RET_QUOTED_DEP: 6285 o = helper_quote_make (o, file, 1 /*is_dep*/, 0 /*is_tgt*/,6294 o = helper_quote_make (o, file, len, 1 /*is_dep*/, 0 /*is_tgt*/, 6286 6295 !is_last /*quote_trailing_slashes*/, NULL); 6287 6296 break; 6288 6297 case Q_RET_QUOTED_DEP_END: 6289 o = helper_quote_make (o, file, 1 /*is_dep*/, 0 /*is_tgt*/,6298 o = helper_quote_make (o, file, len, 1 /*is_dep*/, 0 /*is_tgt*/, 6290 6299 0 /*quote_trailing_slashes*/, NULL); 6291 6300 break; 6292 6301 case Q_RET_QUOTED_TGT: 6293 o = helper_quote_make (o, file, 0 /*is_dep*/, 1 /*is_tgt*/,6302 o = helper_quote_make (o, file, len, 0 /*is_dep*/, 1 /*is_tgt*/, 6294 6303 !is_last /*quote_trailing_slashes*/, NULL); 6295 6304 break; 6296 6305 case Q_RET_QUOTED_TGT_END: 6297 o = helper_quote_make (o, file, 0 /*is_dep*/, 1 /*is_tgt*/,6306 o = helper_quote_make (o, file, len, 0 /*is_dep*/, 1 /*is_tgt*/, 6298 6307 0 /*quote_trailing_slashes*/, NULL); 6299 6308 break; … … 6401 6410 } 6402 6411 6403 /* Parses a file/word list according to STYLE and returns a name list. */ 6412 /* Parses a file/word list according to STYLE and returns a name list. 6413 6414 Note! The FILELIST parameter may be modified. 6415 6416 TODO/XXX: Unquote and split up the FILELIST directly. All function 6417 arguments are heap copies already, so we are free to modify 6418 them. Would be nice to ditch the nameseq in favor of something 6419 which also includes the length. */ 6404 6420 6405 6421 static struct nameseq * … … 6407 6423 { 6408 6424 if (filelist && *filelist != '\0') 6409 switch (style & (Q_IN_MASK | Q_IN_SEP_COMMA)) 6410 { 6411 case Q_IN_QUOTED: 6412 case Q_IN_QUOTED_DEP: /** @todo ?? */ 6413 case Q_IN_QUOTED_TGT: /** @todo ?? */ 6414 return PARSE_FILE_SEQ(&filelist, struct nameseq, MAP_NUL, NULL, 6415 !glob 6416 ? PARSEFS_NOGLOB | PARSEFS_NOSTRIP | PARSEFS_NOCACHE 6417 : PARSEFS_NOSTRIP | PARSEFS_NOCACHE | PARSEFS_EXISTS); 6418 6419 case Q_IN_UNQUOTED: 6420 { 6421 struct nameseq *chain = NULL; 6422 struct nameseq **ppnext = &chain; 6423 const char *it = filelist; 6424 const char *cur; 6425 unsigned int curlen; 6426 while ((cur = find_next_token (&it, &curlen)) != NULL) 6427 { 6425 { 6426 /* Q_IN_SEP_COMMA: VMS tricks for qbasename, qdir, qnotdir and qsuffix 6427 where commas are treated as separtors in FILELIST. We simply 6428 replace commas in the FILELIST before doing the regular parsing. */ 6429 if (!(style & Q_IN_SEP_COMMA)) 6430 { /* typical */ } 6431 else 6432 { 6433 size_t len = strlen (filelist); 6434 char *start = filelist; 6435 char *comma = (char *)memchr (filelist, ',', len); 6436 while (comma) 6437 { 6438 *comma = ' '; 6439 len -= comma - start - 1; 6440 if (len) 6441 { 6442 start = comma + 1; 6443 comma = (char *)memchr (start, ',', len); 6444 } 6445 else 6446 break; 6447 } 6448 } 6449 6450 switch (style & Q_IN_MASK) 6451 { 6452 case Q_IN_QUOTED: 6453 case Q_IN_QUOTED_DEP: /** @todo ?? */ 6454 case Q_IN_QUOTED_TGT: /** @todo ?? */ 6455 return PARSE_FILE_SEQ(&filelist, struct nameseq, MAP_NUL, NULL, 6456 !glob 6457 ? PARSEFS_NOGLOB | PARSEFS_NOSTRIP | PARSEFS_NOCACHE 6458 : PARSEFS_NOSTRIP | PARSEFS_NOCACHE | PARSEFS_EXISTS); 6459 6460 case Q_IN_UNQUOTED: 6461 { 6462 struct nameseq *chain = NULL; 6463 struct nameseq **ppnext = &chain; 6464 const char *it = filelist; 6465 const char *cur; 6466 unsigned int curlen; 6467 while ((cur = find_next_token (&it, &curlen)) != NULL) 6468 { 6428 6469 #ifndef CONFIG_WITH_ALLOC_CACHES 6429 struct nameseq *newp = xcalloc (sizeof (*newp));6470 struct nameseq *newp = xcalloc (sizeof (*newp)); 6430 6471 #else 6431 struct nameseq *newp = alloccache_calloc (&nameseq_cache); 6432 #endif 6433 newp->name = xstrndup (cur, curlen); 6434 newp->next = NULL; 6435 *ppnext = newp; 6436 ppnext = &newp->next; 6437 } 6438 if (!glob) 6439 return chain; 6440 return helper_glob_chain (chain); 6441 } 6442 6443 /* Following works recursively. Mainly for VMS. */ 6444 case Q_IN_SEP_COMMA | Q_IN_UNQUOTED: 6445 case Q_IN_SEP_COMMA | Q_IN_QUOTED: 6446 case Q_IN_SEP_COMMA | Q_IN_QUOTED_DEP: /** @todo ?? */ 6447 case Q_IN_SEP_COMMA | Q_IN_QUOTED_TGT: /** @todo ?? */ 6448 { 6449 size_t len = strlen (filelist); 6450 char *comma = (char *)memchr (filelist, ',', len); 6451 struct nameseq *chain; 6452 if (!comma) 6453 chain = helper_parse_file_list (filelist, style & ~Q_IN_SEP_COMMA, 0); 6454 else 6455 { 6456 char *copy; 6457 char *start; 6458 start = copy = xmalloc (len + 1); 6459 memcpy (copy, filelist, len + 1); 6460 comma = copy + (comma - filelist); 6461 do 6462 { 6463 *comma = ' '; 6464 len -= comma - start - 1; 6465 if (len) 6466 { 6467 start = comma + 1; 6468 comma = (char *)memchr (start, ',', len); 6469 } 6470 else 6471 break; 6472 } 6473 while (comma != NULL); 6474 6475 chain = helper_parse_file_list (filelist, style & ~Q_IN_SEP_COMMA, 0); 6476 6477 free (copy); 6478 } 6479 return chain; 6480 } 6481 6482 default: 6483 assert (0); 6484 return NULL; 6485 } 6472 struct nameseq *newp = alloccache_calloc (&nameseq_cache); 6473 #endif 6474 newp->name = xstrndup (cur, curlen); 6475 newp->next = NULL; 6476 *ppnext = newp; 6477 ppnext = &newp->next; 6478 } 6479 if (!glob) 6480 return chain; 6481 return helper_glob_chain (chain); 6482 } 6483 6484 default: 6485 assert (0); 6486 return NULL; 6487 } 6488 } 6486 6489 return NULL; 6487 6490 } 6488 6491 6489 /* $(firstfile file1 file2 ... fileN) - same as $(firstfile ), except for files 6490 rather than word tokens. See func_firstword(). */ 6492 /* $(requote style, file1 file2 ... fileN). */ 6493 6494 static char *func_requote (char *o, char **argv, const char *funcname UNUSED) 6495 { 6496 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6497 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0); 6498 return helper_return_and_free_chain (o, chain, style); 6499 } 6500 6501 6502 /* Common worker for func_firstfile() and func_qfirstfile(). */ 6503 6504 static char *common_firstfile (char *o, char **argv, unsigned int style) 6505 { 6506 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0); 6507 if (chain) 6508 { 6509 o = helper_return_file (o, chain->name, style, 1); 6510 free_ns_chain_no_strcache (chain); 6511 } 6512 return o; 6513 } 6514 6515 /* $(firstfile file1 file2 ... fileN) - same as $(firstfile ), except 6516 for files rather than word tokens. See func_firstword(). */ 6491 6517 6492 6518 static char *func_firstfile (char *o, char **argv, const char *funcname UNUSED) 6493 6519 { 6494 unsigned int const style = helper_file_return_style (argv[1], Q_QDEFAULT); 6495 char *line = argv[0]; 6496 if (line && *line != '\0') 6497 { 6498 struct nameseq *chain = helper_parse_file_list (line, style, 0); 6499 if (chain) 6500 { 6501 o = helper_return_file (o, chain->name, style, 1); 6502 free_ns_chain_no_strcache (chain); 6503 } 6504 } 6505 return o; 6506 } 6507 6508 /* $(lastfile file1 file2 ... fileN) - same as $(lastfile ), except for files 6509 rather than word tokens. See func_lastword(). */ 6520 return common_firstfile(o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE); 6521 } 6522 6523 /* $(qfirstfile style, file1 file2 ... fileN) - same as $(firstfile ), except 6524 for files rather than word tokens. See func_firstword(). */ 6525 6526 static char *func_q_firstfile (char *o, char **argv, const char *funcname UNUSED) 6527 { 6528 unsigned int style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6529 return common_firstfile(o, &argv[1], style); 6530 } 6531 6532 6533 /* Common worker for func_lastfile() and func_q_lastfile(). */ 6534 6535 static char *common_lastfile (char *o, char **argv, unsigned int style) 6536 { 6537 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0); 6538 if (chain) 6539 { 6540 struct nameseq *last = chain; 6541 while (last->next) 6542 last = last->next; 6543 o = helper_return_file (o, last->name, style, 1); 6544 free_ns_chain_no_strcache (chain); 6545 } 6546 return o; 6547 } 6548 6549 /* $(lastfile file1 file2 ... fileN) - same as $(lastfile ), except 6550 for files rather than word tokens. See func_lastword(). */ 6510 6551 6511 6552 static char *func_lastfile (char *o, char **argv, const char *funcname UNUSED) 6512 6553 { 6513 unsigned int const style = helper_file_return_style (argv[1], Q_QDEFAULT); 6514 char *line = argv[0]; 6515 if (line && *line != '\0') 6516 { 6517 struct nameseq *chain = helper_parse_file_list (line, style, 0); 6518 if (chain) 6519 { 6520 struct nameseq *last = chain; 6521 while (last->next) 6522 last = last->next; 6523 o = helper_return_file (o, last->name, style, 1); 6524 free_ns_chain_no_strcache (chain); 6525 } 6526 } 6527 return o; 6528 } 6529 6530 /* $(filelist start, end, file1..fileN [, style]) - same as $(wordlist), 6531 except for files rather than word tokens. See func_wordlist(). */ 6532 6533 static char *func_filelist (char *o, char **argv, const char *funcname UNUSED) 6534 { 6535 unsigned int const style = helper_file_return_style (argv[3], Q_QDEFAULT); 6554 return common_lastfile (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE); 6555 } 6556 6557 /* $(qlastfile style, file1 file2 ... fileN) - same as $(lastfile ), except 6558 for files rather than word tokens. See func_lastword(). */ 6559 6560 static char *func_q_lastfile (char *o, char **argv, const char *funcname UNUSED) 6561 { 6562 unsigned int style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6563 return common_lastfile (o, &argv[1], style); 6564 } 6565 6566 6567 /* Common worker for func_filelist() and func_q_filelist(). */ 6568 6569 static char *common_filelist (char *o, char **argv, unsigned int style) 6570 { 6536 6571 int start; 6537 6572 int count; … … 6572 6607 } 6573 6608 6574 /* $(countfiles file1 file2 ... fileN[,style]) - same as $(words ), except for 6609 /* $(filelist start, end, file1..fileN) - same as $(wordlist), 6610 except for files rather than word tokens. See func_wordlist(). */ 6611 6612 static char *func_filelist (char *o, char **argv, const char *funcname UNUSED) 6613 { 6614 return common_filelist (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE); 6615 } 6616 6617 /* $(qfilelist style, start, end, file1..fileN) - same as $(wordlist), 6618 except for files rather than word tokens. See func_wordlist(). */ 6619 6620 static char *func_q_filelist (char *o, char **argv, const char *funcname UNUSED) 6621 { 6622 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6623 return common_filelist (o, &argv[1], style); 6624 } 6625 6626 6627 /* Common worker for func_countfiles() and func_q_countfiles(). */ 6628 6629 static char *common_countfiles (char *o, char **argv, unsigned int style) 6630 { 6631 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0); 6632 struct nameseq *cur; 6633 unsigned int files = 0; 6634 char retval[32]; 6635 6636 for (cur = chain; cur; cur = cur->next) 6637 files++; 6638 free_ns_chain_no_strcache (chain); 6639 6640 return variable_buffer_output (o, retval, sprintf (retval, "%u", files)); 6641 } 6642 6643 /* $(countfiles file1 file2 ... fileN) - same as $(words ), except for 6575 6644 files rather than word tokens. See func_words(). */ 6576 6645 6577 6646 static char *func_countfiles (char *o, char **argv, const char *funcname UNUSED) 6578 6647 { 6579 unsigned int const style = helper_file_return_style (argv[1], Q_QDEFAULT); /* simpler */ 6580 char retval[32]; 6581 unsigned int files = 0; 6582 char *line = argv[0]; 6583 if (line && *line != '\0') 6584 { 6585 struct nameseq *cur; 6586 struct nameseq *chain = helper_parse_file_list (line, style, 0); 6587 for (cur = chain; cur; cur = cur->next) 6588 files++; 6589 free_ns_chain_no_strcache (chain); 6590 } 6591 6592 return variable_buffer_output (o, retval, sprintf (retval, "%u", files)); 6593 } 6648 return common_countfiles (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE); 6649 } 6650 6651 /* $(qcountfiles style, file1 file2 ... fileN) - same as $(words ), except for 6652 files rather than word tokens and the STYLE argument. See func_words(). */ 6653 6654 static char *func_q_countfiles (char *o, char **argv, const char *funcname UNUSED) 6655 { 6656 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6657 return common_countfiles (o, &argv[1], style); 6658 } 6659 6594 6660 6595 6661 /* Helper that sets the variable value. */ … … 6620 6686 } 6621 6687 6622 /* $(foreachfile var, filelist, body [, style]) - same as $(foreach ), except 6623 for file rather than word tokens and flexible variable value encoding. 6624 See also func_foreach(). */ 6625 6626 static char * 6627 func_foreachfile (char *o, char **argv, const char *funcname UNUSED) 6688 /* Common worker for func_foreachfile and func_qforeachfile. */ 6689 6690 static char * 6691 common_foreachfile (char *o, char **argv, unsigned int style) 6628 6692 { 6629 6693 /* expand only the first two. */ … … 6635 6699 #endif 6636 6700 6637 unsigned int const style = helper_file_return_style (argv[3], Q_QDEFAULT);6638 6701 struct nameseq *chain = helper_parse_file_list (list, style, 0); 6639 6702 struct nameseq *cur; … … 6698 6761 } 6699 6762 6700 /* $(sortfiles file1 ... fileN [,style]) and 6701 $(rsortfiles file1 ... fileN [,style]) - same to $(sort ) and $(rsort ), 6763 /* $(foreachfile var, filelist, body) - same as $(foreach ), except 6764 for file rather than word tokens. 6765 See also func_foreach(). */ 6766 6767 static char * 6768 func_foreachfile (char *o, char **argv, const char *funcname UNUSED) 6769 { 6770 return common_foreachfile (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE); 6771 } 6772 6773 /* $(qforeachfile style, var, filelist, body) - same as $(foreach ), except 6774 for file rather than word tokens and flexible variable value encoding. 6775 See also func_foreach(). */ 6776 6777 static char * 6778 func_q_foreachfile (char *o, char **argv, const char *funcname UNUSED) 6779 { 6780 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6781 return common_foreachfile (o, &argv[1], style); 6782 } 6783 6784 6785 /* Common worker for func_sortfiles() and func_q_sortfiles(). */ 6786 6787 static char *common_sortfiles (char *o, char **argv, unsigned int style, 6788 int ascending) 6789 { 6790 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0); 6791 6792 /* Count the number of files to determin the array size and whether we've 6793 got anything to sort. */ 6794 struct nameseq *cur; 6795 unsigned int num_files = 0; 6796 for (cur = chain; cur; cur = cur->next) 6797 num_files++; 6798 6799 if (num_files <= 1) 6800 o = helper_return_and_free_chain (o, chain, style); 6801 else 6802 { 6803 /* Create array of string pointers from the chain. */ 6804 char **files = (char **)xmalloc (num_files * sizeof (char *)); 6805 unsigned int idx = 0; 6806 for (cur = chain; cur; cur = cur->next) 6807 files[idx++] = (char *)cur->name; 6808 6809 /* Sort it. */ 6810 qsort (files, num_files, sizeof (files[0]), alpha_compare); 6811 6812 /* Output. We skip equal files. */ 6813 if (ascending) 6814 for (idx = 0; idx < num_files; idx++) 6815 { 6816 const char *curfile = files[idx]; 6817 while (idx + 1 < num_files && strcmp(files[idx + 1], curfile) == 0) 6818 idx++; 6819 o = helper_return_file(o, files[idx], style, idx + 1 >= num_files); 6820 } 6821 else 6822 { 6823 idx = num_files; 6824 while (idx-- > 0) 6825 { 6826 const char *curfile = files[idx]; 6827 while (idx > 0 && strcmp(files[idx - 1], curfile) == 0) 6828 idx--; 6829 o = helper_return_file (o, curfile, style, idx == 0); 6830 } 6831 } 6832 6833 free (files); 6834 free_ns_chain_no_strcache (chain); 6835 } 6836 return o; 6837 } 6838 6839 /* $(sortfiles file1 ... fileN) and 6840 $(rsortfiles file1 ... fileN) - same as $(sort ) and $(rsort ), 6702 6841 except for files rather than word tokens. See func_sort(). */ 6703 6842 6704 static char *func_sortfiles (char *o, char **argv, const char *funcname UNUSED) 6705 { 6706 unsigned int const style = helper_file_return_style (argv[1], Q_QDEFAULT); 6707 char *line = argv[0]; 6708 if (line && *line != '\0') 6709 { 6710 unsigned int num_files = 0; 6711 struct nameseq *cur; 6712 struct nameseq *chain = helper_parse_file_list (line, style, 0); 6713 for (cur = chain; cur; cur = cur->next) 6714 num_files++; 6715 if (num_files > 0) 6716 { 6717 char *prev_file; 6718 char **files = (char **)xmalloc (num_files * sizeof (char *)); 6719 unsigned int idx = 0; 6720 for (cur = chain; cur; cur = cur->next) 6721 files[idx++] = (char *)cur->name; 6722 6723 qsort (files, num_files, sizeof (char *), alpha_compare); 6724 6725 prev_file = NULL; 6726 if (funcname[0] == 'r') 6727 { 6728 idx = num_files; 6729 while (idx-- > 0) 6730 if (prev_file == NULL || strcmp (files[idx], prev_file) != 0) 6731 { 6732 prev_file = files[idx]; 6733 o = helper_return_file (o, files[idx], style, idx == 0); 6734 } 6735 } 6736 else 6737 for (idx = 0; idx < num_files; idx++) 6738 if (prev_file == NULL || strcmp (files[idx], prev_file) != 0) 6739 { 6740 prev_file = files[idx]; 6741 o = helper_return_file(o, files[idx], style, 6742 idx + 1 == num_files); 6743 } 6744 6745 free (files); 6746 } 6747 free_ns_chain_no_strcache (chain); 6748 } 6749 6750 return o; 6751 } 6843 static char *func_sortfiles (char *o, char **argv, const char *funcname) 6844 { 6845 return common_sortfiles (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE, 6846 funcname[0] != 'r'); 6847 } 6848 6849 /* $(qsortfiles style, file1 ... fileN) and 6850 $(qrsortfiles style, file1 ... fileN) - same as $(sort ) and $(rsort ), 6851 except for files rather than word tokens and the flexible style. 6852 See func_sort(). */ 6853 6854 static char *func_q_sortfiles (char *o, char **argv, const char *funcname) 6855 { 6856 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6857 return common_sortfiles (o, &argv[1], style, funcname[1] != 'r'); 6858 } 6859 6752 6860 6753 6861 /* Helper for determining whether the given path is absolute or not. */ … … 6819 6927 } 6820 6928 6821 /* $(qabspath file1 file2 ... fileN [, style]) - same to$(abspath ), except6929 /* $(qabspath style, file1 file2 ... fileN) - same as $(abspath ), except 6822 6930 for files rather than word tokens. See func_abspath(). */ 6823 6931 6824 6932 static char *func_q_abspath (char *o, char **argv, const char *funcname UNUSED) 6825 6933 { 6826 return worker_abspath (o, argv[ 0], NULL, 0,6827 helper_file_ return_style (argv[1], Q_QDEFAULT));6934 return worker_abspath (o, argv[1], NULL, 0, 6935 helper_file_quoting_style (argv[0], Q_QDEFAULT)); 6828 6936 } 6829 6937 6830 6938 # ifdef CONFIG_WITH_ABSPATHEX 6831 /* $(qabspathex file1 file2 ... fileN [,cwd [, style]]) - same to$(abspathex ),6939 /* $(qabspathex style, file1 file2 ... fileN [,cwd]) - same as $(abspathex ), 6832 6940 except for files rather than word tokens. See func_abspath_ex(). */ 6833 6941 … … 6835 6943 func_q_abspathex (char *o, char **argv, const char *funcname UNUSED) 6836 6944 { 6837 char *cwd = argv[1];6838 char *style = cwd ? argv[2] : NULL;6839 6840 6945 /* cwd needs leading spaces chopped and may be optional, 6841 6946 in which case we're exactly like $(abspath ). */ 6947 char *cwd = argv[2]; 6842 6948 if (cwd) 6843 6949 { … … 6848 6954 } 6849 6955 6850 return worker_abspath (o, argv[ 0], cwd, cwd ? strlen (cwd) : 0,6851 helper_file_ return_style (style, Q_QDEFAULT));6956 return worker_abspath (o, argv[1], cwd, cwd ? strlen (cwd) : 0, 6957 helper_file_quoting_style (argv[0], Q_QDEFAULT)); 6852 6958 } 6853 6959 # endif 6854 6960 6855 /* $(qaddprefix prefix, file1 ... fileN [, style]) and6856 $(qaddsuffix prefix, file1 ... fileN [, style]) - same to$(addprefix )6961 /* $(qaddprefix style, prefix, file1 ... fileN) and 6962 $(qaddsuffix style, prefix, file1 ... fileN) - same as $(addprefix ) 6857 6963 and $(addsuffix ) except for files rather than word tokens. 6858 6964 The suffix/prefix is unquoted on input and subjected to the same quoting … … 6862 6968 static char *func_q_addsuffix_addprefix (char *o, char **argv, const char *funcname UNUSED) 6863 6969 { 6864 unsigned int const style = helper_file_ return_style (argv[1], Q_QDEFAULT);6865 const char * const fix = argv[ 0];6970 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 6971 const char * const fix = argv[1]; 6866 6972 size_t const fixlen = strlen (fix); 6867 char *line = argv[0];6868 if ( line && *line != '\0')6973 struct nameseq *chain = helper_parse_file_list (argv[2], style, 0); 6974 if (chain) 6869 6975 { 6870 6976 size_t tmpsize = (fixlen + 512) & ~(size_t)63; 6871 6977 char *tmp = (char *)xmalloc (tmpsize); 6872 6978 struct nameseq *cur; 6873 struct nameseq *chain = helper_parse_file_list (line, style, 0);6874 6979 6875 6980 if (funcname[4] == 'p') … … 6913 7018 } 6914 7019 6915 /* $(qbasename path1 .. pathN[, style]) and $(qdir path1 .. pathN[, style])6916 - same to$(basename ) and $(dir ), except for files rather than word tokens.7020 /* $(qbasename style, path1 .. pathN) and $(qdir style, path1 .. pathN) 7021 - same as $(basename ) and $(dir ), except for files rather than word tokens. 6917 7022 See func_basename_dir(). */ 6918 7023 … … 6920 7025 func_q_basename_dir (char *o, char **argv, const char *funcname) 6921 7026 { 6922 unsigned int const style = helper_file_ return_style (argv[1], Q_QDEFAULT_VMS_TRICKS);6923 struct nameseq *chain = helper_parse_file_list (argv[ 0], style, 0);7027 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT_VMS_TRICKS); 7028 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0); 6924 7029 struct nameseq *cur; 6925 7030 … … 6972 7077 } 6973 7078 6974 /* $(qnotdir path1 ... pathN[, style]) - same as $(notdir ), except for7079 /* $(qnotdir style, path1 ... pathN) - same as $(notdir ), except for 6975 7080 files rather than word tokens. See func_notdir_suffix(). */ 6976 7081 … … 6978 7083 func_q_notdir (char *o, char **argv, const char *funcname) 6979 7084 { 6980 unsigned int const style = helper_file_ return_style (argv[1], Q_QDEFAULT_VMS_TRICKS);6981 struct nameseq *chain = helper_parse_file_list (argv[ 0], style, 0);7085 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT_VMS_TRICKS); 7086 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0); 6982 7087 struct nameseq *cur; 6983 7088 int const stop = MAP_DIRSEP; … … 7008 7113 } 7009 7114 7010 /* $(qsuffix path1 ... pathN[, style]) - same as $(suffix ), except for7115 /* $(qsuffix style, path1 ... pathN) - same as $(suffix ), except for 7011 7116 files rather than word tokens. See func_notdir_suffix(). */ 7012 7117 … … 7014 7119 func_q_suffix (char *o, char **argv, const char *funcname) 7015 7120 { 7016 unsigned int const style = helper_file_ return_style (argv[1], Q_QDEFAULT_VMS_TRICKS);7017 struct nameseq *chain = helper_parse_file_list (argv[ 0], style, 0);7121 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT_VMS_TRICKS); 7122 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0); 7018 7123 struct nameseq *prev; 7019 7124 struct nameseq *cur; … … 7053 7158 # ifdef CONFIG_WITH_ROOT_FUNC 7054 7159 /* 7055 $(qroot path...pathN [,style]) - same as $(root ), except files rather7160 $(qroot style, path...pathN) - same as $(root ), except files rather 7056 7161 than space delimited word tokens. See func_root(). 7057 7162 … … 7062 7167 func_q_root (char *o, char **argv, const char *funcname UNUSED) 7063 7168 { 7064 unsigned int const style = helper_file_ return_style (argv[0] ? argv[1] : NULL, Q_QDEFAULT);7065 struct nameseq *chain = helper_parse_file_list (argv[ 0], style, 0);7169 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 7170 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0); 7066 7171 struct nameseq *prev; 7067 7172 struct nameseq *cur; … … 7132 7237 7133 7238 /* 7134 $(qnotroot path1 .. pathN [, style]) - same as $(notroot ), except files7239 $(qnotroot style, path1 .. pathN) - same as $(notroot ), except files 7135 7240 rather than space delimited word tokens. See func_notroot(). 7136 7241 … … 7141 7246 func_q_notroot (char *o, char **argv, const char *funcname UNUSED) 7142 7247 { 7143 unsigned int const style = helper_file_ return_style (argv[0] ? argv[1] : NULL, Q_QDEFAULT);7144 struct nameseq *chain = helper_parse_file_list (argv[ 0], style, 0);7248 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 7249 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0); 7145 7250 struct nameseq *cur; 7146 7251 … … 7196 7301 # endif 7197 7302 7198 /* $(qrealpath path1 .. pathN [, style]) - same as $(realpath ), except files7303 /* $(qrealpath style, path1 .. pathN) - same as $(realpath ), except files 7199 7304 rather than space delimited word tokens. See func_realpath(). */ 7200 7305 … … 7203 7308 { 7204 7309 PATH_VAR (outbuf); 7205 unsigned int const style = helper_file_ return_style (argv[1], Q_QDEFAULT);7206 struct nameseq *chain = helper_parse_file_list (argv[ 0], style, 0);7310 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 7311 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0); 7207 7312 7208 7313 /* Pass one: Do the realpath/abspath thing and remove anything that fails … … 7247 7352 func_q_wildcard (char *o, char **argv, const char *funcname UNUSED) 7248 7353 { 7249 unsigned int const style = helper_file_ return_style (argv[1], Q_QDEFAULT);7250 struct nameseq *chain = helper_parse_file_list (argv[ 0], style, 1 /*glob*/);7354 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT); 7355 struct nameseq *chain = helper_parse_file_list (argv[1], style, 1 /*glob*/); 7251 7356 #ifdef _AMIGA 7252 7357 OS (fatal, NILF, _("$(%s ) is not implemented on this platform"), funcname); … … 7460 7565 FT_ENTRY ("quote-sh-dq", 1, 1, 1, func_quote_shell_dq), 7461 7566 FT_ENTRY ("quote-sh-sq", 1, 1, 1, func_quote_shell_sq), 7567 FT_ENTRY ("requote", 1, 0, 1, func_requote), 7462 7568 /* Quoted input and maybe output variants of functions typically 7463 7569 working with files: */ 7464 FT_ENTRY ("firstfile", 0, 1+1, 1,func_firstfile),7465 FT_ENTRY ("lastfile", 0, 1+1, 1,func_lastfile),7466 FT_ENTRY ("filelist", 3, 3+1, 1,func_filelist),7467 FT_ENTRY ("countfiles", 0, 1+1, 1,func_countfiles),7468 FT_ENTRY ("foreachfile", 3, 3+1, 0,func_foreachfile),7469 FT_ENTRY ("sortfiles", 0, 1+1, 1,func_sortfiles),7570 FT_ENTRY ("firstfile", 0, 1, 1, func_firstfile), 7571 FT_ENTRY ("lastfile", 0, 1, 1, func_lastfile), 7572 FT_ENTRY ("filelist", 3, 3, 1, func_filelist), 7573 FT_ENTRY ("countfiles", 0, 1, 1, func_countfiles), 7574 FT_ENTRY ("foreachfile", 3, 3, 0, func_foreachfile), 7575 FT_ENTRY ("sortfiles", 0, 1, 1, func_sortfiles), 7470 7576 # ifdef CONFIG_WITH_RSORT 7471 FT_ENTRY ("rsortfiles", 0, 1+1, 1,func_sortfiles),7577 FT_ENTRY ("rsortfiles", 0, 1, 1, func_sortfiles), 7472 7578 # endif 7473 FT_ENTRY ("qabspath", 0, 1+1, 1, func_q_abspath), 7474 FT_ENTRY ("qaddprefix", 2, 2+1, 1, func_q_addsuffix_addprefix), 7475 FT_ENTRY ("qaddsuffix", 2, 2+1, 1, func_q_addsuffix_addprefix), 7476 FT_ENTRY ("qbasename", 0, 1+1, 1, func_q_basename_dir), 7477 FT_ENTRY ("qdir", 0, 1+1, 1, func_q_basename_dir), 7478 FT_ENTRY ("qnotdir", 0, 1+1, 1, func_q_notdir), 7479 ///@todo # ifdef CONFIG_WITH_ROOT_FUNC 7480 ///@todo FT_ENTRY ("qroot", 0, 1+1, 1, func_q_root), 7481 ///@todo FT_ENTRY ("qnotroot", 0, 1+1, 1, func_q_notroot), 7482 ///@todo # endif 7483 FT_ENTRY ("qsuffix", 0, 1+1, 1, func_q_suffix), 7484 FT_ENTRY ("qrealpath", 0, 1+1, 1, func_q_realpath), 7579 /* Function variants with preceding style argument and quoting by default. */ 7580 FT_ENTRY ("qfirstfile", 1+0, 1+1, 1, func_q_firstfile), 7581 FT_ENTRY ("qlastfile", 1+0, 1+1, 1, func_q_lastfile), 7582 FT_ENTRY ("qfilelist", 1+3, 1+3, 1, func_q_filelist), 7583 FT_ENTRY ("qcountfiles", 1+0, 1+1, 1, func_q_countfiles), 7584 FT_ENTRY ("qforeachfile", 1+3, 1+3, 0, func_q_foreachfile), 7585 FT_ENTRY ("qsortfiles", 1+0, 1+1, 1, func_q_sortfiles), 7586 # ifdef CONFIG_WITH_RSORT 7587 FT_ENTRY ("qrsortfiles", 1+0, 1+1, 1, func_q_sortfiles), 7588 # endif 7589 FT_ENTRY ("qabspath", 1+0, 1+1, 1, func_q_abspath), 7590 FT_ENTRY ("qaddprefix", 1+2, 1+2, 1, func_q_addsuffix_addprefix), 7591 FT_ENTRY ("qaddsuffix", 1+2, 1+2, 1, func_q_addsuffix_addprefix), 7592 FT_ENTRY ("qbasename", 1+0, 1+1, 1, func_q_basename_dir), 7593 FT_ENTRY ("qdir", 1+0, 1+1, 1, func_q_basename_dir), 7594 FT_ENTRY ("qnotdir", 1+0, 1+1, 1, func_q_notdir), 7595 # ifdef CONFIG_WITH_ROOT_FUNC 7596 FT_ENTRY ("qroot", 1+0, 1+1, 1, func_q_root), 7597 FT_ENTRY ("qnotroot", 1+0, 1+1, 1, func_q_notroot), 7598 # endif 7599 FT_ENTRY ("qsuffix", 1+0, 1+1, 1, func_q_suffix), 7600 FT_ENTRY ("qrealpath", 1+0, 1+1, 1, func_q_realpath), 7485 7601 # ifdef CONFIG_WITH_ABSPATHEX 7486 FT_ENTRY ("qabspathex", 0, 2+1, 1,func_q_abspathex),7602 FT_ENTRY ("qabspathex", 1+0, 1+2, 1, func_q_abspathex), 7487 7603 # endif 7488 FT_ENTRY ("qwildcard", 0, 1+1, 1, func_q_wildcard), 7604 FT_ENTRY ("qwildcard", 1+0, 1+1, 1, func_q_wildcard), 7605 /** @todo XXX: Add more qxxxx variants. */ 7489 7606 #endif 7490 7607 };
Note:
See TracChangeset
for help on using the changeset viewer.