Esempio n. 1
0
varstr *
varstr_fromstr(char *str)
{
	varstr *	v = varstr_new(strlen(str));

	return varstr_cat(v, str);
}
Esempio n. 2
0
struct linereader *
linereader_new( void )
{
   struct linereader *tp;

   tp = ( struct linereader * ) malloc( sizeof ( struct linereader ) );
   if ( _IS_NULL( tp ) )
      return NULL;

   tp->in = stdin;                               /* default */
   tp->text = varstr_new(  );

   return tp;
}
Esempio n. 3
0
struct token token_stream_read(struct token_stream * ts)
{
	if(ts->end)
		return token_new(TOKEN_TYPE_END);
	enum states{
		READ_NEXT = 0,
		SCAN, SCAN_ERR,
		BUILD_SECTION, BUILD_SECTION1, BUILD_SECTION_END,
		BUILD_NAME, BUILD_NAME1, BUILD_NAME_END,
		BUILD_ASSIGNMENT,
		BUILD_STRING, BUILD_STRING1, BUILD_STRING_END,
		BUILD_COMMENT,
		BUILD_NEWLINE,
		BUILD_END,
		ERROR,
		SKIP_LINE,
	} state = ts->next_state;
	
	struct varstr * buf = varstr_new();
	struct char_stream * cs = ts->cs;
	struct token tok;
	int running = 1;
	do switch(state){
	case READ_NEXT:
		next_char(cs);
		
		state = SCAN;
	case SCAN:
		if(!cs->escaped)
		{
			if(cs->c == ' ' || cs->c == '\t')
				state = READ_NEXT;
			else if(cs->c == '[')
				state = BUILD_SECTION;
			else if(char_is_name(cs))
				state = BUILD_NAME;
			else if(cs->c == '=')
				state = BUILD_ASSIGNMENT;
			else if(cs->c == '"')
				state = BUILD_STRING;
			else if(cs->c == '#')
				state = BUILD_COMMENT;
			else if(cs->c == '\n')
				state = BUILD_NEWLINE;
			else if(cs->c == EOF)
				state = BUILD_END;
			else
				state = SCAN_ERR;
		}
		else
			state = SCAN_ERR;
		break;
	case SCAN_ERR:
		fprintf(stderr,"next_token: "
			"bad token at row %d, column %d\n",
			cs->row, cs->col);
		state = SKIP_LINE;
		break;

	case BUILD_SECTION:
		// [section]
		varstr_clear(buf);
		tok = token_new(TOKEN_TYPE_SECTION);
		state = BUILD_SECTION1;
	case BUILD_SECTION1:
		next_char(cs);
		if(char_is_name(cs))
			varstr_append(buf, cs->c);
		else
			state = BUILD_SECTION_END;
		break;
	case BUILD_SECTION_END:
		if(cs->c == ']' && !cs->escaped)
		{
			ts->next_state = READ_NEXT;
			tok.text = cstr_dup(varstr_view(buf));
			running = 0;
		}
		else
		{
			fprintf(stderr, "next_token: "
				"bad section name at row %d, column %d, "
				"expected ']'\n",
				cs->row, cs->col);
			state = ERROR;
		}
		break;
	case BUILD_NAME:
		// name
		tok = token_new(TOKEN_TYPE_NAME);
		varstr_clear(buf);
		varstr_append(buf, cs->c);
		state = BUILD_NAME1;
	case BUILD_NAME1:
		next_char(cs);
		if(char_is_name(cs))
			varstr_append(buf, cs->c);
		else
			state = BUILD_NAME_END;
		break;
	case BUILD_NAME_END:
		ts->next_state = SCAN;
		tok.text = cstr_dup(varstr_view(buf));
		running = 0;
		break;
	case BUILD_ASSIGNMENT:
		// =
		tok = token_new(TOKEN_TYPE_ASSIGNMENT);
		ts->next_state = READ_NEXT;
		running = 0;
		break;
	case BUILD_STRING:
		/* "multi
			line
				string
					with escape /"/n"
		*/
		tok = token_new(TOKEN_TYPE_STRING);
		varstr_clear(buf);
		state = BUILD_STRING1;
	case BUILD_STRING1:
		next_char(cs);
		if(cs->c == EOF)
			state = BUILD_STRING_END;
		else if(cs->c == '"' && !cs->escaped)
			state = BUILD_STRING_END;
		else
			varstr_append(buf, cs->c);
		break;
	case BUILD_STRING_END:
		if(cs->c == '"' && !cs->escaped)
		{
			ts->next_state = READ_NEXT;
			tok.text = cstr_dup(varstr_view(buf));
			running = 0;
		}
		else if(cs->c == EOF)
		{
			fprintf(stderr, "next_token"
				"bad string at row %d, column %d, "
				"expected '\"'\n",
				cs->row, cs->col);
			state = ERROR;
		}
		break;
	case BUILD_COMMENT:
		// # comment
		state = SKIP_LINE;
		break;
	case BUILD_NEWLINE:
		tok = token_new(TOKEN_TYPE_NEWLINE);
		ts->next_state = READ_NEXT;
		running = 0;
		break;
	case BUILD_END:
		tok = token_new(TOKEN_TYPE_NEWLINE);
		ts->end = 1;
		running = 0;
		break;
	case ERROR:
		state = SKIP_LINE;
	case SKIP_LINE:
		if(cs->c == '\n' && !cs->escaped)
			state = BUILD_NEWLINE;
		else if(cs->c == EOF)
			state = BUILD_END;
		else
			next_char(cs);
		break;
	}while(running);
	varstr_del(buf);
	return tok;
}