From: Pawel Wodkowski <pawelx.wodkow...@intel.com>

Signed-off-by: Pawel Wodkowski <pawelx.wodkowski at intel.com>
---
 lib/librte_cfgfile/rte_cfgfile.c |  147 ++++++++++++++++++++++++++++++++++----
 1 file changed, 133 insertions(+), 14 deletions(-)

diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index 2e78583..4e77ef5 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -116,6 +116,122 @@ strip_comment(char *buffer, size_t len)
        return len;
 }

+/* Get line from file. It concatanate lines with line continue.
+ * If *line is not NULL it must point to malloced data buffer and *len must
+ * be the length of *line.
+ */
+static int
+rte_cfgfile_getline(char **line, size_t *len, FILE *f, size_t *lineno)
+{
+       char *str = NULL;
+       size_t str_len = 0;
+
+       void *buf;
+       char *line_str = NULL;
+       size_t line_size = 0; /* Whole buffer size */
+       ssize_t line_len = 0; /* Length of line_str */
+
+       size_t line_cnt = 0;
+       int status = 0;
+
+       if (!line) {
+               status = EINVAL;
+               goto error_exit;
+       }
+
+       while (1) {
+               line_len = getline(&line_str, &line_size, f);
+               if (line_len <= 0) {
+                       if (!feof(f)) {
+                               status = -EIO;
+                               goto error_exit;
+                       }
+
+                       break;
+               }
+
+               line_cnt++;
+               /* Replace last CR with LF */
+               if (line_len > 0 && line_str[line_len - 1] == '\r')
+                       line_str[line_len - 1] = '\n';
+
+               /* Replace last CRLF with LF */
+               if (line_len > 1 && line_str[line_len - 2] == '\r' &&
+                                       line_str[line_len - 1] == '\n') {
+                       line_str[line_len - 1] = '\0';
+                       line_str[line_len - 2] = '\n';
+                       line_len -= 1;
+               }
+
+               line_len = strip_comment(line_str, line_len);
+
+               /* Special case for first line. */
+               if (str == NULL) {
+                       if (line_len == 0)
+                               continue;
+
+                       str = line_str;
+                       str_len = line_len;
+
+                       line_str = NULL;
+                       line_len = 0;
+               } else {
+                       if (line_len == 0)
+                               break;
+
+                       buf = realloc(str, str_len + line_len + 1);
+                       if (buf == NULL) {
+                               status = -ENOMEM;
+                               goto error_exit;
+                       }
+
+                       str = buf;
+                       memcpy(&str[str_len], line_str, line_len + 1);
+
+                       str_len += line_len;
+               }
+
+               /* Check for line continue */
+               if (str_len < 2 || str[str_len - 1] != '\n' || str[str_len - 2] 
!= '\\')
+                       break;
+
+               /* Remove line continue character. */
+               str[str_len - 1] = '\0';
+               /* Change new line into space */
+               str[str_len - 2] = ' ';
+               str_len -= 1;
+       }
+
+       if (str_len) {
+               /* Squeeze str */
+               buf = realloc(str, str_len + 1);
+               if (buf == NULL) {
+                       status = -ENOMEM;
+                       goto error_exit;
+               }
+
+               free(*line);
+               *line = buf;
+       }
+
+       if (len)
+               *len = str_len;
+
+       if (lineno)
+               *lineno += line_cnt;
+
+       free(line_str);
+       return 0;
+
+error_exit:
+       printf("Error: %s\n", strerror(status));
+       if (lineno)
+               *lineno += line_cnt;
+       free(str);
+       free(line_str);
+       return status;
+}
+
 /**
  * Create new apty config file object.
  *
@@ -153,9 +269,11 @@ rte_cfgfile_read(FILE *f, int flags)
        int allocated_entries = 0;
        int curr_section = -1;
        int curr_entry = -1;
-       char buffer[256];
-       int lineno = 0;
+       char *buffer = NULL;
+       size_t len;
+       size_t lineno = 0;
        struct rte_cfgfile *cfg = NULL;
+       int status;

        if (f == NULL)
                return NULL;
@@ -164,15 +282,12 @@ rte_cfgfile_read(FILE *f, int flags)
        if (cfg == NULL)
                goto error2;

-       while (fgets(buffer, sizeof(buffer), f) != NULL) {
-               size_t len = strnlen(buffer, sizeof(buffer));
-               lineno++;
-               if ((len >= sizeof(buffer) - 1) && (buffer[len-1] != '\n')) {
-                       printf("Error line %d - no \\n found on string. "
-                                       "Check if line too long\n", lineno);
-                       goto error1;
-               }
-               len = strip_comment(buffer, len);
+       while (!feof(f)) {
+               status = rte_cfgfile_getline(&buffer, &len, f, &lineno);
+               if (status)
+                       break;
+               else if (!len)
+                       continue;

                len = _strip(buffer, len);
                if (buffer[0] != '[' && memchr(buffer, '=', len) == NULL)
@@ -182,7 +297,7 @@ rte_cfgfile_read(FILE *f, int flags)
                        /* section heading line */
                        char *end = memchr(buffer, ']', len);
                        if (end == NULL) {
-                               printf("Error line %d - no terminating '['"
+                               printf("Error line %zu - no terminating '['"
                                        "character found\n", lineno);
                                goto error1;
                        }
@@ -227,7 +342,7 @@ rte_cfgfile_read(FILE *f, int flags)
                } else {
                        /* value line */
                        if (curr_section < 0) {
-                               printf("Error line %d - value outside of"
+                               printf("Error line %zu - value outside of"
                                        "section\n", lineno);
                                goto error1;
                        }
@@ -237,7 +352,7 @@ rte_cfgfile_read(FILE *f, int flags)
                        char *split[2];
                        if (rte_strsplit(buffer, sizeof(buffer), split, 2, '=')
                                != 2) {
-                               printf("Error at line %d - cannot split "
+                               printf("Error at line %zu - cannot split "
                                        "string\n", lineno);
                                goto error1;
                        }
@@ -275,6 +390,10 @@ rte_cfgfile_read(FILE *f, int flags)
                                sizeof(entry->value)));
                }
        }
+
+       if (status)
+               goto error1;
+
        fclose(f);
        cfg->flags = flags;
        cfg->num_sections = curr_section + 1;
-- 
1.7.9.5

Reply via email to