PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Plugins/APP_Links2/links-2.1pre23/regexp.c

http://pspradio-mod.googlecode.com/
C | 301 lines | 269 code | 23 blank | 9 comment | 70 complexity | 31b4bd604faefedf31354c7550b190ab MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0
  1. /* regexp.c
  2. * (c) 2005 Konstantin S. Kravtsov <k6@pisem.net>
  3. * Written on the base of code of pcre_subst designed by Bert Driehuis <driehuis@playbeing.org>
  4. * with some changes.
  5. * Used here PCRE library is a library of functions to support regular expressions whose syntax
  6. * and semantics are as close as possible to those of the Perl 5 language.
  7. * PCRE used in case that HAVE_PCRE is defined (-DHAVE_PCRE), libc regex (POSIX regex functions)
  8. * used otherwise.
  9. */
  10. #include "cfg.h"
  11. #ifdef JS
  12. #include "links.h"
  13. #include "struct.h"
  14. #include <ctype.h>
  15. #if defined(HAVE_PCRE) || defined(HAVE_REGEX)
  16. #ifdef HAVE_PCRE
  17. #include <pcre.h>
  18. #else /* HAVE_PCRE */
  19. #include <regex.h>
  20. #endif /* HAVE_PCRE */
  21. #define MAXCAPTURE 300 /*supposed to be a multiple of 3*/
  22. #define REGEX_DEBUG
  23. #undef REGEX_DEBUG
  24. #ifdef REGEX_DEBUG
  25. static void
  26. dumpstr(const char *str, int len, int start, int end)
  27. {
  28. int i;
  29. for (i = 0; i < strlen(str); i++) {
  30. if (i >= start && i < end)
  31. putchar(str[i]);
  32. else
  33. putchar('-');
  34. }
  35. putchar('\n');
  36. }
  37. static void
  38. dumpmatch(const char *str, int len, const char *rep, int nmat, const int *ovec)
  39. {
  40. int i;
  41. printf("%s Input\n", str);
  42. printf("nmat=%d", nmat);
  43. for (i = 0; i < nmat * 2; i++)
  44. printf(" %d", ovec[i]);
  45. printf("\n");
  46. for (i = 0; i < nmat * 2; i += 2)
  47. dumpstr(str, len, ovec[i], ovec[i+1]);
  48. printf("\n");
  49. }
  50. #endif /* REGEX_DEBUG */
  51. static int
  52. findreplen(const char *rep, int nmat, const int *replen)
  53. {
  54. int len = 0;
  55. int val;
  56. char *cp = (char *)rep;
  57. while(*cp) {
  58. if (*cp == '$' && isdigit(cp[1])) {
  59. val = strtoul(&cp[1], &cp, 10);
  60. if (val && val <= nmat)
  61. len += replen[val -1];
  62. #ifdef REGEX_DEBUG
  63. else
  64. fprintf(stderr, "repl %d out of range\n", val);
  65. #endif /* REGEX_DEBUG */
  66. } else {
  67. cp++;
  68. len++;
  69. }
  70. }
  71. return len;
  72. }
  73. static void
  74. doreplace(char *out, const char *rep, int nmat, int *replen, const char **repstr)
  75. {
  76. int val;
  77. char *cp = (char *)rep;
  78. while(*cp) {
  79. if (*cp == '$' && isdigit(cp[1])) {
  80. val = strtoul(&cp[1], &cp, 10);
  81. if (val && val <= nmat) {
  82. strncpy(out, repstr[val - 1], replen[val - 1]);
  83. out += replen[val -1];
  84. }
  85. } else {
  86. *out++ = *cp++;
  87. }
  88. }
  89. }
  90. char *cp, *ep;
  91. static char *
  92. edit(const char *str, int len, const char *rep, int nmat, const int *ovec, char *res)
  93. {
  94. int i, slen, rlen;
  95. const int *mvec = ovec;
  96. int replen[MAXCAPTURE];
  97. const char *repstr[MAXCAPTURE];
  98. nmat--;
  99. ovec += 2;
  100. for (i = 0; i < nmat; i++)
  101. {
  102. replen[i] = ovec[i * 2 + 1] - ovec[i * 2];
  103. repstr[i] = &str[ovec[i * 2]];
  104. #ifdef REGEX_DEBUG
  105. printf(">>>%d %d %.*s\n", i, replen[i], replen[i], repstr[i]);
  106. #endif /* REGEX_DEBUG */
  107. }
  108. slen = len;
  109. len -= mvec[1] - mvec[0];
  110. len += rlen = findreplen(rep, nmat, replen);
  111. #ifdef REGEX_DEBUG
  112. printf("resulting length %d (srclen=%d)\n", len, slen);
  113. #endif /* REGEX_DEBUG */
  114. if (mvec[0] > 0)
  115. {
  116. strncpy(cp, str, (mvec[0] > ep - cp - 1)? ep - cp - 1 :mvec[0]);
  117. cp += mvec[0];
  118. }
  119. if(ep - cp < rlen)
  120. return NULL;
  121. doreplace(cp, rep, nmat, replen, repstr);
  122. cp += rlen;
  123. return res;
  124. }
  125. char *
  126. regexp_replace(char * from, char *to, char *text)
  127. {
  128. int nmat, offset = 0, textlen;
  129. int ovec[MAXCAPTURE];
  130. char *res, *ret, *pom;
  131. const char *overfl = NULL; /* warning, go away */
  132. int global, i;
  133. #ifdef HAVE_PCRE
  134. const char *er_ptr;
  135. int erroffset;
  136. #else
  137. regmatch_t pmat[MAXCAPTURE/3];
  138. regex_t ppat_data;
  139. regex_t *ppat;
  140. #endif
  141. if( from == NULL || to == NULL || text == NULL)
  142. {
  143. if(text == NULL) return NULL;
  144. ret = (unsigned char *)js_mem_alloc(strlen(text)+1);
  145. strcpy(ret,text);
  146. return ret;
  147. }
  148. while(*from == ' ' || *from == '\t') from++;
  149. #ifdef HAVE_PCRE
  150. pom = pcre_malloc(strlen(from)+1);
  151. #else /* HAVE_PCRE */
  152. pom = mem_alloc(strlen(from)+1);
  153. #endif /* HAVE_PCRE */
  154. if(*from != '/' || !from[1])
  155. {
  156. strcpy(pom, from);
  157. global = 0;
  158. }
  159. else
  160. {
  161. for( i = strlen(from)-1; i > 1 && (from[i] == ' ' || from[i] == '\t'); i--);
  162. if( from[i] == '/')
  163. {
  164. strncpy(pom, from+1, i-1);
  165. pom[i-1] = '\0';
  166. global = 0;
  167. }else if( i > 1 && from[i] == 'g' && from[i-1] == '/')
  168. {
  169. strncpy(pom, from+1, i-2);
  170. pom[i-2] = '\0';
  171. global = 1;
  172. }else
  173. {
  174. strncpy(pom, from, i+1);
  175. pom[i+1] = '\0';
  176. global = 0;
  177. }
  178. }
  179. #ifdef REGEX_DEBUG
  180. printf("Search pattern is '%s', global = %d\n",pom,global);
  181. #endif /* REGEX_DEBUG */
  182. #ifdef HAVE_PCRE
  183. pcre *ppat = pcre_compile(pom, 0/*PCRE_ANCHORED*/, &er_ptr, &erroffset, NULL);
  184. pcre_free(pom);
  185. #else /* HAVE_PCRE */
  186. ppat = &ppat_data;
  187. if (regcomp(ppat, pom, REG_EXTENDED)) ppat = NULL;
  188. mem_free(pom);
  189. #endif /* HAVE_PCRE */
  190. if (ppat == NULL)
  191. {
  192. if(text == NULL) return NULL;
  193. ret = (unsigned char *)js_mem_alloc(strlen(text)+1);
  194. strcpy(ret,text);
  195. return ret;
  196. }
  197. textlen = strlen(text);
  198. #ifdef HAVE_PCRE
  199. res = pcre_malloc(MAXCAPTURE+textlen);
  200. #else /* HAVE_PCRE */
  201. res = mem_alloc(MAXCAPTURE+textlen);
  202. #endif /* HAVE_PCRE */
  203. cp = res;
  204. ep = res+MAXCAPTURE+textlen;
  205. if(global)
  206. {
  207. do {
  208. #ifdef HAVE_PCRE
  209. nmat = pcre_exec(ppat, NULL, text, textlen, offset, 0, ovec, sizeof(ovec)/sizeof(int));
  210. #else /* HAVE_PCRE */
  211. if (regexec(ppat, text+offset, MAXCAPTURE/3, pmat, 0))
  212. nmat = 0;
  213. else
  214. for( nmat = 0; nmat < MAXCAPTURE/3; nmat++ )
  215. if((ovec[nmat<<1] = pmat[nmat].rm_so) == -1 ||
  216. (ovec[(nmat<<1)+1] = pmat[nmat].rm_eo) == -1) break;
  217. #endif /* HAVE_PCRE */
  218. #ifdef HAVE_PCRE
  219. for(i = 0; i < nmat*2; i++)
  220. ovec[i]-=offset;
  221. #endif /* HAVE_PCRE */
  222. #ifdef REGEX_DEBUG
  223. dumpmatch(text+offset, textlen-offset, to, nmat, ovec);
  224. #endif /* REGEX_DEBUG */
  225. if(nmat > 0)
  226. {
  227. overfl = edit(text+offset, textlen - offset, to, nmat, ovec, res);
  228. offset += ovec[1];
  229. }
  230. } while (nmat >0 && overfl);
  231. }
  232. else
  233. {
  234. #ifdef HAVE_PCRE
  235. nmat = pcre_exec(ppat, NULL, text, textlen, 0, 0, ovec, sizeof(ovec)/sizeof(int));
  236. #else /* HAVE_PCRE */
  237. if (regexec(ppat, text, MAXCAPTURE/3, pmat, 0))
  238. nmat = 0;
  239. else
  240. for( nmat = 0; nmat < MAXCAPTURE/3; nmat++ )
  241. if((ovec[nmat<<1] = pmat[nmat].rm_so) == -1 ||
  242. (ovec[(nmat<<1)+1] = pmat[nmat].rm_eo) == -1) break;
  243. #endif /* HAVE_PCRE */
  244. #ifdef REGEX_DEBUG
  245. dumpmatch(text+offset, textlen-offset, to, nmat, ovec);
  246. #endif /* REGEX_DEBUG */
  247. if(nmat > 0)
  248. {
  249. overfl = edit(text+offset, textlen - offset, to, nmat, ovec, res);
  250. offset += ovec[1];
  251. }
  252. }
  253. if ( textlen >= offset && cp + textlen - offset < ep)
  254. {
  255. strncpy(cp, text+offset, textlen - offset);
  256. *(cp +textlen - offset) = '\0';
  257. }
  258. else
  259. *(ep-1) = '\0';
  260. ret = (unsigned char *)js_mem_alloc(strlen(res)+1);
  261. strcpy(ret,res);
  262. #ifdef HAVE_PCRE
  263. pcre_free(res);
  264. pcre_free(ppat);
  265. #else /* HAVE_PCRE */
  266. mem_free(res);
  267. regfree(ppat);
  268. #endif /* HAVE_PCRE */
  269. return ret;
  270. }
  271. #else
  272. char *
  273. regexp_replace(char * from, char *to, char *text)
  274. {
  275. return stracpy1("Regular expressions not supported");
  276. }
  277. #endif
  278. #endif