regerror.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <sys/types.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <limits.h>
  6. #include <stdlib.h>
  7. #include "regex.h"
  8. #include "utils.h"
  9. #include "regerror.ih"
  10. #include "php.h"
  11. /*
  12. = #define REG_OKAY 0
  13. = #define REG_NOMATCH 1
  14. = #define REG_BADPAT 2
  15. = #define REG_ECOLLATE 3
  16. = #define REG_ECTYPE 4
  17. = #define REG_EESCAPE 5
  18. = #define REG_ESUBREG 6
  19. = #define REG_EBRACK 7
  20. = #define REG_EPAREN 8
  21. = #define REG_EBRACE 9
  22. = #define REG_BADBR 10
  23. = #define REG_ERANGE 11
  24. = #define REG_ESPACE 12
  25. = #define REG_BADRPT 13
  26. = #define REG_EMPTY 14
  27. = #define REG_ASSERT 15
  28. = #define REG_INVARG 16
  29. = #define REG_ATOI 255 // convert name to number (!)
  30. = #define REG_ITOA 0400 // convert number to name (!)
  31. */
  32. static const struct rerr {
  33. int code;
  34. const char *name;
  35. const char *explain;
  36. } rerrs[] = {
  37. {REG_OKAY, "REG_OKAY", "no errors detected"},
  38. {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
  39. {REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
  40. {REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},
  41. {REG_ECTYPE, "REG_ECTYPE", "invalid character class"},
  42. {REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"},
  43. {REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"},
  44. {REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"},
  45. {REG_EPAREN, "REG_EPAREN", "parentheses not balanced"},
  46. {REG_EBRACE, "REG_EBRACE", "braces not balanced"},
  47. {REG_BADBR, "REG_BADBR", "invalid repetition count(s)"},
  48. {REG_ERANGE, "REG_ERANGE", "invalid character range"},
  49. {REG_ESPACE, "REG_ESPACE", "out of memory"},
  50. {REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"},
  51. {REG_EMPTY, "REG_EMPTY", "empty (sub)expression"},
  52. {REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"},
  53. {REG_INVARG, "REG_INVARG", "invalid argument to regex routine"},
  54. {-1, "", "*** unknown regexp error code ***"},
  55. };
  56. /*
  57. - regerror - the interface to error numbers
  58. = API_EXPORT(size_t) regerror(int, const regex_t *, char *, size_t);
  59. */
  60. /* ARGSUSED */
  61. API_EXPORT(size_t)
  62. regerror(
  63. int errcode,
  64. const regex_t *preg,
  65. char *errbuf,
  66. size_t errbuf_size)
  67. {
  68. register const struct rerr *r;
  69. register size_t len;
  70. register int target = errcode &~ REG_ITOA;
  71. register const char *s;
  72. char convbuf[50];
  73. if (errcode == REG_ATOI)
  74. s = regatoi(preg, convbuf, sizeof(convbuf));
  75. else {
  76. for (r = rerrs; r->code >= 0; r++)
  77. if (r->code == target)
  78. break;
  79. if (errcode&REG_ITOA) {
  80. if (r->code >= 0) {
  81. (void) strncpy(convbuf, r->name, sizeof(convbuf) - 1);
  82. convbuf[sizeof(convbuf) - 1] = '\0';
  83. } else {
  84. snprintf(convbuf, sizeof(convbuf), "REG_0x%x", target);
  85. }
  86. assert(strlen(convbuf) < sizeof(convbuf));
  87. s = convbuf;
  88. } else
  89. s = r->explain;
  90. }
  91. len = strlen(s) + 1;
  92. if (errbuf_size > 0) {
  93. if (errbuf_size > len)
  94. (void) strcpy(errbuf, s);
  95. else {
  96. (void) strncpy(errbuf, s, errbuf_size-1);
  97. errbuf[errbuf_size-1] = '\0';
  98. }
  99. }
  100. return(len);
  101. }
  102. /*
  103. - regatoi - internal routine to implement REG_ATOI
  104. == static char *regatoi(const regex_t *preg, char *localbuf, int bufsize);
  105. */
  106. static char *
  107. regatoi(preg, localbuf, bufsize)
  108. const regex_t *preg;
  109. char *localbuf;
  110. int bufsize;
  111. {
  112. register const struct rerr *r;
  113. for (r = rerrs; r->code >= 0; r++)
  114. if (strcmp(r->name, preg->re_endp) == 0)
  115. break;
  116. if (r->code < 0)
  117. return("0");
  118. snprintf(localbuf, bufsize, "%d", r->code);
  119. return(localbuf);
  120. }