prepargs.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* Parse arguments from a string and prepend them to an argv.
  2. Copyright 1999-2001, 2007, 2013-2014 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /* Written by Paul Eggert <[email protected]>. */
  14. #ifdef HAVE_CONFIG_H
  15. # include <config.h>
  16. #endif
  17. #include "prepargs.h"
  18. #include <sys/types.h>
  19. #include <xalloc.h>
  20. #if HAVE_STRING_H
  21. # include <string.h>
  22. #endif
  23. #include <ctype.h>
  24. /* Find the white-space-separated options specified by OPTIONS, and
  25. using BUF to store copies of these options, set ARGV[0], ARGV[1],
  26. etc. to the option copies. Return the number N of options found.
  27. Do not set ARGV[N]. If ARGV is null, do not store ARGV[0]
  28. etc. Backslash can be used to escape whitespace (and backslashes). */
  29. static int
  30. prepend_args (char const *options, char *buf, char **argv)
  31. {
  32. char const *o = options;
  33. char *b = buf;
  34. int n = 0;
  35. for (;;)
  36. {
  37. while (isspace ((unsigned char) *o))
  38. o++;
  39. if (!*o)
  40. return n;
  41. if (argv)
  42. argv[n] = b;
  43. n++;
  44. do
  45. if ((*b++ = *o++) == '\\' && *o)
  46. b[-1] = *o++;
  47. while (*o && ! isspace ((unsigned char) *o));
  48. *b++ = '\0';
  49. }
  50. }
  51. /* Prepend the whitespace-separated options in OPTIONS to the argument
  52. vector of a main program with argument count *PARGC and argument
  53. vector *PARGV. */
  54. void
  55. prepend_default_options (char const *options, int *pargc, char ***pargv)
  56. {
  57. if (options)
  58. {
  59. char *buf = xmalloc (strlen (options) + 1);
  60. int prepended = prepend_args (options, buf, (char **) 0);
  61. int argc = *pargc;
  62. char * const *argv = *pargv;
  63. char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
  64. *pargc = prepended + argc;
  65. *pargv = pp;
  66. *pp++ = *argv++;
  67. pp += prepend_args (options, buf, pp);
  68. while ((*pp++ = *argv++))
  69. continue;
  70. }
  71. }