popt/poptparse.c

ソースコードを見る。

関数

int poptDupArgv (int argc, const char **argv, int *argcPtr, const char ***argvPtr)
 Duplicate an argument array.
int poptParseArgvString (const char *s, int *argcPtr, const char ***argvPtr)
 Parse a string into an argument array.
int poptConfigFileToString (FILE *fp, char **argstrp, int flags)
 Parses an input configuration file and returns an string that is a command line.


説明

poptparse.c で定義されています。


関数

int poptDupArgv ( int  argc,
const char **  argv,
int *  argcPtr,
const char ***  argvPtr 
)

Duplicate an argument array.

覚え書き:
: The argument array is malloc'd as a single area, so only argv must be free'd.
引数:
argc no. of arguments
argv argument array
戻り値:
argcPtr address of returned no. of arguments
argvPtr address of returned argument array
戻り値:
0 on success, POPT_ERROR_NOARG on failure

poptparse.c14 行で定義されています。

参照元 handleAlias()poptParseArgvString()poptStuffArgs().

00016 {
00017     size_t nb = (argc + 1) * sizeof(*argv);
00018     const char ** argv2;
00019     char * dst;
00020     int i;
00021 
00022     if (argc <= 0 || argv == NULL)      /* XXX can't happen */
00023         return POPT_ERROR_NOARG;
00024     for (i = 0; i < argc; i++) {
00025         if (argv[i] == NULL)
00026             return POPT_ERROR_NOARG;
00027         nb += strlen(argv[i]) + 1;
00028     }
00029         
00030     dst = malloc(nb);
00031     if (dst == NULL)                    /* XXX can't happen */
00032         return POPT_ERROR_MALLOC;
00033     argv2 = (void *) dst;
00034     dst += (argc + 1) * sizeof(*argv);
00035 
00036     /*@-branchstate@*/
00037     for (i = 0; i < argc; i++) {
00038         argv2[i] = dst;
00039         dst += strlen(strcpy(dst, argv[i])) + 1;
00040     }
00041     /*@=branchstate@*/
00042     argv2[argc] = NULL;
00043 
00044     if (argvPtr) {
00045         *argvPtr = argv2;
00046     } else {
00047         free(argv2);
00048         argv2 = NULL;
00049     }
00050     if (argcPtr)
00051         *argcPtr = argc;
00052     return 0;
00053 }

int poptParseArgvString ( const char *  s,
int *  argcPtr,
const char ***  argvPtr 
)

Parse a string into an argument array.

The parse allows ', ", and \ quoting, but ' is treated the same as " and both may include \ quotes.

覚え書き:
: The argument array is malloc'd as a single area, so only argv must be free'd.
引数:
s string to parse
戻り値:
argcPtr address of returned no. of arguments
argvPtr address of returned argument array

poptparse.c57 行で定義されています。

参照先 alloca()bufpoptDupArgv().

参照元 configLine()net_rpc_shell()process_cmd().

00058 {
00059     const char * src;
00060     char quote = '\0';
00061     int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
00062     const char ** argv = malloc(sizeof(*argv) * argvAlloced);
00063     int argc = 0;
00064     int buflen = strlen(s) + 1;
00065     char * buf = memset(alloca(buflen), 0, buflen);
00066     int rc = POPT_ERROR_MALLOC;
00067 
00068     if (argv == NULL) return rc;
00069     argv[argc] = buf;
00070 
00071     for (src = s; *src != '\0'; src++) {
00072         if (quote == *src) {
00073             quote = '\0';
00074         } else if (quote != '\0') {
00075             if (*src == '\\') {
00076                 src++;
00077                 if (!*src) {
00078                     rc = POPT_ERROR_BADQUOTE;
00079                     goto exit;
00080                 }
00081                 if (*src != quote) *buf++ = '\\';
00082             }
00083             *buf++ = *src;
00084         } else if (isspace(*src)) {
00085             if (*argv[argc] != '\0') {
00086                 buf++, argc++;
00087                 if (argc == argvAlloced) {
00088                     argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
00089                     argv = realloc(argv, sizeof(*argv) * argvAlloced);
00090                     if (argv == NULL) goto exit;
00091                 }
00092                 argv[argc] = buf;
00093             }
00094         } else switch (*src) {
00095           case '"':
00096           case '\'':
00097             quote = *src;
00098             /*@switchbreak@*/ break;
00099           case '\\':
00100             src++;
00101             if (!*src) {
00102                 rc = POPT_ERROR_BADQUOTE;
00103                 goto exit;
00104             }
00105             /*@fallthrough@*/
00106           default:
00107             *buf++ = *src;
00108             /*@switchbreak@*/ break;
00109         }
00110     }
00111 
00112     if (strlen(argv[argc])) {
00113         argc++, buf++;
00114     }
00115 
00116     rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
00117 
00118 exit:
00119     if (argv) free(argv);
00120     return rc;
00121 }

int poptConfigFileToString ( FILE *  fp,
char **  argstrp,
int  flags 
)

Parses an input configuration file and returns an string that is a command line.

For use with popt. You must free the return value when done.

Given the file:

# this line is ignored
    #   this one too
aaa
  bbb
    ccc
bla=bla

this_is   =   fdsafdas
     bad_line=
  reall bad line
  reall bad line  = again
5555=   55555
  test = with lots of spaces

The result is:

--aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces"

Passing this to poptParseArgvString() yields an argv of:

'--aaa'
'--bbb'
'--ccc'
'--bla=bla'
'--this_is=fdsafdas'
'--5555=55555'
'--test=with lots of spaces'

バグ:
NULL is returned if file line is too long.

Silently ignores invalid lines.

引数:
fp file handle to read
*argstrp return string of options (malloc'd)
flags unused
戻り値:
0 on success
参照:
poptParseArgvString

poptparse.c129 行で定義されています。

参照先 linet.

00130 {
00131     char line[999];
00132     char * argstr;
00133     char * p;
00134     char * q;
00135     char * x;
00136     int t;
00137     int argvlen = 0;
00138     size_t maxlinelen = sizeof(line);
00139     size_t linelen;
00140     int maxargvlen = 480;
00141     int linenum = 0;
00142 
00143     *argstrp = NULL;
00144 
00145     /*   |   this_is   =   our_line
00146      *       p             q      x
00147      */
00148 
00149     if (fp == NULL)
00150         return POPT_ERROR_NULLARG;
00151 
00152     argstr = calloc(maxargvlen, sizeof(*argstr));
00153     if (argstr == NULL) return POPT_ERROR_MALLOC;
00154 
00155     while (fgets(line, (int)maxlinelen, fp) != NULL) {
00156         linenum++;
00157         p = line;
00158 
00159         /* loop until first non-space char or EOL */
00160         while( *p != '\0' && isspace(*p) )
00161             p++;
00162 
00163         linelen = strlen(p);
00164         if (linelen >= maxlinelen-1)
00165             return POPT_ERROR_OVERFLOW; /* XXX line too long */
00166 
00167         if (*p == '\0' || *p == '\n') continue; /* line is empty */
00168         if (*p == '#') continue;                /* comment line */
00169 
00170         q = p;
00171 
00172         while (*q != '\0' && (!isspace(*q)) && *q != '=')
00173             q++;
00174 
00175         if (isspace(*q)) {
00176             /* a space after the name, find next non space */
00177             *q++='\0';
00178             while( *q != '\0' && isspace((int)*q) ) q++;
00179         }
00180         if (*q == '\0') {
00181             /* single command line option (ie, no name=val, just name) */
00182             q[-1] = '\0';               /* kill off newline from fgets() call */
00183             argvlen += (t = q - p) + (sizeof(" --")-1);
00184             if (argvlen >= maxargvlen) {
00185                 maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
00186                 argstr = realloc(argstr, maxargvlen);
00187                 if (argstr == NULL) return POPT_ERROR_MALLOC;
00188             }
00189             strcat(argstr, " --");
00190             strcat(argstr, p);
00191             continue;
00192         }
00193         if (*q != '=')
00194             continue;   /* XXX for now, silently ignore bogus line */
00195 
00196         /* *q is an equal sign. */
00197         *q++ = '\0';
00198 
00199         /* find next non-space letter of value */
00200         while (*q != '\0' && isspace(*q))
00201             q++;
00202         if (*q == '\0')
00203             continue;   /* XXX silently ignore missing value */
00204 
00205         /* now, loop and strip all ending whitespace */
00206         x = p + linelen;
00207         while (isspace(*--x))
00208             *x = 0;     /* null out last char if space (including fgets() NL) */
00209 
00210         /* rest of line accept */
00211         t = x - p;
00212         argvlen += t + (sizeof("' --='")-1);
00213         if (argvlen >= maxargvlen) {
00214             maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
00215             argstr = realloc(argstr, maxargvlen);
00216             if (argstr == NULL) return POPT_ERROR_MALLOC;
00217         }
00218         strcat(argstr, " --");
00219         strcat(argstr, p);
00220         strcat(argstr, "=\"");
00221         strcat(argstr, q);
00222         strcat(argstr, "\"");
00223     }
00224 
00225     *argstrp = argstr;
00226     return 0;
00227 }


Sambaに対してSat Aug 29 21:24:02 2009に生成されました。  doxygen 1.4.7