From c0b7ca96b844a6c9ff7dc2410f1e4cdf0cd9e2ee Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 9 Nov 2011 01:35:19 +0000 Subject: [PATCH] perform shell-style filename globbing on Win32 too --- dtool/src/dtoolutil/Sources.pp | 27 +- dtool/src/dtoolutil/dtoolutil_composite1.cxx | 12 +- dtool/src/dtoolutil/dtoolutil_composite2.cxx | 4 +- dtool/src/{prc => dtoolutil}/globPattern.I | 0 dtool/src/{prc => dtoolutil}/globPattern.cxx | 0 dtool/src/{prc => dtoolutil}/globPattern.h | 2 +- dtool/src/dtoolutil/preprocess_argv.cxx | 50 +++ dtool/src/dtoolutil/preprocess_argv.h | 24 ++ dtool/src/dtoolutil/win32ArgParser.cxx | 361 ++++++++++++++++++ dtool/src/dtoolutil/win32ArgParser.h | 67 ++++ dtool/src/interrogate/interrogate.cxx | 4 +- dtool/src/interrogate/interrogate_module.cxx | 2 + dtool/src/interrogate/parse_file.cxx | 4 +- dtool/src/prc/Sources.pp | 3 - dtool/src/prc/prc_composite2.cxx | 1 - dtool/src/prckeys/makePrcKey.cxx | 4 +- dtool/src/prckeys/signPrcFile_src.cxx | 4 +- .../src/test_interrogate/test_interrogate.cxx | 4 +- panda/src/downloadertools/apply_patch.cxx | 5 +- panda/src/downloadertools/build_patch.cxx | 4 +- panda/src/downloadertools/check_md5.cxx | 4 +- panda/src/downloadertools/multify.cxx | 4 +- panda/src/downloadertools/pdecrypt.cxx | 4 +- panda/src/downloadertools/pencrypt.cxx | 4 +- panda/src/downloadertools/punzip.cxx | 4 +- panda/src/downloadertools/pzip.cxx | 4 +- panda/src/testbed/pgrid.cxx | 5 +- panda/src/testbed/pview.cxx | 4 +- pandatool/src/progbase/programBase.cxx | 5 +- pandatool/src/progbase/programBase.h | 2 +- 30 files changed, 584 insertions(+), 38 deletions(-) rename dtool/src/{prc => dtoolutil}/globPattern.I (100%) rename dtool/src/{prc => dtoolutil}/globPattern.cxx (100%) rename dtool/src/{prc => dtoolutil}/globPattern.h (98%) create mode 100755 dtool/src/dtoolutil/preprocess_argv.cxx create mode 100755 dtool/src/dtoolutil/preprocess_argv.h create mode 100755 dtool/src/dtoolutil/win32ArgParser.cxx create mode 100755 dtool/src/dtoolutil/win32ArgParser.h diff --git a/dtool/src/dtoolutil/Sources.pp b/dtool/src/dtoolutil/Sources.pp index c534b644d8..6cecd97158 100644 --- a/dtool/src/dtoolutil/Sources.pp +++ b/dtool/src/dtoolutil/Sources.pp @@ -12,50 +12,63 @@ #define SOURCES \ checkPandaVersion.h \ config_dtoolutil.h \ + dSearchPath.I dSearchPath.h \ executionEnvironment.I executionEnvironment.h filename.I \ filename.h \ $[if $[IS_OSX],filename_assist.mm filename_assist.h,] \ - load_dso.h dSearchPath.I dSearchPath.h \ + globPattern.I globPattern.h \ + load_dso.h \ pandaFileStream.h pandaFileStream.I \ pandaFileStreamBuf.h \ pandaSystem.h pandaVersion.h \ panda_getopt.h panda_getopt_long.h panda_getopt_impl.h \ pfstream.h pfstream.I pfstreamBuf.h \ + preprocess_argv.h \ stringDecoder.h stringDecoder.I \ textEncoder.h textEncoder.I \ unicodeLatinMap.h \ vector_string.h \ - vector_src.h + vector_src.h \ + win32ArgParser.h #define INCLUDED_SOURCES \ checkPandaVersion.cxx \ config_dtoolutil.cxx \ - executionEnvironment.cxx filename.cxx load_dso.cxx \ dSearchPath.cxx \ + executionEnvironment.cxx filename.cxx \ + globPattern.cxx \ + load_dso.cxx \ pandaFileStream.cxx pandaFileStreamBuf.cxx \ pandaSystem.cxx \ panda_getopt_impl.cxx \ pfstreamBuf.cxx pfstream.cxx \ + preprocess_argv.cxx \ stringDecoder.cxx \ textEncoder.cxx \ unicodeLatinMap.cxx \ - vector_string.cxx + vector_string.cxx \ + win32ArgParser.cxx #define INSTALL_HEADERS \ checkPandaVersion.h \ config_dtoolutil.h \ - executionEnvironment.I executionEnvironment.h filename.I \ - filename.h load_dso.h dSearchPath.I dSearchPath.h \ + dSearchPath.I dSearchPath.h \ + executionEnvironment.I executionEnvironment.h filename.I \ + filename.h \ + globPattern.I globPattern.h \ + load_dso.h \ pandaFileStream.h pandaFileStream.I \ pandaFileStreamBuf.h \ pandaSystem.h pandaVersion.h \ panda_getopt.h panda_getopt_long.h panda_getopt_impl.h \ pfstream.h pfstream.I pfstreamBuf.h \ + preprocess_argv.h \ stringDecoder.h stringDecoder.I \ textEncoder.h textEncoder.I \ unicodeLatinMap.h \ vector_string.h \ - vector_src.cxx vector_src.h + vector_src.cxx vector_src.h \ + win32ArgParser.h #end lib_target #begin test_bin_target diff --git a/dtool/src/dtoolutil/dtoolutil_composite1.cxx b/dtool/src/dtoolutil/dtoolutil_composite1.cxx index 86eb708076..0cd4ec6cd8 100644 --- a/dtool/src/dtoolutil/dtoolutil_composite1.cxx +++ b/dtool/src/dtoolutil/dtoolutil_composite1.cxx @@ -1,8 +1,10 @@ -#include "config_dtoolutil.cxx" -#include "filename.cxx" -#include "load_dso.cxx" -#include "dSearchPath.cxx" -#include "pandaSystem.cxx" #include "checkPandaVersion.cxx" +#include "config_dtoolutil.cxx" +#include "dSearchPath.cxx" +#include "executionEnvironment.cxx" +#include "filename.cxx" +#include "globPattern.cxx" +#include "load_dso.cxx" +#include "pandaSystem.cxx" diff --git a/dtool/src/dtoolutil/dtoolutil_composite2.cxx b/dtool/src/dtoolutil/dtoolutil_composite2.cxx index d66178f591..7d1198beda 100644 --- a/dtool/src/dtoolutil/dtoolutil_composite2.cxx +++ b/dtool/src/dtoolutil/dtoolutil_composite2.cxx @@ -1,11 +1,11 @@ #include "pandaFileStream.cxx" #include "pandaFileStreamBuf.cxx" #include "panda_getopt_impl.cxx" -#include "executionEnvironment.cxx" #include "pfstream.cxx" #include "pfstreamBuf.cxx" +#include "preprocess_argv.cxx" #include "stringDecoder.cxx" #include "textEncoder.cxx" #include "unicodeLatinMap.cxx" #include "vector_string.cxx" - +#include "win32ArgParser.cxx" diff --git a/dtool/src/prc/globPattern.I b/dtool/src/dtoolutil/globPattern.I similarity index 100% rename from dtool/src/prc/globPattern.I rename to dtool/src/dtoolutil/globPattern.I diff --git a/dtool/src/prc/globPattern.cxx b/dtool/src/dtoolutil/globPattern.cxx similarity index 100% rename from dtool/src/prc/globPattern.cxx rename to dtool/src/dtoolutil/globPattern.cxx diff --git a/dtool/src/prc/globPattern.h b/dtool/src/dtoolutil/globPattern.h similarity index 98% rename from dtool/src/prc/globPattern.h rename to dtool/src/dtoolutil/globPattern.h index af03539a10..f22125b060 100644 --- a/dtool/src/prc/globPattern.h +++ b/dtool/src/dtoolutil/globPattern.h @@ -34,7 +34,7 @@ // example, to scan a directory for all files matching a // particular pattern. //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG GlobPattern { +class EXPCL_DTOOL GlobPattern { PUBLISHED: INLINE GlobPattern(const string &pattern = string()); INLINE GlobPattern(const GlobPattern ©); diff --git a/dtool/src/dtoolutil/preprocess_argv.cxx b/dtool/src/dtoolutil/preprocess_argv.cxx new file mode 100755 index 0000000000..2d112fab37 --- /dev/null +++ b/dtool/src/dtoolutil/preprocess_argv.cxx @@ -0,0 +1,50 @@ +// Filename: preprocess_argv.cxx +// Created by: drose (08Nov11) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "preprocess_argv.h" +#include "win32ArgParser.h" + +//////////////////////////////////////////////////////////////////// +// Function: preprocess_argv +// Description: Processes the argc, argv pair as needed before +// passing it to getopt(). If this program is running +// on Windows, but not within Cygwin, this ignores the +// incoming argv, argv values, replacing them from the +// GetCommandLine() string, and expanding glob patterns +// like *.egg to a list of all matching egg files. On +// other platforms, this function does nothing and +// returns argc, argv unchanged. +// +// The argc and argv values are modified by this +// function, if necessary, to point to +// statically-allocated memory that will be valid until +// the next call to preprocess_argv(). +//////////////////////////////////////////////////////////////////// +void +preprocess_argv(int &argc, char **&argv) { +#ifndef _WIN32 + // Not Windows: do nothing. +#else // _WIN32 + static Win32ArgParser parser; + if (parser.is_cygwin_shell()) { + // Running within Cygwin: do nothing. + return; + } + + // On Windows, and not within Cygwin. Process the args. + parser.set_system_command_line(); + argc = parser.get_argc(); + argv = parser.get_argv(); +#endif // _WIN32 +} diff --git a/dtool/src/dtoolutil/preprocess_argv.h b/dtool/src/dtoolutil/preprocess_argv.h new file mode 100755 index 0000000000..9c63161d17 --- /dev/null +++ b/dtool/src/dtoolutil/preprocess_argv.h @@ -0,0 +1,24 @@ +// Filename: preprocess_argv.h +// Created by: drose (08Nov11) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PREPROCESS_ARGV_H +#define PREPROCESS_ARGV_H + +#include "dtoolbase.h" + +extern EXPCL_DTOOL void +preprocess_argv(int &argc, char **&argv); + +#endif + diff --git a/dtool/src/dtoolutil/win32ArgParser.cxx b/dtool/src/dtoolutil/win32ArgParser.cxx new file mode 100755 index 0000000000..d380c34e9d --- /dev/null +++ b/dtool/src/dtoolutil/win32ArgParser.cxx @@ -0,0 +1,361 @@ +// Filename: win32ArgParser.cxx +// Created by: drose (08Nov11) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "win32ArgParser.h" + +#ifdef _WIN32 + +#include "memoryBase.h" +#include "textEncoder.h" +#include "globPattern.h" +#include "filename.h" +#include "executionEnvironment.h" + +#include +#include + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +Win32ArgParser:: +Win32ArgParser() : + _argv(NULL), + _argc(0) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +Win32ArgParser:: +~Win32ArgParser() { + clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::clear +// Access: Public +// Description: Resets the parser to empty command line and +// deallocates the internal argv array. +//////////////////////////////////////////////////////////////////// +void Win32ArgParser:: +clear() { + assert(_argc == (int)_args.size()); + + if (_argv != NULL) { + for (int i = 0; i < _argc; ++i) { + PANDA_FREE_ARRAY(_argv[i]); + } + PANDA_FREE_ARRAY(_argv); + _argv = NULL; + } + + _argc = 0; + _args.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::set_command_line +// Access: Public +// Description: Sets the string that indicates the full Win32 command +// line, and starts parsing this into argc, argv. +//////////////////////////////////////////////////////////////////// +void Win32ArgParser:: +set_command_line(const string &command_line) { + clear(); + + const char *p = command_line.c_str(); + while (*p != '\0') { + if (*p == '"') { + parse_quoted_arg(p); + } else { + parse_unquoted_arg(p); + } + + // Skip whitespace. + while (*p != '\0' && isspace(*p)) { + ++p; + } + } + + assert(_argc == 0 && _argv == NULL); + _argc = (int)_args.size(); + _argv = (char **)PANDA_MALLOC_ARRAY(_argc * sizeof(char *)); + for (int i = 0; i < _argc; ++i) { + const string &arg = _args[i]; + char *astr = (char *)PANDA_MALLOC_ARRAY(arg.size() + 1); + memcpy(astr, arg.data(), arg.size()); + astr[arg.size()] = '\0'; + _argv[i] = astr; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::set_command_line +// Access: Public +// Description: Sets the Unicode string that indicates the full Win32 +// command line, and starts parsing this into argc, +// argv. +//////////////////////////////////////////////////////////////////// +void Win32ArgParser:: +set_command_line(const wstring &command_line) { + TextEncoder encoder; + encoder.set_encoding(Filename::get_filesystem_encoding()); + encoder.set_wtext(command_line); + set_command_line(encoder.get_text()); +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::set_system_command_line +// Access: Public +// Description: Tells the parser to call GetCommandLine() to query +// the system command line string, and parse it into +// argc, argv. +//////////////////////////////////////////////////////////////////// +void Win32ArgParser:: +set_system_command_line() { + LPWSTR command_line = GetCommandLineW(); + set_command_line(command_line); +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::get_argv +// Access: Public +// Description: Returns the argv array as computed by +// set_command_line() or set_system_command_line(). +// This array indexes directly into data allocated +// within the Win32ArgParser object; it will remain +// valid until set_command_line() or clear() is again +// called, or until the parser object destructs. +//////////////////////////////////////////////////////////////////// +char **Win32ArgParser:: +get_argv() { + return _argv; +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::get_argc +// Access: Public +// Description: Returns the number of elements in the argv array. +//////////////////////////////////////////////////////////////////// +int Win32ArgParser:: +get_argc() { + return _argc; +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::is_cygwin_shell +// Access: Public, Static +// Description: Tries to determine if this program was launched from +// a Cygwin shell. Returns true if so, false otherwise. +//////////////////////////////////////////////////////////////////// +bool Win32ArgParser:: +is_cygwin_shell() { + // First, we check for the PANDA_CYGWIN environment variable. If + // this is present, it overrides any other checks: "0" means not + // Cygwin, "1" means Cygwin. + string envvar = ExecutionEnvironment::get_environment_variable("PANDA_CYGWIN"); + if (!envvar.empty()) { + istringstream strm(envvar); + int value; + strm >> value; + if (!strm.fail()) { + return (value != 0); + } + } + + // Nothing explicit, so we have to determine Cygwin status + // implicitly. + + // Our strategy is to check the parent process name for one of the + // known Cygwin shells. Unfortunately, it is surprisingly difficult + // to determine the parent process in Windows. We have to enumerate + // all of the processes to find it. + + HANDLE toolhelp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + PROCESSENTRY32 entry; + memset(&entry, 0, sizeof(entry)); + entry.dwSize = sizeof(entry); + + DWORD current_id = GetCurrentProcessId(); + DWORD parent_id = -1; + + if (Process32First(toolhelp, &entry)) { + do { + if (entry.th32ProcessID == current_id) { + parent_id = entry.th32ParentProcessID; + break; + } + } while (Process32Next(toolhelp, &entry)); + } + + Filename parent_exe; + if (parent_id != -1) { + // Now we've got the parent process ID, go back through the list + // to get its process name. + if (Process32First(toolhelp, &entry)) { + do { + if (entry.th32ProcessID == parent_id) { + parent_exe = Filename::from_os_specific(entry.szExeFile); + break; + } + } while (Process32Next(toolhelp, &entry)); + } + } + + CloseHandle(toolhelp); + string basename = parent_exe.get_basename(); + if (basename == "sh.exe" || basename == "bash.exe" || + basename == "csh.exe" || basename == "tcsh.exe" || + basename == "zsh.exe" || basename == "ash.exe") { + // These are the standard Unix shell names. Assume one of these + // as the parent process name means we were launched from a Cygwin + // shell. Even if it's from something other than the Cygwin + // implementation, these filenames suggests a smart shell that + // will have already pre-processed the command line. + return true; + } + + // Something else means a standard Windows shell that doesn't + // process the command line. + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::parse_quoted_arg +// Access: Private +// Description: Parses the quoted argument beginning at p and saves +// it in _char_args. Advances p to the first character +// following the close quote. +//////////////////////////////////////////////////////////////////// +void Win32ArgParser:: +parse_quoted_arg(const char *&p) { + char quote = *p; + ++p; + string result; + + while (*p != '\0' && *p != quote) { + // TODO: handle caret? What does it mean? + + if (*p == '\\') { + // A backslash is an escape character only when it precedes a + // quote mark, or a series of backslashes precede a quote mark. + int num_slashes = 1; + ++p; + while (*p == '\\') { + ++p; + ++num_slashes; + } + if (*p == quote) { + // A series of backslashes precede a quote mark. This means + // something special. First, each pair of backslashes means a + // single backslash. + for (int i = 0; i < num_slashes; i += 2) { + result += '\\'; + } + // And if there's no odd backslashes left over, we've reached + // the closing quote and we're done. + if ((num_slashes & 1) == 0) { + ++p; + save_arg(result); + return; + } + + // But if there's an odd backslash, it simply escapes the + // quote mark. + result += quote; + ++p; + + } else { + // A series of backslashes not followed by a quote mark is + // interpreted literally, not even counting them by twos, per + // Win32's weird rules. + for (int i = 0; i < num_slashes; ++i) { + result += '\\'; + } + } + + } else { + // Neither a backslash nor a quote mark, so just interpret it + // literally. + result += *p; + ++p; + } + } + + if (*p == quote) { + ++p; + } + + save_arg(result); +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::parse_unquoted_arg +// Access: Private +// Description: Parses the unquoted argument beginning at p and saves +// it in _char_args. Advances p to the first whitespace +// following the argument. +//////////////////////////////////////////////////////////////////// +void Win32ArgParser:: +parse_unquoted_arg(const char *&p) { + string result; + while (*p != '\0' && !isspace(*p)) { + result += *p; + ++p; + } + + Filename filename = Filename::from_os_specific(result); + GlobPattern glob(filename); + if (glob.has_glob_characters()) { + // If the arg contains one or more glob characters, we attempt to + // expand the files. This means we interpret it as a + // Windows-specific filename. + vector_string expand; + if (glob.match_files(expand) != 0) { + // The files matched. Add the expansions. + vector_string::const_iterator ei; + for (ei = expand.begin(); ei != expand.end(); ++ei) { + Filename filename(*ei); + save_arg(filename.to_os_specific()); + } + } else { + // There wasn't a match. Just add the original, unexpanded + // string, like bash does. + save_arg(result); + } + + } else { + // No glob characters means we just store it directly. + save_arg(result); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: Win32ArgParser::save_arg +// Access: Private +// Description: Stores the indicated string as the next argument in +// _args. +//////////////////////////////////////////////////////////////////// +void Win32ArgParser:: +save_arg(const string &arg) { + _args.push_back(arg); +} + +#endif // _WIN32 diff --git a/dtool/src/dtoolutil/win32ArgParser.h b/dtool/src/dtoolutil/win32ArgParser.h new file mode 100755 index 0000000000..e923c2246d --- /dev/null +++ b/dtool/src/dtoolutil/win32ArgParser.h @@ -0,0 +1,67 @@ +// Filename: win32ArgParser.h +// Created by: drose (08Nov11) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef WIN32ARGPARSER_H +#define WIN32ARGPARSER_H + +#include "dtoolbase.h" + +#ifdef _WIN32 + +#include "vector_string.h" +#include "pvector.h" + +#include + +//////////////////////////////////////////////////////////////////// +// Class : Win32ArgParser +// Description : This class is used to parse the single command-line +// string provided by Windows into the standard argc, +// argv array of strings. In this way it duplicates the +// functionality of Windows' own CommandLineToArgv() +// function, but it is also supports automatic expansion +// of glob filenames, e.g. *.egg is turned into an +// explicit list of egg files in the directory. +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOL Win32ArgParser { +public: + Win32ArgParser(); + ~Win32ArgParser(); + + void clear(); + + void set_command_line(const string &command_line); + void set_command_line(const wstring &command_line); + void set_system_command_line(); + + char **get_argv(); + int get_argc(); + + static bool is_cygwin_shell(); + +private: + void parse_quoted_arg(const char *&p); + void parse_unquoted_arg(const char *&p); + void save_arg(const string &arg); + + typedef vector_string Args; + Args _args; + + char **_argv; + int _argc; +}; + +#endif // _WIN32 + +#endif diff --git a/dtool/src/interrogate/interrogate.cxx b/dtool/src/interrogate/interrogate.cxx index 3ca0abdac8..504deb97fb 100644 --- a/dtool/src/interrogate/interrogate.cxx +++ b/dtool/src/interrogate/interrogate.cxx @@ -19,6 +19,7 @@ #include "cppGlobals.h" #include "pnotify.h" #include "panda_getopt_long.h" +#include "preprocess_argv.h" #include CPPParser parser; @@ -302,7 +303,8 @@ predefine_macro(CPPParser& parser, const string& inoption) { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { + preprocess_argv(argc, argv); string command_line; int i; for (i = 0; i < argc; i++) { diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 9bc05a2885..eb7045ece9 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -23,6 +23,7 @@ #include "pystub.h" #include "pnotify.h" #include "panda_getopt_long.h" +#include "preprocess_argv.h" #include "pset.h" Filename output_code_filename; @@ -237,6 +238,7 @@ int main(int argc, char *argv[]) { extern int optind; int flag; + preprocess_argv(argc, argv); flag = getopt_long_only(argc, argv, short_options, long_options, NULL); while (flag != EOF) { switch (flag) { diff --git a/dtool/src/interrogate/parse_file.cxx b/dtool/src/interrogate/parse_file.cxx index a68491dc49..524461b9df 100644 --- a/dtool/src/interrogate/parse_file.cxx +++ b/dtool/src/interrogate/parse_file.cxx @@ -22,6 +22,7 @@ #include "cppType.h" #include "cppGlobals.h" #include "panda_getopt_long.h" +#include "preprocess_argv.h" #include CPPParser parser; @@ -192,10 +193,11 @@ show_typedefs(const string &str) { int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "I:S:D:o:l:vp"; + preprocess_argv(argc, argv); parser.set_verbose(2); bool prompt = false; diff --git a/dtool/src/prc/Sources.pp b/dtool/src/prc/Sources.pp index 4a1740b6fd..60f2b708ee 100644 --- a/dtool/src/prc/Sources.pp +++ b/dtool/src/prc/Sources.pp @@ -27,7 +27,6 @@ configVariableSearchPath.I configVariableSearchPath.h \ configVariableString.I configVariableString.h \ encryptStreamBuf.h encryptStreamBuf.I encryptStream.h encryptStream.I \ - globPattern.I globPattern.h \ littleEndian.h \ nativeNumericData.I nativeNumericData.h \ pnotify.I pnotify.h \ @@ -63,7 +62,6 @@ configVariableSearchPath.cxx \ configVariableString.cxx \ encryptStreamBuf.cxx encryptStream.cxx \ - globPattern.cxx \ nativeNumericData.cxx \ notify.cxx \ notifyCategory.cxx \ @@ -93,7 +91,6 @@ configVariableSearchPath.I configVariableSearchPath.h \ configVariableString.I configVariableString.h \ encryptStreamBuf.h encryptStreamBuf.I encryptStream.h encryptStream.I \ - globPattern.I globPattern.h \ littleEndian.h \ nativeNumericData.I nativeNumericData.h \ pnotify.I pnotify.h \ diff --git a/dtool/src/prc/prc_composite2.cxx b/dtool/src/prc/prc_composite2.cxx index be7e26b368..0b4c5a8f7b 100644 --- a/dtool/src/prc/prc_composite2.cxx +++ b/dtool/src/prc/prc_composite2.cxx @@ -3,7 +3,6 @@ #include "configVariableString.cxx" #include "encryptStreamBuf.cxx" #include "encryptStream.cxx" -#include "globPattern.cxx" #include "nativeNumericData.cxx" #include "notify.cxx" #include "notifyCategory.cxx" diff --git a/dtool/src/prckeys/makePrcKey.cxx b/dtool/src/prckeys/makePrcKey.cxx index c6ae13832d..17a95286fb 100644 --- a/dtool/src/prckeys/makePrcKey.cxx +++ b/dtool/src/prckeys/makePrcKey.cxx @@ -17,6 +17,7 @@ #include "filename.h" #include "pvector.h" #include "panda_getopt.h" +#include "preprocess_argv.h" #include // Pick up the public key definitions. @@ -317,7 +318,7 @@ usage() { // Description: //////////////////////////////////////////////////////////////////// int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "a:b:p:h"; @@ -329,6 +330,7 @@ main(int argc, char *argv[]) { string pass_phrase; bool got_pass_phrase = false; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optstr); while (flag != EOF) { diff --git a/dtool/src/prckeys/signPrcFile_src.cxx b/dtool/src/prckeys/signPrcFile_src.cxx index 3d88d6efb4..62a9b4c5a3 100644 --- a/dtool/src/prckeys/signPrcFile_src.cxx +++ b/dtool/src/prckeys/signPrcFile_src.cxx @@ -21,6 +21,7 @@ #include "filename.h" #include "executionEnvironment.h" #include "panda_getopt.h" +#include "preprocess_argv.h" #include @@ -285,7 +286,8 @@ usage() { // Description: //////////////////////////////////////////////////////////////////// int -main(int argc, char *argv[]) { +main(int argc, char **argv) { + preprocess_argv(argc, argv); if (argv[0] != NULL && *argv[0]) { // Get the program name from the command-line arguments, if the OS // provides it. diff --git a/dtool/src/test_interrogate/test_interrogate.cxx b/dtool/src/test_interrogate/test_interrogate.cxx index 22dec6e0d3..e328693905 100644 --- a/dtool/src/test_interrogate/test_interrogate.cxx +++ b/dtool/src/test_interrogate/test_interrogate.cxx @@ -20,6 +20,7 @@ #include "filename.h" #include "pystub.h" #include "panda_getopt.h" +#include "preprocess_argv.h" #include @@ -516,7 +517,7 @@ usage() { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "p:ftqh"; @@ -524,6 +525,7 @@ main(int argc, char *argv[]) { bool all_functions = false; bool all_types = false; bool quick_load = false; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optstr); while (flag != EOF) { diff --git a/panda/src/downloadertools/apply_patch.cxx b/panda/src/downloadertools/apply_patch.cxx index eaebce2414..e741e00fcf 100644 --- a/panda/src/downloadertools/apply_patch.cxx +++ b/panda/src/downloadertools/apply_patch.cxx @@ -14,11 +14,14 @@ #include "pandabase.h" #include "panda_getopt.h" +#include "preprocess_argv.h" #include "patchfile.h" #include "filename.h" int -main(int argc, char *argv[]) { +main(int argc, char **argv) { + preprocess_argv(argc, argv); + if (argc < 3) { cerr << "Usage: apply_patch " << endl; cerr << "Will overwrite old_file" << endl; diff --git a/panda/src/downloadertools/build_patch.cxx b/panda/src/downloadertools/build_patch.cxx index d25a29b0ee..a36caf99c1 100644 --- a/panda/src/downloadertools/build_patch.cxx +++ b/panda/src/downloadertools/build_patch.cxx @@ -14,6 +14,7 @@ #include "pandabase.h" #include "panda_getopt.h" +#include "preprocess_argv.h" #include "patchfile.h" #include "filename.h" @@ -51,7 +52,7 @@ help() { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { Filename patch_file; bool complete_file = false; int footprint_length = 0; @@ -59,6 +60,7 @@ main(int argc, char *argv[]) { // extern char *optarg; extern int optind; static const char *optflags = "o:cf:h"; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optflags); Filename rel_path; while (flag != EOF) { diff --git a/panda/src/downloadertools/check_md5.cxx b/panda/src/downloadertools/check_md5.cxx index f0f84f7619..27c33fa357 100644 --- a/panda/src/downloadertools/check_md5.cxx +++ b/panda/src/downloadertools/check_md5.cxx @@ -16,6 +16,7 @@ #include "hashVal.h" #include "filename.h" #include "panda_getopt.h" +#include "preprocess_argv.h" bool output_decimal = false; bool suppress_filename = false; @@ -65,7 +66,7 @@ output_hash(const string &filename, const HashVal &hash) { int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "i:db:qh"; @@ -74,6 +75,7 @@ main(int argc, char *argv[]) { string input_string; Filename binary_output_filename; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optstr); while (flag != EOF) { diff --git a/panda/src/downloadertools/multify.cxx b/panda/src/downloadertools/multify.cxx index 6341475750..82aee54ab4 100644 --- a/panda/src/downloadertools/multify.cxx +++ b/panda/src/downloadertools/multify.cxx @@ -14,6 +14,7 @@ #include "pandabase.h" #include "panda_getopt.h" +#include "preprocess_argv.h" #include "multifile.h" #include "pointerTo.h" #include "filename.h" @@ -747,7 +748,8 @@ tokenize_extensions(const string &str, pset &extensions) { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { + preprocess_argv(argc, argv); if (argc < 2) { usage(); return 1; diff --git a/panda/src/downloadertools/pdecrypt.cxx b/panda/src/downloadertools/pdecrypt.cxx index 8f2a002ee7..1c91407a01 100644 --- a/panda/src/downloadertools/pdecrypt.cxx +++ b/panda/src/downloadertools/pdecrypt.cxx @@ -16,6 +16,7 @@ #include "encrypt_string.h" #include "pnotify.h" #include "panda_getopt.h" +#include "preprocess_argv.h" string password; bool got_password = false; @@ -44,7 +45,7 @@ usage() { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "o:p:h"; @@ -52,6 +53,7 @@ main(int argc, char *argv[]) { Filename dest_filename; bool got_dest_filename = false; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optstr); while (flag != EOF) { diff --git a/panda/src/downloadertools/pencrypt.cxx b/panda/src/downloadertools/pencrypt.cxx index 2c2f3560a6..2e915551ee 100644 --- a/panda/src/downloadertools/pencrypt.cxx +++ b/panda/src/downloadertools/pencrypt.cxx @@ -16,6 +16,7 @@ #include "encrypt_string.h" #include "pnotify.h" #include "panda_getopt.h" +#include "preprocess_argv.h" string password; bool got_password = false; @@ -82,7 +83,7 @@ usage() { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "o:p:ta:k:i:h"; @@ -91,6 +92,7 @@ main(int argc, char *argv[]) { bool got_dest_filename = false; bool text_file = false; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optstr); while (flag != EOF) { diff --git a/panda/src/downloadertools/punzip.cxx b/panda/src/downloadertools/punzip.cxx index c362b64eb4..486d58be67 100644 --- a/panda/src/downloadertools/punzip.cxx +++ b/panda/src/downloadertools/punzip.cxx @@ -16,6 +16,7 @@ #include "compress_string.h" #include "pnotify.h" #include "panda_getopt.h" +#include "preprocess_argv.h" void usage() { @@ -31,7 +32,7 @@ usage() { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "o:ch"; @@ -40,6 +41,7 @@ main(int argc, char *argv[]) { bool got_dest_filename = false; bool use_stdout = false; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optstr); while (flag != EOF) { diff --git a/panda/src/downloadertools/pzip.cxx b/panda/src/downloadertools/pzip.cxx index 11f55d4856..45a27f9d52 100644 --- a/panda/src/downloadertools/pzip.cxx +++ b/panda/src/downloadertools/pzip.cxx @@ -16,6 +16,7 @@ #include "compress_string.h" #include "pnotify.h" #include "panda_getopt.h" +#include "preprocess_argv.h" void usage() { @@ -55,7 +56,7 @@ usage() { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { extern char *optarg; extern int optind; const char *optstr = "o:c123456789h"; @@ -65,6 +66,7 @@ main(int argc, char *argv[]) { bool use_stdout = false; int compression_level = 6; + preprocess_argv(argc, argv); int flag = getopt(argc, argv, optstr); while (flag != EOF) { diff --git a/panda/src/testbed/pgrid.cxx b/panda/src/testbed/pgrid.cxx index a85cc1662f..422de94766 100644 --- a/panda/src/testbed/pgrid.cxx +++ b/panda/src/testbed/pgrid.cxx @@ -19,6 +19,7 @@ #include "string_utils.h" #include "pvector.h" #include "panda_getopt.h" +#include "preprocess_argv.h" #define RANDFRAC (rand()/(PN_stdfloat)(RAND_MAX)) @@ -382,9 +383,9 @@ load_gridded_models(WindowFramework *window, } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { + preprocess_argv(argc, argv); PandaFramework framework; - vector_string args; framework.open_framework(argc, argv); framework.set_window_title("Gridded Object Viewer"); diff --git a/panda/src/testbed/pview.cxx b/panda/src/testbed/pview.cxx index 52548cc2e8..312adcda6f 100644 --- a/panda/src/testbed/pview.cxx +++ b/panda/src/testbed/pview.cxx @@ -24,6 +24,7 @@ #include "bamCache.h" #include "virtualFileSystem.h" #include "panda_getopt.h" +#include "preprocess_argv.h" // By including checkPandaVersion.h, we guarantee that runtime // attempts to run pview will fail if it inadvertently links with the @@ -223,7 +224,8 @@ report_version() { } int -main(int argc, char *argv[]) { +main(int argc, char **argv) { + preprocess_argv(argc, argv); framework.open_framework(argc, argv); framework.set_window_title("Panda Viewer"); diff --git a/pandatool/src/progbase/programBase.cxx b/pandatool/src/progbase/programBase.cxx index fcb74971cd..c5f3051748 100644 --- a/pandatool/src/progbase/programBase.cxx +++ b/pandatool/src/progbase/programBase.cxx @@ -26,6 +26,7 @@ #include "configVariableInt.h" #include "configVariableBool.h" #include "panda_getopt_long.h" +#include "preprocess_argv.h" #include #include @@ -198,8 +199,8 @@ show_text(const string &prefix, int indent_width, string text) { // exit(1). //////////////////////////////////////////////////////////////////// void ProgramBase:: -parse_command_line(int argc, char *argv[]) { - +parse_command_line(int argc, char **argv) { + preprocess_argv(argc, argv); // Setting this variable to zero reinitializes the options parser // This is only necessary for processing multiple command lines in diff --git a/pandatool/src/progbase/programBase.h b/pandatool/src/progbase/programBase.h index 1e2d01b161..c84c8e4742 100644 --- a/pandatool/src/progbase/programBase.h +++ b/pandatool/src/progbase/programBase.h @@ -46,7 +46,7 @@ public: INLINE void show_text(const string &text); void show_text(const string &prefix, int indent_width, string text); - virtual void parse_command_line(int argc, char *argv[]); + virtual void parse_command_line(int argc, char **argv); string get_exec_command() const;