00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055 #include <string.h>
00056 #include <strings.h>
00057 
00058 
00059 
00060 #ifdef __WIN32__
00061 #include "../windows/regex/regex.h"
00062 #else
00063 #include <regex.h>
00064 #endif
00065 
00066 #include "tcrip.h"
00067 
00068 typedef struct regsub {
00069   regex_t rx;
00070   regmatch_t *m;
00071   const char *s;
00072 }
00073 regsub_t;
00074 
00075 static char *rs_lookup(char *n, void *d) {
00076   regsub_t *rs = d;
00077   char *t;
00078   int ml;
00079   unsigned int m = strtol(n, &t, 0);
00080 
00081   if(*t)
00082     return NULL;
00083   if(m > rs->rx.re_nsub)
00084     return NULL;
00085   if(rs->m[m].rm_so < 0)
00086     return strdup("");
00087 
00088   ml = rs->m[m].rm_eo - rs->m[m].rm_so;
00089   t = malloc(ml + 1);
00090   strncpy(t, rs->s + rs->m[m].rm_so, ml);
00091   t[ml] = 0;
00092 
00093   return t;
00094 }
00095 
00096 char* tcregsub(const char *str, const char *pat, const char *sub, int cflags) {
00097   regsub_t rs;
00098   const char *s;
00099   char *ss, *p;
00100   int r, l;
00101 
00102   if((r = regcomp(&rs.rx, pat, cflags))) {
00103     char buf[256];
00104     regerror(r, &rs.rx, buf, sizeof(buf));
00105     fprintf(stderr, "tcregsub: %s\n", buf);
00106     return NULL;
00107   }
00108 
00109   rs.m = calloc(rs.rx.re_nsub + 1, sizeof(*rs.m));
00110   l = strlen(str);
00111   ss = malloc(l + 1);
00112   p = ss;
00113   s = str;
00114 
00115   while(*s) {
00116     int ml;
00117     if(regexec(&rs.rx, s, rs.rx.re_nsub + 1, rs.m, 0))
00118       break;
00119 
00120     strncpy(p, s, rs.m[0].rm_so);
00121     p += rs.m[0].rm_so;
00122     ml = rs.m[0].rm_eo - rs.m[0].rm_so;
00123     if(ml > 0) {
00124       char *ms = malloc(ml + 1);
00125       char *rp;
00126       int sl, o;
00127 
00128       rs.s = s;
00129       rp = tcstrexp(sub, "{", "}", 0, rs_lookup, &rs,
00130                     TCSTREXP_KEEPUNDEF | TCSTREXP_FREE);
00131       sl = strlen(rp);
00132       o = p - ss;
00133       ss = realloc(ss, l += sl);
00134       p = ss + o;
00135 
00136       strcpy(p, rp);
00137       p += sl;
00138       free(rp);
00139       free(ms);
00140     }
00141     s += rs.m[0].rm_eo;
00142   }
00143 
00144   strcpy(p, s);
00145   free(rs.m);
00146   regfree(&rs.rx);
00147   return ss;
00148 }
00149