int poptAddAlias(poptContext con, struct poptAlias alias, /*@unused@*/ int flags) { poptItem item = (poptItem)alloca(sizeof(*item)); memset(item, 0, sizeof(*item)); item->option.longName = alias.longName; item->option.shortName = alias.shortName; item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; item->option.arg = 0; item->option.val = 0; item->option.descrip = NULL; item->option.argDescrip = NULL; item->argc = alias.argc; item->argv = alias.argv; return poptAddItem(con, item, 0); }
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ static int poptConfigLine(poptContext con, char * line) /*@globals fileSystem, internalState @*/ /*@modifies con, fileSystem, internalState @*/ { char *b = NULL; size_t nb = 0; char * se = line; const char * appName; const char * entryType; const char * opt; struct poptItem_s item_buf; poptItem item = &item_buf; int i, j; int rc = POPT_ERROR_BADCONFIG; if (con->appName == NULL) goto exit; memset(item, 0, sizeof(*item)); appName = se; while (*se != '\0' && !_isspaceptr(se)) se++; if (*se == '\0') goto exit; else *se++ = '\0'; if (configAppMatch(con, appName)) goto exit; while (*se != '\0' && _isspaceptr(se)) se++; entryType = se; while (*se != '\0' && !_isspaceptr(se)) se++; if (*se != '\0') *se++ = '\0'; while (*se != '\0' && _isspaceptr(se)) se++; if (*se == '\0') goto exit; opt = se; while (*se != '\0' && !_isspaceptr(se)) se++; if (opt[0] == '-' && *se == '\0') goto exit; if (*se != '\0') *se++ = '\0'; while (*se != '\0' && _isspaceptr(se)) se++; if (opt[0] == '-' && *se == '\0') goto exit; /*@-temptrans@*/ /* FIX: line alias is saved */ if (opt[0] == '-' && opt[1] == '-') item->option.longName = opt + 2; else if (opt[0] == '-' && opt[2] == '\0') item->option.shortName = opt[1]; else { const char * fn = opt; /* XXX handle globs and directories in fn? */ if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0) goto exit; if (b == NULL || nb == 0) goto exit; /* Append remaining text to the interpolated file option text. */ if (*se != '\0') { size_t nse = strlen(se) + 1; if ((b = realloc(b, (nb + nse))) == NULL) /* XXX can't happen */ goto exit; (void) stpcpy( stpcpy(&b[nb-1], " "), se); nb += nse; } se = b; /* Use the basename of the path as the long option name. */ { const char * longName = strrchr(fn, '/'); if (longName != NULL) longName++; else longName = fn; if (longName == NULL) /* XXX can't happen. */ goto exit; /* Single character basenames are treated as short options. */ if (longName[1] != '\0') item->option.longName = longName; else item->option.shortName = longName[0]; } } /*@=temptrans@*/ if (poptParseArgvString(se, &item->argc, &item->argv)) goto exit; /*@-modobserver@*/ item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; for (i = 0, j = 0; i < item->argc; i++, j++) { const char * f; if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { f = item->argv[i] + sizeof("--POPTdesc="); if (f[0] == '$' && f[1] == '"') f++; item->option.descrip = f; item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; j--; } else if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { f = item->argv[i] + sizeof("--POPTargs="); if (f[0] == '$' && f[1] == '"') f++; item->option.argDescrip = f; item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; item->option.argInfo |= POPT_ARG_STRING; j--; } else if (j != i) item->argv[j] = item->argv[i]; } if (j != i) { item->argv[j] = NULL; item->argc = j; } /*@=modobserver@*/ /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ if (!strcmp(entryType, "alias")) rc = poptAddItem(con, item, 0); else if (!strcmp(entryType, "exec")) rc = poptAddItem(con, item, 1); /*@=nullstate@*/ exit: rc = 0; /* XXX for now, always return success */ if (b) free(b); return rc; }
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ static void configLine(poptContext con, char * line) /*@modifies con @*/ { /*@-type@*/ int nameLength = strlen(con->appName); /*@=type@*/ const char * entryType; const char * opt; poptItem item = alloca(sizeof(*item)); int i, j; /*@-boundswrite@*/ memset(item, 0, sizeof(*item)); /*@-type@*/ if (strncmp(line, con->appName, nameLength)) return; /*@=type@*/ line += nameLength; if (*line == '\0' || !isspace(*line)) return; while (*line != '\0' && isspace(*line)) line++; entryType = line; while (*line == '\0' || !isspace(*line)) line++; *line++ = '\0'; while (*line != '\0' && isspace(*line)) line++; if (*line == '\0') return; opt = line; while (*line == '\0' || !isspace(*line)) line++; *line++ = '\0'; while (*line != '\0' && isspace(*line)) line++; if (*line == '\0') return; /*@-temptrans@*/ /* FIX: line alias is saved */ if (opt[0] == '-' && opt[1] == '-') item->option.longName = opt + 2; else if (opt[0] == '-' && opt[2] == '\0') item->option.shortName = opt[1]; /*@=temptrans@*/ if (poptParseArgvString(line, &item->argc, &item->argv)) return; /*@-modobserver@*/ item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; for (i = 0, j = 0; i < item->argc; i++, j++) { const char * f; if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { f = item->argv[i] + sizeof("--POPTdesc="); if (f[0] == '$' && f[1] == '"') f++; item->option.descrip = f; item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; j--; } else if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { f = item->argv[i] + sizeof("--POPTargs="); if (f[0] == '$' && f[1] == '"') f++; item->option.argDescrip = f; item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; item->option.argInfo |= POPT_ARG_STRING; j--; } else if (j != i) item->argv[j] = item->argv[i]; } if (j != i) { item->argv[j] = NULL; item->argc = j; } /*@=modobserver@*/ /*@=boundswrite@*/ /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ if (!strcmp(entryType, "alias")) (void) poptAddItem(con, item, 0); else if (!strcmp(entryType, "exec")) (void) poptAddItem(con, item, 1); /*@=nullstate@*/ }