⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 popt.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    char * bufStart = buf;
    char * src, * dst;
    char quote = '\0';
    int argvAlloced = 5;
    char ** argv = malloc(sizeof(*argv) * argvAlloced);
    char ** argv2;
    int argc = 0;
    int i;

    src = s;
    dst = buf;
    argv[argc] = buf;

    memset(buf, '\0', strlen(s) + 1);

    while (*src) {
	if (quote == *src) {
	    quote = '\0';
	} else if (quote) {
	    if (*src == '\\') {
		src++;
		if (!*src) {
		    free(argv);
		    free(bufStart);
		    return POPT_ERROR_BADQUOTE;
		}
		if (*src != quote) *buf++ = '\\';
	    }
	    *buf++ = *src;
	} else if (isspace(*src)) {
	    if (*argv[argc]) {
		buf++, argc++;
		if (argc == argvAlloced) {
		    argvAlloced += 5;
		    argv = realloc(argv, sizeof(*argv) * argvAlloced);
		}
		argv[argc] = buf;
	    }
	} else switch (*src) {
	  case '"':
	  case '\'':
	    quote = *src;
	    break;
	  case '\\':
	    src++;
	    if (!*src) {
		free(argv);
		free(bufStart);
		return POPT_ERROR_BADQUOTE;
	    }
	    /* fallthrough */
	  default:
	    *buf++ = *src;
	}

	src++;
    }

    if (strlen(argv[argc])) {
	argc++;
	buf++;
    }

    argv2 = malloc(argc * sizeof(*argv) + (buf - bufStart));
    dst = (char *)argv2;
    dst += argc * sizeof(*argv);
    memcpy(argv2, argv, argc * sizeof(*argv));
    memcpy(dst, bufStart, buf - bufStart);

    for (i = 0; i < argc; i++) {
	argv2[i] = dst + (argv[i] - bufStart);
    }

    free(argv);
    free(bufStart);
    *argvPtr = argv2;
    *argcPtr = argc;

    return 0;
}

static void configLine(poptContext con, char * line) {
    int nameLength = strlen(con->appName);
    char * opt;
    struct poptAlias alias;

    if (strncmp(line, con->appName, nameLength)) return;
    line += nameLength;
    if (!*line || !isspace(*line)) return;
    while (*line && isspace(*line)) line++;

    if (!strncmp(line, "alias", 5)) {
	line += 5;
	if (!*line || !isspace(*line)) return;
	while (*line && isspace(*line)) line++;
	if (!*line) return;

	opt = line;
	while (*line && !isspace(*line)) line++;
	if (!*line) return;
	*line++ = '\0';
	while (*line && isspace(*line)) line++;
	if (!*line) return;

	if (!strlen(opt)) return;

	if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;

	if (opt[0] == '-' && opt[1] == '-') {
	    alias.longName = opt + 2;
	    alias.shortName = '\0';
	    poptAddAlias(con, alias, 0);
	} else if (opt[0] == '-' && !opt[2]) {
	    alias.longName = NULL;
	    alias.shortName = opt[1];
	    poptAddAlias(con, alias, 0);
	}
    }
}

int poptReadConfigFile(poptContext con, char * fn) {
    char * file, * chptr, * end;
    char * buf, * dst;
    int fd, rc;
    int fileLength;

    fd = open(fn, O_RDONLY);
    if (fd < 0) {
	if (errno == ENOENT)
	    return 0;
	else
	    return POPT_ERROR_ERRNO;
    }

    fileLength = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, 0);

#ifndef HAVE_MMAP
    file = (char*) xmalloc (fileLength, "poptReadConfigFile");
    if (file == NULL)
#else /* HAVE_MMAP */
    file = mmap(NULL, fileLength, PROT_READ, MAP_PRIVATE, fd, 0);
    if (file == (void *) -1)
#endif /* HAVE_MMAP */
    {
	rc = errno;
	close(fd);
	errno = rc;
	return POPT_ERROR_ERRNO;
    }
#ifndef HAVE_MMAP
	do
	{
	    lseek(fd, 0, 0);
		rc = read(fd, file, fileLength);
		if (rc == -1 && errno != EINTR)
		{
			free(file);
			return POPT_ERROR_ERRNO;
		}
	} while (rc != fileLength || (rc == -1 && errno == EINTR));
#endif /* HAVE_MMAP */
    close(fd);

    dst = buf = malloc(fileLength + 1);

    chptr = file;
    end = (file + fileLength);
    while (chptr < end) {
	switch (*chptr) {
	  case '\n':
	    *dst = '\0';
	    dst = buf;
	    while (*dst && isspace(*dst)) dst++;
	    if (*dst && *dst != '#') {
		configLine(con, dst);
	    }
	    chptr++;
	    break;
	  case '\\':
	    *dst++ = *chptr++;
	    if (chptr < end) {
		if (*chptr == '\n')
		    dst--, chptr++;
		    /* \ at the end of a line does not insert a \n */
		else
		    *dst++ = *chptr++;
	    }
	    break;
	  default:
	    *dst++ = *chptr++;
	}
    }
    free (buf);
#ifndef HAVE_MMAP
    free (file);
#else
    munmap (file, fileLength);
#endif
    return 0;
}

int poptReadDefaultConfig(poptContext con, int useEnv) {
    char * envName, * envValue, * envValueStart;
    char * fn, * home, * chptr;
    int rc, skip;
    struct poptAlias alias;

    if (!con->appName) return 0;

    rc = poptReadConfigFile(con, "/etc/popt");
    if (rc) return rc;
    if ((home = getenv("HOME"))) {
	fn = (char *) malloc (strlen(home) + 20);
	sprintf(fn, "%s/.popt", home);
	rc = poptReadConfigFile(con, fn);
	free (fn);
	if (rc) return rc;
    }

    envName = malloc(strlen(con->appName) + 20);
    strcpy(envName, con->appName);
    chptr = envName;
    while (*chptr) {
	*chptr = toupper(*chptr);
	chptr++;
    }
    strcat(envName, "_POPT_ALIASES");

    if (useEnv && (envValue = getenv(envName))) {
	envValue = envValueStart = strcpy(malloc(strlen(envValue) + 1), envValue);

	while (envValue && *envValue) {
	    chptr = strchr(envValue, '=');
	    if (!chptr) {
		envValue = strchr(envValue, '\n');
		if (envValue) envValue++;
		continue;
	    }

	    *chptr = '\0';

	    skip = 0;
	    if (!strncmp(envValue, "--", 2)) {
		alias.longName = envValue + 2;
		alias.shortName = '\0';
	    } else if (*envValue == '-' && strlen(envValue) == 2) {
		alias.longName = NULL;
		alias.shortName = envValue[1];
	    } else {
		skip = 1;
	    }

	    envValue = chptr + 1;
	    chptr = strchr(envValue, '\n');
	    if (chptr) *chptr = '\0';

	    if (!skip) {
		poptParseArgvString(envValue, &alias.argc, &alias.argv);
		poptAddAlias(con, alias, 0);
	    }

	    if (chptr)
		envValue = chptr + 1;
	    else
		envValue = NULL;
	}
	free(envValueStart);
    }

    free (envName);
    return 0;
}

char * poptBadOption(poptContext con, int flags) {
    struct optionStackEntry * os;

    if (flags & POPT_BADOPTION_NOALIAS)
	os = con->optionStack;
    else
	os = con->os;

    return os->argv[os->next - 1];
}

#define POPT_ERROR_NOARG	-10
#define POPT_ERROR_BADOPT	-11
#define POPT_ERROR_OPTSTOODEEP	-13
#define POPT_ERROR_BADQUOTE	-15	/* only from poptParseArgString() */
#define POPT_ERROR_ERRNO	-16	/* only from poptParseArgString() */

const char * poptStrerror(const int error) {
    switch (error) {
      case POPT_ERROR_NOARG:
	return "missing argument";
      case POPT_ERROR_BADOPT:
	return "unknown option";
      case POPT_ERROR_OPTSTOODEEP:
	return "aliases nested too deeply";
      case POPT_ERROR_BADQUOTE:
	return "error in paramter quoting";
      case POPT_ERROR_BADNUMBER:
	return "invalid numeric value";
      case POPT_ERROR_OVERFLOW:
	return "number too large or too small";
      case POPT_ERROR_ERRNO:
#ifdef HAVE_STRERROR
        return strerror (errno);
#else
      {
        extern int sys_nerr;
        extern char *sys_errlist [];
        if ((0 <= errno) && (errno < sys_nerr))
          return sys_errlist[errno];
        else
          return "strange errno";
      }
#endif
      default:
	return "unknown error";
    }
}

int poptStuffArgs(poptContext con, char ** argv) {
    int i;

    if ((con->os - con->optionStack) == POPT_OPTION_DEPTH)
	return POPT_ERROR_OPTSTOODEEP;

    for (i = 0; argv[i]; i++);

    con->os++;
    con->os->next = 0;
    con->os->nextArg = con->os->nextCharArg = NULL;
    con->os->currAlias = NULL;
    con->os->argc = i;
    con->os->argv = argv;

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -