TinyMAZE/
TinyMAZE/config/
TinyMAZE/doc/
TinyMAZE/run/msgs/
TinyMAZE/src/
TinyMAZE/src/db/
TinyMAZE/src/ident/
TinyMAZE/src/io/
TinyMAZE/src/prog/
TinyMAZE/src/softcode/
TinyMAZE/src/util/
#include <stdio.h>
#include <string.h>
#include "externs.h"

static bool is_glob_token(char c)
{
  return((c == '?' || c == '*'));
}

static void add_glob(char *str, int len, char ***globs)
{
  char buf[4096];
  int i;

  if(!len)
    return;

  strncpy(buf, str, len);
  *(buf+len) = '\0';

  for(i = 0;(*globs)[i];i++); /* Whole loop */
  *globs = (char **)stack_realloc_tmp(*globs, sizeof(char *)*(i+2));
  (*globs)[i] = stack_string_alloc(buf, 0);
  (*globs)[i+1] = NULL;
}

static void wildcard_parse(char *str, char ***globs)
{
  char *p;

  *globs = (char **)stack_alloc(sizeof(char *), 0, 0);
  (*globs)[0] = NULL;

  for(p = str;*p;p++)
  {
    if(!is_glob_token(*p))
      continue;
    add_glob(str, p-str, globs);
    add_glob(p, 1, globs);
    str = p+1;
  }

  add_glob(str, p-str, globs);
}

static void add_glob_arg(char *p, int len, char ***args)
{
  char buf[4096];
  int i;

  if(!args)
    return;

  strncpy(buf, p, len);
  *(buf+len) = '\0';

  for(i = 0;(*args)[i];i++); /* Whole loop */
  *args = (char **)stack_realloc_tmp(*args, sizeof(char *)*(i+2));
  (*args)[i] = stack_string_alloc(buf, 0);
  (*args)[i+1] = NULL;
}

bool wildcard_match(char *wildcard_str, char *match_str, char ***args)
{
  char **globs;
  char *q;
  int i;

  wildcard_parse(wildcard_str, &globs);

  if(args)
  {
    *args = (char **)stack_alloc(sizeof(char *), 0, 0);
    (*args)[0] = NULL;
  }

  for(i = 0;globs[i] && *match_str;i++)
  {
    switch(*(globs[i]))
    {
      case '?':
        add_glob_arg(match_str++, 1, args);
        break;
      case '*':
        if(!globs[i+1])
        {
          add_glob_arg(match_str, strlen(match_str), args);
          match_str += strlen(match_str);
        }
        else
        {
          if(is_glob_token(*(globs[i+1])))
          {
            if(!*(match_str+1))
              return(0);
            add_glob_arg(match_str++, 1, args);
          }
          else
          {
            if(!(q = strstr(match_str+1, globs[i+1])))
              return(0);
            add_glob_arg(match_str, q-match_str, args);
            match_str = q;
          }
        }
        break;
      default:
        if(strncmp(match_str, globs[i], strlen(globs[i])))
          return(0);
        match_str += strlen(globs[i]);
    }
  }

  return((bool)(!globs[i] && !*match_str));
}