diff options
Diffstat (limited to 'winsup/mingw/samples/fixargv')
-rw-r--r-- | winsup/mingw/samples/fixargv/fixargv.c | 290 | ||||
-rw-r--r-- | winsup/mingw/samples/fixargv/fixargv.h | 24 | ||||
-rw-r--r-- | winsup/mingw/samples/fixargv/readme.txt | 85 |
3 files changed, 0 insertions, 399 deletions
diff --git a/winsup/mingw/samples/fixargv/fixargv.c b/winsup/mingw/samples/fixargv/fixargv.c deleted file mode 100644 index c2e2a41e6..000000000 --- a/winsup/mingw/samples/fixargv/fixargv.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * fixargv.c - * - * A special function which "fixes" an argv array by replacing arguments - * that need quoting with quoted versions. - * - * NOTE: In order to be reasonably consistent there is some misuse of the - * const keyword here-- which leads to compilation warnings. These - * should be ok to ignore. - * - * This is a sample distributed as part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warrenties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#include <string.h> -#include "fixargv.h" - -/* - * This takes a single string and fixes it, enclosing it in quotes if it - * contains any spaces and/or escaping the quotes it contains. - */ -char* -fix_arg (const char* szArg) -{ - int nQuoteAll; /* Does the whole arg need quoting? */ - int nBkSlRun; /* How may backslashes in a row? */ - char* sz; - char* szNew; - size_t sizeLen; - - nQuoteAll = 0; - nBkSlRun = 0; - sz = szArg; - sizeLen = 1; - - /* First we figure out how much bigger the new string has to be - * than the old one. */ - while (*sz != '\0') - { - /* - * Arguments containing whitespace of wildcards will be - * quoted to preserve tokenization and/or those special - * characters (i.e. wildcarding will NOT be done at the - * other end-- they will get the * and ? characters as is). - * TODO: Is this the best way? Do we want to enable wildcards? - * If so, when? - */ - if (!nQuoteAll && - (*sz == ' ' || *sz == '\t' || *sz == '*' || *sz == '?')) - { - nQuoteAll = 1; - } - else if (*sz == '\\') - { - nBkSlRun++; - } - else - { - if (*sz == '\"') - { - sizeLen += nBkSlRun + 1; - } - nBkSlRun = 0; - } - - sizeLen++; - sz++; - } - - if (nQuoteAll) - { - sizeLen += 2; - } - - /* - * Make a new string big enough. - */ - szNew = (char*) malloc (sizeLen); - if (!szNew) - { - return NULL; - } - sz = szNew; - - /* First enclosing quote for fully quoted args. */ - if (nQuoteAll) - { - *sz = '\"'; - sz++; - } - - /* - * Go through the string putting backslashes in front of quotes, - * and doubling all backslashes immediately in front of quotes. - */ - nBkSlRun = 0; - while (*szArg != '\0') - { - if (*szArg == '\\') - { - nBkSlRun++; - } - else - { - if (*szArg == '\"') - { - while (nBkSlRun > 0) - { - *sz = '\\'; - sz++; - nBkSlRun--; - } - *sz = '\\'; - sz++; - } - nBkSlRun = 0; - } - - *sz = *szArg; - sz++; - szArg++; - } - - /* Closing quote for fully quoted args. */ - if (nQuoteAll) - { - *sz = '\"'; - sz++; - } - - *sz = '\0'; - return szNew; -} - -/* - * Takes argc and argv and returns a new argv with escaped members. Pass - * this fixed argv (along with the old one) to free_fixed_argv after - * you finish with it. Pass in an argc of -1 and make sure the argv vector - * ends with a null pointer to have fix_argv count the arguments for you. - */ -char* const* -fix_argv (int argc, char* const* szaArgv) -{ - char** szaNew; - char* sz; - int i; - - if (!szaArgv) - { - return NULL; - } - - /* - * Count the arguments if asked. - */ - if (argc == -1) - { - for (i = 0; szaArgv[i]; i++) - ; - - argc = i; - } - - /* - * If there are no args or only one arg then do no escaping. - */ - if (argc < 2) - { - return szaArgv; - } - - for (i = 1, szaNew = NULL; i < argc; i++) - { - sz = szaArgv[i]; - - /* - * If an argument needs fixing, then fix it. - */ - if (strpbrk (sz, "\" \t*?")) - { - /* - * If we haven't created a new argv list already - * then make one. - */ - if (!szaNew) - { - szaNew = (char**) malloc ((argc + 1) * - sizeof (char*)); - if (!szaNew) - { - return NULL; - } - - /* - * Copy previous args from old to new. - */ - memcpy (szaNew, szaArgv, sizeof(char*) * i); - } - - /* - * Now do the fixing. - */ - szaNew[i] = fix_arg (sz); - if (!szaNew[i]) - { - /* Fixing failed, free up and return error. */ - free_fixed_argv (szaNew, szaArgv); - return NULL; - } - } - else if (szaNew) - { - szaNew[i] = sz; - } - } - - if (szaNew) - { - /* If we have created a new argv list then we might as well - * terminate it nicely. (And we depend on it in - * free_fixed_argv.) */ - szaNew[argc] = NULL; - } - else - { - /* If we didn't create a new argv list then return the - * original. */ - return szaArgv; - } - - return szaNew; -} - -void -free_fixed_argv (char* const* szaFixed, char* const* szaOld) -{ - char* const* sza; - - /* - * Check for error conditions. Also note that if no corrections - * were required the fixed argv will actually be the same as - * the old one, and we don't need to do anything. - */ - if (!szaFixed || !szaOld || szaFixed == szaOld) - { - return; - } - - /* - * Go through all members of the argv list. If any of the - * members in the fixed list are different from the old - * list we free those members. - * NOTE: The first member is never modified, so we don't need to - * check. - */ - sza = szaFixed + 1; - szaOld++; - while (*sza) - { - if (*sza != *szaOld) - { - free (*sza); - } - sza++; - szaOld++; - } - - /* - * Now we can free the array of char pointers itself. - */ - free (szaFixed); -} - diff --git a/winsup/mingw/samples/fixargv/fixargv.h b/winsup/mingw/samples/fixargv/fixargv.h deleted file mode 100644 index e4a83fae1..000000000 --- a/winsup/mingw/samples/fixargv/fixargv.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * fixargv.h - * - * Prototypes of utility functions for 'properly' escaping argv vectors. - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * $Revision$ - * $Author$ - * $Date$ - * - */ - -#ifndef _FIXARGV_H_ -#define _FIXARGV_H_ - -char* fix_arg (const char* szArg); -char* const* fix_argv (int argc, char* const* szaArgv); -void free_fixed_argv (char* const* szaFixed, char* const* szaOld); - -#endif diff --git a/winsup/mingw/samples/fixargv/readme.txt b/winsup/mingw/samples/fixargv/readme.txt deleted file mode 100644 index 555ef9bde..000000000 --- a/winsup/mingw/samples/fixargv/readme.txt +++ /dev/null @@ -1,85 +0,0 @@ - -This code is a utility function I was considering adding to Mingw32. The -Microsoft versions of argc, argv construction use quotes and backslashes -to allow the user to pass arguments containing spaces (or quotes) to -programs they invoke. The rules are - - - Arguments containing spaces must be enclosed in quotes. - - A quote can be passed by preceeding it with a backslash. - - Backslashes immediately preceeding a quote must be doubled to avoid - escaping the quote. - -Thus an argument like: - - -D="Foo Bar\\" - -needs to be mangled as: - - "-D\"Foo Bar\\\\\"" - -in order to get to the program as what was intended above. - -The fix_argv set of functions is meant to be used with spawnv and the -like to allow a program to set up an argv array for the spawned program -and have that array duplicated *exactly* in the spawned program, no -matter what it contains (it also quotes 'globbing' characters like * -and ?, so it does not matter if the destination has globbing turned on -or not; it might be a reasonable extension to allow a flag to allow -globbing characters to pass through unmolested, but they would still -be quoted if the string contained whitespace). - -The reason for writing this came up because of problems with arguments -like -DBLAH="Foo Bar" to GCC (define BLAH as a preprocessor constant -being the string "Foo Bar", including the quotes). Because GCC simply -passes the argument directly to CPP (the preprocessor) it had to be -escaped *twice*: - - "-DBLAH=\"\\\"Foo Bar\\\"\"" - -This would reach GCC as - - -DBLAH="\"Foo Bar\"" - -And that would reach CPP as the desired - - -DBLAH="Foo Bar" - -One level of quoting and escaping is to be expected (although MS's -standard is, arguably, not very good), but forcing the user to know -how many different programs the argument is going to pass through, -and perform double quoting and escaping, seems unreasonable. If -GCC and friends all used fix_argv (they use their own version of -it now) then the original argument could be - - "-DBLAH=\"Foo Bar\"" - -And that would work fine, no matter how many different tools it -passed through. - -The only basic limitation with this code is that it assumes that all -the spawned programs use Microsoft-type escaping when interpreting -their command line. Most programs on Win32 machines do (anything -compiled with Mingw32 will). - -For now, this code has been relegated to 'sample' status. If you want -to use it, feel free (it is public domain after all). - -Colin. - -P.S. Just out of interest you might try writing your own little program - to look at the interaction of wildcards and quotes. Use the glob.exe - program in ../globbing and see what it does with - - glob "foo*.txt" - - even if there are files foo.txt and foobar.txt in the same directory. - - Note that - - del "My *.txt" - - works (i.e. it deletes all files starting with My<space>). This could - not be done unless del does globbing *after* processing escapes and - quotes, which is not the way it seems to work normally (again see - the glob example). - |