X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/c0a8159289da8df577cc28be1f0c9f7f5c8d33c1..ae0500e538e2fb821ef1ad8529aed7999acf7a19:/winutils.c diff --git a/winutils.c b/winutils.c index f47eb1b5..b2921245 100644 --- a/winutils.c +++ b/winutils.c @@ -1,15 +1,18 @@ /* - * winutils.c: miscellaneous Windows utilities + * winutils.c: miscellaneous Windows utilities for GUI apps */ #include #include +#include -#define lenof(x) ( sizeof((x)) / sizeof(*(x)) ) +#include "misc.h" #ifdef TESTMODE /* Definitions to allow this module to be compiled standalone for testing. */ #define smalloc malloc +#define srealloc realloc +#define sfree free #endif /* @@ -20,13 +23,22 @@ * utilities which get a whole command line and must break it * themselves). * - * Does not modify the input command line (just in case). + * Does not modify the input command line. + * + * The final parameter (argstart) is used to return a second array + * of char * pointers, the same length as argv, each one pointing + * at the start of the corresponding element of argv in the + * original command line. So if you get half way through processing + * your command line in argc/argv form and then decide you want to + * treat the rest as a raw string, you can. If you don't want to, + * `argstart' can be safely left NULL. */ -void split_into_argv(const char *cmdline, int *argc, char ***argv) +void split_into_argv(char *cmdline, int *argc, char ***argv, + char ***argstart) { - const char *p; + char *p; char *outputline, *q; - char **outputargv; + char **outputargv, **outputargstart; int outputargc; /* @@ -121,11 +133,24 @@ void split_into_argv(const char *cmdline, int *argc, char ***argv) */ /* + * First deal with the simplest of all special cases: if there + * aren't any arguments, return 0,NULL,NULL. + */ + while (*cmdline && isspace(*cmdline)) cmdline++; + if (!*cmdline) { + if (argc) *argc = 0; + if (argv) *argv = NULL; + if (argstart) *argstart = NULL; + return; + } + + /* * This will guaranteeably be big enough; we can realloc it * down later. */ - outputline = malloc(1+strlen(cmdline)); - outputargv = malloc(sizeof(char *) * (strlen(cmdline)+1 / 2)); + outputline = snewn(1+strlen(cmdline), char); + outputargv = snewn(strlen(cmdline)+1 / 2, char *); + outputargstart = snewn(strlen(cmdline)+1 / 2, char *); p = cmdline; q = outputline; outputargc = 0; @@ -137,7 +162,9 @@ void split_into_argv(const char *cmdline, int *argc, char ***argv) if (!*p) break; /* We have an argument; start it. */ - outputargv[outputargc++] = q; + outputargv[outputargc] = q; + outputargstart[outputargc] = p; + outputargc++; quote = 0; /* Copy data into the argument until it's finished. */ @@ -190,10 +217,12 @@ void split_into_argv(const char *cmdline, int *argc, char ***argv) *q++ = '\0'; } - outputargv = realloc(outputargv, sizeof(char *) * outputargc); + outputargv = sresize(outputargv, outputargc, char *); + outputargstart = sresize(outputargstart, outputargc, char *); if (argc) *argc = outputargc; - if (argv) *argv = outputargv; + if (argv) *argv = outputargv; else sfree(outputargv); + if (argstart) *argstart = outputargstart; else sfree(outputargstart); } #ifdef TESTMODE @@ -431,4 +460,4 @@ int main(int argc, char **argv) return 0; } -#endif \ No newline at end of file +#endif