treewrite: use Lindent to reformat to kernel coding style
[oweals/opkg-lede.git] / libopkg / parse_util.c
1 /* parse_util.c - the opkg package management system
2
3    Copyright (C) 2009 Ubiq Technologies <graham.gower@gmail.com>
4
5    Steven M. Ayer
6    Copyright (C) 2002 Compaq Computer Corporation
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 */
18
19 #include <ctype.h>
20
21 #include "opkg_utils.h"
22 #include "libbb/libbb.h"
23
24 #include "parse_util.h"
25 #include "pkg_parse.h"
26
27 int is_field(const char *type, const char *line)
28 {
29         if (!strncmp(line, type, strlen(type)))
30                 return 1;
31         return 0;
32 }
33
34 char *parse_simple(const char *type, const char *line)
35 {
36         char *field = trim_xstrdup(line + strlen(type) + 1);
37         if (strlen(field) == 0) {
38                 free(field);
39                 return NULL;
40         }
41         return field;
42 }
43
44 /*
45  * Parse a comma separated string into an array.
46  */
47 char **parse_list(const char *raw, unsigned int *count, const char sep,
48                   int skip_field)
49 {
50         char **depends = NULL;
51         const char *start, *end;
52         int line_count = 0;
53
54         /* skip past the "Field:" marker */
55         if (!skip_field) {
56                 while (*raw && *raw != ':')
57                         raw++;
58                 raw++;
59         }
60
61         if (line_is_blank(raw)) {
62                 *count = line_count;
63                 return NULL;
64         }
65
66         while (*raw) {
67                 depends = xrealloc(depends, sizeof(char *) * (line_count + 1));
68
69                 while (isspace(*raw))
70                         raw++;
71
72                 start = raw;
73                 while (*raw != sep && *raw)
74                         raw++;
75                 end = raw;
76
77                 while (end > start && isspace(*end))
78                         end--;
79
80                 if (sep == ' ')
81                         end++;
82
83                 depends[line_count] = xstrndup(start, end - start);
84
85                 line_count++;
86                 if (*raw == sep)
87                         raw++;
88         }
89
90         *count = line_count;
91         return depends;
92 }
93
94 int
95 parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE * fp,
96                            uint mask, char **buf0, size_t buf0len)
97 {
98         int ret, lineno;
99         char *buf, *nl;
100         size_t buflen;
101
102         lineno = 1;
103         ret = 0;
104
105         buflen = buf0len;
106         buf = *buf0;
107         buf[0] = '\0';
108
109         while (1) {
110                 if (fgets(buf, (int)buflen, fp) == NULL) {
111                         if (ferror(fp)) {
112                                 opkg_perror(ERROR, "fgets");
113                                 ret = -1;
114                         } else if (strlen(*buf0) == buf0len - 1) {
115                                 opkg_msg(ERROR, "Missing new line character"
116                                          " at end of file!\n");
117                                 parse_line(item, *buf0, mask);
118                         }
119                         break;
120                 }
121
122                 nl = strchr(buf, '\n');
123                 if (nl == NULL) {
124                         if (strlen(buf) < buflen - 1) {
125                                 /*
126                                  * Line could be exactly buflen-1 long and
127                                  * missing a newline, but we won't know until
128                                  * fgets fails to read more data.
129                                  */
130                                 opkg_msg(ERROR, "Missing new line character"
131                                          " at end of file!\n");
132                                 parse_line(item, *buf0, mask);
133                                 break;
134                         }
135                         if (buf0len >= EXCESSIVE_LINE_LEN) {
136                                 opkg_msg(ERROR, "Excessively long line at "
137                                          "%d. Corrupt file?\n", lineno);
138                                 ret = -1;
139                                 break;
140                         }
141
142                         /*
143                          * Realloc and point buf past the data already read,
144                          * at the NULL terminator inserted by fgets.
145                          * |<--------------- buf0len ----------------->|
146                          * |                     |<------- buflen ---->|
147                          * |---------------------|---------------------|
148                          * buf0                   buf
149                          */
150                         buflen = buf0len + 1;
151                         buf0len *= 2;
152                         *buf0 = xrealloc(*buf0, buf0len);
153                         buf = *buf0 + buflen - 2;
154
155                         continue;
156                 }
157
158                 *nl = '\0';
159
160                 lineno++;
161
162                 if (parse_line(item, *buf0, mask))
163                         break;
164
165                 buf = *buf0;
166                 buflen = buf0len;
167                 buf[0] = '\0';
168         }
169
170         return ret;
171 }