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 19:45:08 UTC
svn commit: r806872 - in /commons/sandbox/runtime/trunk/src/main/native:
include/acr_ini.h shared/ini.c test/sample.properties test/testsuite.c
Author: mturk
Date: Sat Aug 22 17:45:08 2009
New Revision: 806872
URL: http://svn.apache.org/viewvc?rev=806872&view=rev
Log:
Java Properties file parser
Added:
commons/sandbox/runtime/trunk/src/main/native/test/sample.properties (with props)
Modified:
commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h
commons/sandbox/runtime/trunk/src/main/native/shared/ini.c
commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c
Modified: 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=806872&r1=806871&r2=806872&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_ini.h Sat Aug 22 17:45:08 2009
@@ -64,6 +64,13 @@
*/
ACR_DECLARE(ini_section_t *) ACR_IniLoadIni(JNIEnv *env, const char *fname);
+/**
+ * Load the Java properties style configuration file.
+ * @param env Current JNI environment.
+ * @param fname INI file to load.
+ */
+ACR_DECLARE(ini_section_t *) ACR_IniLoadProps(JNIEnv *_E, const char *fname);
+
#ifdef __cplusplus
}
Modified: 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=806872&r1=806871&r2=806872&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/ini.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/ini.c Sat Aug 22 17:45:08 2009
@@ -151,6 +151,22 @@
return s + i;
}
+static char *rltrim_p(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]) || s[i] == ':' || s[i] == '='); i++)
+ ;
+
+ return s + i;
+}
+
static char *expand_envars(char *s)
{
/* TODO: Implement ${ENV} expansion.
@@ -216,7 +232,7 @@
continue;
}
line = ltrim(buffer);
- /* Skip comments and empty lines*/
+ /* Skip comments and empty lines */
if (*line == '\0' || *line == '#' || *line == ';')
continue;
if (*line == '[') {
@@ -272,3 +288,136 @@
return NULL;
}
+ACR_DECLARE(ini_section_t *) ACR_IniLoadProps(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;
+
+ 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;
+ char *ssep;
+ /* Trim readed line */
+ counter++;
+ line = rtrim(buffer);
+ if (nextline) {
+ nextline = 0;
+ /* Java props are left trimmed
+ */
+ line = ltrim(line);
+ 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;
+ /* TODO: Use strpbrk that understands quoted char's
+ */
+ ssep = strpbrk(line, ". :=");
+ if (ssep && *ssep == '.') {
+ char *val = NULL;
+ char *equ;
+ char *sub;
+ *(ssep++) = '\0';
+ /* Get root subsection */
+ section = line;
+ if (!(ini = ini_section_get(top, section))) {
+ ini = ini_section_new(top);
+ ini->name = ACR_StrdupA(_E, THROW_NMARK, section);
+ }
+ while ((sub = strpbrk(ssep, ". :="))) {
+ ini_section_t *sec = ini;
+ /* Check for '=' char */
+ if (*sub != '.') {
+ /* We have found a '.' after '='
+ * The dot is part of value. bail out
+ */
+ break;
+ }
+ *(sub++) = '\0';
+ section = ssep;
+ if (!(ini = ini_section_get(sec, section))) {
+ ini = ini_child_new(sec);
+ ini->name = ACR_StrdupA(_E, THROW_NMARK, section);
+ }
+ ssep = sub;
+ }
+ if (*ssep == '=' || *ssep == ':')
+ ssep++;
+ if ((equ = strpbrk(ssep, " =:"))) {
+ *equ++ = '\0';
+ val = rltrim_p(equ);
+ if (val[strlen(val) - 1] == '\\') {
+ val[strlen(val) - 1] = '\0';
+ nextline = 1;
+ }
+ if (!*val)
+ val = NULL;
+ }
+ ssep = rltrim(ssep);
+ if (!*ssep) {
+ /* Skip entries without keys **/
+ nextline = 0;
+ continue;
+ }
+ node = ini_node_new(ini);
+ node->key = ACR_StrdupA(_E, THROW_NMARK, ssep);
+ node->val = ACR_StrdupA(_E, THROW_NMARK, val);
+ if (node->val && !nextline) {
+ node->val = expand_envars(node->val);
+ }
+ }
+ else {
+ char *val = NULL;
+ char *equ;
+ if (*line == '=' || *line == ':')
+ line++;
+ if ((equ = strpbrk(line, " =:"))) {
+ *equ++ = '\0';
+ val = rltrim_p(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(top);
+ 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;
+
+}
+
Added: commons/sandbox/runtime/trunk/src/main/native/test/sample.properties
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/sample.properties?rev=806872&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/test/sample.properties (added)
+++ commons/sandbox/runtime/trunk/src/main/native/test/sample.properties Sat Aug 22 17:45:08 2009
@@ -0,0 +1,42 @@
+# Example properties file
+! It behaves like java properties
+
+foo=level0
+section.name =:level1
+section.subsection.name = level2a
+section.subsection.name
+section.subsection.name is:level2b
+value
+second.
+third.multiline : value \
+ over multiple \
+ lines
+third.next level
+
+! Some examples from the Java 2 Documentation
+!
+Truth = Beauty
+ Truth:Beauty
+Truth :Beauty
+! As another example the following lines are
+! specify a single property
+
+fruits apple, bannana, pear, \
+ kiwi, mango
+
+invalid. remaining is ignored
+.missing
+.missing section has empty name (different then NULL)
+
+key\ with\ quoted\ chars\=: value
+
+some wired sequences
+=a
+:b
+=:
+=::what to do with that ?
+: :Double separators behave like comment
+=c=d
+:e:f
+
+
Propchange: commons/sandbox/runtime/trunk/src/main/native/test/sample.properties
------------------------------------------------------------------------------
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=806872&r1=806871&r2=806872&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 17:45:08 2009
@@ -274,6 +274,39 @@
return 0;
}
+static void dump_ini_section(ini_section_t *ini, int level)
+{
+ while (ini) {
+ ini_node_t *node = ini->nodes;
+ fprintf(stdout, "%*sSection [%s]\n", level, "", ini->name);
+ while (node) {
+ fprintf(stdout, "%*s%s -> %s\n", level + 2, "", node->key, node->val);
+ node = node->next;
+ }
+ if (ini->child) {
+ dump_ini_section(ini->child, level + 2);
+ }
+ ini = ini->next;
+ }
+
+}
+
+static int test_props(int argc, const char *const argv[])
+{
+ ini_section_t *ini;
+ ini_section_t *top;
+ if (argc < 1)
+ return 1;
+
+ ini = ACR_IniLoadProps(NULL, argv[0]);
+ fprintf(stdout, "Using Property `%s\'\n", argv[0]);
+ top = ini;
+ dump_ini_section(ini, 0);
+ ACR_IniTableFree(top);
+
+ return 0;
+}
+
int main(int argc, const char *const argv[])
{
int rv = 0;
@@ -336,6 +369,9 @@
else if (!strcasecmp(run_test, "msini")) {
rv = test_msini(argc, argv);
}
+ else if (!strcasecmp(run_test, "props")) {
+ rv = test_props(argc, argv);
+ }
}
cleanup: