parse_util.c 3.5 KB

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