/*----------------------------------------------------------------
   Parses a string containing wild cards into a token list
   which can be used by pattern_match() to check strings
   to see if they match the specified patterns.

   Entry Requirements:
      pattern : A string containing the specifications for a
		pattern. 
      single : The character which is to be interpreted as
	       a wild card for any single character.
      mulitple : The character which is to be interpreted as
	         a wild card for any number of characters.
      escape : The character which is used to escape the meaning of
	       the next character. The next character is taken
	       literally.

   Return Value:
      NULL : If pattern is NULL or unable to create instances of
	     required variables.
      otherwise : A pointer to a PATTERN structure which contains
	     a token list.

   Development History:
      Begun: 03/02/92 - Todd King

   Version:
      @(#)p_parse.c	1.1    (UCLA/IGPP)   03 Mar 1992
------------------------------------------------------------------*/
#include <string.h>
#include "pattern.h"

PATTERN *
pattern_parse(pattern, single, mulitple, escape)
char pattern[];
char single;
char mulitple;
char escape;
{
   PATTERN *p;
   PATTERN *head = NULL;
   PATTERN *last = NULL;
   char *s;
   char *t;
   int new_pattern = 1;

   if(pattern == NULL) return(NULL);

   s = strdup(pattern);
   if(s == NULL) return(NULL);


   for(; *s != '\0'; s++) {
      if(*s == single || *s == mulitple) {
	 new_pattern = 1;
	 p = pattern_make();
	 if(p == NULL) return(NULL);
	 if(head == NULL) { head = p; }
	 else { last->next = p; }
	 last = p;
	 if(*s == mulitple) p->type = PATTERN_TYPE_MULTIPLE_CHAR;
	 if(*s == single) p->type = PATTERN_TYPE_SINGLE_CHAR;
	 *s = '\0';
      } else {
	 if(new_pattern) {
	    new_pattern = 0;
	    p = pattern_make();
	    if(p == NULL) return(NULL);
	    if(head == NULL) { head = p; }
	    else { last->next = p; }
	    last = p;
	    p->type = PATTERN_TYPE_FIXED;
	    p->text = s;
	    if (*s == escape && *(s + 1) != '\0') { s++; }
	 }
      }

   }

   /* Now compress out literal escapes and set text_len field */

   for(p = head; p != NULL; p = p->next) {
      switch(p->type) {
	 case PATTERN_TYPE_FIXED:
	    for(t = s = p->text; *s != '\0'; s++, t++) {
	       if(*s == escape) { s++; }
	       *t = *s;
	    }
	    *t = '\0';
	    p->text_len = strlen(p->text);
	    break;
      }
   }

   return(head);
      
}

