/sources/host-tools/sed-4.2.1/testsuite/tst-pcre.c

https://github.com/CyanogenMod/android_ndk · C · 249 lines · 195 code · 33 blank · 21 comment · 61 complexity · d1eb70bdae7dcac2a1f60320910c88c9 MD5 · raw file

  1. /* Regular expression tests.
  2. Copyright (C) 2003 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, write to the Free
  15. Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301 USA. */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include <sys/types.h>
  21. #ifdef HAVE_MCHECK_H
  22. #include <mcheck.h>
  23. #endif
  24. #include <regex.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. int
  29. main (int argc, char **argv)
  30. {
  31. int ret = 0;
  32. char *line = NULL;
  33. size_t line_len = 0;
  34. ssize_t len;
  35. FILE *f;
  36. char *pattern = NULL, *string = NULL;
  37. regmatch_t rm[20];
  38. size_t pattern_alloced = 0, string_alloced = 0;
  39. int ignorecase = 0;
  40. int pattern_valid = 0, rm_valid = 0;
  41. size_t linenum;
  42. #ifdef HAVE_MCHECK_H
  43. mtrace ();
  44. #endif
  45. if (argc < 2)
  46. {
  47. fprintf (stderr, "Missing test filename\n");
  48. return 1;
  49. }
  50. f = fopen (argv[1], "r");
  51. if (f == NULL)
  52. {
  53. fprintf (stderr, "Couldn't open %s\n", argv[1]);
  54. return 1;
  55. }
  56. if ((len = getline (&line, &line_len, f)) <= 0
  57. || strncmp (line, "# PCRE", 6) != 0)
  58. {
  59. fprintf (stderr, "Not a PCRE test file\n");
  60. fclose (f);
  61. free (line);
  62. return 1;
  63. }
  64. linenum = 1;
  65. while ((len = getline (&line, &line_len, f)) > 0)
  66. {
  67. char *p;
  68. unsigned long num;
  69. ++linenum;
  70. if (line[len - 1] == '\n')
  71. line[--len] = '\0';
  72. if (line[0] == '#')
  73. continue;
  74. if (line[0] == '\0')
  75. {
  76. /* End of test. */
  77. ignorecase = 0;
  78. pattern_valid = 0;
  79. rm_valid = 0;
  80. continue;
  81. }
  82. if (line[0] == '/')
  83. {
  84. /* Pattern. */
  85. p = strrchr (line + 1, '/');
  86. pattern_valid = 0;
  87. rm_valid = 0;
  88. if (p == NULL)
  89. {
  90. printf ("%lu: Invalid pattern line: %s\n", linenum, line);
  91. ret = 1;
  92. continue;
  93. }
  94. if (p[1] == 'i' && p[2] == '\0')
  95. ignorecase = 1;
  96. else if (p[1] != '\0')
  97. {
  98. printf ("%lu: Invalid pattern line: %s\n", linenum, line);
  99. ret = 1;
  100. continue;
  101. }
  102. if (pattern_alloced < (size_t) (p - line))
  103. {
  104. pattern = realloc (pattern, p - line);
  105. if (pattern == NULL)
  106. {
  107. printf ("%lu: Cannot record pattern: %m\n", linenum);
  108. ret = 1;
  109. break;
  110. }
  111. pattern_alloced = p - line;
  112. }
  113. memcpy (pattern, line + 1, p - line - 1);
  114. pattern[p - line - 1] = '\0';
  115. pattern_valid = 1;
  116. continue;
  117. }
  118. if (strncmp (line, " ", 4) == 0)
  119. {
  120. regex_t re;
  121. int n;
  122. if (!pattern_valid)
  123. {
  124. printf ("%lu: No previous valid pattern %s\n", linenum, line);
  125. continue;
  126. }
  127. if (string_alloced < (size_t) (len - 3))
  128. {
  129. string = realloc (string, len - 3);
  130. if (string == NULL)
  131. {
  132. printf ("%lu: Cannot record search string: %m\n", linenum);
  133. ret = 1;
  134. break;
  135. }
  136. string_alloced = len - 3;
  137. }
  138. memcpy (string, line + 4, len - 3);
  139. n = regcomp (&re, pattern,
  140. REG_EXTENDED | (ignorecase ? REG_ICASE : 0));
  141. if (n != 0)
  142. {
  143. char buf[500];
  144. regerror (n, &re, buf, sizeof (buf));
  145. printf ("%lu: regcomp failed for %s: %s\n",
  146. linenum, pattern, buf);
  147. ret = 1;
  148. continue;
  149. }
  150. if (regexec (&re, string, 20, rm, 0))
  151. {
  152. rm[0].rm_so = -1;
  153. rm[0].rm_eo = -1;
  154. }
  155. regfree (&re);
  156. rm_valid = 1;
  157. continue;
  158. }
  159. if (!rm_valid)
  160. {
  161. printf ("%lu: No preceeding pattern or search string\n", linenum);
  162. ret = 1;
  163. continue;
  164. }
  165. if (strcmp (line, "No match") == 0)
  166. {
  167. if (rm[0].rm_so != -1 || rm[0].rm_eo != -1)
  168. {
  169. printf ("%lu: /%s/ on %s unexpectedly matched %d..%d\n",
  170. linenum, pattern, string, rm[0].rm_so, rm[0].rm_eo);
  171. ret = 1;
  172. }
  173. continue;
  174. }
  175. p = line;
  176. if (*p == ' ')
  177. ++p;
  178. num = strtoul (p, &p, 10);
  179. if (num >= 20 || *p != ':' || p[1] != ' ')
  180. {
  181. printf ("%lu: Invalid line %s\n", linenum, line);
  182. ret = 1;
  183. continue;
  184. }
  185. if (rm[num].rm_so == -1 || rm[num].rm_eo == -1)
  186. {
  187. if (strcmp (p + 2, "<unset>") != 0)
  188. {
  189. printf ("%lu: /%s/ on %s unexpectedly failed to match register %ld %d..%d\n",
  190. linenum, pattern, string, num,
  191. rm[num].rm_so, rm[num].rm_eo);
  192. ret = 1;
  193. }
  194. continue;
  195. }
  196. if (rm[num].rm_eo < rm[num].rm_so
  197. || rm[num].rm_eo - rm[num].rm_so != len - (p + 2 - line)
  198. || strncmp (p + 2, string + rm[num].rm_so,
  199. rm[num].rm_eo - rm[num].rm_so) != 0)
  200. {
  201. printf ("%lu: /%s/ on %s unexpectedly failed to match %s for register %ld %d..%d\n",
  202. linenum, pattern, string, p + 2, num,
  203. rm[num].rm_so, rm[num].rm_eo);
  204. ret = 1;
  205. continue;
  206. }
  207. }
  208. free (pattern);
  209. free (string);
  210. free (line);
  211. fclose (f);
  212. return ret;
  213. }