4 * A special function which "fixes" an argv array by replacing arguments
5 * that need quoting with quoted versions.
7 * NOTE: In order to be reasonably consistent there is some misuse of the
8 * const keyword here-- which leads to compilation warnings. These
9 * should be ok to ignore.
11 * This is a sample distributed as part of the Mingw32 package.
14 * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
16 * THIS SOFTWARE IS NOT COPYRIGHTED
18 * This source code is offered for use in the public domain. You may
19 * use, modify or distribute it freely.
21 * This code is distributed in the hope that it will be useful but
22 * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
23 * DISCLAMED. This includes but is not limited to warrenties of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
36 * This takes a single string and fixes it, enclosing it in quotes if it
37 * contains any spaces and/or escaping the quotes it contains.
40 fix_arg (const char* szArg)
42 int nQuoteAll; /* Does the whole arg need quoting? */
43 int nBkSlRun; /* How may backslashes in a row? */
53 /* First we figure out how much bigger the new string has to be
54 * than the old one. */
58 * Arguments containing whitespace of wildcards will be
59 * quoted to preserve tokenization and/or those special
60 * characters (i.e. wildcarding will NOT be done at the
61 * other end-- they will get the * and ? characters as is).
62 * TODO: Is this the best way? Do we want to enable wildcards?
66 (*sz == ' ' || *sz == '\t' || *sz == '*' || *sz == '?'))
78 sizeLen += nBkSlRun + 1;
93 * Make a new string big enough.
95 szNew = (char*) malloc (sizeLen);
102 /* First enclosing quote for fully quoted args. */
110 * Go through the string putting backslashes in front of quotes,
111 * and doubling all backslashes immediately in front of quotes.
114 while (*szArg != '\0')
141 /* Closing quote for fully quoted args. */
153 * Takes argc and argv and returns a new argv with escaped members. Pass
154 * this fixed argv (along with the old one) to free_fixed_argv after
155 * you finish with it. Pass in an argc of -1 and make sure the argv vector
156 * ends with a null pointer to have fix_argv count the arguments for you.
159 fix_argv (int argc, char* const* szaArgv)
171 * Count the arguments if asked.
175 for (i = 0; szaArgv[i]; i++)
182 * If there are no args or only one arg then do no escaping.
189 for (i = 1, szaNew = NULL; i < argc; i++)
194 * If an argument needs fixing, then fix it.
196 if (strpbrk (sz, "\" \t*?"))
199 * If we haven't created a new argv list already
204 szaNew = (char**) malloc ((argc + 1) *
212 * Copy previous args from old to new.
214 memcpy (szaNew, szaArgv, sizeof(char*) * i);
220 szaNew[i] = fix_arg (sz);
223 /* Fixing failed, free up and return error. */
224 free_fixed_argv (szaNew, szaArgv);
236 /* If we have created a new argv list then we might as well
237 * terminate it nicely. (And we depend on it in
238 * free_fixed_argv.) */
243 /* If we didn't create a new argv list then return the
252 free_fixed_argv (char* const* szaFixed, char* const* szaOld)
257 * Check for error conditions. Also note that if no corrections
258 * were required the fixed argv will actually be the same as
259 * the old one, and we don't need to do anything.
261 if (!szaFixed || !szaOld || szaFixed == szaOld)
267 * Go through all members of the argv list. If any of the
268 * members in the fixed list are different from the old
269 * list we free those members.
270 * NOTE: The first member is never modified, so we don't need to
286 * Now we can free the array of char pointers itself.