Changeset 208

Show
Ignore:
Timestamp:
02/12/08 13:37:54 (9 months ago)
Author:
conrad
Message:

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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • xsel/trunk/xsel.c

    r205 r208  
    9090static long timeout = 0; 
    9191static struct itimerval timer; 
     92 
     93static int saved_argc; 
     94static char ** saved_argv; 
    9295 
    9396/* 
     
    18021805} 
    18031806 
     1807/* 
     1808 * free_saved_argv () 
     1809 * 
     1810 * atexit function for freeing argv, after it has been relocated to the 
     1811 * heap. 
     1812 */ 
     1813static void 
     1814free_saved_argv (void) 
     1815{ 
     1816  int i; 
     1817 
     1818  for (i=0; i < saved_argc; i++) { 
     1819    free (saved_argv[i]); 
     1820  } 
     1821  free (saved_argv); 
     1822} 
     1823 
     1824/* 
     1825 * expand_argv (&argc, &argv) 
     1826 * 
     1827 * Explodes single letter options so that the argument parser can see 
     1828 * all of them. Relocates argv and all arguments to the heap. 
     1829 */ 
     1830static void  
     1831expand_argv(int * argc, char **argv[]) 
     1832{ 
     1833  int i, new_i, arglen, new_argc = *argc; 
     1834  char ** new_argv; 
     1835  char * arg; 
     1836  
     1837  /* Calculate new argc */ 
     1838  for (i = 0; i < *argc; i++) { 
     1839    arglen = strlen((*argv)[i]); 
     1840    /* An option we need to expand? */ 
     1841    if ((arglen > 2) && (*argv)[i][0] == '-' && (*argv)[i][1] != '-') 
     1842      new_argc += arglen-2; 
     1843  } 
     1844 
     1845  /* Allocate new_argv */ 
     1846  new_argv = xs_malloc (new_argc * sizeof(char *)); 
     1847 
     1848  /* Copy args into new argv */ 
     1849  for (i = 0, new_i = 0; i < *argc; i++) { 
     1850    arglen = strlen((*argv)[i]); 
     1851    
     1852    /* An option we need to expand? */ 
     1853    if ((arglen > 2) 
     1854        && (*argv)[i][0] == '-' && (*argv)[i][1] != '-') { 
     1855      /* Make each letter a new argument. */ 
     1856 
     1857      char * c = ((*argv)[i] + 1); 
     1858      
     1859      while (*c != '\0') { 
     1860        arg = xs_malloc(sizeof(char) * 3); 
     1861        arg[0] = '-'; 
     1862        arg[1] = *c; 
     1863        arg[2] = '\0'; 
     1864        new_argv[new_i++] = arg; 
     1865        c++; 
     1866      } 
     1867    } else { 
     1868      /* Simply copy the argument pointer to new_argv */ 
     1869      new_argv[new_i++] = strdup ((*argv)[i]); 
     1870    } 
     1871  } 
     1872 
     1873  /* Set the expected return values */ 
     1874  *argc = new_argc; 
     1875  *argv = new_argv; 
     1876 
     1877  /* Save the new argc, argv values and free them on exit */ 
     1878  saved_argc = new_argc; 
     1879  saved_argv = new_argv; 
     1880  atexit (free_saved_argv); 
     1881} 
    18041882 
    18051883/* 
     
    18551933 
    18561934#define OPT(s) (strcmp (argv[i], (s)) == 0) 
     1935 
     1936  /* Expand argv array before parsing to uncombine arguments. */ 
     1937  expand_argv(&argc, &argv); 
    18571938 
    18581939  /* Parse options; modify behaviour according to user-specified options */