Beispiel #1
0
String getword() {
	String s=EmptyString;
	int i=0;
	char c;
	wor++;
	while (i==0) {
		wpos=pos;wrow=row;wcol=col;
		c=(char)fgetc(f);
		pos++;
		col++;
		if (c=='\n') {
			row++;
			col=0;
		}
		if (c==EOF)
			break;
		while (alphanum(c)) {
			s[i]=c;
			i++;
			c=(char)fgetc(f);
			pos++; col++;
			if (c=='\n') {
				row++;
				col=0;
			}
			if (c==EOF)
				break;
		}
	}
	s[i]='\0';
	return s;
}
Beispiel #2
0
void
setname (	/* does parameter assignments */
    unsigned char *argi,
    int xp
)
{
	register unsigned char *argscan = argi;
	register struct namnod *n;

	if (letter(*argscan))
	{
		while (alphanum(*argscan))
			argscan++;

		if (*argscan == '=')
		{
			*argscan = 0;	/* make name a cohesive string */

			n = lookup(argi);
			*argscan++ = '=';
			attrib(n, xp);
			if (xp & N_ENVNAM)
			{
				n->namenv = n->namval = argscan;
				if (n == &pathnod)
					set_builtins_path();
			}
			else
				assign(n, argscan);

			dolocale(n->namid);
			return;
		}
	}
}
Beispiel #3
0
BOOL
chkid(unsigned char *nam)
{
	register unsigned char *cp = nam;

	if (!letter(*cp))
		return(FALSE);
	else
	{
		while (*++cp)
		{
			if (!alphanum(*cp))
				return(FALSE);
		}
	}
	return(TRUE);
}
Beispiel #4
0
static int matchsequence(char *start,char *end,char *pattern,
                         char symbols[MAX_OPT_VARS][MAX_ALIAS+1],
                         int *match_length)
{
  int var,i;
  char str[MAX_ALIAS+1];
  char *start_org=start;
  cell value;
  char *ptr;

  *match_length=0;
  for (var=0; var<MAX_OPT_VARS; var++)
    symbols[var][0]='\0';

  while (*start=='\t' || *start==' ')
    start++;
  while (*pattern) {
    if (start>=end)
      return FALSE;
    switch (*pattern) {
    case '%':   /* new "symbol" */
      pattern++;
      assert(isdigit(*pattern));
      var=atoi(pattern) - 1;
      assert(var>=0 && var<MAX_OPT_VARS);
      assert(*start=='-' || alphanum(*start));
      for (i=0; start<end && (*start=='-' || *start=='+' || alphanum(*start)); i++,start++) {
        assert(i<=MAX_ALIAS);
        str[i]=*start;
      } /* for */
      str[i]='\0';
      if (symbols[var][0]!='\0') {
        if (strcmp(symbols[var],str)!=0)
          return FALSE; /* symbols should be identical */
      } else {
        strcpy(symbols[var],str);
      } /* if */
      break;
    case '-':
      value=-strtol(pattern+1,&pattern,16);
      ptr=itoh((ucell)value);
      while (*ptr!='\0') {
        if (tolower(*start) != tolower(*ptr))
          return FALSE;
        start++;
        ptr++;
      } /* while */
      pattern--;  /* there is an increment following at the end of the loop */
      break;
    case ' ':
      if (*start!='\t' && *start!=' ')
        return FALSE;
      while ((start<end && *start=='\t') || *start==' ')
        start++;
      break;
    case '!':
      while ((start<end && *start=='\t') || *start==' ')
        start++;                /* skip trailing white space */
      if (*start!='\n')
        return FALSE;
      assert(*(start+1)=='\0');
      start+=2;                 /* skip '\n' and '\0' */
      if (*(pattern+1)!='\0')
        while ((start<end && *start=='\t') || *start==' ')
          start++;              /* skip leading white space of next instruction */
      break;
    default:
      if (tolower(*start) != tolower(*pattern))
        return FALSE;
      start++;
    } /* switch */
    pattern++;
  } /* while */

  *match_length=(int)(start-start_org);
  return TRUE;
}
static int matchsequence(char *start, char *end, char *pattern,
                         char symbols[_maxoptvars][_aliasmax + 1], int *match_length) {
    int var, i;
    char str[_aliasmax + 1];
    char *start_org = start;

    *match_length = 0;
    for (var = 0; var < _maxoptvars; var++)
        symbols[var][0] = '\0';

    while (*start == '\t' || *start == ' ')
        start++;
    while (*pattern) {
        if (start >= end)
            return FALSE;
        switch (*pattern) {
        case '%': /* new "symbol" */
            pattern++;
            assert(isdigit(*pattern));
            var = atoi(pattern) - 1;
            assert(var >= 0 && var < _maxoptvars);
            assert(alphanum(*start));
            for (i = 0; start < end && alphanum(*start); i++, start++) {
                assert(i <= _aliasmax);
                str[i] = *start;
            } /* for */
            str[i] = '\0';
            if (symbols[var][0] != '\0') {
                if (strcmp(symbols[var], str) != 0)
                    return FALSE; /* symbols should be identical */
            } else {
                strcpy(symbols[var], str);
            } /* if */
            break;
        case ' ':
            if (*start != '\t' && *start != ' ')
                return FALSE;
            while ((start < end && *start == '\t') || *start == ' ')
                start++;
            break;
        case '!':
            while ((start < end && *start == '\t') || *start == ' ')
                start++; /* skip trailing white space */
            if (*start != '\n')
                return FALSE;
            assert(*(start + 1) == '\0');
            start += 2; /* skip '\n' and '\0' */
            if (*(pattern + 1) != '\0')
                while ((start < end && *start == '\t') || *start == ' ')
                    start++; /* skip leading white space of next instruction */
            break;
        default:
            if (tolower(*start) != tolower(*pattern))
                return FALSE;
            start++;
            break;
        } /* switch */
        pattern++;
    } /* while */

    *match_length = (int) (start - start_org);
    return TRUE;
}
Beispiel #6
0
int 
word(void)
{
	register unsigned int	c, d, cc;
	struct argnod	*arg = (struct argnod *)locstak();
	register unsigned char	*argp = arg->argval;
	unsigned char	*oldargp;
	int		alpha = 1;
	unsigned char *pc;

	wdnum = 0;
	wdset = 0;

	while (1)
	{
		while (c = nextwc(), space(c))		/* skipc() */
			;

		if (c == COMCHAR)
		{
			while ((c = readwc()) != NL && c != EOF);
			peekc = c;
		}
		else
		{
			break;	/* out of comment - white space loop */
		}
	}
	if (!eofmeta(c))
	{
		do
		{
			if (c == LITERAL)
			{
				oldargp = argp;
				while ((c = readwc()) && c != LITERAL){
					/*
					 * quote each character within
					 * single quotes
					 */
					pc = readw(c);
					if (argp >= brkend)
						growstak(argp);
					*argp++='\\';
				/* Pick up rest of multibyte character */
					if (c == NL)
						chkpr();
					while (c = *pc++) {
						if (argp >= brkend)
							growstak(argp);
						*argp++ = (unsigned char)c;
					}
				}
				if (argp == oldargp) { /* null argument - '' */
				/*
				 * Word will be represented by quoted null
				 * in macro.c if necessary
				 */
					if (argp >= brkend)
						growstak(argp);
					*argp++ = '"';
					if (argp >= brkend)
						growstak(argp);
					*argp++ = '"';
				}
			}
			else
			{
				if (c == 0) {
					if (argp >= brkend)
						growstak(argp);
					*argp++ = 0;
				} else {
					pc = readw(c);
					while (*pc) {
						if (argp >= brkend)
							growstak(argp);
						*argp++ = *pc++;
					}
				}
				if (c == '\\') {
					if ((cc = readwc()) == 0) {
						if (argp >= brkend)
							growstak(argp);
						*argp++ = 0;
					} else {
						pc = readw(cc);
						while (*pc) {
							if (argp >= brkend)
								growstak(argp);
							*argp++ = *pc++;
						}
					}
				}
				if (c == '=')
					wdset |= alpha;
				if (!alphanum(c))
					alpha = 0;
				if (qotchar(c))
				{
					d = c;
					for (;;)
					{
						if ((c = nextwc()) == 0) {
							if (argp >= brkend)
								growstak(argp);
							*argp++ = 0;
						} else {
							pc = readw(c);
							while (*pc) {
								if (argp >= brkend)
									growstak(argp);
								*argp++ = *pc++;
							}
						}
						if (c == 0 || c == d)
							break;
						if (c == NL)
							chkpr();
						/*
						 * don't interpret quoted
						 * characters
						 */
						if (c == '\\') {
							if ((cc = readwc()) == 0) {
								if (argp >= brkend)
									growstak(argp);
								*argp++ = 0;
							} else {
								pc = readw(cc);
								while (*pc) {
									if (argp >= brkend)
										growstak(argp);
									*argp++ = *pc++;
								}
							}
						}
					}
				}
			}
		} while ((c = nextwc(), !eofmeta(c)));
		argp = endstak(argp);
		if (!letter(arg->argval[0]))
			wdset = 0;

		peekn = c | MARK;
		if (arg->argval[1] == 0 &&
		    (d = arg->argval[0], digit(d)) &&
		    (c == '>' || c == '<'))
		{
			word();
			wdnum = d - '0';
		}else{ /* check for reserved words */
			if (reserv == FALSE ||
			    (wdval = syslook(arg->argval,
					reserved, no_reserved)) == 0) {
				wdval = 0;
			}
			/* set arg for reserved words too */
			wdarg = arg;
		}
	}else if (dipchar(c)){
		if ((d = nextwc()) == c)
		{
			wdval = c | SYMREP;
			if (c == '<')
			{
				if ((d = nextwc()) == '-')
					wdnum |= IOSTRIP;
				else
					peekn = d | MARK;
			}
		}
		else
		{
			peekn = d | MARK;
			wdval = c;
		}
	}
	else
	{
		if ((wdval = c) == EOF)
			wdval = EOFSYM;
		if (iopend && eolchar(c))
		{
			struct ionod *tmp_iopend;
			tmp_iopend = iopend;
			iopend = 0;
			copy(tmp_iopend);
		}
	}
	reserv = FALSE;
	return (wdval);
}
Beispiel #7
0
static char *replacesequence(const char *pattern,char symbols[MAX_OPT_VARS+1][MAX_ALIAS+1],int *repl_length)
{
  char *lptr;
  int var,optsym;
  char *buffer;

  /* calculate the length of the new buffer
   * this is the length of the pattern plus the length of all symbols (note
   * that the same symbol may occur multiple times in the pattern) plus
   * line endings and startings ('\t' to start a line and '\n\0' to end one)
   */
  assert(repl_length!=NULL);
  *repl_length=0;
  optsym=FALSE;
  lptr=(char*)pattern;
  while (*lptr) {
    switch (*lptr) {
    case '%':
      lptr++;           /* skip '%' */
      assert(isdigit(*lptr));
      var=atoi(lptr);
      assert(var>=0 && var<=MAX_OPT_VARS);
      assert(symbols[var][0]!='\0' || optsym);  /* variable should be defined */
      assert(var!=0 || strlen(symbols[var])==pc_cellsize || (symbols[var][0]=='-' && strlen(symbols[var])==pc_cellsize+1) || atoi(symbols[var])==0);
      *repl_length+=(int)strlen(symbols[var]);
      optsym=FALSE;
      break;
    case '~': /* optional space followed by optional symbol */
      assert(lptr[1]=='%');
      assert(isdigit(lptr[2]));
      var=atoi(lptr+2);
      assert(var>=0 && var<=MAX_OPT_VARS);
      if (symbols[var][0]!='\0')
        *repl_length+=1;  /* copy space if following symbol is valid */
      else
        optsym=TRUE;      /* don't copy space, and symbol is optional */
      break;
    case '#':
      lptr++;           /* skip '#' */
      assert(alphanum(*lptr));
      while (alphanum(lptr[1]))
        lptr++;
      *repl_length+=pc_cellsize*2;
      break;
    case '!':
      *repl_length+=3;  /* '\t', '\n' & '\0' */
      break;
    default:
      *repl_length+=1;
    } /* switch */
    lptr++;
  } /* while */

  /* allocate a buffer to replace the sequence in */
  if ((buffer=(char*)malloc(*repl_length))==NULL) {
	error(103);
    return NULL;
  } /* if */

  /* replace the pattern into this temporary buffer */
  optsym=FALSE;
  lptr=buffer;
  *lptr++='\t';         /* the "replace" patterns do not have tabs */
  while (*pattern) {
    assert((int)(lptr-buffer)<*repl_length);
    switch (*pattern) {
    case '%':
      /* write out the symbol */
      pattern++;
      assert(isdigit(*pattern));
      var=atoi(pattern);
      assert(var>=0 && var<=MAX_OPT_VARS);
      assert(symbols[var][0]!='\0' || optsym);  /* variable should be defined */
      assert(symbols[var][0]=='\0' || !optsym); /* but optional variable should be undefined */
      strcpy(lptr,symbols[var]);
      lptr+=strlen(symbols[var]);
      optsym=FALSE;
      break;
    case '~':
      assert(pattern[1]=='%');
      assert(isdigit(pattern[2]));
      var=atoi(pattern+2);
      assert(var>=0 && var<=MAX_OPT_VARS);
      if (symbols[var][0]!='\0')
        *lptr++=' ';      /* replace ~ by a space */
      else
        optsym=TRUE;      /* don't copy space, and symbol is optional */
      break;
    case '#': {
      ucell v=hex2ucell(pattern+1,NULL);
      char *ptr=itoh(v);
      strcpy(lptr,ptr);
      lptr+=strlen(ptr);
      assert(alphanum(pattern[1]));
      while (alphanum(pattern[1]))
        pattern++;
      break;
    } /* case */
    case '!':
      /* finish the line, optionally start the next line with an indent */
      *lptr++='\n';
      *lptr++='\0';
      if (*(pattern+1)!='\0')
        *lptr++='\t';
      break;
    default:
      *lptr++=*pattern;
    } /* switch */
    pattern++;
  } /* while */

  assert((int)(lptr-buffer)==*repl_length);
  return buffer;
}
Beispiel #8
0
static int matchsequence(char *start,char *end,const char *pattern,
                         char symbols[MAX_OPT_VARS+1][MAX_ALIAS+1],
                         int *match_length)
{
  int var,i,optsym;
  char str[MAX_ALIAS+1];
  char *start_org=start;
  cell value;
  char *ptr;

  *match_length=0;
  optsym=FALSE;
  for (var=0; var<=MAX_OPT_VARS; var++)
    symbols[var][0]='\0';

  while (*start=='\t' || *start==' ')
    start++;
  while (*pattern) {
    if (start>=end)
      return FALSE;
    switch (*pattern) {
    case '%':   /* new "symbol" */
      pattern++;
      assert(isdigit(*pattern));
      var=atoi(pattern);
      assert(var>=0 && var<=MAX_OPT_VARS);
      assert(*start=='-' || alphanum(*start) || optsym);
      for (i=0; start<end && (*start=='-' || *start=='+' || alphanum(*start)); i++,start++) {
        assert(i<=MAX_ALIAS);
        str[i]=*start;
      } /* for */
      str[i]='\0';
      if (var==0) {
        /* match only if the parameter is numeric and in the range of a half cell */
        const char *ptr;
        /* getparamvalue() resolves leading '-' on values and adds multiple
         * values (the peephole optimizer may create such variants)
         */
        ucell v=getparamvalue(str,&ptr);
        if (*ptr>' ' || v>=((ucell)1<<((pc_cellsize*4)-1)) && v<=~((ucell)1<<((pc_cellsize*4)-1)))
          return FALSE;
        /* reconvert the value to a string (without signs or expressions) */
        ptr=itoh(v);
        #if !defined NDEBUG
          assert(strlen(ptr)==2*pc_cellsize);
          assert((ptr[0]=='0' || ptr[0]=='f') && (ptr[1]=='0' || ptr[1]=='f'));
          if (pc_cellsize>=32)
            assert((ptr[2]=='0' || ptr[2]=='f') && (ptr[3]=='0' || ptr[3]=='f'));
          if (pc_cellsize>=64) {
            assert((ptr[4]=='0' || ptr[4]=='f') && (ptr[5]=='0' || ptr[5]=='f'));
            assert((ptr[6]=='0' || ptr[6]=='f') && (ptr[7]=='0' || ptr[7]=='f'));
          } /* if */
        #endif
        if (v==0) {
          str[0]='0'; /* make zero transform to '0' rather than '0000' */
          str[1]='\0';
        } else {
          memmove(str,ptr+pc_cellsize,pc_cellsize+1);
        } /* if */
      } /* if */
      if (symbols[var][0]!='\0') {
        if (strcmp(symbols[var],str)!=0)
          return FALSE; /* symbols should be identical */
      } else {
        strcpy(symbols[var],str);
      } /* if */
      optsym=FALSE;
      break;
    case '-':
      value=-hex2cell(pattern+1,&pattern);
      ptr=itoh((ucell)value);
      while (*ptr!='\0') {
        if (tolower(*start) != tolower(*ptr))
          return FALSE;
        start++;
        ptr++;
      } /* while */
      pattern--;  /* there is an increment following at the end of the loop */
      break;
    case '+':
      value=hex2cell(pattern+1,&pattern);
      ptr=itoh((ucell)value);
      while (*ptr!='\0') {
        if (tolower(*start) != tolower(*ptr))
          return FALSE;
        start++;
        ptr++;
      } /* while */
      pattern--;  /* there is an increment following at the end of the loop */
      break;
    case ' ':     /* required whitespace */
      if (*start!='\t' && *start!=' ')
        return FALSE;
      while (start<end && (*start=='\t' || *start==' '))
        start++;
      break;
    case '~':     /* optional whitespace (followed by optional symbol) */
      while (start<end && (*start=='\t' || *start==' '))
        start++;
      optsym= (pattern[1]=='%');
      break;
    case '!':
      while (start<end && (*start=='\t' || *start==' '))
        start++;                /* skip trailing white space */
      if (*start==';')
        while (start<end && *start!='\n')
          start++;              /* skip trailing comment */
      if (*start!='\n')
        return FALSE;
      assert(*(start+1)=='\0');
      start+=2;                 /* skip '\n' and '\0' */
      if (*(pattern+1)!='\0')
        while (start<end && *start=='\t' || *start==' ')
          start++;              /* skip leading white space of next instruction */
      break;
    default:
      if (tolower(*start) != tolower(*pattern))
        return FALSE;
      start++;
    } /* switch */
    pattern++;
  } /* while */

  *match_length=(int)(start-start_org);
  return TRUE;
}
Beispiel #9
0
int word(void)
{
	register char c, d;
	register char *argp = locstak() + BYTESPERWORD;
	int alpha = 1;

	wdnum = 0;
	wdset = 0;

	while (1)
	{
		while (c = nextc(0), space(c))		/* skipc() */
			;

		if (c == COMCHAR)
		{
			while ((c = readc()) != NL && c != EOF);
			peekc = c;
		}
		else
		{
			break;	/* out of comment - white space loop */
		}
	}

	if (!eofmeta(c)) {
		do {
			if (c == LITERAL) {
				*argp++ = (DQUOTE);
				while ((c = readc()) && c != LITERAL) {
					*argp++ = (c | QUOTE);
					chkpr(c);
				}
				*argp++ = (DQUOTE);
			} else {
				*argp++ = (c);
				if (c == '=')
					wdset |= alpha;
				if (!alphanum(c))
					alpha = 0;
				if (qotchar(c)) {
					d = c;
					while ((*argp++ = (c = nextc(d))) && c != d)
						chkpr(c);
				}
			}
		} while ((c = nextc(0), !eofmeta(c)));

		argp = endstak(argp);

		if (!letter(((ARGPTR) argp)->argval[0]))
			wdset = 0;

		peekc = c | MARK;

		if (((ARGPTR) argp)->argval[1] == 0
		    && (d = ((ARGPTR) argp)->argval[0], digit(d))
		    && (c == '>' || c == '<')) {
			word();
			wdnum = d - '0';
		} else {	/*check for reserved words */
			if (reserv == FALSE
			    || (wdval =	syslook(((ARGPTR) argp)->argval, reserved)) == 0) {
				wdarg = (ARGPTR) argp;
				wdval = 0;
			}
		}

	} else if (dipchar(c)) {
		if ((d = nextc(0)) == c)
			wdval = c | SYMREP;
		else {
			peekc = d | MARK;
			wdval = c;
		}
	} else {
		if ((wdval = c) == EOF)
			wdval = EOFSYM;
		if (iopend && eolchar(c)) {
			copy(iopend);
			iopend = 0;
		}
	}
	reserv = FALSE;
	return wdval;
}
Beispiel #10
0
Datei: macro.c Projekt: 8l/FUZIX
static int getch(char endch)
{
	register char d;

retry:
	d = readc();
	if (!subchar(d))
		return (d);

	if (d == DOLLAR) {
		register int c;
		if ((c = readc(), dolchar(c))) {
			NAMPTR n = (NAMPTR) NIL;
			int dolg = 0;
			BOOL bra;
			register const char *argp;
			register const char *v;
			CHAR idb[2];
			char *id = idb;

			if (bra = (c == BRACE))
				c = readc();

			if (letter(c)) {
				argp = (STRING) relstak();
				while (alphanum(c)) {
					pushstak(c);
					c = readc();
				}
				zerostak();
				n = lookup(absstak(argp));
				setstak(argp);
				v = n->namval;
				id = (char *)n->namid;
				peekc = c | MARK;;
			} else if (digchar(c)) {
				*id = c;
				idb[1] = 0;
				if (astchar(c)) {
					dolg = 1;
					c = '1';
				}
				c -= '0';
				v = ((c == 0) ? (const char *)cmdadr :
				         (c <= dolc) ? dolv[c]
					 : (dolg = 0, NULL));
			} else if (c == '$') {
				v = pidadr;
			} else if (c == '!') {
				v = pcsadr;
			} else if (c == '#') {
				v = dolladr;
			} else if (c == '?') {
				v = exitadr;
			} else if (c == '-') {
				v = flagadr;
			} else if (bra) {
				error(badsub);
			} else {
				goto retry;
			}
			c = readc();

			if (!defchar(c) && bra)
				error(badsub);

			argp = 0;
			if (bra) {
				if (c != '}') {
					argp = (STRING) relstak();
					if ((v == 0) ^ (setchar(c)))
						copyto('}');
					else
						skipto('}');

					argp = absstak(argp);
				}
			} else {
				peekc = c | MARK;
				c = 0;
			}
			if (v) {
				if (c != '+') {
					for (;;) {
						while (c = *v++)
							pushstak(c | quote);

						if (dolg == 0 || (++dolg > dolc))
							break;
						else {
							v = dolv[dolg];
							pushstak(SP | (*id == '*' ? quote : 0));
						}
					}
				}
			} else if (argp) {
				if (c == '?') {
					failed(id,
					       *argp ? argp : badparam);
				} else if (c == '=') {
					if (n)
						assign(n, argp);
					else
						error(badsub);
				}
                        } else if (flags & setflg) {
				failed(id, badparam);
			}
			goto retry;
		} else {
			peekc = c | MARK;
		}
	} else if (d == endch) {
		return (d);
	} else if (d == SQUOTE) {
		comsubst();
		goto retry;
	} else if (d == DQUOTE) {
		quoted++;
		quote ^= QUOTE;
		goto retry;
	}
	return d;
}
Beispiel #11
0
int main(int argc, char** argv) {

	// between
	ok(between('a','z','c'), "c is between a and z");
	fail(between('a','z','C'), "C is not between a and z");

	// num
	ok(num('0'), "0 is a number");
	ok(num('9'), "9 is a number");
	fail(num('/'), "/ is not a number");
	fail(num(':'), "0 is not a number");

	// alpha
	ok(alpha('a'), "a is a letter");	
	ok(alpha('z'), "z is a letter");	
	ok(alpha('A'), "A is a letter");	
	ok(alpha('Z'), "Z is a letter");	
	fail(alpha('@'), "@ is not a letter");	
	fail(alpha('['), "[ is not a letter");	
	fail(alpha('`'), "` is not a letter");	
	fail(alpha('{'), "{ is not a letter");	
	
	// alphanum
	ok(alphanum('a'), "a is alphanum");
	ok(alphanum('z'), "z is alphanum");
	ok(alphanum('A'), "A is alphanum");
	ok(alphanum('Z'), "Z is alphanum");
	ok(alphanum('0'), "0 is alphanum");
	ok(alphanum('9'), "9 is alphanum");
	fail(alpha('@'), "@ is not alphanum ");	
	fail(alpha('['), "[ is not alphanum");	
	fail(alpha('`'), "` is not alphanum");	
	fail(alpha('{'), "{ is not alphanum");	

	// space
	ok(space(' '), "space is space");
	fail(space('\n'), "new line is not space");
	fail(space('\r'), "cr is not space");
	fail(space('\t'), "tab is not space");

	// tab
	ok(tab('\t'), "tab is tab");
	fail(tab(' '), "space is not tab");
	fail(tab('\n'), "new line is not tab");
	fail(tab('\r'), "cr is not tab");
	
	// nl
	ok(nl('\n'), "new line is new line");
	fail(nl('\t'), "tab is not new line");
	fail(nl(' '), "space is not new line");
	fail(nl('\r'), "cr is not new line");
	
	// cr
	fail(cr('\n'), "new line is not cr");
	fail(cr('\t'), "tab is not cr");
	fail(cr(' '), "space is not cr");
	ok(cr('\r'), "cr is cr");
	
	// whitespace
	ok(whitespace('\n'), "new line is whitespace");
	ok(whitespace('\t'), "tab is whitespace");
	ok(whitespace(' '), "space is whitespace");
	ok(whitespace('\r'), "cr is whitespace");
	fail(whitespace('\b'), "backspace is not whitespace");

	// colon
	ok(colon(':'), "colon is colon");
	fail(colon(';'), "semicolon is not colon");

	// semi
	fail(semi(':'), "colon is not semicolon");
	ok(semi(';'), "semicolon is semicolon");

	// slash
	fail(slash('\\'), "\\ is not /");
	ok(slash('/'), "/ is /");

	// dot
	fail(dot('*'), "* is not .");
	ok(dot('.'), ". is .");
	
	// star
	ok(star('*'), "* is *");
	fail(star('.'), ". is not *");
	
	// question
	ok(question('?'), "? is ?");

	// hex
	ok(hex('a'), "a is hex");
	ok(hex('f'), "f is hex");
	ok(hex('A'), "A is hex");
	ok(hex('F'), "F is hex");
	ok(hex('0'), "0 is hex");
	ok(hex('9'), "9 is hex");
	fail(hex('g'), "g is not hex");
	fail(hex('G'), "G is not hex");
	
	// decimal
	ok(decimal('0'), "0 is decimal");
	ok(decimal('9'), "9 is decimal");
	ok(decimal('.'), ". is decimal");
	fail(decimal('a'), "a is not decimal");

	// ctrl
	ok(ctrl('\b'), "Backspace is ctrl");
	ok(ctrl('\a'), "Bell is ctrl");
	ok(ctrl(127), "Del is ctrl");
	fail(ctrl('a'), "a is not ctrl");

	// any 
	value(3,any(alpha,"abc123"), "three letters at abc123");
	value(0,any(num,"abc123"), "no numbers at abc123");
	value(6,any(alphanum,"abc123"), "six alphanum in abc123");
	
	// until
	value(5,until(space,"hello world!"), "5 letters until space");
	value(11,until(question,"hello world?"), "11 letters until question");
	value(12,until(ctrl,"hello world?"), "12 chacters till end");

	// crlf, eol, and upto
	value(6, upto(eol, "line 1\r\nline 1\r\n"), "6 chars upto crlf");
	value(0, upto(eol, "\r\n\r\n"), "0 characters to end of line");
	value(12, upto(eol, "hello world!"), "12 characters to eol");

	// all test
	value(5, all(dot, ".....\r\n"), "there are 5 dots");

	return done("test_parse");
}