fbecba6eb700954b811c6e09a712e02a00cee2f7
[project/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
28 is_field(const char *type, const char *line)
29 {
30 if (!strncmp(line, type, strlen(type)))
31 return 1;
32 return 0;
33 }
34
35 char *
36 parse_simple(const char *type, const char *line)
37 {
38 return trim_xstrdup(line + strlen(type) + 1);
39 }
40
41 /*
42 * Parse a comma separated string into an array.
43 */
44 char **
45 parse_list(const char *raw, unsigned int *count, const char sep, int skip_field)
46 {
47 char **depends = NULL;
48 const char *start, *end;
49 int line_count = 0;
50
51 /* skip past the "Field:" marker */
52 if (!skip_field) {
53 while (*raw && *raw != ':')
54 raw++;
55 raw++;
56 }
57
58 if (line_is_blank(raw)) {
59 *count = line_count;
60 return NULL;
61 }
62
63 while (*raw) {
64 depends = xrealloc(depends, sizeof(char *) * (line_count + 1));
65
66 while (isspace(*raw))
67 raw++;
68
69 start = raw;
70 while (*raw != sep && *raw)
71 raw++;
72 end = raw;
73
74 while (end > start && isspace(*end))
75 end--;
76
77 if (sep == ' ')
78 end++;
79
80 depends[line_count] = xstrndup(start, end-start);
81
82 line_count++;
83 if (*raw == sep)
84 raw++;
85 }
86
87 *count = line_count;
88 return depends;
89 }
90
91 int
92 parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
93 char **buf0, size_t buf0len)
94 {
95 int ret, lineno;
96 char *buf, *nl;
97 size_t buflen;
98
99 lineno = 1;
100 ret = 0;
101
102 buflen = buf0len;
103 buf = *buf0;
104 buf[0] = '\0';
105
106 while (1) {
107 if (fgets(buf, (int)buflen, fp) == NULL) {
108 if (ferror(fp)) {
109 opkg_perror(ERROR, "fgets");
110 ret = -1;
111 } else if (strlen(*buf0) == buf0len-1) {
112 opkg_msg(ERROR, "Missing new line character"
113 " at end of file!\n");
114 parse_line(item, *buf0, mask);
115 }
116 break;
117 }
118
119 nl = strchr(buf, '\n');
120 if (nl == NULL) {
121 if (strlen(buf) < buflen-1) {
122 /*
123 * Line could be exactly buflen-1 long and
124 * missing a newline, but we won't know until
125 * fgets fails to read more data.
126 */
127 opkg_msg(ERROR, "Missing new line character"
128 " at end of file!\n");
129 parse_line(item, *buf0, mask);
130 break;
131 }
132 if (buf0len >= EXCESSIVE_LINE_LEN) {
133 opkg_msg(ERROR, "Excessively long line at "
134 "%d. Corrupt file?\n",
135 lineno);
136 ret = -1;
137 break;
138 }
139
140 /*
141 * Realloc and point buf past the data already read,
142 * at the NULL terminator inserted by fgets.
143 * |<--------------- buf0len ----------------->|
144 * | |<------- buflen ---->|
145 * |---------------------|---------------------|
146 * buf0 buf
147 */
148 buflen = buf0len +1;
149 buf0len *= 2;
150 *buf0 = xrealloc(*buf0, buf0len);
151 buf = *buf0 + buflen -2;
152
153 continue;
154 }
155
156 *nl = '\0';
157
158 lineno++;
159
160 if (parse_line(item, *buf0, mask))
161 break;
162
163 buf = *buf0;
164 buflen = buf0len;
165 buf[0] = '\0';
166 }
167
168 return ret;
169 }
170