You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/08/22 16:18:48 UTC
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
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: