Exemplo n.º 1
0
static ZZJSON *parse_value(ZZJSON_CONFIG *config) {
    ZZJSON *retval = NULL;
    int c;

    SKIPWS();
    c = GETC();
    UNGETC(c);
    switch (c) {
        case '"':   retval = parse_string2(config); break;
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9': case '-':
                    retval = parse_number(config); break;
        case '{':   retval = parse_object(config); break;
        case '[':   retval = parse_array(config); break;
        case 't':   retval = parse_true(config); break;
        case 'f':   retval = parse_false(config); break;
        case 'n':   retval = parse_null(config); break;
    }

    if (!retval) {
        ERROR("value: invalid value");
        return retval;
    }

    return retval;
}
Exemplo n.º 2
0
/*
 * local function to read a cons node
 */
static LVAL readcons(tpLspObject pLSP,FILE *f)
{
   int ch;

   spaceat(ch,f);
   if( ch == pLSP->cClose )return NIL;
   UNGETC(ch);
   return readlist(f);
}
Exemplo n.º 3
0
int peekc( FILE *file ) {
  int const c = getc( file );
  if ( c == EOF ) {
    if ( ferror( file ) )
      PERROR_EXIT( READ_ERROR );
  } else {
    UNGETC( c, file );
  }
  return c;
}
Exemplo n.º 4
0
/*FUNCTION*/
LVAL c_readexpr(tpLspObject pLSP,
                FILE *f
  ){
/*noverbatim
CUT*/
  int ch;

  spaceat(ch,f);
  if( ch == EOF )return NIL;
  UNGETC(ch);
  return _readexpr(pLSP,f);
  }
Exemplo n.º 5
0
Arquivo: lex.c Projeto: lufia/wf
static int
skip(char *s)
{
	int n, c;

	n = 0;
	while((c=GETC()) >= 0 && strchr(s, c))
		n++;
	if(c != Beof)
		UNGETC(c);
	return n;
}
Exemplo n.º 6
0
Arquivo: lex.c Projeto: lufia/wf
static int
fail(int st)
{
	int c;

	while((c=GETC()) >= 0 && c != '\n')
		;
	if(c == '\n')
		UNGETC(c);
	setstate(st);
	return Terror;
}
Exemplo n.º 7
0
/* getherevar -- read a variable from a here doc */
extern Tree *getherevar(void) {
	int c;
	char *s;
	Buffer *buf = openbuffer(0);
	while (!dnw[c = GETC()])
		buf = bufputc(buf, c);
	s = sealcountedbuffer(buf);
	if (buf->len == 0) {
		yyerror("null variable name in here document");
		return NULL;
	}
	if (c != '^')
		UNGETC(c);
	return flatten(mk(nVar, mk(nWord, s)), " ");
}
Exemplo n.º 8
0
void
push_back_char(
	int ch
	)
{
	if (input_from_file)
		UNGETC(ch, ip_file);
	else {
		if (ch == '\n') {
			ip_file->col_no = ip_file->prev_line_col_no;
			ip_file->prev_line_col_no = -1;
			--ip_file->line_no;
		}
		--ip_file->col_no;

		remote_config.pos--;
	}
}
Exemplo n.º 9
0
static Boolean getfds(int fd[2], int c, int default0, int default1) {
	int n;
	fd[0] = default0;
	fd[1] = default1;

	if (c != '[') {
		UNGETC(c);
		return TRUE;
	}
	if ((unsigned int) (n = GETC() - '0') > 9) {
		scanerror("expected digit after '['");
		return FALSE;
	}

	while ((unsigned int) (c = GETC() - '0') <= 9)
		n = n * 10 + c;
	fd[0] = n;

	switch (c += '0') {
	case '=':
		if ((unsigned int) (n = GETC() - '0') > 9) {
			if (n != ']' - '0') {
				scanerror("expected digit or ']' after '='");
				return FALSE;
			}
			fd[1] = CLOSED;
		} else {
			while ((unsigned int) (c = GETC() - '0') <= 9)
				n = n * 10 + c;
			if (c != ']' - '0') {
				scanerror("expected ']' after digit");
				return FALSE;
			}
			fd[1] = n;
		}
		break;
	case ']':
		break;
	default:
		scanerror("expected '=' or ']' after digit");
		return FALSE;
	}
	return TRUE;
}
Exemplo n.º 10
0
Arquivo: lex.c Projeto: lufia/wf
static int
rreadstr(char *delim, char *s)	/* if s != 0, skip this chars before reading */
{
	int c;

	s_reset(sbuf);
	if(s)
		skip(s);
	while((c=GETC()) >= 0){
		if(strchr(delim, c)){
			UNGETC(c);
			s_terminate(sbuf);
			return Tstring;
		}
		s_putc(sbuf, c);
	}
	if(c == Beof)
		yyerror("eof in string");
	return Terror;
}
Exemplo n.º 11
0
/*FUNCTION*/
LVAL c_readlist(tpLspObject pLSP,
                FILE *f
  ){
/*noverbatim
CUT*/
   int ch;
   LVAL p,q;

   spaceat(ch,f);
   if( ch == pLSP->cClose || ch == EOF )return NIL;
   UNGETC(ch);
   q = cons();
   if( null(q) )
   {
      return NIL;
   }
   p = _readexpr(pLSP,f);
   setcar(q,p);
   setcdr(q,readlist(f));
   return q;
}
Exemplo n.º 12
0
static void skipws(ZZJSON_CONFIG *config) {
    int d, c = GETC();
morews:
    while (isspace(c)) c = GETC();
    if (!ALLOW_COMMENTS) goto endws;
    if (c != '/') goto endws;
    d = GETC();
    if (d != '*') goto endws; /* pushing back c will generate a parse error */
    c = GETC();
morecomments:
    while (c != '*') {
        if (c == EOF) goto endws;
        c = GETC();
    }
    c = GETC();
    if (c != '/') goto morecomments;
    c = GETC();
    if (isspace(c) || c == '/') goto morews;
endws:
    UNGETC(c);
}
Exemplo n.º 13
0
Arquivo: lex.c Projeto: lufia/wf
static int
readname(char *s)
{
	int c;

	s_reset(sbuf);
	if(s)
		skip(s);
	while((c=GETC()) >= 0 && (isalnum(c) || c == '-'))
		s_putc(sbuf, c);
	if(c == Beof){
		yyerror("eof in id/class");
		return Terror;
	}
	UNGETC(c);
	if(s_len(sbuf) == 0){
		yyerror("empty name");
		return Terror;
	}
	s_terminate(sbuf);
	return Tstring;
}
Exemplo n.º 14
0
ZZJSON *zzjson_parse(ZZJSON_CONFIG *config) {
    ZZJSON *retval;
    int c;

    SKIPWS();   
    c = GETC();
    UNGETC(c);
    if (c == '[')       retval = parse_array(config);
    else if (c == '{')  retval = parse_object(config);
    else                { ERROR("expected '[' or '{'"); return NULL; }

    if (!retval) return NULL;

    SKIPWS();
    c = GETC();
    if (c >= 0 && !ALLOW_GARBAGE_AT_END) {
        ERROR("parse: garbage at end of file");
        zzjson_free(config, retval);
        return NULL;
    }

    return retval;
}
Exemplo n.º 15
0
Arquivo: lex.c Projeto: lufia/wf
static int
getcc(char *c, char *s)	/* returning inline cmd or 0, c as a text */
{
	int c1, c2;

	c1 = GETC();
	if(c1 == Beof || c1 == '\n')
		return c1;

	if(strchr(s, c1) == nil){
		*c = c1;
		return 0;
	}

	c2 = GETC();
	if(c2 == c1){
		*c = c1;
		return 0;
	}

	UNGETC(c2);
	return c1;
}
Exemplo n.º 16
0
static char *parse_string(ZZJSON_CONFIG *config) {
    unsigned int len = 16, pos = 0;
    int c;
    char *str = NULL;

    SKIPWS();
    c = GETC();
    if (c != '"') {
        ERROR("string: expected \" at the start");
        return NULL;
    }

    str = config->malloc(len);
    if (!str) {
        MEMERROR();
        return NULL;
    }
    c = GETC();
    while (c > 0 && c != '"') {
        if (!ALLOW_CONTROL_CHARS && c >= 0 && c <= 31) {
            ERROR("string: control characters not allowed");
            goto errout;
        }
        if (c == '\\') {
            c = GETC();
            switch (c) {
                case 'b': c = '\b'; break;
                case 'f': c = '\f'; break;
                case 'n': c = '\n'; break;
                case 'r': c = '\r'; break;
                case 't': c = '\t'; break;
                case 'u': {
                    UNGETC(c);    /* ignore \uHHHH, copy verbatim */
                    c = '\\';
                    break;
                }
                case '\\': case '/': case '"':
                          break;
                default:
                    if (!ALLOW_ILLEGAL_ESCAPE) {
                        ERROR("string: illegal escape character");
                        goto errout;
                    }
            }
        }
        str[pos++] = c;
        if (pos == len-1) {
            void *tmp = str;
            len *= 2;
            str = config->realloc(str, len);
            if (!str) {
                MEMERROR();
                str = tmp;
                goto errout;
            }
        }
        c = GETC();
    }
    if (c != '"') {
        ERROR("string: expected \" at the end");
        goto errout;
    }
    str[pos] = 0;
    return str;

errout:
    config->free(str);
    return NULL;
}
Exemplo n.º 17
0
static ZZJSON *parse_number(ZZJSON_CONFIG *config) {
    ZZJSON *zzjson;
    unsigned long long ival = 0, expo = 0;
    double dval = 0.0, frac = 0.0, fracshft = 10.0;
    int c, dbl = 0, sign = 1, signexpo = 1;

    SKIPWS();
    c = GETC();
    if (c == '-') {
        sign = -1;
        c = GETC();
    }
    if (c == '0') {
        c = GETC();
        goto skip;
    }

    if (!isdigit(c)) {
        ERROR("number: digit expected");
        return NULL;
    }

    while (isdigit(c)) {
        ival *= 10;
        ival += c - '0';
        c = GETC();
    }

skip:
    if (c != '.') goto skipfrac;

    dbl = 1;

    c = GETC();
    if (!isdigit(c)) {
        ERROR("number: digit expected");
        return NULL;
    }

    while (isdigit(c)) {
        frac += (double)(c - '0') / fracshft;
        fracshft *= 10.0;
        c = GETC();
    }

skipfrac:
    if (c != 'e' && c != 'E') goto skipexpo;

    dbl = 1;

    c = GETC();
    if (c == '+')
        c = GETC();
    else if (c == '-') {
        signexpo = -1;
        c = GETC();
    }

    if (!isdigit(c)) {
        ERROR("number: digit expected");
        return NULL;
    }

    while (isdigit(c)) {
        expo *= 10;
        expo += c - '0';
        c = GETC();
    }

skipexpo:
    UNGETC(c);

    if (dbl) {
        dval = sign * (long long) ival;
        dval += sign * frac;
        dval *= pow(10.0, (double) signexpo * expo);
    }

    zzjson = config->calloc(1, sizeof(ZZJSON));
    if (!zzjson) {
        MEMERROR();
        return NULL;
    }
    if (dbl) {
        zzjson->type = ZZJSON_NUMBER_DOUBLE;
        zzjson->value.number.val.dval = dval;
    } else {
        zzjson->type = sign < 0 ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
        zzjson->value.number.val.ival = ival;
    }
    
    return zzjson;
}
Exemplo n.º 18
0
extern int yylex(void) {
	static Boolean dollar = FALSE;
	int c;
	size_t i;			/* The purpose of all these local assignments is to	*/
	const char *meta;		/* allow optimizing compilers like gcc to load these	*/
	char *buf = tokenbuf;		/* values into registers. On a sparc this is a		*/
	YYSTYPE *y = &yylval;		/* win, in code size *and* execution time		*/

	if (goterror) {
		goterror = FALSE;
		return NL;
	}

	/* rc variable-names may contain only alnum, '*' and '_', so use dnw if we are scanning one. */
	meta = (dollar ? dnw : nw);
	dollar = FALSE;
	if (newline) {
		--input->lineno; /* slight space optimization; print_prompt2() always increments lineno */
		print_prompt2();
		newline = FALSE;
	}
top:	while ((c = GETC()) == ' ' || c == '\t')
		w = NW;
	if (c == EOF)
		return ENDFILE;
	if (!meta[(unsigned char) c]) {	/* it's a word or keyword. */
		InsertFreeCaret();
		w = RW;
		i = 0;
		do {
			buf[i++] = c;
			if (i >= bufsize)
				buf = tokenbuf = erealloc(buf, bufsize *= 2);
		} while ((c = GETC()) != EOF && !meta[(unsigned char) c]);
		UNGETC(c);
		buf[i] = '\0';
		w = KW;
		if (buf[1] == '\0') {
			int k = *buf;
			if (k == '@' || k == '~')
				return k;
		} else if (*buf == 'f') {
			if (streq(buf + 1, "n"))	return FN;
			if (streq(buf + 1, "or"))	return FOR;
		} else if (*buf == 'l') {
			if (streq(buf + 1, "ocal"))	return LOCAL;
			if (streq(buf + 1, "et"))	return LET;
		} else if (streq(buf, "~~"))
			return EXTRACT;
		else if (streq(buf, "%closure"))
			return CLOSURE;
		w = RW;
		y->str = gcdup(buf);
		return WORD;
	}
	if (c == '`' || c == '!' || c == '$' || c == '\'') {
		InsertFreeCaret();
		if (c == '!')
			w = KW;
	}
	switch (c) {
	case '!':
		return '!';
	case '`':
		c = GETC();
		if (c == '`')
			return BACKBACK;
		UNGETC(c);
		return '`';
	case '$':
		dollar = TRUE;
		switch (c = GETC()) {
		case '#':	return COUNT;
		case '^':	return FLAT;
		case '&':	return PRIM;
		default:	UNGETC(c); return '$';
		}
	case '\'':
		w = RW;
		i = 0;
		while ((c = GETC()) != '\'' || (c = GETC()) == '\'') {
			buf[i++] = c;
			if (c == '\n')
				print_prompt2();
			if (c == EOF) {
				w = NW;
				scanerror("eof in quoted string");
				return ERROR;
			}
			if (i >= bufsize)
				buf = tokenbuf = erealloc(buf, bufsize *= 2);
		}
		UNGETC(c);
		buf[i] = '\0';
		y->str = gcdup(buf);
		return QWORD;
	case '\\':
		if ((c = GETC()) == '\n') {
			print_prompt2();
			UNGETC(' ');
			goto top; /* Pretend it was just another space. */
		}
		if (c == EOF) {
			UNGETC(EOF);
			goto badescape;
		}
		UNGETC(c);
		c = '\\';
		InsertFreeCaret();
		w = RW;
		c = GETC();
		switch (c) {
		case 'a':	*buf = '\a';	break;
		case 'b':	*buf = '\b';	break;
		case 'e':	*buf = '\033';	break;
		case 'f':	*buf = '\f';	break;
		case 'n':	*buf = '\n';	break;
		case 'r':	*buf = '\r';	break;
		case 't':	*buf = '\t';	break;
		case 'x': case 'X': {
			int n = 0;
			for (;;) {
				c = GETC();
				if (!isxdigit(c))
					break;
				n = (n << 4)
				  | (c - (isdigit(c) ? '0' : ((islower(c) ? 'a' : 'A') - 0xA)));
			}
			if (n == 0)
				goto badescape;
			UNGETC(c);
			*buf = n;
			break;
		}
		case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': {
			int n = 0;
			do {
				n = (n << 3) | (c - '0');
				c = GETC();
			} while (isodigit(c));
			if (n == 0)
				goto badescape;
			UNGETC(c);
			*buf = n;
			break;
		}
		default:
			if (isalnum(c)) {
			badescape:
				scanerror("bad backslash escape");
				return ERROR;
			}
			*buf = c;
			break;
		}
		buf[1] = 0;
		y->str = gcdup(buf);
		return QWORD;
	case '#':
		while ((c = GETC()) != '\n') /* skip comment until newline */
			if (c == EOF)
				return ENDFILE;
		/* FALLTHROUGH */
	case '\n':
		input->lineno++;
		newline = TRUE;
		w = NW;
		return NL;
	case '(':
		if (w == RW)	/* not keywords, so let & friends work */
			c = SUB;
		/* FALLTHROUGH */
	case ';':
	case '^':
	case ')':
	case '=':
	case '{': case '}':
		w = NW;
		return c;
	case '&':
		w = NW;
		c = GETC();
		if (c == '&')
			return ANDAND;
		UNGETC(c);
		return '&';

	case '|': {
		int p[2];
		w = NW;
		c = GETC();
		if (c == '|')
			return OROR;
		if (!getfds(p, c, 1, 0))
			return ERROR;
		if (p[1] == CLOSED) {
			scanerror("expected digit after '='");	/* can't close a pipe */
			return ERROR;
		}
		y->tree = mk(nPipe, p[0], p[1]);
		return PIPE;
	}

	{
		char *cmd;
		int fd[2];
	case '<':
		fd[0] = 0;
		if ((c = GETC()) == '>')
			if ((c = GETC()) == '>') {
				c = GETC();
				cmd = "%open-append";
			} else
				cmd = "%open-write";
		else if (c == '<')
			if ((c = GETC()) == '<') {
				c = GETC();
				cmd = "%here";
			} else
				cmd = "%heredoc";
		else if (c == '=')
			return CALL;
		else
			cmd = "%open";
		goto redirection;
	case '>':
		fd[0] = 1;
		if ((c = GETC()) == '>')
			if ((c = GETC()) == '<') {
				c = GETC();
				cmd = "%open-append";
			} else
				cmd = "%append";
		else if (c == '<') {
			c = GETC();
			cmd = "%open-create";
		} else
			cmd = "%create";
		goto redirection;
	redirection:
		w = NW;
		if (!getfds(fd, c, fd[0], DEFAULT))
			return ERROR;
		if (fd[1] != DEFAULT) {
			y->tree = (fd[1] == CLOSED)
					? mkclose(fd[0])
					: mkdup(fd[0], fd[1]);
			return DUP;
		}
		y->tree = mkredircmd(cmd, fd[0]);
		return REDIR;
	}

	default:
		assert(c != '\0');
		w = NW;
		return c; /* don't know what it is, let yacc barf on it */
	}
}
Exemplo n.º 19
0
static ZZJSON *parse_array(ZZJSON_CONFIG *config) {
    ZZJSON *retval = NULL, **next = &retval;
    int c;

    SKIPWS();
    c = GETC();
    if (c != '[') {
        ERROR("array: expected '['");
        return NULL;
    }

    SKIPWS();
    c = GETC();
    while (c > 0 && c != ']') {
        ZZJSON *zzjson = NULL, *val = NULL;

        UNGETC(c);

        SKIPWS();
        val = parse_value(config);
        if (!val) {
            ERROR("array: value expected");
            goto errout;
        }

        SKIPWS();
        c = GETC();
        if (c != ',' && c != ']') {
            ERROR("array: expected ',' or ']'");
errout_with_val:
            zzjson_free(config, val);
            goto errout;
        }
        if (c == ',') {
            SKIPWS();
            c = GETC();
            if (c == ']' && !ALLOW_EXTRA_COMMA) {
                ERROR("array: expected value after ','");
                goto errout_with_val;
            }
        }
        UNGETC(c);

        zzjson = config->calloc(1, sizeof(ZZJSON));
        if (!zzjson) {
            MEMERROR();
            zzjson_free(config, val);
            goto errout_with_val;
        }
        zzjson->type            = ZZJSON_ARRAY;
        zzjson->value.array.val = val;
        *next = zzjson;
        next = &zzjson->next;

        c = GETC();
    }

    if (c != ']') {
        ERROR("array: expected ']'");
        goto errout;
    }

    if (!retval) {  /* empty array, [ ] */
        retval = config->calloc(1, sizeof(ZZJSON));
        if (!retval) {
            MEMERROR();
            return NULL;
        }
        retval->type = ZZJSON_ARRAY;
    }
            
    return retval;

errout:
    zzjson_free(config, retval);
    return NULL;
}
Exemplo n.º 20
0
static ZZJSON *parse_object(ZZJSON_CONFIG *config) {
    ZZJSON *retval = NULL;
    int c;
    ZZJSON **next = &retval;

    SKIPWS();
    c = GETC();
    if (c != '{') {
        ERROR("object: expected '{'");
        return NULL;
    }

    SKIPWS();
    c = GETC();
    while (c > 0 && c != '}') {
        ZZJSON *zzjson = NULL, *val = NULL;
        char *str;

        UNGETC(c);

        str = parse_string(config);
        if (!str) {
            ERROR("object: expected string");
errout_with_str:
            config->free(str);
            goto errout;
        }

        SKIPWS();
        c = GETC();
        if (c != ':') {
            ERROR("object: expected ':'");
            goto errout_with_str;
        }

        SKIPWS();
        val = parse_value(config);
        if (!val) {
            ERROR("object: value expected");
            goto errout_with_str;
        }

        SKIPWS();
        c = GETC();
        if (c != ',' && c != '}') {
            ERROR("object: expected ',' or '}'");
errout_with_str_and_val:
            zzjson_free(config, val);
            goto errout_with_str;
        }
        if (c == ',') {
            SKIPWS();
            c = GETC();
            if (c == '}' && !ALLOW_EXTRA_COMMA) {
                ERROR("object: expected pair after ','");
                goto errout_with_str_and_val;
            }
        }
        UNGETC(c);

        zzjson = config->calloc(1, sizeof(ZZJSON));
        if (!zzjson) {
            MEMERROR();
            goto errout_with_str_and_val;
        }
        zzjson->type                = ZZJSON_OBJECT;
        zzjson->value.object.label  = str;
        zzjson->value.object.val    = val;
        *next = zzjson;
        next = &zzjson->next;

        c = GETC();
    }

    if (c != '}') {
        ERROR("object: expected '}'");
        goto errout;
    }

    if (!retval) {  /* empty object, { } */
        retval = config->calloc(1, sizeof(ZZJSON));
        if (!retval) {
            MEMERROR();
            return NULL;
        }
        retval->type = ZZJSON_OBJECT;
    }
            
    return retval;

errout:
    zzjson_free(config, retval);
    return NULL;
}
Exemplo n.º 21
0
/*
 * local function to read an expression
 */
static LVAL _readexpr(tpLspObject pLSP,FILE *f)
{
   int ch,ch1,ch2,i;
   LVAL p;
   char *s;
   double dval;
   long lval;


   spaceat(ch,f);
   if( ch == EOF )
   {
      return NIL;
   }
   if( ch == pLSP->cClose )
   {
      return NIL;
   }

   if( ch == pLSP->cOpen )/* Read a cons node. */
      return readcons(pLSP,f);

   /**** Note: XLISP allows 1E++10 as a symbol. This is dangerous.
         We do not change XLISP (so far), but here I exclude all symbol
         names starting with numeral. */
   if( const_p1(ch) )/* Read a symbol. */
   {
      for( i = 0 ; const_p(ch) ; i++ ){
        if( storech(pLSP,i,ch) )return NIL;
        ch = getC(pLSP,f);
        }
      UNGETC(ch);
      /* Recognize NIL and nil symbols. */
      if( !strcmp(BUFFER,"NIL") || !strcmp(BUFFER,"nil") )
         return NIL;
      p = newsymbol();
      s = StrDup( BUFFER );
      if( null(p) || s == NULL )return NIL;
      setsymbol(p,s);
      return p;
   }
   if( ch == '\"' ){
     ch = GETC(f);
     storech(pLSP,0,0); /* inititalize the buffer */
     if( ch != '\"' )goto SimpleString;
     ch = GETC(f);
     if( ch != '\"' ){
       UNGETC(ch);
       ch = '\"';/* ch should hold the first character of the string that is " now */
       goto SimpleString;
       }
     ch = GETC(f);     
     /* multi line string */
     for( i = 0 ; ch != EOF ; i++ ){
       if( ch == '\"' ){
         ch1 = GETC(f);
         ch2 = GETC(f);
         if( ch1 == '\"' && ch2 == '\"' )break;
         UNGETC(ch2);
         UNGETC(ch1);
         }
       if( ch == '\\' ){
         ch = GETC(f);
         s = escapers;
         while( *s ){
           if( *s++ == ch ){
             ch = *s;
             break;
             }
           if( *s )s++;
           }
         }
       if( storech(pLSP,i,ch) )return NIL;
       ch = GETC(f);
       }
     p = newstring();
     s = StrDup( BUFFER );
     if( null(p) || s == NULL )return NIL;
     setstring(p,s);
     return p;
     }

   if( ch == '\"' ){/* Read a string. */
     ch = GETC(f);/* Eat the " character. */
SimpleString:
     for( i = 0 ; ch != '\"' && ch != EOF ; i++ ){
       if( ch == '\\' ){
         ch = GETC(f);
         s = escapers;
         while( *s ){
           if( *s++ == ch ){
             ch = *s;
             break;
             }
           if( *s )s++;
           }
         }
       if( ch == '\n' )return NIL;
       if( storech(pLSP,i,ch) )return NIL;
       ch = GETC(f);
       }
      p = newstring();
      s = StrDup( BUFFER );
      if( null(p) || s == NULL )
      {
         return NIL;
      }
      setstring(p,s);
      return p;
   }
   if( numeral1(ch) )
   {
      for( i = 0 ; isinset(ch,"0123456789+-eE.") ; i++ )
      {
         if( storech(pLSP,i,ch) )return NIL;
         ch = getC(pLSP,f);
      }
      UNGETC(ch);
      cnumeric(BUFFER,&i,&dval,&lval);
      switch( i )
      {
      case 0:
         return NIL;
      case 1:
         /* A float number is coming. */
         p = newfloat();
         if( null(p) )
         {
            return NIL;
         }
         setfloat(p,dval);
         return p;
      case 2:
         /* An integer is coming. */
         p = newint();
         if( null(p) )
         {
            return NIL;
         }
         setint(p,lval);
         return p;
      default:
         return NIL;
      }
   }
   return NIL;
}
Exemplo n.º 22
0
Arquivo: lex.c Projeto: lufia/wf
int
yylex(void)
{
	int c, r;
	char c1;
	Sym *s;

genblock:
	if(block != nblock){
		if(block > nblock){
			if(debug)
				fprint(2, "%s %d -> %d\n", ty(Tend), block, nblock);
			block--;
			return Tend;
		}else{
			if(debug)
				fprint(2, "%s %d -> %d\n", ty(Tbegin), block, nblock);
			block++;
			return Tbegin;
		}
	}

	c = GETC();
	if(c == Beof){
		nblock = 0;
		if(block != nblock)
			goto genblock;
		return 0;
	}
	UNGETC(c);

	switch(state){
	case Head0:			/* [%type] string */
		c = GETC();
		if(c != '%'){
			UNGETC(c);
			setstate(Body0);
			goto genblock;
		}
		r = readname(" \t");
		if(r == Terror)
			return fail(Head2);

		s = lookup(s_to_c(sbuf));
		yylval.sym = s;
		if(debug)
			fprint(2, "Sym[%s] %s\n", ty(s->type), s->name);
		setstate(Head1);
		return s->type;

	case Head1:			/* %type [string] */
		r = readstr("\n", " \t", 0);
		if(r == Terror)
			return fail(Head2);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		setstate(Head2);
		return Tstring;

	case Head2:
		skip(" \t");
		c = GETC();
		assert(c == '\n' || c == Beof);
		setstate(Head0);
		return ';';

	case Body0:			/* [indent] cmd inline */
		c = GETC();
		if(c == '%'){
			UNGETC(c);
			setstate(Head0);
			goto genblock;
		}
		UNGETC(c);

		r = skip(" \t");
		c = GETC();
		if(c == '\n'){
			if(debug)
				fprint(2, "%s\n", ty(Tbreak));
			return Tbreak;
		}
		UNGETC(c);

		nblock = r;
		setstate(Body1);
		goto genblock;

	case Body1:			/* indent [cmd] inline */
		switch(c = GETC()){
		case Beof:
			yyerror("eof in body");
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		case '=':
		case '\\':
		case '+':
		case '*':
		case ':':
		case '-':
		case '>':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Body2);
			return c;
		case '!':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Code);
			return c;
		case '{':
		case '}':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Body3);
			return c;
		case '#':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(ID);
			return c;
		case '.':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Class);
			return c;
		case '|':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Table);
			return c;
		default:
			UNGETC(c);
			if(debug)
				fprint(2, "\\\n");
			setstate(Body2);
			return '\\';
		}

	case Body2:			/* indent cmd [inline] */
	case Table:
		r = skip(" \t");
		if(state == Table && r > 0)
			return ',';

		switch(c = getcc(&c1, "*[]|<>")){
		case Beof:
			yyerror("eof in body");
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		case '\n':
			UNGETC(c);
			setstate(Body3);
			break;
		case '*':
		case '[':
		case ']':
		case '|':
		case '<':
		case '>':
			if(c == '[' || c == '|' || c == '<')
				skip(" \t\n");
			if(debug)
				fprint(2, "%c\n", c);
			return c;
		default:
			s_reset(sbuf);
			s_putc(sbuf, c1);
			while((c=getcc(&c1, "*[]|<>")) == 0){
				if(state == Table && c1 == '\t'){
					UNGETC(c);
					break;
				}
				s_putc(sbuf, c1);
			}
			s_terminate(sbuf);
			if(c > 0)
				UNGETC(c);
			yylval.s = estrdup(s_to_c(sbuf));
			if(debug)
				fprint(2, "%s %q\n", ty(Tstring), yylval.s);
			return Tstring;
		}

	case Body3:
		skip(" \t");
		c = GETC();
		if(c != '\n')
			return fail(Body3);
		setstate(Body0);
		return ';';

	case Code:
		r = readstr("\n", "", 1);
		if(r == Terror){
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		}
		setstate(Body3);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		return Tstring;

	case ID:
	case Class:
		r = readname(" \t");
		if(r == Terror){
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		}
		setstate(Body3);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		return Tstring;

	default:
		assert(0);
		return Terror;
	}
}
Exemplo n.º 23
0
/* snarfheredoc -- read a heredoc until the eof marker */
extern Tree *snarfheredoc(const char *eof, Boolean quoted) {
	Tree *tree, **tailp;
	Buffer *buf;
	unsigned char *s;

	assert(quoted || strchr(eof, '$') == NULL);	/* can never be typed (whew!) */
	if (strchr(eof, '\n') != NULL) {
		yyerror("here document eof-marker contains a newline");
		return NULL;
	}
	disablehistory = TRUE;

	for (tree = NULL, tailp = &tree, buf = openbuffer(0);;) {
		int c;
		print_prompt2();
		for (s = (unsigned char *) eof; (c = GETC()) == *s; s++)
			;
		if (*s == '\0' && (c == '\n' || c == EOF)) {
			if (buf->current == 0 && tree != NULL)
				freebuffer(buf);
			else
				*tailp = treecons(mk(nQword, sealcountedbuffer(buf)), NULL);
			break;
		}
		if (s != (unsigned char *) eof)
			buf = bufncat(buf, eof, s - (unsigned char *) eof);
		for (;; c = GETC()) {
			if (c == EOF) {
				yyerror("incomplete here document");
				freebuffer(buf);
				disablehistory = FALSE;
				return NULL;
			}
			if (c == '$' && !quoted && (c = GETC()) != '$') {
				Tree *var;
				UNGETC(c);
				if (buf->current == 0)
					freebuffer(buf);
				else {
					*tailp = treecons(mk(nQword, sealcountedbuffer(buf)), NULL);
					tailp = &(*tailp)->CDR;
				}
				var = getherevar();
				if (var == NULL) {
					freebuffer(buf);
					disablehistory = FALSE;
					return NULL;
				}
				*tailp = treecons(var, NULL);
				tailp = &(*tailp)->CDR;
				buf = openbuffer(0);
				continue;
			}
			buf = bufputc(buf, c);
			if (c == '\n')
				break;
		}
	}

	disablehistory = FALSE;
	return tree->CDR == NULL ? tree->CAR : tree;
}
Exemplo n.º 24
0
static int yylex2(void) {
  int ch;
  int chkcomment = FALSE;

yuk_a_goto:
	eatwhite();
	if ((ch = GETC(fname)) == EOF) {
	  if (firstsemi == 1) {
	    firstsemi = 0;
	    fclose(fname);
	    fname = fnamesave;
	    goto yuk_a_goto;
	  }
	  else {
	    return(TENDOFFILE);
	  }
	}
	do {
		if (ch == '/')
			if ((ch = GETC(fname)) == '*') {
				eatcomment();
				eatwhite();
				chkcomment = TRUE;
				if ((ch = GETC(fname)) == EOF)
					return(TENDOFFILE);
			} else {
				UNGETC(ch, fname);
				ch = '/';
				chkcomment = FALSE;
			}
		else if (ch == '-')	/* -- is a comment in our language */
		{
			if ((ch = GETC(fname)) == '-')
			{
				eatline();	 /* ignore rest of line */
				if (firstsemi != 1) yylineno++;
				eatwhite();
				chkcomment = TRUE;
				if ((ch = GETC(fname)) == EOF)
					return(TENDOFFILE);
			}
			else
			{
				UNGETC(ch, fname);
				ch = '-';
				chkcomment = FALSE;
			}
		}
		else
			chkcomment = FALSE;
	} while (chkcomment);
	if (isalpha(ch) || ch == '_')
		return(eatident(ch));
	if (isdigit(ch))
		return(eatnumber(ch));
	if (ch == '"')
		return(eatstring());
	if (ch == '\'') {
	  char ch2;
	  char ch3;
	  char chat;
	  int ate;
	  
	  ch2 = GETC(fname);
	  ch3 = GETC(fname);
	  UNGETC(ch3,fname);
	  UNGETC(ch2,fname);
	  if (ch2 != ' ' || ch3 != '\'') {
	    /* can't eat whitespace if char contains whitespace */
	    ate = eatwhite();
	    chat = GETC(fname);
	    UNGETC(chat,fname);
	    if (chat == '@') {
	      if (ate || (ch2 != '@' && ch3 != '\'')) {
		return TPRIME;
	      }
	    }
	  }
	  return eatcharacter();
	}
	if (ch == '.') {
		if (isdigit(ch = GETC(fname))) {
			UNGETC(ch, fname);
			ch = '.';
			return(eatnumber(ch));
		} else {
			UNGETC(ch, fname);
			ch = '.';
		}
	}
	if (ch == '#') {
	  char ch2;
		eatwhite();
		/* remove "line" if it exists - some vers of cpp have this */
		if ((ch2 = GETC(fname)) == '[') {
		  UNGETC(ch2, fname);
		  return eatleftovers(ch);
		}
		else {
		  UNGETC(ch2, fname);
		}
		if (!isdigit(ch = GETC(fname))) {
			UNGETC(ch, fname);
			yylex2();
			if (!strcmp(buffer,"pragma")) {
			  for (ch = GETC(fname); ch != '\n'; ch = GETC(fname)) ;
			  goto yuk_a_goto;
			}
			if (strcmp(buffer,"line")) {
			  USR_FATALX(yylineno, in_file,
				     "syntax error (appears to be a cpp directive: try -cpp)");
			}
			eatwhite();
		} else {
			UNGETC(ch, fname);
		}

		if (!isdigit(ch = GETC(fname))) {
			UNGETC(ch, fname);
			USR_FATALX(yylineno, in_file,
				   "syntax error (appears to be a cpp directive: use -cpp)");
		} else
			UNGETC(ch, fname);
		yylex2();
		yylineno = atoi(buffer);

		for (ch = GETC(fname); ch != '"' && ch != '\n'; ch = GETC(fname))
			;
		if (ch != '"') {
			goto yuk_a_goto;
		} else
			UNGETC(ch, fname);
		yylex2();

		
		in_file = (char *)PMALLOC((strlen(buffer) + 1)*sizeof(char));
		strcpy(in_file, buffer);
		base_in_file = strrchr(in_file,'/');
		if (base_in_file == NULL) {
		  base_in_file = in_file;
		} else {
		  base_in_file++;
		}
		for (ch = GETC(fname); ch != '\n'; ch = GETC(fname))
			;

		goto yuk_a_goto;
	}
	if (ispunct(ch))
		return(eatleftovers(ch));

	
	buffer[0] = ch; buffer[1] = '\0';

	  if (firstsemi == 1) {
	    firstsemi = 0;
	    fclose(fname);
	    fname = fnamesave;
	    goto yuk_a_goto;
	  }

	return(-1);
}
Exemplo n.º 25
0
static int _pdc_vsscanf(const char *buf, const char *fmt, va_list arg_ptr)
{
    int count, chars, c, width, radix, d, i;
    int *int_ptr;
    long *long_ptr;
    short *short_ptr;
    char *char_ptr;
    unsigned char f;
    char neg, assign, ok, size;
    long n;
    char map[256], end;
    double dx, dd, *dbl_ptr;
    float *flt_ptr;
    int exp;
    char eneg;

    count = 0;
    chars = 0;
    c = 0;
    while ((f = *fmt) != 0)
    {
        if (WHITE(f))
        {
            do
            {
                ++fmt;
                f = *fmt;
            }
            while (WHITE(f));
            do
            {
                c = *buf++;
                if (!c)
                {
                    if (!f || count)
                        return count;
                    else
                        return EOF;
                } else
                    ++chars;
            }
            while (WHITE(c));
            UNGETC();
        } else if (f != '%')
        {
            NEXT(c);
            if (c != f)
                return count;
            ++fmt;
        } else
        {
            assign = TRUE;
            width = INT_MAX;
            char_ptr = NULL;
            ++fmt;
            if (*fmt == '*')
            {
                assign = FALSE;
                ++fmt;
            }
            if (isdigit(*fmt))
            {
                width = 0;
                while (isdigit(*fmt))
                    width = width * 10 + (*fmt++ - '0');
                if (!width)
                    width = INT_MAX;
            }
            size = 0;
            if (*fmt == 'h' || *fmt == 'l')
                size = *fmt++;
            f = *fmt;
            switch (f)
            {
            case 'c':
                if (width == INT_MAX)
                    width = 1;
                if (assign)
                    char_ptr = va_arg(arg_ptr, char *);
                while (width > 0)
                {
                    --width;
                    NEXT(c);
                    if (assign)
                    {
                        *char_ptr++ = (char) c;
                        ++count;
                    }
                }
                break;
            case '[':
                memset(map, 0, 256);
                end = 0;
                ++fmt;
                if (*fmt == '^')
                {
                    ++fmt;
                    end = 1;
                }
                i = 0;
                for (;;)
                {
                    f = (unsigned char) *fmt;
                    switch (f)
                    {
                    case 0:
                        /* avoid skipping past 0 */
                        --fmt;
                        NEXT(c);
                        goto string;
                    case ']':
                        if (i > 0)
                        {
                            NEXT(c);
                            goto string;
                        }
                        /* no break */
                    default:
                        if (fmt[1] == '-' && fmt[2]
                            && f < (unsigned char)fmt[2])
                        {
                            memset(map + f, 1, (unsigned char)fmt[2] - f);
                            fmt += 2;
                        }
                        else
                            map[f] = 1;
                        break;
                    }
                    ++fmt;
                    ++i;
                }
            case 's':
                memset(map, 0, 256);
                map[' '] = 1;
                map['\n'] = 1;
                map['\r'] = 1;
                map['\t'] = 1;
                end = 1;
                do
                {
                    NEXT(c);
                }
                while (WHITE(c));
            string:
                if (assign)
                    char_ptr = va_arg(arg_ptr, char *);
                while (width > 0 && map[(unsigned char) c] != end)
                {
                    --width;
                    if (assign)
                        *char_ptr++ = (char) c;
                    c = *buf++;
                    if (!c)
                        break;
                    else
                        ++chars;
                }
                if (assign)
                {
                    *char_ptr = 0;
                    ++count;
                }
                if (!c)
                    return count;
                else
                    UNGETC();
                break;
            case 'f':
            case 'e':
            case 'E':
            case 'g':
            case 'G':
                neg = ok = FALSE;
                dx = 0.0;
                do
                {
                    NEXT(c);
                }
                while (WHITE(c));
                if (c == '+')
                {
                    NEXT(c);
                    --width;
                } else if (c == '-')
                {
                    neg = TRUE;
                    NEXT(c);
                    --width;
                }
                while (width > 0 && isdigit(c))
                {
                    --width;
                    dx = dx * 10.0 + (double) (c - '0');
                    ok = TRUE;
                    c = *buf++;
                    if (!c)
                        break;
                    else
                        ++chars;
                }
                if (width > 0 && c == '.')
                {
                    --width;
                    dd = 10.0;
                    NEXT(c);
                    while (width > 0 && isdigit(c))
                    {
                        --width;
                        dx += (double) (c - '0') / dd;
                        dd *= 10.0;
                        ok = TRUE;
                        c = *buf++;
                        if (!c)
                            break;
                        else
                            ++chars;
                    }
                }
                if (!ok)
                    return count;
                if (width > 0 && (c == 'e' || c == 'E'))
                {
                    eneg = FALSE;
                    exp = 0;
                    NEXT(c);
                    --width;
                    if (width > 0 && c == '+')
                    {
                        NEXT(c);
                        --width;
                    } else if (width > 0 && c == '-')
                    {
                        eneg = TRUE;
                        NEXT(c);
                        --width;
                    }
                    if (!(width > 0 && isdigit(c)))
                    {
                        UNGETC();
                        return count;
                    }
                    while (width > 0 && isdigit(c))
                    {
                        --width;
                        exp = exp * 10 + (c - '0');
                        c = *buf++;
                        if (!c)
                            break;
                        else
                            ++chars;
                    }
                    if (eneg)
                        exp = -exp;
                    while (exp > 0)
                    {
                        dx *= 10.0;
                        --exp;
                    }
                    while (exp < 0)
                    {
                        dx /= 10.0;
                        ++exp;
                    }
                }
                if (assign)
                {
                    if (neg)
                        dx = -dx;
                    if (size == 'l')
                    {
                        dbl_ptr = va_arg(arg_ptr, double *);
                        *dbl_ptr = dx;
                    }
                    else
                    {
                        flt_ptr = va_arg(arg_ptr, float *);
                        *flt_ptr = (float)dx;
                    }
                    ++count;
                }
                if (!c)
                    return count;
                else
                    UNGETC();
                break;
            case 'i':
                neg = FALSE;
                radix = 10;
                do
                {
                    NEXT(c);
                }
                while (WHITE(c));
                if (!(width > 0 && c == '0'))
                    goto scan_complete_number;
                NEXT(c);
                --width;
                if (width > 0 && (c == 'x' || c == 'X'))
                {
                    NEXT(c);
                    radix = 16;
                    --width;
                }
                else if (width > 0 && (c >= '0' && c <= '7'))
                    radix = 8;
                goto scan_unsigned_number;
            case 'd':
            case 'u':
            case 'o':
            case 'x':
            case 'X':
                do
                {
                    NEXT(c);
                }
                while (WHITE(c));
                switch (f)
                {
                case 'o':
                    radix = 8;
                    break;
                case 'x':
                case 'X':
                    radix = 16;
                    break;
                default:
                    radix = 10;
                    break;
                }
            scan_complete_number:
                neg = FALSE;
                if (width > 0 && c == '+')
                {
                    NEXT(c);
                    --width;
                }
                else if (width > 0 && c == '-' && radix == 10)
                {
                    neg = TRUE;
                    NEXT(c);
                    --width;
                }
            scan_unsigned_number:
                n = 0;
                ok = FALSE;
                while (width > 0)
                {
                    --width;
                    if (isdigit(c))
                        d = c - '0';
                    else if (isupper(c))
                        d = c - 'A' + 10;
                    else if (islower(c))
                        d = c - 'a' + 10;
                    else
                        break;
                    if (d < 0 || d >= radix)
                        break;
                    ok = TRUE;
                    n = n * radix + d;
                    c = *buf++;
                    if (!c)
                        break;
                    else
                        ++chars;
                }
                if (!ok)
                    return count;
                if (assign)
                {
                    if (neg)
                        n = -n;
                    switch (size)
                    {
                    case 'h':
                        short_ptr = va_arg(arg_ptr, short *);
                        *short_ptr = (short) n;
                        break;
                    case 'l':
                        long_ptr = va_arg(arg_ptr, long *);
                        *long_ptr = (long) n;
                        break;
                    default:
                        int_ptr = va_arg(arg_ptr, int *);
                        *int_ptr = (int) n;
                    }
                    ++count;
                }
                if (!c)
                    return count;
                else
                    UNGETC();
                break;
            case 'n':
                if (assign)
                {
                    int_ptr = va_arg(arg_ptr, int *);
                    *int_ptr = chars;
                    ++count;
                }
                break;
            default:
                if (!f) /* % at end of string */
                    return count;
                NEXT(c);
                if (c != f)
                    return count;
                break;
            }
            ++fmt;
        }
Exemplo n.º 26
0
char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
                  char *ep, char *endbuf, int seof)
{
    int c;
    int eof = seof;
    char *lastep;
    int cclcnt;
    char bracket[NBRA], *bracketp;
    int closed;
    int neg;
    int lc;
    int i, cflg;
    int iflag; /* used for non-ascii characters in brackets */
    int nodelim = 0;
    char *sp = commands->cp;
    int regerrno = 0;

    lastep = 0;
    if ((c = GETC()) == eof || c == '\n') {
        if (c == '\n') {
            UNGETC(c);
            nodelim = 1;
        }
        commands->cp = sp;
        goto out;
    }
    bracketp = bracket;
    compargs->circf = closed = compargs->nbra = 0;
    if (c == '^')
        compargs->circf++;
    else
        UNGETC(c);
    while (1) {
        if (ep >= endbuf)
            SEDCOMPILE_ERROR(50);
        c = GETC();
        if (c != '*' && ((c != '\\') || (PEEKC() != '{')))
            lastep = ep;
        if (c == eof) {
            *ep++ = CCEOF;
            if (bracketp != bracket)
                SEDCOMPILE_ERROR(42);
            commands->cp = sp;
            goto out;
        }
        switch (c) {

        case '.':
            *ep++ = CDOT;
            continue;

        case '\n':
            SEDCOMPILE_ERROR(36);
            commands->cp = sp;
            goto out;
        case '*':
            if (lastep == 0 || *lastep == CBRA || *lastep == CKET)
                goto defchar;
            *lastep |= STAR;
            continue;

        case '$':
            if (PEEKC() != eof && PEEKC() != '\n')
                goto defchar;
            *ep++ = CDOL;
            continue;

        case '[':
            if (&ep[17] >= endbuf)
                SEDCOMPILE_ERROR(50);

            *ep++ = CCL;
            lc = 0;
            for (i = 0; i < 16; i++)
                ep[i] = 0;

            neg = 0;
            if ((c = GETC()) == '^') {
                neg = 1;
                c = GETC();
            }
            iflag = 1;
            do {
                c &= 0377;
                if (c == '\0' || c == '\n')
                    SEDCOMPILE_ERROR(49);
                if ((c & 0200) && iflag) {
                    iflag = 0;
                    if (&ep[32] >= endbuf)
                        SEDCOMPILE_ERROR(50);
                    ep[-1] = CXCL;
                    for (i = 16; i < 32; i++)
                        ep[i] = 0;
                }
                if (c == '-' && lc != 0) {
                    if ((c = GETC()) == ']') {
                        PLACE('-');
                        break;
                    }
                    if ((c & 0200) && iflag) {
                        iflag = 0;
                        if (&ep[32] >= endbuf)
                            SEDCOMPILE_ERROR(50);
                        ep[-1] = CXCL;
                        for (i = 16; i < 32; i++)
                            ep[i] = 0;
                    }
                    while (lc < c) {
                        PLACE(lc);
                        lc++;
                    }
                }
                lc = c;
                PLACE(c);
            } while ((c = GETC()) != ']');

            if (iflag)
                iflag = 16;
            else
                iflag = 32;

            if (neg) {
                if (iflag == 32) {
                    for (cclcnt = 0; cclcnt < iflag;
                        cclcnt++)
                        ep[cclcnt] ^= 0377;
                    ep[0] &= 0376;
                } else {
                    ep[-1] = NCCL;
                    /* make nulls match so test fails */
                    ep[0] |= 01;
                }
            }

            ep += iflag;

            continue;

        case '\\':
            switch (c = GETC()) {

            case '(':
                if (compargs->nbra >= NBRA)
                    SEDCOMPILE_ERROR(43);
                *bracketp++ = compargs->nbra;
                *ep++ = CBRA;
                *ep++ = compargs->nbra++;
                continue;

            case ')':
                if (bracketp <= bracket)
                    SEDCOMPILE_ERROR(42);
                *ep++ = CKET;
                *ep++ = *--bracketp;
                closed++;
                continue;

            case '{':
                if (lastep == (char *) 0)
                    goto defchar;
                *lastep |= RNGE;
                cflg = 0;
            nlim:
                c = GETC();
                i = 0;
                do {
                    if ('0' <= c && c <= '9')
                        i = 10 * i + c - '0';
                    else
                        SEDCOMPILE_ERROR(16);
                } while (((c = GETC()) != '\\') && (c != ','));
                if (i >= 255)
                    SEDCOMPILE_ERROR(11);
                *ep++ = i;
                if (c == ',') {
                    if (cflg++)
                        SEDCOMPILE_ERROR(44);
                    if ((c = GETC()) == '\\')
                        *ep++ = (char) 255;
                    else {
                        UNGETC(c);
                        goto nlim;
                        /* get 2'nd number */
                    }
                }
                if (GETC() != '}')
                    SEDCOMPILE_ERROR(45);
                if (!cflg)    /* one number */
                    *ep++ = i;
                else if ((ep[-1] & 0377) < (ep[-2] & 0377))
                    SEDCOMPILE_ERROR(46);
                continue;

            case '\n':
                SEDCOMPILE_ERROR(36);

            case 'n':
                c = '\n';
                goto defchar;

            default:
                if (c >= '1' && c <= '9') {
                    if ((c -= '1') >= closed)
                        SEDCOMPILE_ERROR(25);
                    *ep++ = CBACK;
                    *ep++ = c;
                    continue;
                }
            }
    /* Drop through to default to use \ to turn off special chars */

        defchar:
        default:
            lastep = ep;
            *ep++ = CCHR;
            *ep++ = c;
        }
    }
out:
    if (regerrno) {
        regerr(commands, regerrno);
        return (char*) NULL;
    }
    /* XXX : Basant : what extra */
    /* int reglength = (int)(ep - expbuf); */
    return ep;
}
Exemplo n.º 27
0
int sc_next (SCAN *scan)
{                               /* --- get next token */
  int  c, ccl;                  /* character and character class */
  int  quote = 0;               /* quote at the start of a string */
  int  ec    = 0;               /* escaped character */
  int  state = 0;               /* state of automaton */
  int  level = 0;               /* comment nesting level */
  char *p;                      /* to traverse the scan buffer */
  char *end;                    /* end of the scan buffer */

  if (scan->back) {             /* if a step backwards has been made, */
    scan->back = 0;             /* clear the corresponding flag, */
    return _swap(scan);         /* swap back the token information, */
  }                             /* and return the current token */
  scan->pline  = scan->line;    /* note the relevant information */
  scan->ptoken = scan->token;   /* of the current token */
  scan->plen   = scan->len;     /* and swap scan buffers */
  if (scan->value == scan->buf[0]) scan->value = p = scan->buf[1];
  else                             scan->value = p = scan->buf[0];
  end = p +SC_BUFSIZE -1;       /* get the end of the scan buffer */

  while (1) {                   /* read loop */
    c   = getc(scan->file);     /* get character and character class */
    ccl = (c < 0) ? EOF : _ccltab[c];
    if (c == '\n') scan->line++; /* count the line */

    switch (state) {            /* evaluate state of automaton */

      case S_SPACE:             /* --- skip white space */
        switch (ccl) {          /* evaluate character category */
          case C_SPACE : /* do nothing */             break;
          case C_LETTER: *p++  = c; state = S_ID;     break;
          case C_DIGIT : *p++  = c; state = S_NUMDIG; break;
          case C_POINT : *p++  = c; state = S_NUMPT;  break;
          case C_SIGN  : *p++  = c; state = S_SIGN;   break;
          case C_CMPOP : *p++  = c; state = S_CMPOP;  break;
          case C_QUOTE : quote = c; state = S_STRING; break;
          case C_SLASH :            state = S_SLASH;  break;
          case C_ACTIVE: *p++  = c; *p = '\0'; scan->len = 1;
                         return scan->token = c;
          case EOF     : strcpy(p, "<eof>");   scan->len = 4;
                         return scan->token = (ferror(scan->file))
                                           ? E_FREAD : T_EOF;
          default      : *p++  = c; *p = '\0'; scan->len = 1;
                         return scan->token = E_ILLCHR;
        } break;

      case S_ID:                /* --- identifier (letter read) */
        if ((ccl == C_LETTER)   /* if another letter */
        ||  (ccl == C_DIGIT)    /* or a digit */
        ||  (ccl == C_POINT)    /* or a decimal point */
        ||  (ccl == C_SIGN)) {  /* or a sign follows */
          if (p >= end) return scan->token = E_BUFOVF;
          *p++ = c; break;      /* buffer character */
        }                       /* otherwise */
        UNGETC(scan, c);        /* put back last character, */
        *p = '\0';              /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_ID;   /* and return 'identifier' */

      case S_NUMDIG:            /* --- number (digit read) */
        if (p < end) *p++ = c;  /* buffer character */
        else return scan->token = E_BUFOVF;
        if  (ccl == C_DIGIT)    /* if another digit follows, */
          break;                /* do nothing */
        if  (ccl == C_POINT) {  /* if a decimal point follows, */
          state = S_FRAC;   break; } /* go to 'fraction' state */
        if ((c == 'e')          /* if an exponent indicator follows */
        ||  (c == 'E')) {       /* (lower- or uppercase), */
          state = S_EXPIND; break; } /* go to 'exponent' state */
        if ((ccl == C_LETTER)   /* if a letter */
        ||  (ccl == C_SIGN)) {  /* or a sign follows, */
          state = S_ID; break;  /* go to 'identifier' state */
        }                       /* otherwise */
        UNGETC(scan, c);        /* put back last character, */
        *--p = '\0';            /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_NUM;      /* and return 'number' */

      case S_NUMPT:             /* --- number (point read) */
        if (p < end) *p++ = c;  /* buffer character */
        else return scan->token = E_BUFOVF;
        if  (ccl == C_DIGIT) {       /* if a digit follows, */
          state = S_FRAC; break; }   /* go to 'fraction' state */
        if ((ccl == C_LETTER)   /* if a letter */
        ||  (ccl == C_POINT)    /* or a decimal point */
        ||  (ccl == C_SIGN)) {  /* or a sign follows */
          state = S_ID; break;  /* go to 'identifier' state */
        }                       /* otherwise */
        UNGETC(scan, c);        /* put back last character, */
        *--p = '\0';            /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_ID;   /* and return 'identifier' */

      case S_FRAC:              /* --- number (digit & point read) */
        if (p < end) *p++ = c;  /* buffer character */
        else return scan->token = E_BUFOVF;
        if  (ccl == C_DIGIT)    /* if another digit follows, */
          break;                /* do nothing else */
        if ((c == 'e')          /* if an exponent indicator follows, */
        ||  (c == 'E')) {       /* (lower- or uppercase), */
          state = S_EXPIND; break; } /* go to exponent state */
        if ((ccl == C_LETTER)   /* if a letter */
        ||  (ccl == C_POINT)    /* or a decimal point */
        ||  (ccl == C_SIGN)) {  /* or a sign follows, */
          state = S_ID; break;  /* go to 'identifier' state */
        }                       /* otherwise */
        UNGETC(scan, c);        /* put back last character, */
        *--p = '\0';            /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_NUM;      /* and return 'number' */

      case S_EXPIND:            /* --- exponent (indicator read) */
        if (p < end) *p++ = c;  /* buffer character */
        else return scan->token = E_BUFOVF;
        if  (ccl == C_SIGN) {        /* if a sign follows, */
          state = S_EXPSGN; break; } /* go to 2nd 'exponent' state */
        if  (ccl == C_DIGIT) {       /* if a digit follows, */
          state = S_EXPDIG; break; } /* go to 3rd 'exponent' state */
        if ((ccl == C_LETTER)   /* if a letter */
        ||  (ccl == C_POINT)) { /* or a decimal point follows */
          state = S_ID; break;  /* go to 'identifier' state */
        }                       /* otherwise */
        UNGETC(scan, c);        /* put back last character, */
        *--p = '\0';            /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_ID;   /* and return 'identifier' */

      case S_EXPSGN:            /* --- exponent (sign read) */
        if (p < end) *p++ = c;  /* buffer character */
        else return scan->token = E_BUFOVF;
        if  (ccl == C_DIGIT) {      /* if a digit follows, */
          state = S_EXPDIG; break;} /* do nothing else */
        if ((ccl == C_LETTER)   /* if a letter */
        ||  (ccl == C_POINT)    /* or a decimal point */
        ||  (ccl == C_SIGN)) {  /* or a sign follows */
          state = S_ID; break;  /* go to 'identifier' state */
        }                       /* otherwise */
        UNGETC(scan, c);        /* put back last character, */
        *--p = '\0';            /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_ID;   /* and return 'identifier' */

      case S_EXPDIG:            /* --- exponent (digit read) */
        if (p < end) *p++ = c;  /* buffer character */
        else return scan->token = E_BUFOVF;
        if  (ccl == C_DIGIT)    /* if another digit follows, */
          break;                /* do nothing else */
        if ((ccl == C_LETTER)   /* if a letter */
        ||  (ccl == C_POINT)    /* or a decimal point */
        ||  (ccl == C_SIGN)) {  /* or a sign follows, */
          state = S_ID; break;  /* go to 'identifier' state */
        }                       /* otherwise */
        UNGETC(scan, c);        /* put back last character, */
        *--p = '\0';            /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_NUM;      /* and return 'number' */

      case S_SIGN:              /* --- number (sign read) */
        *p++ = c;               /* buffer character */
        if  (ccl == C_DIGIT) {       /* if a digit follows, */
          state = S_NUMDIG; break; } /* go to 'number' state */
        if  (ccl == C_POINT) {       /* if a decimal point follows, */
          state = S_NUMPT; break; }  /* go to fraction state */
        if ((ccl == C_LETTER)        /* if a letter */
        ||  (ccl == C_SIGN)) {       /* or a sign follows, */
          state = S_ID; break; }     /* go to 'identifier' state */
        if ((c == '>')          /* if a '>' follows and previous */
        &&  (scan->value[0] == '-')) {   /* char was a minus sign */
          *p = '\0'; scan->len = 2; return scan->token = T_RGT; }
        UNGETC(scan, c);        /* otherwise put back last character, */
        *--p = '\0';            /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_ID;   /* and return 'identifier' */

      case S_CMPOP:             /* --- comparison operator read */
        if ((c == '-')          /* if a minus sign follows and */
        &&  (scan->value[0] == '<')) {  /* prev. char was a '<' */
          *p++ = '-';       scan->token = T_LFT; }
        else if (c == '=') {    /* if an equal sign follows */
          *p++ = '=';       scan->token = T_CMP; }
        else {                  /* if anything else follows */
          UNGETC(scan, c);  scan->token = scan->value[0]; }
        *p = '\0';              /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token;        /* and return the token read */

      case S_STRING:            /* --- quoted string */
        if ((c == '\n') || (c == EOF))  /* if end of line or file, */
          return scan->token = E_UNTSTR;   /* string is unterminated */
        if (c != quote) {       /* if not at end of string */
          if (p >= end) return scan->token = E_BUFOVF;
          if (c == '\\') {      /* if escaped character follows, */
            state = S_ESC; break; }  /* go to escaped char state */
          *p++ = c; break;      /* otherwise buffer character */
        }                       /* if at end of string, */
        *p = '\0';              /* terminate string in buffer */
        scan->len = (int)(p -scan->value); /* set string length */
        return scan->token = T_ID;   /* and return 'identifier' */

      case S_ESC:               /* --- after '\' in quoted string */
        if ((c >= '0') && (c <= '7')) {        /* if octal digit, */
          ec = c -'0'; state = S_OCT1; break; }/* evaluate digit  */
        if (c == 'x') {         /* if hexadecimal character code, */
          state = S_HEX1; break;} /* go to hexadecimal evaluation */
        switch (c) {            /* evaluate character after '\' */
          case  'a': c = '\a'; break;
          case  'b': c = '\b'; break;
          case  'f': c = '\f'; break;
          case  'n': c = '\n'; break;
          case  'r': c = '\r'; break;
          case  't': c = '\t'; break;
          case  'v': c = '\v'; break;
          case '\n': c = -1;   break;
          default  :           break;
        }                       /* get escaped character */
        if (c >= 0) *p++ = c;   /* and store it, then */
        state = S_STRING; break;/* return to quoted string state */

      case S_OCT1:              /* --- escaped octal number 1 */
        if ((c >= '0')          /* if an octal digit follows, */
        &&  (c <= '7')) {       /* evaluate it */
          ec = ec *8 +c -'0'; state = S_OCT2; break; }
        UNGETC(scan, c);        /* otherwise put back last character */
        *p++  = ec;             /* store escaped character and */
        state = S_STRING; break;/* return to quoted string state */

      case S_OCT2:              /* --- escaped octal number 2 */
        if ((c >= '0') || (c <= '7'))
          ec = ec *8 +c -'0';   /* if octal digit, evaluate it */
        else UNGETC(scan, c);   /* otherwise put back last character */
        *p++  = ec;             /* store escaped character and */
        state = S_STRING; break;/* return to quoted string state */

      case S_HEX1:              /* --- escaped hexadecimal number 1 */
        if (ccl == C_DIGIT) {   /* if hexadecimal digit, evaluate it */
          ec = c -'0';     state = S_HEX2; break; }
        if ((c >= 'a') && (c <= 'f')) {
          ec = c -'a' +10; state = S_HEX2; break; }
        if ((c >= 'A') && (c <= 'F')) {
          ec = c -'A' +10; state = S_HEX2; break; }
        UNGETC(scan, c);        /* otherwise put back last character */
        *p++  = 'x';            /* store escaped character ('x') and */
        state = S_STRING; break;/* return to quoted string state */

      case S_HEX2:              /* --- escaped hexadecimal number 2 */
        if (ccl == C_DIGIT)     /* if hexadecimal digit, evaluate it */
          ec = ec*16 +c -'0';
        else if ((c >= 'a') && (c <= 'f'))
          ec = ec*16 +c -'a' +10;
        else if ((c >= 'A') && (c <= 'F'))
          ec = ec*16 +c -'A' +10;
        else UNGETC(scan, c);   /* otherwise put back last character */
        *p++  = ec;             /* store escaped character and */
        state = S_STRING; break;/* return to quoted string state */

      case S_SLASH:             /* --- slash '/' */
        if (c == '/') {         /* if C++ style comment, then */
          state = S_CPPCOM; break; }   /* skip to end of line */
        if (c == '*') {         /* if C style comment */
          scan->start = scan->line; level = 1;
          state = S_CCOM1; break;    /* note start line, init. level */
        }                       /* and go to first 'comment' state */
        UNGETC(scan, c);        /* otherwise put back last character */
        *p++ = '/'; *p = '\0';  /* store character in buffer */
        scan->len = 1;          /* set string length and */
        return scan->token = '/';  /* return `character' */

      case S_CPPCOM:            /* --- C++ style comment */
        if ((c == '\n')         /* if at end of line */
        ||  (c == EOF))         /* or at end of file */
          state = S_SPACE;      /* return to white space skipping */
        break;                  /* (skip to end of line) */

      case S_CCOM1:             /* --- C style comment 1 */
        if      (c == EOF)      /* if end of file, abort */
          return scan->token = E_UNTCOM;
        if      (c == '*')      /* if possibly 'end of comment', */
          state = S_CCOM2;      /* go to 2nd 'comment' state */
        else if (c == '/')      /* if possibly 'start of comment', */
          state = S_CCOM3;      /* go to 3rd 'comment' state */
        break;

      case S_CCOM2:             /* --- C style comment 2 */
        if      (c == EOF)      /* if end of file, abort */
          return scan->token = E_UNTCOM;
        if      (c == '/') {    /* if end of comment found */
          if (--level <= 0) state = S_SPACE;
          else              state = S_CCOM1; }
        else if (c != '*')      /* if end of comment impossible */
          state = S_CCOM1;      /* return to comment skipping */
        break;                  /* (possible start of comment) */

      case S_CCOM3:             /* --- C style comment 3 */
        if      (c == EOF)      /* if end of file, abort */
          return scan->token = E_UNTCOM;
        if      (c == '*') {    /* if start of comment found */
          level++; state = S_CCOM1; }
        else if (c != '/')      /* if start of comment impossible */
          state = S_CCOM1;      /* return to comment skipping */
        break;                  /* (possible end of comment) */

      default:                  /* if state is illegal, abort */
        return scan->token = E_STATE;

    }  /* switch() */
  }  /* while(1) */
}  /* sc_next() */