prepargs.c 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* Parse arguments from a string and prepend them to an argv.
  2. Copyright 1999, 2000 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 2, 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, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  14. 02111-1307, USA. */
  15. /* Written by Paul Eggert <[email protected]>. */
  16. #ifdef HAVE_CONFIG_H
  17. # include <config.h>
  18. #endif
  19. #include "prepargs.h"
  20. #include <sys/types.h>
  21. #include <xalloc.h>
  22. #include <ctype.h>
  23. /* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
  24. as an argument to <ctype.h> macros like "isspace". */
  25. #ifdef STDC_HEADERS
  26. # define IN_CTYPE_DOMAIN(c) 1
  27. #else
  28. # define IN_CTYPE_DOMAIN(c) ((c) <= 0177)
  29. #endif
  30. #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
  31. /* Find the white-space-separated options specified by OPTIONS, and
  32. using BUF to store copies of these options, set ARGV[0], ARGV[1],
  33. etc. to the option copies. Return the number N of options found.
  34. Do not set ARGV[N]. If ARGV is null, do not store ARGV[0]
  35. etc. Backslash can be used to escape whitespace (and backslashes). */
  36. static int
  37. prepend_args (char const *options, char *buf, char **argv)
  38. {
  39. char const *o = options;
  40. char *b = buf;
  41. int n = 0;
  42. for (;;)
  43. {
  44. while (ISSPACE ((unsigned char) *o))
  45. o++;
  46. if (!*o)
  47. return n;
  48. if (argv)
  49. argv[n] = b;
  50. n++;
  51. do
  52. if ((*b++ = *o++) == '\\' && *o)
  53. b[-1] = *o++;
  54. while (*o && ! ISSPACE ((unsigned char) *o));
  55. *b++ = '\0';
  56. }
  57. }
  58. /* Prepend the whitespace-separated options in OPTIONS to the argument
  59. vector of a main program with argument count *PARGC and argument
  60. vector *PARGV. */
  61. void
  62. prepend_default_options (char const *options, int *pargc, char ***pargv)
  63. {
  64. if (options)
  65. {
  66. char *buf = xmalloc (strlen (options) + 1);
  67. int prepended = prepend_args (options, buf, (char **) 0);
  68. int argc = *pargc;
  69. char * const *argv = *pargv;
  70. char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
  71. *pargc = prepended + argc;
  72. *pargv = pp;
  73. *pp++ = *argv++;
  74. pp += prepend_args (options, buf, pp);
  75. while ((*pp++ = *argv++))
  76. continue;
  77. }
  78. }