#include <string.h>
#include <ctype.h>
#include "common.h"
-
+#include "newalloc.h"
+#include "dbuf.h"
+
char *stringLiteral();
char *currFname;
-extern int lineno ;
+extern int lineno, column;
extern char *filename ;
-extern char *fullSrcFileName ;
int yylineno = 1 ;
void count() ;
-void comment();
int process_pragma(char *);
#undef yywrap
}
#define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
check_type(yytext))
-char asmbuff[MAX_INLINEASM] ;
+char *asmbuff=NULL;
+int asmbuffSize=0;
char *asmp ;
extern int check_type ();
extern int isTargetKeyword ();
P_STACKAUTO ,
P_NOJTBOUND ,
P_NOOVERLAY ,
+ P_LESSPEDANTIC,
P_NOGCSE ,
P_CALLEE_SAVES,
P_EXCLUDE ,
- P_LOOPREV
+ P_NOIV ,
+ P_LOOPREV ,
+ P_OVERLAY_ /* I had a strange conflict with P_OVERLAY while */
+ /* cross-compiling for MINGW32 with gcc 3.2 */
};
%}
%x asm
%%
-"_asm" { count(); asmp = asmbuff ;BEGIN(asm) ;}
-<asm>"_endasm" { count() ;
- *asmp = '\0' ;
- strcpy(yylval.yyinline,asmbuff) ;
- BEGIN(INITIAL) ;
- return (INLINEASM) ; }
-<asm>. { *asmp++ = yytext[0] ; }
-<asm>\n { count(); *asmp++ = '\n' ;}
-"/*" { comment(); }
+"_asm" {
+ count();
+ asmp = asmbuff = realloc (asmbuff, INITIAL_INLINEASM);
+ asmbuffSize=INITIAL_INLINEASM;
+ BEGIN(asm) ;
+}
+<asm>"_endasm" {
+ count();
+ *asmp = '\0';
+ yylval.yyinline = strdup (asmbuff);
+ BEGIN(INITIAL);
+ return (INLINEASM);
+}
+<asm>. {
+ if (asmp-asmbuff >= asmbuffSize-2) {
+ // increase the buffersize with 50%
+ int size=asmp-asmbuff;
+ asmbuffSize=asmbuffSize*3/2;
+ asmbuff = realloc (asmbuff, asmbuffSize);
+ asmp=asmbuff+size;
+ }
+ *asmp++ = yytext[0];
+}
+<asm>\n {
+ count();
+ if (asmp-asmbuff >= asmbuffSize-3) {
+ // increase the buffersize with 50%
+ int size=asmp-asmbuff;
+ asmbuffSize=asmbuffSize*3/2;
+ asmbuff = realloc (asmbuff, asmbuffSize);
+ asmp=asmbuff+size;
+ }
+ *asmp++ = '\n' ;
+}
"at" { count(); TKEYWORD(AT) ; }
"auto" { count(); return(AUTO); }
"bit" { count(); TKEYWORD(BIT) ; }
"void" { count(); return(VOID); }
"volatile" { count(); return(VOLATILE); }
"using" { count(); TKEYWORD(USING); }
+"_naked" { count(); TKEYWORD(NAKED); }
"while" { count(); return(WHILE); }
"xdata" { count(); TKEYWORD(XDATA); }
-"_data" { count(); TKEYWORD(_NEAR); }
-"_code" { count(); TKEYWORD(_CODE); }
-"_eeprom" { count(); TKEYWORD(_EEPROM); }
-"_flash" { count(); TKEYWORD(_CODE); }
-"_generic" { count(); TKEYWORD(_GENERIC); }
-"_near" { count(); TKEYWORD(_NEAR); }
-"_sram" { count(); TKEYWORD(_XDATA);}
-"_xdata" { count(); TKEYWORD(_XDATA);}
-"_pdata" { count(); TKEYWORD(_PDATA); }
-"_idata" { count(); TKEYWORD(_IDATA); }
"..." { count(); return(VAR_ARGS);}
+"__typeof" { count(); return TYPEOF;}
+"_JavaNative" { count(); TKEYWORD(JAVANATIVE);}
+"_overlay" { count(); TKEYWORD(OVERLAY);}
{L}({L}|{D})* { count(); return(check_type()); }
0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
-'(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
+'(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */}
{D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
{D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
{D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
"\r\n" { count(); }
"\n" { count(); }
[ \t\v\f] { count(); }
+\\ {
+ char ch=input();
+ if (ch!='\n') {
+ // that could have been removed by the preprocessor anyway
+ werror (W_STRAY_BACKSLASH, column);
+ unput(ch);
+ }
+}
. { count() ; }
%%
-
+
int checkCurrFile ( char *s)
{
char lineNum[10] ;
/* set the current line number to */
/* line number if printFlag is on */
if (!*s) {
- yylineno = lNum ;
- return 0;
+ lineno = yylineno = lNum ;
+ return 0;
}
/* if we have a filename then check */
/* get the currentfile name info */
s++ ;
- if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
- yylineno = lNum - 2;
- currFname = fullSrcFileName ;
+ /* in c1mode fullSrcFileName is NULL */
+ if ( fullSrcFileName &&
+ strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
+ lineno = yylineno = lNum;
+ currFname = fullSrcFileName ;
} else {
char *sb = s;
/* mark the end of the filename */
while (*s != '"') s++;
*s = '\0';
- ALLOC_ATOMIC(currFname,strlen(sb)+1);
- strcpy(currFname,sb);
- yylineno = lNum - 2;
+ currFname = strdup (sb);
+ lineno = yylineno = lNum;
}
filename = currFname ;
return 0;
}
-void comment()
-{
- char c, c1;
-
-loop:
- while ((c = input()) != '*' && c != 0)
- if ( c == '\n')
- yylineno++ ;
-
- if ((c1 = input()) != '/' && c != 0) {
- if ( c1 == '\n' )
- yylineno++ ;
-
- unput(c1);
- goto loop;
- }
-
-}
-
-
-
int column = 0;
int plineIdx=0;
void count()
{
- int i;
- for (i = 0; yytext[i] != '\0'; i++) {
- if (yytext[i] == '\n') {
- column = 0;
- lineno = ++yylineno ;
- }
- else
- if (yytext[i] == '\t')
- column += 8 - (column % 8);
- else
- column++;
- }
-
- /* ECHO; */
+ int i;
+ for (i = 0; yytext[i] != '\0'; i++) {
+ if (yytext[i] == '\n') {
+ column = 0;
+ lineno = ++yylineno ;
+ }
+ else
+ if (yytext[i] == '\t')
+ column += 8 - (column % 8);
+ else
+ column++;
+ }
+ /* ECHO; */
}
int check_type()
{
/* check if it is in the typedef table */
if (findSym(TypedefTab,NULL,yytext)) {
- strcpy(yylval.yychar,yytext);
+ strncpyz(yylval.yychar,yytext, SDCC_NAME_MAX);
return (TYPE_NAME) ;
}
else {
- strcpy (yylval.yychar,yytext);
+ strncpyz (yylval.yychar,yytext, SDCC_NAME_MAX);
return(IDENTIFIER);
}
}
-char strLitBuff[2048] ;
+/*
+ * Change by JTV 2001-05-19 to not concantenate strings
+ * to support ANSI hex and octal escape sequences in string liteals
+ */
-char *stringLiteral ()
+char *stringLiteral()
{
- int ch;
- char *str = strLitBuff ;
-
- *str++ = '\"' ;
- /* put into the buffer till we hit the */
- /* first \" */
- while (1) {
-
- ch = input() ;
- if (!ch) break ; /* end of input */
- /* if it is a \ then everything allowed */
- if (ch == '\\') {
- *str++ = ch ; /* backslash in place */
- *str++ = input() ; /* following char in place */
- continue ; /* carry on */
- }
-
- /* if new line we have a new line break */
- if (ch == '\n') break ;
-
- /* if this is a quote then we have work to do */
- /* find the next non whitespace character */
- /* if that is a double quote then carry on */
- if (ch == '\"') {
-
- while ((ch = input()) && isspace(ch)) ;
- if (!ch) break ;
- if (ch != '\"') {
- unput(ch) ;
- break ;
- }
-
- continue ;
+#define STR_BUF_CHUNCK_LEN 1024
+ int ch;
+ static struct dbuf_s dbuf;
+ char buf[2];
+
+ if (dbuf.alloc == 0)
+ dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
+ else
+ dbuf_set_size(&dbuf, 0);
+
+
+ dbuf_append(&dbuf, "\"", 1);
+ /* put into the buffer till we hit the first \" */
+
+ while ((ch = input()) != 0) {
+ switch (ch) {
+ case '\\':
+ /* if it is a \ then escape char's are allowed */
+ ch = input();
+ if (ch == '\n') {
+ /* \<newline> is a continuator */
+ lineno = ++yylineno;
+ column = 0;
+ }
+ else {
+ buf[0] = '\\';
+ buf[1] = ch;
+ dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
+ }
+ break; /* carry on */
+
+ case '\n':
+ /* if new line we have a new line break, which is illegal */
+ werror(W_NEWLINE_IN_STRING);
+ dbuf_append(&dbuf, "\n", 1);
+ lineno = ++yylineno;
+ column = 0;
+ break;
+
+ case '"':
+ /* if this is a quote then we have work to do */
+ /* find the next non whitespace character */
+ /* if that is a double quote then carry on */
+ dbuf_append(&dbuf, "\"", 1); /* Pass end of this string or substring to evaluator */
+ while ((ch = input()) && (isspace(ch) || ch=='\\')) {
+ switch (ch) {
+ case '\\':
+ if ((ch = input()) != '\n') {
+ werror(W_STRAY_BACKSLASH, column);
+ unput(ch);
+ }
+ else {
+ lineno = ++yylineno;
+ column = 0;
+ }
+ break;
+
+ case '\n':
+ yylineno++;
+ break;
}
- *str++ = ch;
- }
- *str++ = '\"' ;
- *str = '\0';
- return strLitBuff ;
+ }
+
+ if (!ch)
+ goto out;
+
+ if (ch != '\"') {
+ unput(ch) ;
+ goto out;
+ }
+ break;
+
+ default:
+ buf[0] = ch;
+ dbuf_append(&dbuf, buf, 1); /* Put next substring introducer into output string */
+ }
+ }
+
+out:
+ return (char *)dbuf_c_str(&dbuf);
}
void doPragma (int op, char *cp)
case P_NOOVERLAY:
options.noOverlay = 1;
break;
+ case P_LESSPEDANTIC:
+ options.lessPedantic = 1;
+ break;
case P_CALLEE_SAVES:
{
int i=0;
/* append to the functions already listed
in callee-saves */
for (; options.calleeSaves[i] ;i++);
- parseWithComma(&options.calleeSaves[i],strdup(cp));
+ parseWithComma(&options.calleeSaves[i], Safe_strdup(cp));
}
break;
case P_EXCLUDE:
- parseWithComma(options.excludeRegs,strdup(cp));
+ parseWithComma(options.excludeRegs, Safe_strdup(cp));
+ break;
+ case P_NOIV:
+ options.noiv = 1;
break;
case P_LOOPREV:
optimize.noLoopReverse = 1;
break;
+ case P_OVERLAY_:
+ break; /* notyet */
}
}
return 0;
}
+ if (strncmp(cp,PRAGMA_LESSPEDANTIC,strlen(PRAGMA_LESSPEDANTIC)) == 0) {
+ doPragma(P_LESSPEDANTIC,cp+strlen(PRAGMA_LESSPEDANTIC));
+ return 0;
+ }
+
if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
return 0;
return 0;
}
+ if (strncmp(cp,PRAGMA_NOIV,strlen(PRAGMA_NOIV)) == 0) {
+ doPragma(P_NOIV,cp+strlen(PRAGMA_NOIV));
+ return 0;
+ }
+
if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
- doPragma(P_EXCLUDE,NULL);
+ doPragma(P_LOOPREV,NULL);
return 0;
}
{
fflush(stdout);
- if (yylineno && filename)
- fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",
- filename,yylineno,
- s,yytext,column);
- fatalError++;
+ if (yylineno && filename) {
+ fprintf(stdout,"\n%s:%d: %s: token -> '%s' ; column %d\n",
+ filename,yylineno,
+ s,yytext,column);
+ fatalError++;
+ } else {
+ // this comes from an empy file, no problem
+ }
return 0;
}