| 1 | cycrow | 1 | #include "bod_parser_base.h"
 | 
        
           |  |  | 2 | #include "../common/strutils.h"
 | 
        
           |  |  | 3 | #include "../common/string_builder.h"
 | 
        
           |  |  | 4 |   | 
        
           |  |  | 5 | #include <stdarg.h>
 | 
        
           |  |  | 6 | #include <stdlib.h>
 | 
        
           |  |  | 7 | #include <stdio.h>
 | 
        
           |  |  | 8 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 9 | void bod_parser_base::error(const bod_text_parser::token *t, ErrorSeverity severity, const char *format, ...)
 | 
        
           |  |  | 10 | {
 | 
        
           |  |  | 11 | 	va_list ap;
 | 
        
           |  |  | 12 | 	va_start(ap, format);
 | 
        
           |  |  | 13 |   | 
        
           |  |  | 14 | 	Error *e=new Error();
 | 
        
           |  |  | 15 | 	e->makeCode(F_Compiler, severity, E_Error);
 | 
        
           |  |  | 16 | 	if(t){
 | 
        
           |  |  | 17 | 		e->line=t->line;
 | 
        
           |  |  | 18 | 		e->col=t->col;
 | 
        
           |  |  | 19 | 	}
 | 
        
           |  |  | 20 | 	else{
 | 
        
           |  |  | 21 | 		e->line=-1;
 | 
        
           |  |  | 22 | 		e->col=-1;
 | 
        
           |  |  | 23 | 	}
 | 
        
           |  |  | 24 | 	_vsnprintf(e->text, sizeof(e->text), format, ap);
 | 
        
           |  |  | 25 | 	va_end(ap);
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 | 	errors.push_back(e);
 | 
        
           |  |  | 28 | }
 | 
        
           |  |  | 29 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 30 | bod_text_parser::token* bod_parser_base::loadValue(token_stream& is, const char *context)
 | 
        
           |  |  | 31 | {
 | 
        
           |  |  | 32 | 	bod_text_parser::token* t=is.tok();
 | 
        
           |  |  | 33 | 	bod_text_parser::token* res;
 | 
        
           |  |  | 34 |   | 
        
           |  |  | 35 | 	if(t==NULL || t->type!=token::t_text){
 | 
        
           |  |  | 36 | 		error(t ? t : is.previous(), S_Error, "%sExpected value after '%s'", context, is.previous()->getText());
 | 
        
           |  |  | 37 | 		return NULL;
 | 
        
           |  |  | 38 | 	}
 | 
        
           |  |  | 39 | 	res=t;
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 | 	t=(++is).tok();
 | 
        
           |  |  | 42 | 	if(t==NULL || t->type!=token::t_semicolon){
 | 
        
           |  |  | 43 | 		error(is.previous(), S_Error, "%sExpected ';' after '%s'", context, is.previous()->getText());
 | 
        
           |  |  | 44 | 		return NULL;
 | 
        
           |  |  | 45 | 	}
 | 
        
           |  |  | 46 | 	++is;
 | 
        
           |  |  | 47 | 	return res;
 | 
        
           |  |  | 48 | }
 | 
        
           |  |  | 49 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 50 | bool bod_parser_base::ungetValue(token_stream& s)
 | 
        
           |  |  | 51 | {
 | 
        
           |  |  | 52 | 	if(s.fail()) return false;
 | 
        
           |  |  | 53 | 	if(s.tell() >= 2){
 | 
        
           |  |  | 54 | 		--s;
 | 
        
           |  |  | 55 | 		if(s.tok()->type==bod_text_parser::token::t_semicolon){
 | 
        
           |  |  | 56 | 			--s;
 | 
        
           |  |  | 57 | 			if(s.tok()->type==bod_text_parser::token::t_text)
 | 
        
           |  |  | 58 | 				return true;
 | 
        
           |  |  | 59 | 		}
 | 
        
           |  |  | 60 | 	}
 | 
        
           |  |  | 61 | 	s.setstate(token_stream::failbit);
 | 
        
           |  |  | 62 | 	return false;
 | 
        
           |  |  | 63 | }
 | 
        
           |  |  | 64 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 65 | bool bod_parser_base::loadIntValue(token_stream& is, int *i, const char *msg)
 | 
        
           |  |  | 66 | {
 | 
        
           |  |  | 67 | 	const char *str;
 | 
        
           |  |  | 68 | 	token *t=loadValue(is, msg);
 | 
        
           |  |  | 69 | 	bool bRes;
 | 
        
           |  |  | 70 | 	if(bRes=(t!=NULL)){	
 | 
        
           |  |  | 71 | 		str=t->text;
 | 
        
           |  |  | 72 | 		while(*str!=0 && *str==' ')
 | 
        
           |  |  | 73 | 			str++;
 | 
        
           |  |  | 74 | 		if(*str=='0' && ((str[1] | 0x20)=='x')){
 | 
        
           |  |  | 75 | 			if(bRes=ishexa(t->text))
 | 
        
           |  |  | 76 | 				*i=hextoi(t->text);
 | 
        
           |  |  | 77 | 		}
 | 
        
           |  |  | 78 | 		else{
 | 
        
           |  |  | 79 | 			if(bRes=isinteger(t->text))
 | 
        
           |  |  | 80 | 				*i=atoi(t->text);
 | 
        
           |  |  | 81 | 		}
 | 
        
           |  |  | 82 | 		if(bRes==false)
 | 
        
           |  |  | 83 | 			error(t, S_Error, "%sExpected integer value", msg);
 | 
        
           |  |  | 84 | 	}
 | 
        
           |  |  | 85 | 	return bRes;
 | 
        
           |  |  | 86 | }
 | 
        
           |  |  | 87 | //---------------------------------------------------------------------------------
 | 
        
           |  |  | 88 | bool bod_parser_base::loadDoubleValue(token_stream& is, double *d, const char *msg)
 | 
        
           |  |  | 89 | {
 | 
        
           |  |  | 90 | 	token *t=loadValue(is, msg);
 | 
        
           |  |  | 91 | 	bool bRes;
 | 
        
           |  |  | 92 | 	if(bRes=(t!=NULL)){
 | 
        
           |  |  | 93 | 		if((bRes=isfloat(t->text))==false)
 | 
        
           |  |  | 94 | 			error(t, S_Error, "%sExpected float value", msg);
 | 
        
           |  |  | 95 | 		else
 | 
        
           |  |  | 96 | 			*d=atof(t->text);
 | 
        
           |  |  | 97 | 	}
 | 
        
           |  |  | 98 | 	return bRes;
 | 
        
           |  |  | 99 | }
 | 
        
           |  |  | 100 | //---------------------------------------------------------------------------------
 | 
        
           | 114 | cycrow | 101 | /*
 | 
        
           |  |  | 102 | 	load a "bod string" - should only be used when the parser is set to "bod compatibility"
 | 
        
           |  |  | 103 | */
 | 
        
           | 1 | cycrow | 104 | char * bod_parser_base::loadString(token_stream& is, const char *context)
 | 
        
           |  |  | 105 | {
 | 
        
           |  |  | 106 | 	bod_text_parser::token *t, *prev=NULL;
 | 
        
           |  |  | 107 | 	string_builder str="";
 | 
        
           |  |  | 108 |   | 
        
           | 114 | cycrow | 109 | 	//while((t=is.tok())!=NULL && (t->type==token::t_text || t->type==token::t_colon)){
 | 
        
           |  |  | 110 | 	while((t=is.tok())!=NULL && !(t->type==token::t_semicolon || t->type==token::t_openCrBracket || t->type==token::t_closeCrBracket)){
 | 
        
           | 1 | cycrow | 111 | 		if(prev!=NULL && prev->type==token::t_text && t->type==token::t_text){
 | 
        
           |  |  | 112 | 			str << ' ';
 | 
        
           |  |  | 113 | 		}
 | 
        
           |  |  | 114 | 		str << t->getText();
 | 
        
           |  |  | 115 | 		prev=t;
 | 
        
           |  |  | 116 | 		++is;
 | 
        
           |  |  | 117 | 	}
 | 
        
           |  |  | 118 | 	if(t==NULL){
 | 
        
           |  |  | 119 | 		error(is.previous(), S_Error, "%sUnexpected end of document found while looking for end of string (;)", context);
 | 
        
           |  |  | 120 | 		return NULL;
 | 
        
           |  |  | 121 | 	}
 | 
        
           |  |  | 122 | 	if(t->type!=token::t_semicolon){
 | 
        
           |  |  | 123 | 		error(t, S_Error, "%sUnexpected here '%s' while loading string", context, t->getText());
 | 
        
           |  |  | 124 | 		return NULL;
 | 
        
           |  |  | 125 | 	}
 | 
        
           |  |  | 126 | 	++is;
 | 
        
           |  |  | 127 | 	return is.fail() ? NULL : str.getbuffer();
 | 
        
           |  |  | 128 | }
 | 
        
           |  |  | 129 | //---------------------------------------------------------------------------------
 |