VirtualBox

Changeset 3321 in kBuild


Ignore:
Timestamp:
Apr 16, 2020 10:21:15 PM (5 years ago)
Author:
bird
Message:

kmk: Revised the *files* function to not take a quoting style argument and added 'q' variants that does. Some fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/function.c

    r3319 r3321  
    36383638    }
    36393639
    3640   /* Note that negative start is and length are used for referencing from the
     3640  /* Note that negative start and length are used for referencing from the
    36413641     end of the string. */
    36423642  if (pad == NULL)
     
    58015801/* Helper for performer GNU make style quoting of one filename. */
    58025802
    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
     5803static char *
     5804helper_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
    58085809                           | MAP_NEWLINE
    58095810                           | MAP_COMMENT
     
    58145815                              is_tgt ? MAP_COLON : 0);
    58155816  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];
    58185821      unsigned long len_out = 0;
    58195822      const char *prev = cur;
    5820       for (;;)
     5823      do
    58215824        {
    58225825          char ch = *cur;
     
    58335836                }
    58345837
    5835               if (flags & MAP_NUL)
    5836                 break;
    5837 
    58385838              /* Dollar is quoted by duplicating the dollar: */
    58395839              if (flags & MAP_VARIABLE)
    58405840                {
     5841                  o = variable_buffer_output (o, "$", 1);
    58415842                  prev = cur++;
    5842                   o = variable_buffer_output (o, "$", 1);
    58435843                }
    58445844              /* The rest is quoted by '\': */
     
    58595859            }
    58605860        }
     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        }
    58615869
    58625870      /* Escape trailing slashes when needed. */
     
    59415949          /* Output the quoted argument: */
    59425950          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,
    59445952                                   quote_trailing_slashes, funcname);
    59455953          else
     
    59485956              int qts = end != arg && end[-1] == '\\'
    59495957                     && 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);
    59515960            }
    59525961        }
     
    61226131}
    61236132
    6124 
     6133/* Decoded style options for the $(q* ) and $(*file* ) functions. */
    61256134#define Q_RET_MASK              0x000f
    6126 #define Q_RET_UNQUOTED          0x0000
    6127 #define Q_RET_QUOTED            0x0001
    6128 #define Q_RET_QUOTED_DEP        0x0002
    6129 #define Q_RET_QUOTED_DEP_END    0x0003
    6130 #define Q_RET_QUOTED_TGT        0x0004
    6131 #define Q_RET_QUOTED_TGT_END    0x0005
     6135#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
    61326141#define Q_RET_SHELL             0x0006
    61336142#define Q_RET_SHELL_IN_DQ       0x0007
     
    61496158#define Q_SEP_COMMA             0x0400  /* for VMS, output only */
    61506159
    6151 #define Q_QDEFAULT              0x0000
     6160#define Q_QDEFAULT              (Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE)
    61526161#ifndef VMS
    61536162# define Q_QDEFAULT_VMS_TRICKS  Q_QDEFAULT
     
    61626171   style, but can also pick the input and space styles (just because we can).  */
    61636172
    6164 static unsigned int helper_file_return_style (char *style, unsigned int intstyle)
     6173static unsigned int helper_file_quoting_style (char *style, unsigned int intstyle)
    61656174{
    61666175  if (style != NULL)
     
    62726281                                     unsigned int style, int is_last)
    62736282{
    6274   assert (file[len] == '\0');
     6283  assert (memchr (file, '\0', len) == NULL);
    62756284  switch (style & Q_RET_MASK)
    62766285    {
     
    62796288        break;
    62806289      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*/,
    62826291                               !is_last /*quote_trailing_slashes*/, NULL);
    62836292        break;
    62846293      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*/,
    62866295                               !is_last /*quote_trailing_slashes*/, NULL);
    62876296        break;
    62886297      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*/,
    62906299                               0 /*quote_trailing_slashes*/, NULL);
    62916300        break;
    62926301      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*/,
    62946303                               !is_last /*quote_trailing_slashes*/, NULL);
    62956304        break;
    62966305      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*/,
    62986307                               0 /*quote_trailing_slashes*/, NULL);
    62996308        break;
     
    64016410}
    64026411
    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. */
    64046420
    64056421static struct nameseq *
     
    64076423{
    64086424  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               {
    64286469#ifndef CONFIG_WITH_ALLOC_CACHES
    6429                 struct nameseq *newp = xcalloc (sizeof (*newp));
     6470                  struct nameseq *newp = xcalloc (sizeof (*newp));
    64306471#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    }
    64866489  return NULL;
    64876490}
    64886491
    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
     6494static 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
     6504static 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().  */
    64916517
    64926518static char *func_firstfile (char *o, char **argv, const char *funcname UNUSED)
    64936519{
    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
     6526static 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
     6535static 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(). */
    65106551
    65116552static char *func_lastfile (char *o, char **argv, const char *funcname UNUSED)
    65126553{
    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
     6560static 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
     6569static char *common_filelist (char *o, char **argv, unsigned int style)
     6570{
    65366571  int start;
    65376572  int count;
     
    65726607}
    65736608
    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
     6612static 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
     6620static 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
     6629static 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
    65756644   files rather than word tokens.  See func_words(). */
    65766645
    65776646static char *func_countfiles (char *o, char **argv, const char *funcname UNUSED)
    65786647{
    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
     6654static 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
    65946660
    65956661/* Helper that sets the variable value. */
     
    66206686}
    66216687
    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
     6690static char *
     6691common_foreachfile (char *o, char **argv, unsigned int style)
    66286692{
    66296693  /* expand only the first two.  */
     
    66356699#endif
    66366700
    6637   unsigned int const style = helper_file_return_style (argv[3], Q_QDEFAULT);
    66386701  struct nameseq *chain = helper_parse_file_list (list, style, 0);
    66396702  struct nameseq *cur;
     
    66986761}
    66996762
    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
     6767static char *
     6768func_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
     6777static char *
     6778func_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
     6787static 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 ),
    67026841   except for files rather than word tokens.  See func_sort(). */
    67036842
    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 }
     6843static 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
     6854static 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
    67526860
    67536861/* Helper for determining whether the given path is absolute or not. */
     
    68196927}
    68206928
    6821 /* $(qabspath file1 file2 ... fileN [, style]) - same to $(abspath ), except
     6929/* $(qabspath style, file1 file2 ... fileN) - same as $(abspath ), except
    68226930   for files rather than word tokens.  See func_abspath(). */
    68236931
    68246932static char *func_q_abspath (char *o, char **argv, const char *funcname UNUSED)
    68256933{
    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));
    68286936}
    68296937
    68306938# ifdef CONFIG_WITH_ABSPATHEX
    6831 /* $(qabspathex file1 file2 ... fileN [,cwd [, style]]) - same to $(abspathex ),
     6939/* $(qabspathex style, file1 file2 ... fileN [,cwd]) - same as $(abspathex ),
    68326940   except for files rather than word tokens.  See func_abspath_ex(). */
    68336941
     
    68356943func_q_abspathex (char *o, char **argv, const char *funcname UNUSED)
    68366944{
    6837   char *cwd = argv[1];
    6838   char *style = cwd ? argv[2] : NULL;
    6839 
    68406945  /* cwd needs leading spaces chopped and may be optional,
    68416946     in which case we're exactly like $(abspath ). */
     6947  char *cwd = argv[2];
    68426948  if (cwd)
    68436949    {
     
    68486954    }
    68496955
    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));
    68526958}
    68536959# endif
    68546960
    6855 /* $(qaddprefix prefix, file1 ... fileN [, style]) and
    6856    $(qaddsuffix prefix, file1 ... fileN [, style]) - same to $(addprefix )
     6961/* $(qaddprefix style, prefix, file1 ... fileN) and
     6962   $(qaddsuffix style, prefix, file1 ... fileN) - same as $(addprefix )
    68576963   and $(addsuffix ) except for files rather than word tokens.
    68586964   The suffix/prefix is unquoted on input and subjected to the same quoting
     
    68626968static char *func_q_addsuffix_addprefix (char *o, char **argv, const char *funcname UNUSED)
    68636969{
    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];
    68666972  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)
    68696975    {
    68706976      size_t tmpsize = (fixlen + 512) & ~(size_t)63;
    68716977      char *tmp = (char *)xmalloc (tmpsize);
    68726978      struct nameseq *cur;
    6873       struct nameseq *chain = helper_parse_file_list (line, style, 0);
    68746979
    68756980      if (funcname[4] == 'p')
     
    69137018}
    69147019
    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.
    69177022   See func_basename_dir(). */
    69187023
     
    69207025func_q_basename_dir (char *o, char **argv, const char *funcname)
    69217026{
    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);
    69247029  struct nameseq *cur;
    69257030
     
    69727077}
    69737078
    6974 /* $(qnotdir path1 ... pathN[, style]) - same as $(notdir ), except for
     7079/* $(qnotdir style, path1 ... pathN) - same as $(notdir ), except for
    69757080   files rather than word tokens.  See func_notdir_suffix(). */
    69767081
     
    69787083func_q_notdir (char *o, char **argv, const char *funcname)
    69797084{
    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);
    69827087  struct nameseq *cur;
    69837088  int const stop = MAP_DIRSEP;
     
    70087113}
    70097114
    7010 /* $(qsuffix path1 ... pathN[, style]) - same as $(suffix ), except for
     7115/* $(qsuffix style, path1 ... pathN) - same as $(suffix ), except for
    70117116   files rather than word tokens.  See func_notdir_suffix(). */
    70127117
     
    70147119func_q_suffix (char *o, char **argv, const char *funcname)
    70157120{
    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);
    70187123  struct nameseq *prev;
    70197124  struct nameseq *cur;
     
    70537158# ifdef CONFIG_WITH_ROOT_FUNC
    70547159/*
    7055  $(qroot path...pathN [,style]) - same as $(root ), except files rather
     7160 $(qroot style, path...pathN) - same as $(root ), except files rather
    70567161 than space delimited word tokens.  See func_root().
    70577162
     
    70627167func_q_root (char *o, char **argv, const char *funcname UNUSED)
    70637168{
    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);
    70667171  struct nameseq *prev;
    70677172  struct nameseq *cur;
     
    71327237
    71337238/*
    7134  $(qnotroot path1 .. pathN [, style]) - same as $(notroot ), except files
     7239 $(qnotroot style, path1 .. pathN) - same as $(notroot ), except files
    71357240 rather than space delimited word tokens.  See func_notroot().
    71367241
     
    71417246func_q_notroot (char *o, char **argv, const char *funcname UNUSED)
    71427247{
    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);
    71457250  struct nameseq *cur;
    71467251
     
    71967301# endif
    71977302
    7198 /* $(qrealpath path1 .. pathN [, style]) - same as $(realpath ), except files
     7303/* $(qrealpath style, path1 .. pathN) - same as $(realpath ), except files
    71997304 rather than space delimited word tokens.  See func_realpath(). */
    72007305
     
    72037308{
    72047309  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);
    72077312
    72087313  /* Pass one: Do the realpath/abspath thing and remove anything that fails
     
    72477352func_q_wildcard (char *o, char **argv, const char *funcname UNUSED)
    72487353{
    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*/);
    72517356#ifdef _AMIGA
    72527357  OS (fatal, NILF, _("$(%s ) is not implemented on this platform"), funcname);
     
    74607565  FT_ENTRY ("quote-sh-dq",   1,  1,  1,  func_quote_shell_dq),
    74617566  FT_ENTRY ("quote-sh-sq",   1,  1,  1,  func_quote_shell_sq),
     7567  FT_ENTRY ("requote",       1,  0,  1,  func_requote),
    74627568  /* Quoted input and maybe output variants of functions typically
    74637569     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),
    74707576# ifdef CONFIG_WITH_RSORT
    7471   FT_ENTRY ("rsortfiles",    0, 1+1, 1, func_sortfiles),
     7577  FT_ENTRY ("rsortfiles",    0,  1, 1, func_sortfiles),
    74727578# 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),
    74857601# 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),
    74877603# 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. */
    74897606#endif
    74907607};
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette