]> git.neil.brown.name Git - edlib.git/commitdiff
Move parse_ini() into a separate include file.
authorNeilBrown <neil@brown.name>
Wed, 28 Jun 2023 06:03:07 +0000 (16:03 +1000)
committerNeilBrown <neil@brown.name>
Wed, 28 Jun 2023 07:51:41 +0000 (17:51 +1000)
This makes it easy for it to be reused, or even take out into another
package.  Unlike the rest of edlib, it can be used under any popular
open source license.

Signed-off-by: NeilBrown <neil@brown.name>
Makefile
lib-config.c
parse-ini.h [new file with mode: 0644]

index c927b30d9a310f7d4f9dfa49f2aaf7ec12fbfc91..aac16c2f2a762040441a6330223ffdb0599cfeda 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -145,6 +145,8 @@ edlib-static: $(OBJ) $(STATICOBJ)  $(XOBJ) O/core-version.o
 $(OBJ) $(SHOBJ) $(LIBOBJ) $(XOBJ) $(STATICOBJ) : $(H) O/.exists
 $(LIBOBJ) : internal.h
 
+O/lib-config.o : parse-ini.h
+
 $(OBJ) : O/%.o : %.c
        $(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) $(INC-$*) -c -o $@ $<
        $(QUIET_CHECK)sparse $(CPPFLAGS) $(INC-$*) $(SPARSEFLAGS) $<
index 931b0a9caefe746f859585f5a325b840b51e5453..f49fd4484a372c8f6979a574e2de91bc086296fe 100644 (file)
  * Sections:
  *   global - set attr on editor
  *   module - set trigger to load module
- *   file:pattern - set attributes when matching file visited
- *         (not implemented fully yet)
+ *   file:glob - set attributes when matching file visited
  *
  * When not in a section, or in the "include" section, include= will
  * load another file.
  *
- * Syntax for ini file
- * - individual lines must not exceed 256 chars.  Longer lines are
- *   silently truncated.
- * - leading white space continues the previous line, this allowing large
- *   values.  The newline and leading white space are stripped.
- * - white space around "=", at EOL, and around section name in [section]
- *   is stripped
- * - Double quotes at both ends of a value are stripped.
- * - If first non-white is '#', line is ignored.
- * - Everything after closing ']' of section is ignored
- * - If value is no quoted, everything after first '#' is ignored
- * - blank lines are ignored
  */
 
 #include <unistd.h>
 #include <stdlib.h>
 #include <fcntl.h>
-#include <stdio.h>
-#include <ctype.h>
 #include "core.h"
+#include "parse-ini.h"
 
-typedef void (*ini_handle)(void *data, char *section safe,
-                          char *name safe, char *value safe,
-                          const char *path safe,
-                          int append);
 static void load_config(const char *path safe, void *data, const char *base);
 
-static void parse_ini(const char *path safe, ini_handle handle, void *data)
-{
-       FILE *f = fopen(path, "r");
-       char line[257];
-       char section[257] = "";
-       char name[257] = "";
-
-       if (!f)
-               return;
-       while (fgets(line, sizeof(line), f) != NULL) {
-               char *st, *eq;
-               char *eol = strchr(line, '\n');
-               int append, quote;
-
-               if (!eol) {
-                       int ch;
-                       while ((ch = fgetc(f)) != '\n' &&
-                              ch != EOF)
-                               ;
-               } else
-                       *eol = 0;
-               if (line[0] == '[') {
-                       eol = strchr(line, ']');
-                       if (!eol)
-                               continue;
-                       while (eol > line && isblank(eol[-1]))
-                               eol -= 1;
-                       *eol = 0;
-                       st = line+1;
-                       while (isblank(*st))
-                               st += 1;
-                       strcpy(section, st);
-                       name[0] = 0;
-                       continue;
-               }
-               /* find/strip comment */
-               st = line; quote = 0;
-               while (*st && (quote || *st != '#')) {
-                       if (*st == '"')
-                               quote = !quote;
-                       st += 1;
-               }
-               if (*st  == '#')
-                       *st = 0;
-               if (isblank(line[0])) {
-                       if (!name[0])
-                               /* Nothing to continue */
-                               continue;
-                       st = line;
-                       while (isblank(*st))
-                               st += 1;
-                       if (!*st)
-                               /* Blank line */
-                               continue;
-                       append = 1;
-               } else {
-                       name[0] = 0;
-                       /* There must be an '=' */
-                       eq = strchr(line, '=');
-                       if (!eq)
-                               continue;
-                       st = eq + 1;
-                       while (eq > line && isblank(eq[-1]))
-                               eq -= 1;
-                       *eq = 0;
-                       if (!line[0])
-                               /* No name before '=' */
-                               continue;
-                       strcpy(name, line);
-                       append = 0;
-               }
-               /* A value is at 'st', to be set or appended */
-               eol = st + strlen(st);
-               while (isblank(*st))
-                       st += 1;
-               while (eol > st && isblank(eol[-1]))
-                       eol -= 1;
-               if (*st == '"' && eol > st + 1 && eol[-1] == '"') {
-                       st += 1;
-                       eol -= 1;
-               }
-               *eol = 0;
-               handle(data, section, name, st, path, append);
-       }
-       fclose(f);
-}
-
 static bool __glob_match(const char *patn safe, const char *path safe)
 {
        while(1) {
diff --git a/parse-ini.h b/parse-ini.h
new file mode 100644 (file)
index 0000000..3b14a28
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright Neil Brown ©2023 <neil@brown.name>
+ * May be distributed under terms of GPLv2 - or indeed any
+ * "Popular / Strong Community" license approved by the Open Source Initiative
+ * https://opensource.org/licenses/?categories=popular-strong-community
+ *
+ * Parse an 'ini' file calling a call-back for each value found.
+ *
+ * Syntax for ini file
+ * - individual lines must not exceed 256 chars.  Longer lines are
+ *   silently truncated.
+ * - leading white space continues the previous line, this allowing large
+ *   values.  The newline and leading white space are stripped.
+ *   Each line is provided separately to the callback, so precise detail of
+ *   how continuation lines are merged are left up to that callback.
+ * - white space around "=", at EOL, and around section name in [section]
+ *   is stripped
+ * - Double quotes at both ends of a value are stripped.  This allows
+ *   white space at either end of a value.
+ * - If first non-white is '#', line is ignored.
+ * - Everything after closing ']' of section is ignored
+ * - If value is not quoted, everything after first '#' is ignored
+ * - blank lines are ignored
+ */
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef safe
+/* "safe" pointers can never be NULL */
+#define safe
+#endif
+
+typedef void (*ini_handle)(void *data, char *section safe,
+                          char *name safe, char *value safe,
+                          const char *path safe,
+                          int append);
+
+static inline void parse_ini(const char *path safe,
+                            ini_handle handle, void *data)
+{
+       FILE *f = fopen(path, "r");
+       char line[257];
+       char section[257] = "";
+       char name[257] = "";
+
+       if (!f)
+               return;
+       while (fgets(line, sizeof(line), f) != NULL) {
+               char *st, *eq;
+               char *eol = strchr(line, '\n');
+               int append, quote;
+
+               if (!eol) {
+                       int ch;
+                       while ((ch = fgetc(f)) != '\n' &&
+                              ch != EOF)
+                               ;
+               } else
+                       *eol = 0;
+               if (line[0] == '[') {
+                       eol = strchr(line, ']');
+                       if (!eol)
+                               continue;
+                       while (eol > line && isblank(eol[-1]))
+                               eol -= 1;
+                       *eol = 0;
+                       st = line+1;
+                       while (isblank(*st))
+                               st += 1;
+                       strcpy(section, st);
+                       name[0] = 0;
+                       continue;
+               }
+               /* find/strip comment */
+               st = line; quote = 0;
+               while (*st && (quote || *st != '#')) {
+                       if (*st == '"')
+                               quote = !quote;
+                       st += 1;
+               }
+               if (*st  == '#')
+                       *st = 0;
+               if (isblank(line[0])) {
+                       if (!name[0])
+                               /* Nothing to continue */
+                               continue;
+                       st = line;
+                       while (isblank(*st))
+                               st += 1;
+                       if (!*st)
+                               /* Blank line */
+                               continue;
+                       append = 1;
+               } else {
+                       name[0] = 0;
+                       /* There must be an '=' */
+                       eq = strchr(line, '=');
+                       if (!eq)
+                               continue;
+                       st = eq + 1;
+                       while (eq > line && isblank(eq[-1]))
+                               eq -= 1;
+                       *eq = 0;
+                       if (!line[0])
+                               /* No name before '=' */
+                               continue;
+                       strcpy(name, line);
+                       append = 0;
+               }
+               /* A value is at 'st', to be set or appended */
+               eol = st + strlen(st);
+               while (isblank(*st))
+                       st += 1;
+               while (eol > st && isblank(eol[-1]))
+                       eol -= 1;
+               if (*st == '"' && eol > st + 1 && eol[-1] == '"') {
+                       st += 1;
+                       eol -= 1;
+               }
+               *eol = 0;
+               handle(data, section, name, st, path, append);
+       }
+       fclose(f);
+}