Back to index

php5  5.3.10
debug.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <ctype.h>
00004 #include <limits.h>
00005 #include <stdlib.h>
00006 #include <sys/types.h>
00007 #include <regex.h>
00008 
00009 #include "utils.h"
00010 #include "regex2.h"
00011 #include "debug.ih"
00012 
00013 /*
00014  - regprint - print a regexp for debugging
00015  == void regprint(regex_t *r, FILE *d);
00016  */
00017 void
00018 regprint(r, d)
00019 regex_t *r;
00020 FILE *d;
00021 {
00022        register struct re_guts *g = r->re_g;
00023        register int i;
00024        register int c;
00025        register int last;
00026        int nincat[NC];
00027 
00028        fprintf(d, "%ld states, %d categories", (long)g->nstates,
00029                                                  g->ncategories);
00030        fprintf(d, ", first %ld last %ld", (long)g->firststate,
00031                                           (long)g->laststate);
00032        if (g->iflags&USEBOL)
00033               fprintf(d, ", USEBOL");
00034        if (g->iflags&USEEOL)
00035               fprintf(d, ", USEEOL");
00036        if (g->iflags&BAD)
00037               fprintf(d, ", BAD");
00038        if (g->nsub > 0)
00039               fprintf(d, ", nsub=%ld", (long)g->nsub);
00040        if (g->must != NULL)
00041               fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
00042                                                         g->must);
00043        if (g->backrefs)
00044               fprintf(d, ", backrefs");
00045        if (g->nplus > 0)
00046               fprintf(d, ", nplus %ld", (long)g->nplus);
00047        fprintf(d, "\n");
00048        s_print(g, d);
00049        for (i = 0; i < g->ncategories; i++) {
00050               nincat[i] = 0;
00051               for (c = CHAR_MIN; c <= CHAR_MAX; c++)
00052                      if (g->categories[c] == i)
00053                             nincat[i]++;
00054        }
00055        fprintf(d, "cc0#%d", nincat[0]);
00056        for (i = 1; i < g->ncategories; i++)
00057               if (nincat[i] == 1) {
00058                      for (c = CHAR_MIN; c <= CHAR_MAX; c++)
00059                             if (g->categories[c] == i)
00060                                    break;
00061                      fprintf(d, ", %d=%s", i, regchar(c));
00062               }
00063        fprintf(d, "\n");
00064        for (i = 1; i < g->ncategories; i++)
00065               if (nincat[i] != 1) {
00066                      fprintf(d, "cc%d\t", i);
00067                      last = -1;
00068                      for (c = CHAR_MIN; c <= CHAR_MAX+1; c++)  /* +1 does flush */
00069                             if (c <= CHAR_MAX && g->categories[c] == i) {
00070                                    if (last < 0) {
00071                                           fprintf(d, "%s", regchar(c));
00072                                           last = c;
00073                                    }
00074                             } else {
00075                                    if (last >= 0) {
00076                                           if (last != c-1)
00077                                                  fprintf(d, "-%s",
00078                                                         regchar(c-1));
00079                                           last = -1;
00080                                    }
00081                             }
00082                      fprintf(d, "\n");
00083               }
00084 }
00085 
00086 /*
00087  - s_print - print the strip for debugging
00088  == static void s_print(register struct re_guts *g, FILE *d);
00089  */
00090 static void
00091 s_print(g, d)
00092 register struct re_guts *g;
00093 FILE *d;
00094 {
00095        register sop *s;
00096        register cset *cs;
00097        register int i;
00098        register int done = 0;
00099        register sop opnd;
00100        register int col = 0;
00101        register int last;
00102        register sopno offset = 2;
00103 #      define GAP()  {      if (offset % 5 == 0) { \
00104                                    if (col > 40) { \
00105                                           fprintf(d, "\n\t"); \
00106                                           col = 0; \
00107                                    } else { \
00108                                           fprintf(d, " "); \
00109                                           col++; \
00110                                    } \
00111                             } else \
00112                                    col++; \
00113                             offset++; \
00114                      }
00115 
00116        if (OP(g->strip[0]) != OEND)
00117               fprintf(d, "missing initial OEND!\n");
00118        for (s = &g->strip[1]; !done; s++) {
00119               opnd = OPND(*s);
00120               switch (OP(*s)) {
00121               case OEND:
00122                      fprintf(d, "\n");
00123                      done = 1;
00124                      break;
00125               case OCHAR:
00126                      if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
00127                             fprintf(d, "\\%c", (unsigned char)opnd);
00128                      else
00129                             fprintf(d, "%s", regchar((unsigned char)opnd));
00130                      break;
00131               case OBOL:
00132                      fprintf(d, "^");
00133                      break;
00134               case OEOL:
00135                      fprintf(d, "$");
00136                      break;
00137               case OBOW:
00138                      fprintf(d, "\\{");
00139                      break;
00140               case OEOW:
00141                      fprintf(d, "\\}");
00142                      break;
00143               case OANY:
00144                      fprintf(d, ".");
00145                      break;
00146               case OANYOF:
00147                      fprintf(d, "[(%ld)", (long)opnd);
00148                      cs = &g->sets[opnd];
00149                      last = -1;
00150                      for (i = 0; i < g->csetsize+1; i++)       /* +1 flushes */
00151                             if (CHIN(cs, i) && i < g->csetsize) {
00152                                    if (last < 0) {
00153                                           fprintf(d, "%s", regchar(i));
00154                                           last = i;
00155                                    }
00156                             } else {
00157                                    if (last >= 0) {
00158                                           if (last != i-1)
00159                                                  fprintf(d, "-%s",
00160                                                         regchar(i-1));
00161                                           last = -1;
00162                                    }
00163                             }
00164                      fprintf(d, "]");
00165                      break;
00166               case OBACK_:
00167                      fprintf(d, "(\\<%ld>", (long)opnd);
00168                      break;
00169               case O_BACK:
00170                      fprintf(d, "<%ld>\\)", (long)opnd);
00171                      break;
00172               case OPLUS_:
00173                      fprintf(d, "(+");
00174                      if (OP(*(s+opnd)) != O_PLUS)
00175                             fprintf(d, "<%ld>", (long)opnd);
00176                      break;
00177               case O_PLUS:
00178                      if (OP(*(s-opnd)) != OPLUS_)
00179                             fprintf(d, "<%ld>", (long)opnd);
00180                      fprintf(d, "+)");
00181                      break;
00182               case OQUEST_:
00183                      fprintf(d, "(?");
00184                      if (OP(*(s+opnd)) != O_QUEST)
00185                             fprintf(d, "<%ld>", (long)opnd);
00186                      break;
00187               case O_QUEST:
00188                      if (OP(*(s-opnd)) != OQUEST_)
00189                             fprintf(d, "<%ld>", (long)opnd);
00190                      fprintf(d, "?)");
00191                      break;
00192               case OLPAREN:
00193                      fprintf(d, "((<%ld>", (long)opnd);
00194                      break;
00195               case ORPAREN:
00196                      fprintf(d, "<%ld>))", (long)opnd);
00197                      break;
00198               case OCH_:
00199                      fprintf(d, "<");
00200                      if (OP(*(s+opnd)) != OOR2)
00201                             fprintf(d, "<%ld>", (long)opnd);
00202                      break;
00203               case OOR1:
00204                      if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
00205                             fprintf(d, "<%ld>", (long)opnd);
00206                      fprintf(d, "|");
00207                      break;
00208               case OOR2:
00209                      fprintf(d, "|");
00210                      if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
00211                             fprintf(d, "<%ld>", (long)opnd);
00212                      break;
00213               case O_CH:
00214                      if (OP(*(s-opnd)) != OOR1)
00215                             fprintf(d, "<%ld>", (long)opnd);
00216                      fprintf(d, ">");
00217                      break;
00218               default:
00219                      fprintf(d, "!%ld(%ld)!", OP(*s), opnd);
00220                      break;
00221               }
00222               if (!done)
00223                      GAP();
00224        }
00225 }
00226 
00227 /*
00228  - regchar - make a character printable
00229  == static char *regchar(int ch);
00230  */
00231 static unsigned char *                    /* -> representation */
00232 regchar(ch)
00233 int ch;
00234 {
00235        static unsigned char buf[10];
00236 
00237        if (isprint(ch) || ch == ' ')
00238               sprintf(buf, "%c", ch);
00239        else
00240               sprintf(buf, "\\%o", ch);
00241        return(buf);
00242 }