prepargs.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* Parse arguments from a string and prepend them to an argv.
  2. Copyright 1999-2001, 2007, 2013 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 <eggert@twinsun.com>. */
  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. /* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
  25. as an argument to <ctype.h> macros like "isspace". */
  26. #ifdef STDC_HEADERS
  27. # define IN_CTYPE_DOMAIN(c) 1
  28. #else
  29. # define IN_CTYPE_DOMAIN(c) ((c) <= 0177)
  30. #endif
  31. #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
  32. /* Find the white-space-separated options specified by OPTIONS, and
  33. using BUF to store copies of these options, set ARGV[0], ARGV[1],
  34. etc. to the option copies. Return the number N of options found.
  35. Do not set ARGV[N]. If ARGV is null, do not store ARGV[0]
  36. etc. Backslash can be used to escape whitespace (and backslashes). */
  37. static int
  38. prepend_args (char const *options, char *buf, char **argv)
  39. {
  40. char const *o = options;
  41. char *b = buf;
  42. int n = 0;
  43. for (;;)
  44. {
  45. while (ISSPACE ((unsigned char) *o))
  46. o++;
  47. if (!*o)
  48. return n;
  49. if (argv)
  50. argv[n] = b;
  51. n++;
  52. do
  53. if ((*b++ = *o++) == '\\' && *o)
  54. b[-1] = *o++;
  55. while (*o && ! ISSPACE ((unsigned char) *o));
  56. *b++ = '\0';
  57. }
  58. }
  59. /* Prepend the whitespace-separated options in OPTIONS to the argument
  60. vector of a main program with argument count *PARGC and argument
  61. vector *PARGV. */
  62. void
  63. prepend_default_options (char const *options, int *pargc, char ***pargv)
  64. {
  65. if (options)
  66. {
  67. char *buf = xmalloc (strlen (options) + 1);
  68. int prepended = prepend_args (options, buf, (char **) 0);
  69. int argc = *pargc;
  70. char * const *argv = *pargv;
  71. char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
  72. *pargc = prepended + argc;
  73. *pargv = pp;
  74. *pp++ = *argv++;
  75. pp += prepend_args (options, buf, pp);
  76. while ((*pp++ = *argv++))
  77. continue;
  78. }
  79. }