Browse Source

faux: ini: faux_ini_parse_file()

Serj Kalichev 4 years ago
parent
commit
0cdcfd79aa
1 changed files with 57 additions and 21 deletions
  1. 57 21
      faux/ini/ini.c

+ 57 - 21
faux/ini/ini.c

@@ -213,6 +213,21 @@ const faux_pair_t *faux_ini_each(faux_ini_node_t **iter) {
 	return (const faux_pair_t *)faux_list_each((faux_list_node_t **)iter);
 }
 
+
+/** @brief Parse string for pairs 'name/value'.
+ *
+ * String can contain an `name/value` pairs in following format:
+ * @code
+ * var1=value1
+ * var2 = "value 2"
+ * @endcode
+ * Function parses that string and stores 'name/value' pairs to
+ * the INI object.
+ *
+ * @param [in] ini Allocated and initialized INI object.
+ * @param [in] string String to parse.
+ * @return 0 - succes, < 0 - error
+ */
 int faux_ini_parse_str(faux_ini_t *ini, const char *string) {
 
 	char *buffer = NULL;
@@ -276,46 +291,67 @@ int faux_ini_parse_str(faux_ini_t *ini, const char *string) {
 }
 
 
+/** @brief Parse file for pairs 'name/value'.
+ *
+ * File can contain an `name/value` pairs in following format:
+ * @code
+ * var1=value1
+ * var2 = "value 2"
+ * @endcode
+ * Function parses file and stores 'name/value' pairs to
+ * the INI object.
+ *
+ * @param [in] ini Allocated and initialized INI object.
+ * @param [in] string String to parse.
+ * @return 0 - succes, < 0 - error
+ * @sa faux_ini_parse_str()
+ */
 int faux_ini_parse_file(faux_ini_t *ini, const char *fn) {
 
-	int ret = -1;
-	FILE *f = NULL;
+	int ret = -1; // Pessimistic retval
+	FILE *fd = NULL;
 	char *buf = NULL;
-	unsigned int p = 0;
+	unsigned int bytes_readed = 0;
 	const int chunk_size = 128;
-	int size = chunk_size;
+	int size = chunk_size; // Buffer size
 
 	assert(ini);
 	assert(fn);
 	if (!ini)
 		return -1;
-	if (!fn || !*fn)
+	if (!fn || '\0' == *fn)
 		return -1;
-	f = fopen(fn, "r");
-	if (!f)
+	fd = fopen(fn, "r");
+	if (!fd)
 		return -1;
 
 	buf = faux_zmalloc(size);
-	while (fgets(buf + p, size - p, f)) {
-		char *tmp = NULL;
-
-		if (feof(f) || strchr(buf + p, '\n') || strchr(buf + p, '\r')) {
-			faux_ini_parse_str(ini, buf);
-			p = 0;
-			continue;
+	while (fgets(buf + bytes_readed, size - bytes_readed, fd)) {
+
+		// Not enough space in buffer. Make it larger.
+		if (feof(fd) == 0 &&
+			!strchr(buf + bytes_readed, '\n') &&
+			!strchr(buf + bytes_readed, '\r')) {
+			char *tmp = NULL;
+			bytes_readed = size - 1; // fgets() put '\0' to last byte
+			size += chunk_size;
+			tmp = realloc(buf, size);
+			if (!tmp) // Memory problems
+				goto error;
+			buf = tmp;
+			continue; // Read the rest of line
 		}
-		p = size - 1;
-		size += chunk_size;
-		tmp = realloc(buf, size);
-		if (!tmp)
-			goto error;
-		buf = tmp;
+
+		// Don't analyze retval because it's not obvious what
+		// to do on error. May be next string will be ok.
+		faux_ini_parse_str(ini, buf);
+		bytes_readed = 0;
 	}
 
 	ret = 0;
 error:
 	faux_free(buf);
-	fclose(f);
+	fclose(fd);
 
 	return ret;
 }