VirtualBox

Changeset 821 in kBuild for trunk/src/gmake


Ignore:
Timestamp:
Feb 1, 2007 5:45:25 AM (18 years ago)
Author:
bird
Message:

New function: $(xargs)

Location:
trunk/src/gmake
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gmake/Makefile.kmk

    r809 r821  
    103103        CONFIG_WITH_STACK \
    104104        CONFIG_WITH_MATH \
     105        CONFIG_WITH_XARGS \
    105106        CONFIG_PRETTY_COMMAND_PRINTING \
    106107        \
  • trunk/src/gmake/function.c

    r763 r821  
    3838#ifdef KMK_HELPERS
    3939# include "kbuild.h"
     40#endif
     41#ifdef CONFIG_WITH_XARGS /* bird */
     42# ifdef HAVE_LIMITS_H
     43#  include <limits.h>
     44# endif
    4045#endif
    4146
     
    21802185
    21812186 return o;
     2187}
     2188#endif
     2189
     2190#ifdef CONFIG_WITH_XARGS
     2191/* Create one or more command lines avoiding the max argument
     2192   lenght restriction of the host OS.
     2193
     2194   The last argument is the list of arguments that the normal
     2195   xargs command would be fed from stdin.
     2196
     2197   The first argument is initial command and it's arguments.
     2198
     2199   If there are three or more arguments, the 2nd argument is
     2200   the command and arguments to be used on subsequent
     2201   command lines. Defaults to the initial command.
     2202
     2203   If there are four or more arguments, the 3rd argument is
     2204   the command to be used at the final command line. Defaults
     2205   to the sub sequent or initial command .
     2206
     2207   A future version of this function may define more arguments
     2208   and therefor anyone specifying six or more arguments will
     2209   cause fatal errors.
     2210
     2211   Typical usage is:
     2212        $(xargs ar cas mylib.a,$(objects))
     2213   or
     2214        $(xargs ar cas mylib.a,ar as mylib.a,$(objects))
     2215
     2216   It will then create one or more "ar mylib.a ..." command
     2217   lines with proper \n\t separation so it can be used when
     2218   writing rules. */
     2219static char *
     2220func_xargs (char *o, char **argv, const char *funcname)
     2221{
     2222  int argc;
     2223  const char *initial_cmd;
     2224  size_t initial_cmd_len;
     2225  const char *subsequent_cmd;
     2226  size_t subsequent_cmd_len;
     2227  const char *final_cmd;
     2228  size_t final_cmd_len;
     2229  const char *args;
     2230  size_t max_args;
     2231  int i;
     2232
     2233#ifdef ARG_MAX
     2234  /* ARG_MAX is a bit unreliable (environment), so drop 25% of the max. */
     2235# define XARGS_MAX  (ARG_MAX - (ARG_MAX / 4))
     2236#else /* FIXME: update configure with a command line length test. */
     2237# define XARGS_MAX  10240
     2238#endif
     2239
     2240  argc = 0;
     2241  while (argv[argc])
     2242    argc++;
     2243  if (argc > 4)
     2244    fatal (NILF, _("Too many arguments for $(xargs)!\n"));
     2245
     2246  /* first: the initial / default command.*/
     2247  initial_cmd = argv[0];
     2248  while (isspace ((unsigned char)*initial_cmd))
     2249    initial_cmd++;
     2250  max_args = initial_cmd_len = strlen (initial_cmd);
     2251
     2252  /* second: the command for the subsequent command lines. defaults to the initial cmd. */
     2253  subsequent_cmd = argc > 2 && argv[1][0] != '\0' ? argv[1] : "";
     2254  while (isspace ((unsigned char)*subsequent_cmd))
     2255    subsequent_cmd++;
     2256  if (*subsequent_cmd)
     2257    {
     2258      subsequent_cmd_len = strlen (subsequent_cmd);
     2259      if (subsequent_cmd_len > max_args)
     2260        max_args = subsequent_cmd_len;
     2261    }
     2262  else
     2263    {
     2264      subsequent_cmd = initial_cmd;
     2265      subsequent_cmd_len = initial_cmd_len;
     2266    }
     2267
     2268  /* third: the final command. defaults to the subseq cmd. */
     2269  final_cmd = argc > 3 && argv[2][0] != '\0' ? argv[2] : "";
     2270  while (isspace ((unsigned char)*final_cmd))
     2271    final_cmd++;
     2272  if (*final_cmd)
     2273    {
     2274      final_cmd_len = strlen (final_cmd);
     2275      if (final_cmd_len > max_args)
     2276        max_args = final_cmd_len;
     2277    }
     2278  else
     2279    {
     2280      final_cmd = subsequent_cmd;
     2281      final_cmd_len = subsequent_cmd_len;
     2282    }
     2283
     2284  /* last: the arguments to split up into sensible portions. */
     2285  args = argv[argc - 1];
     2286
     2287  /* calc the max argument length. */
     2288  if (XARGS_MAX <= max_args + 2)
     2289    fatal (NILF, _("$(xargs): the commands are longer than the max exec argument length. (%lu <= %lu)\n"),
     2290           (unsigned long)XARGS_MAX, (unsigned long)max_args + 2);
     2291  max_args = XARGS_MAX - max_args - 1;
     2292
     2293  /* generate the commands. */
     2294  i = 0;
     2295  for (i = 0; ; i++)
     2296    {
     2297      unsigned int len;
     2298      char *iterator = (char *)args;
     2299      const char *end = args;
     2300      const char *cur;
     2301      const char *tmp;
     2302
     2303      /* scan the arguments till we reach the end or the max length. */
     2304      while ((cur = find_next_token(&iterator, &len))
     2305          && (size_t)((cur + len) - args) < max_args)
     2306        end = cur + len;
     2307      if (cur && end == args)
     2308        fatal (NILF, _("$(xargs): command + one single arg is too much. giving up.\n"));
     2309
     2310      /* emit the command. */
     2311      if (i == 0)
     2312        {
     2313          o = variable_buffer_output (o, (char *)initial_cmd, initial_cmd_len);
     2314          o = variable_buffer_output (o, " ", 1);
     2315        }
     2316      else if (cur)
     2317        {
     2318          o = variable_buffer_output (o, "\n\t", 2);
     2319          o = variable_buffer_output (o, (char *)subsequent_cmd, subsequent_cmd_len);
     2320          o = variable_buffer_output (o, " ", 1);
     2321        }
     2322      else
     2323        {
     2324          o = variable_buffer_output (o, "\n\t", 2);
     2325          o = variable_buffer_output (o, (char *)final_cmd, final_cmd_len);
     2326          o = variable_buffer_output (o, " ", 1);
     2327        }
     2328
     2329      tmp = end;
     2330      while (tmp > args && isspace ((unsigned char)tmp[-1])) /* drop trailing spaces. */
     2331        tmp--;
     2332      o = variable_buffer_output (o, (char *)args, tmp - args);
     2333
     2334
     2335      /* next */
     2336      if (!cur)
     2337        break;
     2338      args = end;
     2339      while (isspace ((unsigned char)*args))
     2340        args++;
     2341    }
     2342
     2343  return o;
    21822344}
    21832345#endif
     
    28733035  { STRING_SIZE_TUPLE("abspathex"),     0,  2,  1,  func_abspathex},
    28743036#endif
     3037#ifdef CONFIG_WITH_XARGS
     3038  { STRING_SIZE_TUPLE("xargs"),         2,  0,  1,  func_xargs},
     3039#endif
    28753040#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
    28763041  { STRING_SIZE_TUPLE("comp-vars"),     3,  3,  1,  func_comp_vars},
  • trunk/src/gmake/variable.c

    r767 r821  
    10401040  && defined(CONFIG_WITH_STACK) \
    10411041  && defined(CONFIG_WITH_MATH) \
     1042  && defined(CONFIG_WITH_XARGS) \
    10421043  && defined(KMK_HELPERS)
    10431044  (void) define_variable ("KMK_FEATURES", 12,
     
    10461047                          " toupper tolower"
    10471048                          " comp-vars comp-cmds"
    1048                           " stack "
    1049                           " math-int "
     1049                          " stack"
     1050                          " math-int"
     1051                          " xargs"
    10501052                          " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one "
    10511053                          , o_default, 0);
     
    10661068#  if defined(CONFIG_WITH_MATH)
    10671069  strcat(buf, " math-int");
     1070#  endif
     1071#  if defined(CONFIG_WITH_XARGS)
     1072  strcat(buf, " xargs");
    10681073#  endif
    10691074#  ifdef KMK_HELPERS
Note: See TracChangeset for help on using the changeset viewer.

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