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

📄 inifile.c

📁 jboss与apache集成的中间件,详情请参看文档说明.
💻 C
字号:
/* *  Copyright 1999-2004 The Apache Software Foundation * *  Licensed under the Apache License, Version 2.0 (the "License"); *  you may not use this file except in compliance with the License. *  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. *//*************************************************************************** * Description: DSAPI plugin for Lotus Domino                              * * Author:      Andy Armstrong <andy@tagish.com>                           * * Date:        20010603                                                   * * Version:     $Revision: 1.4 $                                           * ***************************************************************************/#include "config.h"#include "inifile.h"#include <ctype.h>#include <stdlib.h>#include <stdio.h>#include <string.h>/* We have one of these for each ini file line. Once we've read the * file and parsed it we'll have an array in key order containing one * of these for each configuration item in file. */typedef struct{    const char *key;    const char *value;} inifile_key;static char *file;              /* the text of the ini file                             */static inifile_key *keys;       /* an array of keys, one per item               */static size_t klen;             /* length of the key array                              *//* Text that will prefix all of our error messages */#define ERRPFX "INIFILE: "/* Various error messages that we can return */ERRTYPE inifile_outofmemory = ERRPFX "Out of memory";ERRTYPE inifile_filenotfound = ERRPFX "File not found";ERRTYPE inifile_readerror = ERRPFX "Error reading file";#define SYNFMT ERRPFX "File %s, line %d: %s"/* Case insensitive string comparison, works like strcmp() */static int inifile__stricmp(const char *s1, const char *s2){    while (*s1 && tolower(*s1) == tolower(*s2))        s1++, s2++;    return tolower(*s1) - tolower(*s2);}/* Compare keys, suitable for passing to qsort() */static int inifile__cmp(const void *k1, const void *k2){    const inifile_key *kk1 = (const inifile_key *)k1;    const inifile_key *kk2 = (const inifile_key *)k2;    return inifile__stricmp(kk1->key, kk2->key);}/* Return a new syntax error message. */static ERRTYPE inifile__syntax(jk_pool_t *p, const char *file, int line,                               const char *msg){    static const char synfmt[] = SYNFMT;    size_t len =        sizeof(synfmt) + strlen(msg) + strlen(file) +        10 /* fudge for line number */ ;    char *buf = jk_pool_alloc(p, len);    sprintf(buf, synfmt, file, line, msg);    return buf;}/* Various macros to tidy up the parsing code *//* Characters that are OK in the keyname */#define KEYCHR(c) \	(isalnum(c) || (c) == '.' || (c) == '_')/* Skip whitespace */#define SKIPSPC() \	while (*fp == '\t' || *fp == ' ') fp++/* Skip to the end of the current line */#define SKIPLN() \	while (*fp != '\0' && *fp != '\r' && *fp != '\n') fp++/* Move from the end of the current line to the start of the next, learning what the * newline character is and counting lines */#define NEXTLN() \	do { while (*fp == '\r' || *fp == '\n') { if (nlc == -1) nlc = *fp; if (*fp == nlc) ln++; fp++; } } while (0)/* Build the index. Called when the inifile is loaded by inifile_load() */static ERRTYPE inifile__index(jk_pool_t *p, const char *name){    int pass;    int ln = 1;    int nlc = -1;    /* Make two passes over the data. First time we're just counting     * the lines that contain values so we can allocate the index, second     * time we build the index.     */    for (pass = 0; pass < 2; pass++) {        char *fp = file;        char *ks = NULL, *ke;   /* key start, end */        char *vs = NULL, *ve;   /* value start, end */        klen = 0;        while (*fp != '\0') {            SKIPSPC();            /* turn a comment into an empty line by moving to the next \r|\n */            if (*fp == '#' || *fp == ';')                SKIPLN();            if (*fp != '\0' && *fp != '\r' && *fp != '\n') {                ks = fp;        /* start of key */                while (KEYCHR(*fp))                    fp++;                ke = fp;        /* end of key */                SKIPSPC();                if (*fp != '=')                    return inifile__syntax(p, name, ln,                                           "Missing '=' or illegal character in key");                fp++;           /* past the = */                SKIPSPC();                vs = fp;                SKIPLN();                ve = fp;                /* back up over any trailing space */                while (ve > vs && (ve[-1] == ' ' || ve[-1] == '\t'))                    ve--;                NEXTLN();       /* move forwards *before* we trash the eol characters */                if (NULL != keys) {     /* second pass? if so stash a pointer */                    *ke = '\0';                    *ve = '\0';                    keys[klen].key = ks;                    keys[klen].value = vs;                }                klen++;            }            else {                NEXTLN();            }        }        if (NULL == keys            && (keys =                jk_pool_alloc(p, sizeof(inifile_key) * klen), NULL == keys))            return inifile_outofmemory;    }    /* got the index now, sort it so we can search it quickly */    qsort(keys, klen, sizeof(inifile_key), inifile__cmp);    return ERRNONE;}/* Read an INI file from disk */ERRTYPE inifile_read(jk_pool_t *p, const char *name){    FILE *fl;    size_t flen;    int ok;    if (fl = fopen(name, "rb"), NULL == fl)        return inifile_filenotfound;    fseek(fl, 0L, SEEK_END);    flen = (size_t) ftell(fl);    fseek(fl, 0L, SEEK_SET);    /* allocate one extra byte for trailing \0     */    if (file = jk_pool_alloc(p, flen + 1), NULL == file) {        fclose(fl);        return inifile_outofmemory;    }    ok = (fread(file, flen, 1, fl) == 1);    fclose(fl);    if (!ok)        return inifile_readerror;    file[flen] = '\0';          /* terminate it to simplify parsing */    return inifile__index(p, name);}/* Find the value associated with the given key returning it or NULL * if no match is found. Key name matching is case insensitive. */const char *inifile_lookup(const char *key){    int lo, mid, hi, cmp;    if (NULL == keys)        return NULL;    for (lo = 0, hi = klen - 1; lo <= hi;) {        mid = (lo + hi) / 2;        cmp = inifile__stricmp(key, keys[mid].key);        if (cmp < 0)            /* key in array is greater */            hi = mid - 1;        else if (cmp > 0)            lo = mid + 1;        else            return keys[mid].value;    }    return NULL;}#ifdef TESTstatic jk_pool_t pool;extern void jk_dump_pool(jk_pool_t *p, FILE * f);       /* not declared in header */int main(void){    ERRTYPE e;    unsigned k;    int rc = 0;    jk_open_pool(&pool, NULL, 0);    e = inifile_read(&pool, "ok.ini");    if (e == ERRNONE) {        printf("%u keys in ok.ini\n", klen);        for (k = 0; k < klen; k++) {            const char *val = inifile_lookup(keys[k].key);            printf("Key: \"%s\", value: \"%s\"\n", keys[k].key, val);        }    }    else {        printf("Error reading ok.ini: %s\n", e);        rc = 1;    }    e = inifile_read(&pool, "bad.ini");    if (e == ERRNONE) {        printf("%u keys in bad.ini\n", klen);        for (k = 0; k < klen; k++) {            const char *val = inifile_lookup(keys[k].key);            printf("Key: \"%s\", value: \"%s\"\n", keys[k].key, val);        }        rc = 1;                 /* should be a syntax error */    }    else {        printf            ("Error reading bad.ini: %s (which is OK: that's what we expected)\n",             e);    }    jk_dump_pool(&pool, stdout);    jk_close_pool(&pool);    return rc;}#endif

⌨️ 快捷键说明

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