Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 9468 invoked from network); 22 Aug 2009 14:19:00 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 22 Aug 2009 14:19:00 -0000 Received: (qmail 61362 invoked by uid 500); 22 Aug 2009 14:19:21 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 61277 invoked by uid 500); 22 Aug 2009 14:19:21 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 61267 invoked by uid 99); 22 Aug 2009 14:19:21 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 22 Aug 2009 14:19:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 22 Aug 2009 14:19:09 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 605C523888FF; Sat, 22 Aug 2009 14:18:48 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r806858 - in /commons/sandbox/runtime/trunk/src/main/native: Makefile.in Makefile.msc.in include/acr_ini.h shared/ini.c test/sample.ini test/testsuite.c Date: Sat, 22 Aug 2009 14:18:48 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090822141848.605C523888FF@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mturk Date: Sat Aug 22 14:18:47 2009 New Revision: 806858 URL: http://svn.apache.org/viewvc?rev=806858&view=rev Log: Add basic ini parsing Added: commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h (with props) commons/sandbox/runtime/trunk/src/main/native/shared/ini.c (with props) commons/sandbox/runtime/trunk/src/main/native/test/sample.ini (with props) Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.in?rev=806858&r1=806857&r2=806858&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/Makefile.in (original) +++ commons/sandbox/runtime/trunk/src/main/native/Makefile.in Sat Aug 22 14:18:47 2009 @@ -86,6 +86,7 @@ $(SRCDIR)/shared/error.$(OBJ) \ $(SRCDIR)/shared/fco.$(OBJ) \ $(SRCDIR)/shared/getopt.$(OBJ) \ + $(SRCDIR)/shared/ini.$(OBJ) \ $(SRCDIR)/shared/mbstr.$(OBJ) \ $(SRCDIR)/shared/memory.$(OBJ) \ $(SRCDIR)/shared/modules.$(OBJ) \ Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=806858&r1=806857&r2=806858&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original) +++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Sat Aug 22 14:18:47 2009 @@ -77,6 +77,7 @@ $(SRCDIR)/shared/error.$(OBJ) \ $(SRCDIR)/shared/fco.$(OBJ) \ $(SRCDIR)/shared/getopt.$(OBJ) \ + $(SRCDIR)/shared/ini.$(OBJ) \ $(SRCDIR)/shared/mbstr.$(OBJ) \ $(SRCDIR)/shared/memory.$(OBJ) \ $(SRCDIR)/shared/modules.$(OBJ) \ Added: commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h?rev=806858&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h (added) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h Sat Aug 22 14:18:47 2009 @@ -0,0 +1,73 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +#ifndef _ACR_INI_H +#define _ACR_INI_H + +#include "acr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file acr_ini.h + * @brief + * + * ACR configuration functions + * + */ + +typedef struct ini_node_t ini_node_t; + +struct ini_node_t { + ini_node_t *next; + ini_node_t **last; + char *key; + char *val; +}; + +typedef struct ini_section_t ini_section_t; + +struct ini_section_t { + ini_section_t *next; + ini_section_t **last; + char *name; + char *attr; + ini_node_t *nodes; + ini_section_t *child; +}; + +/** + * Free the memory used by ini table. + * @param root Root ini section. + */ +ACR_DECLARE(void) ACR_IniTableFree(ini_section_t *root); + +/** + * Load the Microsoft ini style configuration file. + * @param env Current JNI environment. + * @param fname INI file to load. + */ +ACR_DECLARE(ini_section_t *) ACR_IniLoadIni(JNIEnv *env, const char *fname); + + +#ifdef __cplusplus +} +#endif + +#endif /* _ACR_INI_H */ + Propchange: commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h ------------------------------------------------------------------------------ svn:eol-style = native Added: commons/sandbox/runtime/trunk/src/main/native/shared/ini.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/ini.c?rev=806858&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/ini.c (added) +++ commons/sandbox/runtime/trunk/src/main/native/shared/ini.c Sat Aug 22 14:18:47 2009 @@ -0,0 +1,267 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +/* + * + * @author Mladen Turk + */ + +#include "acr.h" +#include "acr_private.h" +#include "acr_arch.h" +#include "acr_error.h" +#include "acr_string.h" +#include "acr_tables.h" +#include "acr_ini.h" + +/** + * Configuration functions + */ + +#if defined(WIN32) +#define STD_FOPEN_RDFLAGS "rt" +#else +#define STD_FOPEN_RDFLAGS "r" +#endif + +static void ini_section_free(ini_section_t *ini) +{ + ini_section_t *p; + + while ((p = ini)) { + ini_node_t *n; + while ((n = ini->nodes)) { + ini->nodes = n->next; + x_free(n->key); + x_free(n->val); + x_free(n); + } + if (ini->child) { + /* Recursevly delete child sections + */ + ini_section_free(ini->child); + } + ini = p->next; + x_free(p->name); + x_free(p->attr); + x_free(p); + } +} + +static ini_section_t *ini_section_new(ini_section_t *top) +{ + ini_section_t *ini = x_calloc(sizeof(ini_section_t)); + if (top) { + *top->last = ini; + top->last = &ini->next; + } + else + ini->last = &ini->next; + + return ini; +} + +static ini_section_t *ini_child_new(ini_section_t *parent) +{ + ini_section_t *top = parent->child; + ini_section_t *ini = x_calloc(sizeof(ini_section_t)); + if (top) { + *top->last = ini; + top->last = &ini->next; + } + else { + ini->last = &ini->next; + parent->child = ini; + } + return ini; +} + +static ini_node_t *ini_node_new(ini_section_t *ini) +{ + ini_node_t *node = x_calloc(sizeof(ini_node_t)); + if (ini->nodes) { + *ini->nodes->last = node; + ini->nodes->last = &node->next; + } + else { + node->last = &node->next; + ini->nodes = node; + } + return node; +} + +static ini_section_t *ini_section_get(ini_section_t *ini, const char *name) +{ + ini_section_t *p; + if (!ini) + return NULL; + for (p = ini; p; p = p->next) { + if (p->name && !strcasecmp(p->name, name)) + return p; + } + return NULL; +} + +static char *rtrim(char *s) +{ + size_t i; + /* check for empty strings */ + if (!(i = strlen(s))) + return s; + for (i = i - 1; i >= 0 && acr_isspace(s[i]); i--) + ; + s[i + 1] = '\0'; + return s; +} + +static char *ltrim(char *s) +{ + size_t i; + for (i = 0; s[i] != '\0' && acr_isspace(s[i]); i++) + ; + + return s + i; +} + +static char *rltrim(char *s) +{ + size_t i; + /* check for empty strings */ + if (!(i = strlen(s))) + return s; + for (i = i - 1; i >= 0 && acr_isspace(s[i]); i--) + ; + s[i + 1] = '\0'; + for (i = 0; s[i] != '\0' && acr_isspace(s[i]); i++) + ; + + return s + i; +} + +static char *expand_envars(char *s) +{ + /* TODO: Implement + */ + return s; +} + +ACR_DECLARE(void) ACR_IniTableFree(ini_section_t *root) +{ + ini_section_free(root); +} + +ACR_DECLARE(ini_section_t *) ACR_IniLoadIni(JNIEnv *_E, const char *fname) +{ + FILE *fp; + ini_section_t *top = NULL; + ini_section_t *ini = NULL; + ini_node_t *node = NULL; + char buffer[ACR_PBUFF_SIZ]; + int counter = 0; + int nextline = 0; + int started = 0; + + if (!(fp = fopen(fname, STD_FOPEN_RDFLAGS))) { + ACR_THROW_IO_ERRNO(); + return NULL; + } + ini = top = ini_section_new(NULL); + while (fgets(buffer, ACR_PBUFF_SIZ, fp)) { + char *section; + char *line; + /* Trim readed line */ + counter++; + line = rtrim(buffer); + if (!started) { + line = ltrim(buffer); + /* Evrything up to first [ is comment + */ + if (*line != '[') + continue; + else + started = 1; + } + if (nextline) { + nextline = 0; + if (!node || *line == '\0') + continue; + node->val = ACR_StrcatA(_E, THROW_NMARK, node->val, line); + if (node->val[strlen(node->val) - 1] == '\\') { + node->val[strlen(node->val) - 1] = '\0'; + nextline = 1; + } + if (!nextline) { + node->val = expand_envars(node->val); + } + continue; + } + line = ltrim(buffer); + /* Skip comments and empty lines*/ + if (*line == '\0' || *line == '#' || *line == ';') + continue; + if (*line == '[') { + char *ends = strchr(++line, ']'); + if (!ends) { + sprintf(buffer, "Unterminated section at line %d", counter); + ACR_ThrowExceptionA(_E, THROW_NMARK, ACR_EX_EINVAL, buffer); + goto cleanup; + } + *ends = '\0'; + section = rltrim(line); + if (!(ini = ini_section_get(top, section))) { + ini = ini_section_new(top); + ini->name = ACR_StrdupA(_E, THROW_NMARK, section); + } + continue; + } + else { + char *val = NULL; + char *equ = line; + if (*equ == '=') + equ++; + if ((equ = strchr(equ, '='))) { + *equ++ = '\0'; + val = rltrim(equ); + if (val[strlen(val) - 1] == '\\') { + val[strlen(val) - 1] = '\0'; + nextline = 1; + } + if (!*val) + val = NULL; + } + line = rltrim(line); + if (!*line) { + /* Skip entries without keys **/ + nextline = 0; + continue; + } + node = ini_node_new(ini); + node->key = ACR_StrdupA(_E, THROW_NMARK, line); + node->val = ACR_StrdupA(_E, THROW_NMARK, val); + if (node->val && !nextline) { + node->val = expand_envars(node->val); + } + } + } + fclose(fp); + return top; + +cleanup: + fclose(fp); + ini_section_free(top); + return NULL; +} + Propchange: commons/sandbox/runtime/trunk/src/main/native/shared/ini.c ------------------------------------------------------------------------------ svn:eol-style = native Added: commons/sandbox/runtime/trunk/src/main/native/test/sample.ini URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/sample.ini?rev=806858&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/test/sample.ini (added) +++ commons/sandbox/runtime/trunk/src/main/native/test/sample.ini Sat Aug 22 14:18:47 2009 @@ -0,0 +1,49 @@ +Sample initialization file + +Everything up to the first '[' is considered as comment. +After the first section is recognized, lines starting with first +'#' or ';' characters are comments. +Empty lines are ignored. + + + [first section] +key without equal char delimiter +this is key without value = +values can be spanned on multiple lines = delimiter is '\'\ + character \ +# comments are allowed in the line \ +and '\' must be the last non whitespace char. Multiline is ended\ +by the first line without '\' char on the end +however keys cannot be spanned on \ +multiple lines +n.#ext = Names don't have to be ascii they can have any chars except = + +[second section] +#sections don't need to have any nodes +[] +; this is comment +# this is comment as well + ; comment is first non space character + +empty = section names are allowed += +== +=== += single equal is considered as key (very dumb) +multiple=keys +multiple=are not +multiple=overwitten. + +;[unterminated +;section] +; is considered as error. + +[duplicate] +section=instances +[duplicate] +section=can be repeted multiple times +[duplicate] +# variable order is preserved + + + Propchange: commons/sandbox/runtime/trunk/src/main/native/test/sample.ini ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c?rev=806858&r1=806857&r2=806858&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c Sat Aug 22 14:18:47 2009 @@ -37,6 +37,7 @@ #include "acr_env.h" #include "acr_io.h" #include "acr_dso.h" +#include "acr_ini.h" #include "acr_version.h" #if defined (WIN32) @@ -246,6 +247,33 @@ return 0; } +static int test_msini(int argc, const char *const argv[]) +{ + ini_section_t *ini; + ini_section_t *top; + if (argc < 1) + return 1; + + ini = ACR_IniLoadIni(NULL, argv[0]); + fprintf(stdout, "Using INI `%s\'\n", argv[0]); + top = ini; + while (ini) { + ini_node_t *node = ini->nodes; + if (!ini->name) + fprintf(stdout, "Root Section has NULL 'name' member\n"); + else + fprintf(stdout, "Section [%s]\n", ini->name); + while (node) { + fprintf(stdout, " %s -> %s\n", node->key, node->val); + node = node->next; + } + ini = ini->next; + } + ACR_IniTableFree(top); + + return 0; +} + int main(int argc, const char *const argv[]) { int rv = 0; @@ -305,6 +333,9 @@ else if (!strcasecmp(run_test, "error")) { rv = test_errno(argc, argv); } + else if (!strcasecmp(run_test, "msini")) { + rv = test_msini(argc, argv); + } } cleanup: