|
From: <in...@us...> - 2002-05-26 10:06:03
|
Update of /cvsroot/mingw/runtime/samples/fixargv
In directory usw-pr-cvs1:/tmp/cvs-serv1023/samples/fixargv
Modified Files:
fixargv.c fixargv.h readme.txt
Log Message:
Convert some text files to Unix format
Index: fixargv.c
===================================================================
RCS file: /cvsroot/mingw/runtime/samples/fixargv/fixargv.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** fixargv.c 5 Jun 2001 00:26:30 -0000 1.2
--- fixargv.c 26 May 2002 10:05:59 -0000 1.3
***************
*** 1,290 ****
! /*
! * 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 <co...@bi...>
! *
! * 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);
! }
!
--- 1,290 ----
! /*
! * 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 <co...@bi...>
! *
! * 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);
! }
!
Index: fixargv.h
===================================================================
RCS file: /cvsroot/mingw/runtime/samples/fixargv/fixargv.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** fixargv.h 5 Jun 2001 00:26:30 -0000 1.2
--- fixargv.h 26 May 2002 10:05:59 -0000 1.3
***************
*** 1,24 ****
! /*
! * 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
--- 1,24 ----
! /*
! * 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
Index: readme.txt
===================================================================
RCS file: /cvsroot/mingw/runtime/samples/fixargv/readme.txt,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** readme.txt 4 Jun 2001 23:26:03 -0000 1.1.1.1
--- readme.txt 26 May 2002 10:06:00 -0000 1.2
***************
*** 1,85 ****
!
! 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).
!
--- 1,85 ----
!
! 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).
!
|