Advertisement
jimccann

non-greedy wildcard matching ignoring consecutive whitespace

Oct 11th, 2017
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.14 KB | None | 0 0
  1. #include <ctype.h>
  2. #include <stdlib.h>
  3. void dispose_matchdata(char **matchdata) {
  4.     if (!matchdata) return;
  5.     for (char **phrase = matchdata; *phrase; ++phrase)
  6.         free(*phrase);
  7.     free(matchdata);
  8. }
  9. char **match(char const *instance, char const *pattern) {
  10.     char **retval;
  11.     char **currdata;
  12.     int astcount = 0;
  13.     char const *lastast = 0;
  14.     int cdatsize = 0;
  15.     int cdatcap = 0;
  16.     for (char const *astchk = pattern; *astchk; ++astchk)
  17.         if (*astchk == '*') ++astcount;
  18.     retval = calloc(astcount + 1, sizeof(char *));
  19.     currdata = retval - 1;
  20.     while (isspace(*instance)) ++instance;
  21.     while (isspace(*pattern)) ++pattern;
  22.     while (*instance && *pattern) {
  23.         if (lastast != pattern && *pattern == '*') {
  24.             lastast = pattern;
  25.             ++currdata;
  26.             cdatsize = 0;
  27.             cdatcap = 16;
  28.             *currdata = malloc(cdatcap);
  29.         }
  30.         if (isspace(*instance) && isspace(*pattern)) {
  31.             do { ++instance; } while (isspace(*instance));
  32.             do { ++pattern; } while (isspace(*pattern));
  33.         } else if (isspace(*instance) && *pattern == '*') {
  34.             do { ++instance; } while (isspace(*instance));
  35.         } else if (isspace(*instance) || isspace(*pattern)) {
  36.             dispose_matchdata(retval);
  37.             return 0;
  38.         } else if (pattern == lastast) {
  39.             int done = 0;
  40.             char const *next_nonws = pattern;
  41.             do { ++next_nonws; }
  42.             while (isspace(*next_nonws));
  43.             while (!done) {
  44.                 int break_outer = 0;
  45.                 do {
  46.                     if (*next_nonws && !*instance) {
  47.                         dispose_matchdata(retval);
  48.                         return 0;
  49.                     }
  50.                     if (isspace(*instance)
  51.                         && *next_nonws == '*') {
  52.                         break_outer = 1;
  53.                         break;
  54.                     }
  55.                     (*currdata)[cdatsize] = *instance;
  56.                     ++cdatsize;
  57.                     if (cdatsize >= cdatcap) {
  58.                         cdatcap *= 2;
  59.                         *currdata = realloc(*currdata,
  60.                             cdatcap);
  61.                     }
  62.                     do { ++instance; }
  63.                     while (isspace(*instance)
  64.                         && isspace(instance[1]));
  65.                 } while (*instance != *next_nonws);
  66.                 if (break_outer) break;
  67.                 done = 1;
  68.                 char const *ichk = instance;
  69.                 char const *pchk = pattern + 1;
  70.                 while (isspace(*ichk)) ++ichk;
  71.                 while (isspace(*pchk)) ++pchk;
  72.                 while (*ichk && *pchk && *pchk != '*') {
  73.                     if (isspace(*ichk) && isspace(*pchk)) {
  74.                         do { ++ichk; } while (isspace(*ichk));
  75.                         do { ++pchk; } while (isspace(*pchk));
  76.                     } else if (*ichk != *pchk) {
  77.                         done = 0;
  78.                         break;
  79.                     } else {
  80.                         ++ichk;
  81.                         ++pchk;
  82.                     }
  83.                 }
  84.                 if (done) {
  85.                     while (isspace(*ichk)) ++ichk;
  86.                     while (isspace(*pchk)) ++pchk;
  87.                     if (!*ichk != !*pchk) {
  88.                         done = 0;
  89.                     }
  90.                 }
  91.             }
  92.             (*currdata)[cdatsize] = 0;
  93.             int i = cdatsize - 1;
  94.             while (isspace((*currdata)[i]) && i > 0) --i;
  95.             cdatcap = i + 2;
  96.             *currdata = realloc(*currdata, cdatcap);
  97.             (*currdata)[i + 1] = 0;
  98.             do { ++pattern; } while (isspace(*pattern));
  99.         } else if (*instance != *pattern) {
  100.             dispose_matchdata(retval);
  101.             return 0;
  102.         } else {
  103.             ++instance;
  104.             ++pattern;
  105.         }
  106.     }
  107.     while (isspace(*instance)) ++instance;
  108.     while (isspace(*pattern)) ++pattern;
  109.     if (*instance || *pattern) {
  110.         dispose_matchdata(retval);
  111.         return 0;
  112.     } else {
  113.         return retval;
  114.     }
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement