Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | /* re.c. Regular expression processing for ksymoops. Copyright Keith Owens <kaos@ocs.com.au>. Released under the GNU Public Licence, Version 2. Tue Nov 3 02:31:01 EST 1998 Version 0.6 PPC trace addresses are not bracketed, add new re. Wed Oct 28 13:47:23 EST 1998 Version 0.4 Split into separate sources. */ #include "ksymoops.h" #include <malloc.h> #include <string.h> /* Compile a regular expression */ void re_compile(regex_t *preg, const char *regex, int cflags, regmatch_t **pmatch) { int i, l; char *p; static char const procname[] = "re_compile"; if (preg->re_nsub) return; /* already compiled */ if (debug) fprintf(stderr, "DEBUG: %s '%s'", procname, regex); if ((i = regcomp(preg, regex, cflags))) { l = regerror(i, preg, NULL, 0); ++l; /* doc is ambiguous, be safe */ p = malloc(l); if (!p) malloc_error("regerror text"); regerror(i, preg, p, l); fprintf(stderr, "%s: fatal %s error on '%s' - %s\n", prefix, procname, regex, p); exit(2); } if (debug) fprintf(stderr, " %d sub expression(s)\n", preg->re_nsub); /* [0] is entire match, [1] is first substring */ *pmatch = malloc((preg->re_nsub+1)*sizeof(**pmatch)); if (!*pmatch) malloc_error("pmatch"); } /* Compile common regular expressions */ void re_compile_common(void) { /* nm: address, type, symbol */ re_compile(&re_nm, "^([0-9a-fA-F]{4,}) +([^ ]) +([^ ]+)$", REG_NEWLINE|REG_EXTENDED, &re_nm_pmatch); /* bracketed address preceded by optional white space */ re_compile(&re_bracketed_address, "^[ \t]*" BRACKETED_ADDRESS, REG_NEWLINE|REG_EXTENDED, &re_bracketed_address_pmatch); /* unbracketed address preceded by optional white space */ re_compile(&re_unbracketed_address, "^[ \t*]*" UNBRACKETED_ADDRESS, REG_NEWLINE|REG_EXTENDED, &re_unbracketed_address_pmatch); } /* Split text into the matching re substrings - Perl is so much easier :). * Each element of *string is set to a malloced copy of the substring or * NULL if the substring did not match (undef). A zero length substring match * is represented by a zero length **string. */ void re_strings(regex_t *preg, const char *text, regmatch_t *pmatch, char ***string) { int i; if (!*string) { *string = malloc((preg->re_nsub+1)*sizeof(**string)); if (!*string) malloc_error("re_strings base"); for (i = 0; i < preg->re_nsub+1; ++i) (*string)[i] = NULL; } for (i = 0; i < preg->re_nsub+1; ++i) { if (debug > 4) fprintf(stderr, "DEBUG: re_string %d offsets %d %d", i, pmatch[i].rm_so, pmatch[i].rm_eo); if (pmatch[i].rm_so == -1) { /* no match for this sub expression */ free((*string)[i]); (*string)[i] = NULL; if (debug > 4) fprintf(stderr, " (undef)\n"); } else { int l = pmatch[i].rm_eo - pmatch[i].rm_so + 1; char *p; p = malloc(l); if (!p) malloc_error("re_strings"); strncpy(p, text+pmatch[i].rm_so, l-1); *(p+l-1) = '\0'; (*string)[i] = p; if (debug > 4) fprintf(stderr, " '%s'\n", p); } } } /* Free the matching re substrings */ void re_strings_free(const regex_t *preg, char ***string) { if (*string) { int i; for (i = 0; i < preg->re_nsub+1; ++i) free((*string)[i]); free(*string); *string = NULL; } } /* Check that there are enough strings for an re */ void re_string_check(int need, int available, const char *msg) { if (need > available) { fprintf(stderr, "%s: fatal not enough re_strings in %s. " "Need %d, available %d\n", prefix, msg, need, available); exit(2); } } |