xsel

Program for manipulating the X clipboard
git clone https://git.sinitax.com/kfish/xsel
Log | Files | Refs | README | LICENSE | sfeed.txt

commit 20967f0e8a0e974e401bf1d64bb12f13d6435a7a
parent 39cd852a98148cf21f1cbc448195137e88285b4a
Author: conrad <conrad@9c49b5d1-7df3-0310-bce2-b7278e68f44c>
Date:   Tue, 12 Feb 2008 04:37:54 +0000

Expand the argument array to handle combined single-letter arguments, eg. so
"xsel -ao" is equivalent to "xsel -a -o".
Patch by Christopher Wellons, adapted to preserve argument order and avoid
potential memory leaks with multiple groups of arguments.


git-svn-id: http://svn.kfish.org/xsel/trunk@208 9c49b5d1-7df3-0310-bce2-b7278e68f44c

Diffstat:
Mxsel.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+), 0 deletions(-)

diff --git a/xsel.c b/xsel.c @@ -90,6 +90,9 @@ static int current_alloc = 0; static long timeout = 0; static struct itimerval timer; +static int saved_argc; +static char ** saved_argv; + /* * usage () * @@ -1801,6 +1804,81 @@ exchange_selections (void) set_selection_pair__daemon (text2, text1); } +/* + * free_saved_argv () + * + * atexit function for freeing argv, after it has been relocated to the + * heap. + */ +static void +free_saved_argv (void) +{ + int i; + + for (i=0; i < saved_argc; i++) { + free (saved_argv[i]); + } + free (saved_argv); +} + +/* + * expand_argv (&argc, &argv) + * + * Explodes single letter options so that the argument parser can see + * all of them. Relocates argv and all arguments to the heap. + */ +static void +expand_argv(int * argc, char **argv[]) +{ + int i, new_i, arglen, new_argc = *argc; + char ** new_argv; + char * arg; + + /* Calculate new argc */ + for (i = 0; i < *argc; i++) { + arglen = strlen((*argv)[i]); + /* An option we need to expand? */ + if ((arglen > 2) && (*argv)[i][0] == '-' && (*argv)[i][1] != '-') + new_argc += arglen-2; + } + + /* Allocate new_argv */ + new_argv = xs_malloc (new_argc * sizeof(char *)); + + /* Copy args into new argv */ + for (i = 0, new_i = 0; i < *argc; i++) { + arglen = strlen((*argv)[i]); + + /* An option we need to expand? */ + if ((arglen > 2) + && (*argv)[i][0] == '-' && (*argv)[i][1] != '-') { + /* Make each letter a new argument. */ + + char * c = ((*argv)[i] + 1); + + while (*c != '\0') { + arg = xs_malloc(sizeof(char) * 3); + arg[0] = '-'; + arg[1] = *c; + arg[2] = '\0'; + new_argv[new_i++] = arg; + c++; + } + } else { + /* Simply copy the argument pointer to new_argv */ + new_argv[new_i++] = strdup ((*argv)[i]); + } + } + + /* Set the expected return values */ + *argc = new_argc; + *argv = new_argv; + + /* Save the new argc, argv values and free them on exit */ + saved_argc = new_argc; + saved_argv = new_argv; + atexit (free_saved_argv); +} /* * main (argc, argv) @@ -1855,6 +1933,9 @@ main(int argc, char *argv[]) #define OPT(s) (strcmp (argv[i], (s)) == 0) + /* Expand argv array before parsing to uncombine arguments. */ + expand_argv(&argc, &argv); + /* Parse options; modify behaviour according to user-specified options */ for (i=1; i < argc; i++) { if (OPT("--help") || OPT("-h")) {