/* vi: set expandtab sw=4 sts=4: */ /* parse_util.c - the opkg package management system Copyright (C) 2009 Ubiq Technologies Steven M. Ayer Copyright (C) 2002 Compaq Computer Corporation SPDX-License-Identifier: GPL-2.0-or-later This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #include "config.h" #include #include #include #include #include "opkg_message.h" #include "opkg_utils.h" #include "xfuncs.h" #include "parse_util.h" int is_field(const char *type, const char *line) { if (strncmp(line, type, strlen(type)) == 0) return 1; return 0; } char *parse_simple(const char *type, const char *line) { char *field = trim_xstrdup(line + strlen(type) + 1); if (strlen(field) == 0) { free(field); return NULL; } return field; } /* * Parse a comma separated string into an array. */ char **parse_list(const char *raw, unsigned int *count, const char sep, int skip_field) { char **depends = NULL; const char *start, *end; int line_count = 0; /* skip past the "Field:" marker */ if (!skip_field) { while (*raw && *raw != ':') raw++; raw++; } if (line_is_blank(raw)) { *count = line_count; return NULL; } while (*raw) { depends = xrealloc(depends, sizeof(char *) * (line_count + 1)); while (isspace(*raw)) raw++; start = raw; while (*raw != sep && *raw) raw++; end = raw; while (end > start && isspace(*end)) end--; if (sep == ' ') end++; depends[line_count] = xstrndup(start, end - start); line_count++; if (*raw == sep) raw++; } *count = line_count; return depends; } int parse_from_stream_nomalloc(parse_line_t parse_line, void *ptr, FILE * fp, uint mask, char **buf0, size_t buf0len) { int ret, lineno; char *buf, *nl; size_t buflen; char *s; int r; lineno = 1; ret = 0; buflen = buf0len; buf = *buf0; buf[0] = '\0'; while (1) { s = fgets(buf, (int)buflen, fp); if (s == NULL) { if (ferror(fp)) { opkg_perror(ERROR, "fgets"); ret = -1; } else if (strlen(*buf0) == buf0len - 1) { opkg_msg(ERROR, "Missing new line character" " at end of file!\n"); parse_line(ptr, *buf0, mask); } break; } nl = strchr(buf, '\n'); if (nl == NULL) { if (strlen(buf) < buflen - 1) { /* * Line could be exactly buflen-1 long and * missing a newline, but we won't know until * fgets fails to read more data. */ opkg_msg(ERROR, "Missing new line character" " at end of file!\n"); parse_line(ptr, *buf0, mask); break; } if (buf0len >= EXCESSIVE_LINE_LEN) { opkg_msg(ERROR, "Excessively long line at " "%d. Corrupt file?\n", lineno); ret = -1; break; } /* * Realloc and point buf past the data already read, * at the NULL terminator inserted by fgets. * |<--------------- buf0len ----------------->| * | |<------- buflen ---->| * |---------------------|---------------------| * buf0 buf */ buflen = buf0len + 1; buf0len *= 2; *buf0 = xrealloc(*buf0, buf0len); buf = *buf0 + buflen - 2; continue; } *nl = '\0'; lineno++; r = parse_line(ptr, *buf0, mask); if (r != 0) break; buf = *buf0; buflen = buf0len; buf[0] = '\0'; } return ret; }