+2006-12-17 Borut Razem <borut.razem AT siol.net>
+
+ * doc/sdccman.lyx, src/pic16/main.c, src/pic/main.c, src/port.h,
+ src/SDCC.lex, src/SDCCutil.[ch], src/z80/main.c,
+ support/Util/SDCCerr.[ch]: removed deprecated pragmas,
+ unified table driven pragma handling, pragma argument type checking
+ * support/Util/dbuf.c: (dbuf_set_size) allow to set size equal to the
+ current one - version 1.1.3
+
2006-12-13 Raphael Neider <rneider AT web.de>
* src/pic/device.h: removed AssignedMemory structure and macros
* src/pic/device.c: removed global finalMapping (linker assigns
- memory locations),
+ memory locations),
(register_map): add SFRs to remembered memRanges
(addMemRange,isSFR,dump_map,dump_sfr,mapRegister,assignRegister,
assignFixedRegisters,assignRelocatableRegisters): removed,
\end_inset
-=z180 (z80) is used to turn on (off) the Z180/HD64180 port addressing instructio
+ z180 (z80) is used to turn on (off) the Z180/HD64180 port addressing instructio
ns
\family typewriter
in0/out0
\layout List
\labelwidthstring 00.00.0000
-wparam
-\emph on
-This pragma is deprecated.
- Its use will cause a warning message to be issued.
-\emph default
-
-\newline
-
-\layout List
-\labelwidthstring 00.00.0000
-
code
\begin_inset LatexCommand \index{PIC16!Pragmas!\#pragma code}
\layout LyX-Code
}
-\layout Standard
-
-This keyword replaces the deprecated wparam pragma.
\layout List
\labelwidthstring 00.00.0000
SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
8/16 bit microcontrollers)
Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997)
-
+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+ what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
D [0-9]
/* forward declarations */
static char *stringLiteral(void);
static void count(void);
-static int process_pragma(char *);
+static int process_pragma(const char *);
static int check_type(void);
static int isTargetKeyword(char *s);
static int checkCurrFile(char *s);
"^" { count(); return('^'); }
"|" { count(); return('|'); }
"?" { count(); return('?'); }
-^#pragma.*"\n" { count(); process_pragma(yytext); }
+^#pragma.*$ { count(); process_pragma(yytext); }
^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
}
-enum pragma_id {
+enum {
P_SAVE = 1,
P_RESTORE,
P_NOINDUCTION,
Safe_free(src);
}
-static void doPragma(int op, char *cp)
+/*
+ * returns 1 if the pragma was processed, 0 if not
+ */
+static int doPragma(int id, const char *name, const char *cp)
{
- int i;
+ struct pragma_token_s token;
+ int err = 0;
+ int processed = 1;
- switch (op) {
- case P_SAVE:
- {
- STACK_PUSH(options_stack, cloneOptions(&options));
- STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
- STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
- }
- break;
+ init_pragma_token(&token);
- case P_RESTORE:
+ switch (id)
{
- struct options *optionsp;
- struct optimize *optimizep;
- struct SDCCERRG *sdccerrgp;
+ case P_SAVE:
+ {
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- optionsp = STACK_POP(options_stack);
- copyAndFreeOptions(&options, optionsp);
+ STACK_PUSH(options_stack, cloneOptions(&options));
+ STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
+ STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG));
+ }
+ break;
- optimizep = STACK_POP(optimize_stack);
- copyAndFreeOptimize(&optimize, optimizep);
+ case P_RESTORE:
+ {
+ struct options *optionsp;
+ struct optimize *optimizep;
+ struct SDCCERRG *sdccerrgp;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- sdccerrgp = STACK_POP(SDCCERRG_stack);
- copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
- }
- break;
+ optionsp = STACK_POP(options_stack);
+ copyAndFreeOptions(&options, optionsp);
+
+ optimizep = STACK_POP(optimize_stack);
+ copyAndFreeOptimize(&optimize, optimizep);
+
+ sdccerrgp = STACK_POP(SDCCERRG_stack);
+ copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp);
+ }
+ break;
- case P_NOINDUCTION:
- optimize.loopInduction = 0;
- break;
+ case P_NOINDUCTION:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_NOINVARIANT:
- optimize.loopInvariant = 0;
- break;
+ optimize.loopInduction = 0;
+ break;
- case P_INDUCTION:
- optimize.loopInduction = 1;
- break;
+ case P_NOINVARIANT:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_STACKAUTO:
- options.stackAuto = 1;
- break;
+ optimize.loopInvariant = 0;
+ break;
- case P_NOJTBOUND:
- optimize.noJTabBoundary = 1;
- break;
+ case P_INDUCTION:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_NOGCSE:
- optimize.global_cse = 0;
- break;
+ optimize.loopInduction = 1;
+ break;
- case P_NOOVERLAY:
- options.noOverlay = 1;
- break;
+ case P_STACKAUTO:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_LESSPEDANTIC:
- options.lessPedantic = 1;
- setErrorLogLevel(ERROR_LEVEL_WARNING);
- break;
+ options.stackAuto = 1;
+ break;
- case P_CALLEE_SAVES:
- /* append to the functions already listed
- in callee-saves */
- setParseWithComma(&options.calleeSavesSet, cp);
- break;
+ case P_NOJTBOUND:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_EXCLUDE:
- {
- deleteSet(&options.excludeRegsSet);
- setParseWithComma(&options.excludeRegsSet, cp);
- }
- break;
+ optimize.noJTabBoundary = 1;
+ break;
- case P_NOIV:
- options.noiv = 1;
- break;
+ case P_NOGCSE:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_LOOPREV:
- optimize.noLoopReverse = 1;
- break;
+ optimize.global_cse = 0;
+ break;
- case P_OVERLAY_:
- break; /* notyet */
+ case P_NOOVERLAY:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- case P_DISABLEWARN:
- if (sscanf(cp, "%d", &i) && (i<MAX_ERROR_WARNING))
+ options.noOverlay = 1;
+ break;
+
+ case P_LESSPEDANTIC:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.lessPedantic = 1;
+ setErrorLogLevel(ERROR_LEVEL_WARNING);
+ break;
+
+ case P_CALLEE_SAVES:
+ /* append to the functions already listed
+ in callee-saves */
+ setParseWithComma(&options.calleeSavesSet, (char *)cp);
+ err = -1;
+ break;
+
+ case P_EXCLUDE:
{
- setWarningDisabled(i);
+ deleteSet(&options.excludeRegsSet);
+ setParseWithComma(&options.excludeRegsSet, (char *)cp);
+ err = -1;
}
- break;
-
- case P_OPTCODESPEED:
- optimize.codeSpeed = 1;
- optimize.codeSize = 0;
- break;
-
- case P_OPTCODESIZE:
- optimize.codeSpeed = 0;
- optimize.codeSize = 1;
- break;
-
- case P_OPTCODEBALANCED:
- optimize.codeSpeed = 0;
- optimize.codeSize = 0;
- break;
-
- case P_STD_C89:
- options.std_c99 = 0;
- options.std_sdcc = 0;
- break;
-
- case P_STD_C99:
- options.std_c99 = 1;
- options.std_sdcc = 0;
- break;
-
- case P_STD_SDCC89:
- options.std_c99 = 0;
- options.std_sdcc = 1;
- break;
-
- case P_STD_SDCC99:
- options.std_c99 = 1;
- options.std_sdcc = 1;
- break;
-
- case P_CODESEG:
- {
- char str[9];
- char *segname = Safe_malloc(15);
- sscanf(cp, " %8s", str);
- str[8] = '\0';
- sprintf(segname, "%-8.8s(CODE)", str);
- options.code_seg = segname;
- }
- break;
+ break;
- case P_CONSTSEG:
- {
- char str[9];
- char *segname = Safe_malloc(15);
- sscanf(cp, " %8s", str);
- str[8] = '\0';
- sprintf(segname, "%-8.8s(CODE)", str);
- options.const_seg = segname;
+ case P_NOIV:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.noiv = 1;
+ break;
+
+ case P_LOOPREV:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.noLoopReverse = 1;
+ break;
+
+ case P_OVERLAY_:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ break; /* notyet */
+
+ case P_DISABLEWARN:
+ {
+ int warn;
+
+ cp = get_pragma_token(cp, &token);
+
+ if (token.type != TOKEN_INT)
+ {
+ err = 1;
+ break;
+ }
+ warn = token.val.int_val;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ if (warn < MAX_ERROR_WARNING)
+ setWarningDisabled(warn);
+ }
+ break;
+
+ case P_OPTCODESPEED:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.codeSpeed = 1;
+ optimize.codeSize = 0;
+ break;
+
+ case P_OPTCODESIZE:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.codeSpeed = 0;
+ optimize.codeSize = 1;
+ break;
+
+ case P_OPTCODEBALANCED:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ optimize.codeSpeed = 0;
+ optimize.codeSize = 0;
+ break;
+
+ case P_STD_C89:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 0;
+ options.std_sdcc = 0;
+ break;
+
+ case P_STD_C99:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 1;
+ options.std_sdcc = 0;
+ break;
+
+ case P_STD_SDCC89:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 0;
+ options.std_sdcc = 1;
+ break;
+
+ case P_STD_SDCC99:
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ options.std_c99 = 1;
+ options.std_sdcc = 1;
+ break;
+
+ case P_CODESEG:
+ {
+ const char *segname;
+
+ cp = get_pragma_token(cp, &token);
+ if (token.type == TOKEN_EOL)
+ {
+ err = 1;
+ break;
+ }
+ segname = get_pragma_string(&token);
+
+ cp = get_pragma_token(cp, &token);
+ if (token.type != TOKEN_EOL)
+ {
+ err = 1;
+ break;
+ }
+
+ if (strlen(segname) > 8)
+ {
+ err = 1;
+ break;
+ }
+ else
+ {
+ dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1);
+ options.code_seg = Safe_strdup(get_pragma_string(&token));
+ }
+ }
+ break;
+
+ case P_CONSTSEG:
+ {
+ const char *segname;
+
+ cp = get_pragma_token(cp, &token);
+ if (token.type == TOKEN_EOL)
+ {
+ err = 1;
+ break;
+ }
+ segname = get_pragma_string(&token);
+
+ cp = get_pragma_token(cp, &token);
+ if (token.type != TOKEN_EOL)
+ {
+ err = 1;
+ break;
+ }
+
+ if (strlen(segname) > 8)
+ {
+ err = 1;
+ break;
+ }
+ else
+ {
+ dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1);
+ options.code_seg = Safe_strdup(get_pragma_string(&token));
+ }
+ }
+ break;
+
+ default:
+ processed = 0;
+ break;
}
- break;
- }
+
+ get_pragma_token(cp, &token);
+
+ if (1 == err || (0 == err && token.type != TOKEN_EOL))
+ werror(W_BAD_PRAGMA_ARGUMENTS, name);
+
+ free_pragma_token(&token);
+ return processed;
}
-static int process_pragma(char *s)
-{
-#define NELEM(x) (sizeof (x) / sizeof (x)[0])
-#define PRAGMA_STR "#pragma"
-#define PRAGMA_LEN ((sizeof PRAGMA_STR) - 1)
+static struct pragma_s pragma_tbl[] = {
+ { "save", P_SAVE, 0, doPragma },
+ { "restore", P_RESTORE, 0, doPragma },
+ { "noinduction", P_NOINDUCTION, 0, doPragma },
+ { "noinvariant", P_NOINVARIANT, 0, doPragma },
+ { "noloopreverse", P_LOOPREV, 0, doPragma },
+ { "induction", P_INDUCTION, 0, doPragma },
+ { "stackauto", P_STACKAUTO, 0, doPragma },
+ { "nojtbound", P_NOJTBOUND, 0, doPragma },
+ { "nogcse", P_NOGCSE, 0, doPragma },
+ { "nooverlay", P_NOOVERLAY, 0, doPragma },
+ { "callee_saves", P_CALLEE_SAVES, 0, doPragma },
+ { "exclude", P_EXCLUDE, 0, doPragma },
+ { "noiv", P_NOIV, 0, doPragma },
+ { "overlay", P_OVERLAY_, 0, doPragma },
+ { "less_pedantic", P_LESSPEDANTIC, 0, doPragma },
+ { "disable_warning",P_DISABLEWARN, 0, doPragma },
+ { "opt_code_speed", P_OPTCODESPEED, 0, doPragma },
+ { "opt_code_size", P_OPTCODESIZE, 0, doPragma },
+ { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma },
+ { "std_c89", P_STD_C89, 0, doPragma },
+ { "std_c99", P_STD_C99, 0, doPragma },
+ { "std_sdcc89", P_STD_SDCC89, 0, doPragma },
+ { "std_sdcc99", P_STD_SDCC99, 0, doPragma },
+ { "codeseg", P_CODESEG, 0, doPragma },
+ { "constseg", P_CONSTSEG, 0, doPragma },
+ { NULL, 0, 0, NULL },
+};
- static struct pragma_s
- {
- const char *name;
- enum pragma_id id;
- char deprecated;
- } pragma_tbl[] = {
- { "save", P_SAVE, 0 },
- { "restore", P_RESTORE, 0 },
- { "noinduction", P_NOINDUCTION, 0 },
- { "noinvariant", P_NOINVARIANT, 0 },
- { "noloopreverse", P_LOOPREV, 0 },
- { "induction", P_INDUCTION, 0 },
- { "stackauto", P_STACKAUTO, 0 },
- { "nojtbound", P_NOJTBOUND, 0 },
- { "nogcse", P_NOGCSE, 0 },
- { "nooverlay", P_NOOVERLAY, 0 },
- { "callee_saves", P_CALLEE_SAVES, 0 },
- { "exclude", P_EXCLUDE, 0 },
- { "noiv", P_NOIV, 0 },
- { "overlay", P_OVERLAY_, 0 },
- { "less_pedantic", P_LESSPEDANTIC, 0 },
- { "disable_warning",P_DISABLEWARN, 0 },
- { "opt_code_speed", P_OPTCODESPEED, 0 },
- { "opt_code_size", P_OPTCODESIZE, 0 },
- { "opt_code_balanced", P_OPTCODEBALANCED, 0 },
- { "std_c89", P_STD_C89, 0 },
- { "std_c99", P_STD_C99, 0 },
- { "std_sdcc89", P_STD_SDCC89, 0 },
- { "std_sdcc99", P_STD_SDCC99, 0 },
- { "codeseg", P_CODESEG, 0 },
- { "constseg", P_CONSTSEG, 0 },
-
- /*
- * The following lines are deprecated pragmas,
- * only for bacward compatibility.
- * They should be removed in next major release after 1.4.0
- */
-
- { "SAVE", P_SAVE, 1 },
- { "RESTORE", P_RESTORE, 1 },
- { "NOINDUCTION", P_NOINDUCTION, 1 },
- { "NOINVARIANT", P_NOINVARIANT, 1 },
- { "NOLOOPREVERSE", P_LOOPREV, 1 },
- { "INDUCTION", P_INDUCTION, 1 },
- { "STACKAUTO", P_STACKAUTO, 1 },
- { "NOJTBOUND", P_NOJTBOUND, 1 },
- { "NOGCSE", P_NOGCSE, 1 },
- { "NOOVERLAY", P_NOOVERLAY, 1 },
- { "CALLEE-SAVES", P_CALLEE_SAVES, 1 },
- { "EXCLUDE", P_EXCLUDE, 1 },
- { "NOIV", P_NOIV, 1 },
- { "OVERLAY", P_OVERLAY_, 1 },
- { "LESS_PEDANTIC", P_LESSPEDANTIC, 1 },
- };
- char *cp;
+/*
+ * returns 1 if the pragma was processed, 0 if not
+ */
+int
+process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s)
+{
+ struct pragma_token_s token;
int i;
+ int ret = 0;
- /* find the pragma */
- while (strncmp(s, PRAGMA_STR, PRAGMA_LEN))
- s++;
- s += PRAGMA_LEN;
-
- /* look for the directive */
- while(isspace((unsigned char)*s))
- s++;
+ init_pragma_token(&token);
- cp = s;
- /* look for the end of the directive */
- while ((!isspace((unsigned char)*s)) && (*s != '\n'))
- s++ ;
+ s = get_pragma_token(s, &token);
/* skip separating whitespace */
- while (isspace((unsigned char)*s) && (*s != '\n'))
+ while ('\n' != *s && isspace((unsigned char)*s))
s++;
- /* First give the port a chance */
- if (port->process_pragma && !port->process_pragma(cp))
- return 0;
-
- for (i = 0; i < NELEM(pragma_tbl); i++)
+ for (i = 0; NULL != pragma_tbl[i].name; ++i)
{
/* now compare and do what needs to be done */
- size_t len = strlen(pragma_tbl[i].name);
-
- if (strncmp(cp, pragma_tbl[i].name, len) == 0)
+ if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0)
{
if (pragma_tbl[i].deprecated != 0)
werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
- doPragma(pragma_tbl[i].id, s);
- return 0;
+ ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s);
+ break;
}
}
- werror(W_UNKNOWN_PRAGMA, cp);
- return 0;
+ free_pragma_token(&token);
+ return ret;
+}
+
+static int process_pragma(const char *s)
+{
+ struct pragma_token_s token;
+
+ init_pragma_token(&token);
+
+ s = get_pragma_token(s, &token);
+ if (0 != strcmp("#pragma", get_pragma_string(&token)))
+ {
+ /* Oops, womething went totally wrong - internal error */
+ }
+
+ /* skip spaces */
+ while ('\n' != *s && isspace((unsigned char)*s))
+ ++s;
+
+ /* First give the port a chance */
+ if (port->process_pragma && port->process_pragma(s))
+ return 1;
+
+ if (process_pragma_tbl(pragma_tbl, s))
+ {
+ return 1;
+ }
+ else
+ {
+ werror(W_UNKNOWN_PRAGMA, s);
+ return 0;
+ }
}
/* will return 1 if the string is a part
if (port->keywords == NULL)
return 0;
-
+
if (s[0] == '_' && s[1] == '_')
{
/* Keywords in the port's array have either 0 or 1 underscore, */
{
fflush(stdout);
- if (mylineno && filename) {
- if(options.vc_err_style)
- fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
- filename, mylineno, s, yytext, column);
- else
- fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
- filename, mylineno, s ,yytext, column);
- fatalError++;
- } else {
- /* this comes from an empy file, no problem */
- }
+ if(options.vc_err_style)
+ fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
+ filename, mylineno, s, yytext, column);
+ else
+ fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
+ filename, mylineno, s ,yytext, column);
+ fatalError++;
+
return 0;
}
-------------------------------------------------------------------------*/
#include <math.h>
+#include <ctype.h>
#ifdef _WIN32
-#include <ctype.h>
#include <windows.h>
#endif
#include <sys/stat.h>
return len;
}
-
#endif
+
+/** Pragma tokenizer
+ */
+void
+init_pragma_token(struct pragma_token_s *token)
+{
+ dbuf_init(&token->dbuf, 16);
+ token->type = TOKEN_UNKNOWN;
+}
+
+char *
+get_pragma_token(const char *s, struct pragma_token_s *token)
+{
+ dbuf_set_size(&token->dbuf, 0);
+
+ /* skip leading spaces */
+ while (*s != '\n' && isspace(*s))
+ ++s;
+
+ if ('\0' == *s || '\n' == *s)
+ {
+ token->type = TOKEN_EOL;
+ }
+ else if (isdigit(*s))
+ {
+ char *end;
+
+ long val = strtol(s, &end, 0);
+
+ if (end != s && ('\0' == *end || isspace(*s)))
+ {
+ token->val.int_val = val;
+ token->type = TOKEN_INT;
+ dbuf_append(&token->dbuf, s, end - s);
+ }
+ s = end;
+ }
+ else
+ {
+ while ('\0' != *s && !isspace(*s))
+ {
+ dbuf_append(&token->dbuf, s, 1);
+ ++s;
+ }
+
+ token->type = TOKEN_STR;
+ }
+
+ return (char *)s;
+}
+
+const char *
+get_pragma_string(struct pragma_token_s *token)
+{
+ return dbuf_c_str(&token->dbuf);
+}
+
+void
+free_pragma_token(struct pragma_token_s *token)
+{
+ dbuf_destroy(&token->dbuf);
+}
#define SDCCUTIL_H
#include "SDCChasht.h"
+#include "dbuf.h"
#include <stdarg.h>
/** Given an array of name, value string pairs creates a new hash
# error "Need at least one of snprintf, vsnprintf, vsprintf!"
# endif
+/** Pragma tokenizer
+ */
+enum pragma_token_e { TOKEN_UNKNOWN, TOKEN_STR, TOKEN_INT, TOKEN_EOL };
+
+struct pragma_token_s {
+ enum pragma_token_e type;
+ struct dbuf_s dbuf;
+ union {
+ int int_val;
+ } val;
+};
+
+void init_pragma_token(struct pragma_token_s *token);
+char *get_pragma_token(const char *s, struct pragma_token_s *token);
+const char *get_pragma_string(struct pragma_token_s *token);
+void free_pragma_token(struct pragma_token_s *token);
+
#endif
return 1;
}
-static int
-_process_pragma(const char *sz)
-{
-#if 0
- static const char *WHITE = " \t";
- char *ptr = strtok((char *)sz, WHITE);
-#endif
- return 1;
-}
-
extern char *udata_section_name;
static bool
NULL, /* genInitStartup */
_pic14_reset_regparm,
_pic14_regparm,
- _process_pragma, /* process a pragma */
+ NULL, /* process a pragma */
NULL,
_hasNativeMulFor,
hasExtBitOp, /* hasExtBitOp */
#include "SDCCutil.h"
#include "glue.h"
#include "pcode.h"
-//#include "gen.h"
static char _defaultRules[] =
} libflags = { 0, 0, 0, 0, 0 };
+enum {
+ P_MAXRAM = 1,
+ P_STACK,
+ P_CODE,
+ P_UDATA,
+ P_LIBRARY
+};
+
static int
-_process_pragma(const char *sz)
+do_pragma(int id, const char *name, const char *cp)
{
- static const char *WHITE = " \t\n";
- static const char *WHITECOMMA = " \t\n,";
- char *ptr = strtok((char *)sz, WHITE);
+ struct pragma_token_s token;
+ int err = 0;
+ int processed = 1;
- /* #pragma maxram [maxram] */
- if (startsWith (ptr, "maxram")) {
- char *maxRAM = strtok((char *)NULL, WHITE);
+ init_pragma_token(&token);
- if (maxRAM != (char *)NULL) {
- int maxRAMaddress;
- value *maxRAMVal;
+ switch (id)
+ {
+ /* #pragma maxram [maxram] */
+ case P_MAXRAM:
+ {
+ int max_ram;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT == token.type)
+ max_ram = token.val.int_val;
+ else
+ {
+ err = 1;
+ break;
+ }
- maxRAMVal = constVal(maxRAM);
- maxRAMaddress = (int)floatFromVal(maxRAMVal);
- pic16_setMaxRAM(maxRAMaddress);
- }
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- return 0;
- }
-
- /* #pragma stack [stack-position] [stack-len] */
- if(startsWith(ptr, "stack")) {
- char *stackPosS = strtok((char *)NULL, WHITE);
- char *stackLenS = strtok((char *)NULL, WHITE);
- value *stackPosVal;
- value *stackLenVal;
- regs *reg;
- symbol *sym;
-
- if (!stackPosS) {
- fprintf (stderr, "%s:%d: #pragma stack [stack-pos] [stack-length] -- stack-position missing\n", filename, lineno-1);
-
- return 0; /* considered an error */
+ pic16_setMaxRAM(max_ram);
}
+ break;
- stackPosVal = constVal( stackPosS );
- stackPos = (unsigned int)floatFromVal( stackPosVal );
-
- if(stackLenS) {
- stackLenVal = constVal( stackLenS );
- stackLen = (unsigned int)floatFromVal( stackLenVal );
- }
+ /* #pragma stack [stack-position] [stack-len] */
+ case P_STACK:
+ {
+ unsigned int stackPos, stackLen;
+ regs *reg;
+ symbol *sym;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT != token.type)
+ {
+ err = 1;
+ break;
+ }
+ stackPos = token.val.int_val;
- if(stackLen < 1) {
- stackLen = 64;
- fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n",
- filename, lineno-1, stackLen, stackLen);
- }
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT != token.type)
+ {
+ err = 1;
+ break;
+ }
+ stackLen = token.val.int_val;
- /* check sanity of stack */
- if ((stackPos >> 8) != ((stackPos+stackLen-1) >> 8)) {
- fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n",
- filename,lineno-1, stackPos, stackPos+stackLen-1);
- }
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- if (pic16) {
- if (stackPos < pic16->acsSplitOfs) {
- fprintf (stderr, "%s:%u: warning: stack [0x%03X, 0x%03X] intersects with the access bank [0x000,0x%03x] -- this is highly discouraged!\n",
- filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->acsSplitOfs);
+ if (stackLen < 1) {
+ stackLen = 64;
+ fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n",
+ filename, lineno, stackLen, stackLen);
}
- if (stackPos+stackLen > 0xF00 + pic16->acsSplitOfs) {
- fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] intersects with special function registers [0x%03X,0xFFF]-- this is highly discouraged!\n",
- filename, lineno-1, stackPos, stackPos+stackLen-1, 0xF00 + pic16->acsSplitOfs);
+ /* check sanity of stack */
+ if ((stackPos >> 8) != ((stackPos + stackLen - 1) >> 8)) {
+ fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n",
+ filename, lineno, stackPos, stackPos + stackLen - 1);
}
- if (stackPos+stackLen > pic16->RAMsize) {
- fprintf (stderr, "%s:%u: error: stack [0x%03X,0x%03X] is placed outside available memory [0x000,0x%03X]!\n",
- filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->RAMsize-1);
- exit(EXIT_FAILURE);
- return 1; /* considered an error, but this reports "invalid pragma stack"... */
+ if (pic16) {
+ if (stackPos < pic16->acsSplitOfs) {
+ fprintf (stderr, "%s:%u: warning: stack [0x%03X, 0x%03X] intersects with the access bank [0x000,0x%03x] -- this is highly discouraged!\n",
+ filename, lineno, stackPos, stackPos + stackLen - 1, pic16->acsSplitOfs);
+ }
+
+ if (stackPos+stackLen > 0xF00 + pic16->acsSplitOfs) {
+ fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] intersects with special function registers [0x%03X,0xFFF]-- this is highly discouraged!\n",
+ filename, lineno, stackPos, stackPos + stackLen - 1, 0xF00 + pic16->acsSplitOfs);
+ }
+
+ if (stackPos+stackLen > pic16->RAMsize) {
+ fprintf (stderr, "%s:%u: error: stack [0x%03X,0x%03X] is placed outside available memory [0x000,0x%03X]!\n",
+ filename, lineno, stackPos, stackPos + stackLen - 1, pic16->RAMsize-1);
+ err = 1;
+ break;
+ }
}
- }
- reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
- addSet(&pic16_fix_udata, reg);
-
- reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL);
- addSet(&pic16_fix_udata, reg);
-
- sym = newSymbol("stack", 0);
- sprintf(sym->rname, "_%s", sym->name);
- addSet(&publics, sym);
+ reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
+ addSet(&pic16_fix_udata, reg);
- sym = newSymbol("stack_end", 0);
- sprintf(sym->rname, "_%s", sym->name);
- addSet(&publics, sym);
-
- initsfpnt = 1; // force glue() to initialize stack/frame pointers */
+ reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL);
+ addSet(&pic16_fix_udata, reg);
- return 0;
- }
-
- /* #pragma code [symbol] [location] */
- if(startsWith(ptr, "code")) {
- char *symname = strtok((char *)NULL, WHITE);
- char *location = strtok((char *)NULL, WHITE);
- absSym *absS;
- value *addr;
-
- if (!symname || !location) {
- fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno-1);
- exit (EXIT_FAILURE);
- return 1; /* considered an error, but this reports "invalid pragma code"... */
- }
+ sym = newSymbol("stack", 0);
+ sprintf(sym->rname, "_%s", sym->name);
+ addSet(&publics, sym);
- absS = Safe_calloc(1, sizeof(absSym));
- sprintf(absS->name, "_%s", symname);
+ sym = newSymbol("stack_end", 0);
+ sprintf(sym->rname, "_%s", sym->name);
+ addSet(&publics, sym);
- addr = constVal( location );
- absS->address = (unsigned int)floatFromVal( addr );
-
- if((absS->address % 2) != 0) {
- absS->address--;
- fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n",
- filename, lineno-1, absS->address);
+ initsfpnt = 1; // force glue() to initialize stack/frame pointers */
}
+ break;
- addSet(&absSymSet, absS);
-// fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
-// __FILE__, __LINE__, symname, absS->address);
+ /* #pragma code [symbol] [location] */
+ case P_CODE:
+ {
+ absSym *absS;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_STR != token.type)
+ goto code_err;
+
+ absS = Safe_calloc(1, sizeof(absSym));
+ sprintf(absS->name, "_%s", get_pragma_string(&token));
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT != token.type)
+ {
+ code_err:
+ //fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno);
+ err = 1;
+ break;
+ }
+ absS->address = token.val.int_val;
- return 0;
- }
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
- /* #pragma udata [section-name] [symbol] */
- if(startsWith(ptr, "udata")) {
- char *sectname = strtok((char *)NULL, WHITE);
- char *symname = strtok((char *)NULL, WHITE);
- symbol *nsym;
- sectSym *ssym;
- sectName *snam;
- int found=0;
-
- if (!symname || !sectname) {
- fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno-1);
- exit (EXIT_FAILURE);
- return 1; /* considered an error, but this reports "invalid pragma code"... */
+ if ((absS->address % 2) != 0) {
+ absS->address--;
+ fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n",
+ filename, lineno, absS->address);
+ }
+
+ addSet(&absSymSet, absS);
+// fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
+// __FILE__, __LINE__, symname, absS->address);
}
-
- while(symname) {
- ssym = Safe_calloc(1, sizeof(sectSym));
- ssym->name = Safe_calloc(1, strlen(symname)+2);
- sprintf(ssym->name, "%s%s", port->fun_prefix, symname);
- ssym->reg = NULL;
+ break;
+
+ /* #pragma udata [section-name] [symbol] */
+ case P_UDATA:
+ {
+ char *sectname;
+ const char *symname;
+ symbol *nsym;
+ sectSym *ssym;
+ sectName *snam;
+ int found = 0;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL == token.type)
+ goto udata_err;
+
+ sectname = Safe_strdup(get_pragma_string(&token));
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL == token.type)
+ {
+ udata_err:
+ //fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno);
+ err = 1;
+ break;
+ }
+ symname = get_pragma_string(&token);
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ while (symname) {
+ ssym = Safe_calloc(1, sizeof(sectSym));
+ ssym->name = Safe_calloc(1, strlen(symname) + 2);
+ sprintf(ssym->name, "%s%s", port->fun_prefix, symname);
+ ssym->reg = NULL;
- addSet(§Syms, ssym);
+ addSet(§Syms, ssym);
- nsym = newSymbol(symname, 0);
- strcpy(nsym->rname, ssym->name);
+ nsym = newSymbol((char *)symname, 0);
+ strcpy(nsym->rname, ssym->name);
#if 0
- checkAddSym(&publics, nsym);
+ checkAddSym(&publics, nsym);
#endif
- found = 0;
- for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) {
- if(!strcmp(sectname, snam->name)){ found=1; break; }
- }
-
- if(!found) {
- snam = Safe_calloc(1, sizeof(sectName));
- snam->name = Safe_strdup( sectname );
- snam->regsSet = NULL;
-
- addSet(§Names, snam);
- }
-
- ssym->section = snam;
-
+ found = 0;
+ for (snam = setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) {
+ if (!strcmp(sectname, snam->name)){ found=1; break; }
+ }
+
+ if(!found) {
+ snam = Safe_calloc(1, sizeof(sectName));
+ snam->name = Safe_strdup(sectname);
+ snam->regsSet = NULL;
+
+ addSet(§Names, snam);
+ }
+
+ ssym->section = snam;
+
#if 0
- fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__,
- ssym->name, snam->name, snam);
+ fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__,
+ ssym->name, snam->name, snam);
#endif
- symname = strtok((char *)NULL, WHITE);
- }
+ cp = get_pragma_token(cp, &token);
+ symname = (TOKEN_EOL != token.type) ? get_pragma_string(&token) : NULL;
+ }
- return 0;
- }
-
- /* #pragma wparam function1[, function2[,...]] */
- if(startsWith(ptr, "wparam")) {
- char *fname = strtok((char *)NULL, WHITECOMMA);
-
-
- while(fname) {
- fprintf(stderr, "PIC16 Warning: `%s' wparam pragma is obsolete. use function attribute `wparam' instead.\n", fname);
- addSet(&wparamList, Safe_strdup(fname));
-
-// debugf("passing with WREG to %s\n", fname);
- fname = strtok((char *)NULL, WHITECOMMA);
+ Safe_free(sectname);
}
-
- return 0;
- }
-
- /* #pragma library library_module */
- if(startsWith(ptr, "library")) {
- char *lmodule = strtok((char *)NULL, WHITE);
-
- if(lmodule) {
- /* lmodule can be:
- * c link the C library
- * math link the math library
- * io link the IO library
- * debug link the debug libary
- * anything else, will link as-is */
-
- if(!strcmp(lmodule, "c"))libflags.want_libc = 1;
- else if(!strcmp(lmodule, "math"))libflags.want_libm = 1;
- else if(!strcmp(lmodule, "io"))libflags.want_libio = 1;
- else if(!strcmp(lmodule, "debug"))libflags.want_libdebug = 1;
- else if(!strcmp(lmodule, "ignore"))libflags.ignore = 1;
- else {
- if(!libflags.ignore) {
- fprintf(stderr, "link library %s\n", lmodule);
- addSetHead(&libFilesSet, lmodule);
- }
+ break;
+
+ /* #pragma library library_module */
+ case P_LIBRARY:
+ {
+ const char *lmodule;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ lmodule = get_pragma_string(&token);
+
+ /* lmodule can be:
+ * c link the C library
+ * math link the math library
+ * io link the IO library
+ * debug link the debug libary
+ * anything else, will link as-is */
+
+ if(!strcmp(lmodule, "c"))libflags.want_libc = 1;
+ else if(!strcmp(lmodule, "math"))
+ libflags.want_libm = 1;
+ else if(!strcmp(lmodule, "io"))
+ libflags.want_libio = 1;
+ else if(!strcmp(lmodule, "debug"))
+ libflags.want_libdebug = 1;
+ else if(!strcmp(lmodule, "ignore"))
+ libflags.ignore = 1;
+ else
+ {
+ if(!libflags.ignore)
+ {
+ fprintf(stderr, "link library %s\n", lmodule);
+ addSetHead(&libFilesSet, (char *)lmodule);
+ }
+ }
+ }
+ else
+ {
+ err = 1;
+ break;
+ }
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
}
- }
-
- return 0;
- }
-
+ break;
+
#if 0
/* This is an experimental code for #pragma inline
and is temporarily disabled for 2.5.0 release */
- if(startsWith(ptr, "inline")) {
- char *tmp = strtok((char *)NULL, WHITECOMMA);
+ case P_INLINE:
+ {
+ char *tmp = strtok((char *)NULL, WHITECOMMA);
- while(tmp) {
- addSet(&asmInlineMap, Safe_strdup( tmp ));
- tmp = strtok((char *)NULL, WHITECOMMA);
- }
+ while(tmp) {
+ addSet(&asmInlineMap, Safe_strdup( tmp ));
+ tmp = strtok((char *)NULL, WHITECOMMA);
+ }
- {
- char *s;
+ {
+ char *s;
for(s = setFirstItem(asmInlineMap); s ; s = setNextItem(asmInlineMap)) {
debugf("inline asm: `%s'\n", s);
}
+ }
}
-
- return 0;
- }
+ break;
#endif /* 0 */
- return 1;
+ default:
+ processed = 0;
+ break;
+ }
+
+ get_pragma_token(cp, &token);
+
+ if (1 == err)
+ werror(W_BAD_PRAGMA_ARGUMENTS, name);
+
+ free_pragma_token(&token);
+ return processed;
+}
+
+static struct pragma_s pragma_tbl[] = {
+ { "maxram", P_MAXRAM, 0, do_pragma },
+ { "stack", P_STACK, 0, do_pragma },
+ { "code", P_CODE, 0, do_pragma },
+ { "udata", P_UDATA, 0, do_pragma },
+ { "library", P_LIBRARY, 0, do_pragma },
+/*{ "inline", P_INLINE, 0, do_pragma }, */
+ { NULL, 0, 0, NULL },
+ };
+
+static int
+_process_pragma(const char *s)
+{
+ return process_pragma_tbl(pragma_tbl, s);
}
#define REP_UDATA "--preplace-udata-with="
#define TARGET_ID_AVR 4
#define TARGET_ID_DS390 5
#define TARGET_ID_PIC 6
-#define TARGET_ID_PIC16 7
+#define TARGET_ID_PIC16 7
#define TARGET_ID_XA51 9
-#define TARGET_ID_DS400 10
+#define TARGET_ID_DS400 10
#define TARGET_ID_HC08 11
/* Macro to test the target we are compiling for.
#define TARGET_IS_DS390 (port->id==TARGET_ID_DS390)
#define TARGET_IS_DS400 (port->id==TARGET_ID_DS400)
#define TARGET_IS_PIC (port->id==TARGET_ID_PIC)
-#define TARGET_IS_PIC16 (port->id==TARGET_ID_PIC16)
+#define TARGET_IS_PIC16 (port->id==TARGET_ID_PIC16)
#define TARGET_IS_XA51 (port->id==TARGET_ID_XA51)
#define TARGET_IS_HC08 (port->id==TARGET_ID_HC08)
-#define MAX_BUILTIN_ARGS 16
+#define MAX_BUILTIN_ARGS 16
/* definition of builtin functions */
typedef struct builtins
-{
- char *name ; /* name of builtin function */
- char *rtype; /* return type as string : see typefromStr */
- int nParms; /* number of parms : max 8 */
+ {
+ char *name; /* name of builtin function */
+ char *rtype; /* return type as string : see typefromStr */
+ int nParms; /* number of parms : max 8 */
char *parm_types[MAX_BUILTIN_ARGS]; /* each parm type as string : see typeFromStr */
-} builtins ;
+ } builtins;
struct ebbIndex;
+/* pragma structure */
+struct pragma_s
+ {
+ const char *name;
+ int id;
+ char deprecated;
+ int (*func)(int id, const char *name, const char *cp);
+ };
+
+/* defined in SDCClex.lex */
+int process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s);
+
/* Processor specific names */
typedef struct
{
{
/** Pointer to glue function */
void (*do_glue)(void);
- /** TRUE if all types of glue functions should be inserted into
- the file that also defines main.
- We dont want this in cases like the z80 where the startup
- code is provided by a seperate module.
- */
- bool glue_up_main;
- /* OR of MODEL_* */
- int supported_models;
- int default_model;
+ /** TRUE if all types of glue functions should be inserted into
+ the file that also defines main.
+ We dont want this in cases like the z80 where the startup
+ code is provided by a seperate module.
+ */
+ bool glue_up_main;
+ /* OR of MODEL_* */
+ int supported_models;
+ int default_model;
}
general;
/** Alternate macro based form. */
const char *mcmd;
/** Arguments for debug mode. */
- const char *debug_opts;
+ const char *debug_opts;
/** Arguments for normal assembly mode. */
- const char *plain_opts;
- /* print externs as global */
- int externGlobal;
- /* assembler file extension */
- const char *file_ext;
+ const char *plain_opts;
+ /* print externs as global */
+ int externGlobal;
+ /* assembler file extension */
+ const char *file_ext;
/** If non-null will be used to execute the assembler. */
- void (*do_assemble) (set *);
+ void (*do_assemble) (set *);
}
assembler;
struct
{
/** Command to run (eg link-z80) */
- const char **cmd;
+ const char **cmd;
/** Alternate macro based form. */
const char *mcmd;
/** If non-null will be used to execute the link. */
- void (*do_link) (void);
+ void (*do_link) (void);
/** Extension for object files (.rel, .obj, ...) */
- const char *rel_ext;
+ const char *rel_ext;
/** 1 if port needs the .lnk file, 0 otherwise */
- const int needLinkerScript;
+ const int needLinkerScript;
}
linker;
struct
{
/** Default peephole rules */
- char *default_rules;
- int (*getSize)(lineNode *line);
- bitVect * (*getRegsRead)(lineNode *line);
- bitVect * (*getRegsWritten)(lineNode *line);
+ char *default_rules;
+ int (*getSize)(lineNode *line);
+ bitVect * (*getRegsRead)(lineNode *line);
+ bitVect * (*getRegsWritten)(lineNode *line);
}
peep;
/** Basic type sizes */
struct
{
- int char_size;
- int short_size;
+ int char_size;
+ int short_size;
unsigned int int_size;
- int long_size;
- int ptr_size; //near
- int fptr_size; //far
- int gptr_size; //generic
- int bit_size;
- int float_size;
- int max_base_size;
+ int long_size;
+ int ptr_size; //near
+ int fptr_size; //far
+ int gptr_size; //generic
+ int bit_size;
+ int float_size;
+ int max_base_size;
}
s;
int tag_code;
}
gp_tags;
-
+
/** memory regions related stuff */
struct
{
- const char *xstack_name;
- const char *istack_name;
- const char *code_name;
- const char *data_name;
- const char *idata_name;
- const char *pdata_name;
- const char *xdata_name;
- const char *bit_name;
- const char *reg_name;
- const char *static_name;
- const char *overlay_name;
- const char *post_static_name;
- const char *home_name;
- const char *xidata_name; // initialized xdata
- const char *xinit_name; // a code copy of xidata
- const char *const_name; // const data (code or not)
- const char *cabs_name; // const absolute data (code or not)
- struct memmap *default_local_map; // default location for auto vars
- struct memmap *default_globl_map; // default location for globl vars
- int code_ro; /* code space read-only 1=yes */
+ const char *xstack_name;
+ const char *istack_name;
+ const char *code_name;
+ const char *data_name;
+ const char *idata_name;
+ const char *pdata_name;
+ const char *xdata_name;
+ const char *bit_name;
+ const char *reg_name;
+ const char *static_name;
+ const char *overlay_name;
+ const char *post_static_name;
+ const char *home_name;
+ const char *xidata_name; // initialized xdata
+ const char *xinit_name; // a code copy of xidata
+ const char *const_name; // const data (code or not)
+ const char *cabs_name; // const absolute data (code or not)
+ struct memmap *default_local_map; // default location for auto vars
+ struct memmap *default_globl_map; // default location for globl vars
+ int code_ro; /* code space read-only 1=yes */
}
mem;
struct
{
- void (*genExtraAreaDeclaration)(FILE *, bool);
- void (*genExtraAreaLinkOptions)(FILE *);
+ void (*genExtraAreaDeclaration)(FILE *, bool);
+ void (*genExtraAreaLinkOptions)(FILE *);
}
extraAreas;
struct
{
/** -1 for grows down (z80), +1 for grows up (mcs51) */
- int direction;
+ int direction;
/** Extra overhead when calling between banks */
- int bank_overhead;
+ int bank_overhead;
/** Extra overhead when the function is an ISR */
- int isr_overhead;
+ int isr_overhead;
/** Standard overhead for a function call */
- int call_overhead;
+ int call_overhead;
/** Re-enterant space */
- int reent_overhead;
- /** 'banked' call overhead.
- Mild overlap with bank_overhead */
- int banked_overhead;
+ int reent_overhead;
+ /** 'banked' call overhead.
+ Mild overlap with bank_overhead */
+ int banked_overhead;
}
stack;
struct
{
- void (*emitDebuggerSymbol) (char *);
- struct
- {
- int (*regNum) (struct regs *);
- bitVect * cfiSame;
- bitVect * cfiUndef;
- int addressSize;
- int regNumRet;
- int regNumSP;
- int regNumBP;
- int offsetSP;
- }
- dwarf;
+ void (*emitDebuggerSymbol) (char *);
+ struct
+ {
+ int (*regNum) (struct regs *);
+ bitVect * cfiSame;
+ bitVect * cfiUndef;
+ int addressSize;
+ int regNumRet;
+ int regNumSP;
+ int regNumBP;
+ int offsetSP;
+ }
+ dwarf;
}
debugger;
const char *fun_prefix;
/** Called once the processor target has been selected.
- First chance to initalise and set any port specific variables.
- 'port' is set before calling this. May be NULL.
+ First chance to initalise and set any port specific variables.
+ 'port' is set before calling this. May be NULL.
*/
void (*init) (void);
/** Parses one option + its arguments */
/** Called after all the options have been parsed. */
void (*finaliseOptions) (void);
/** Called after the port has been selected but before any
- options are parsed. */
+ options are parsed. */
void (*setDefaultOptions) (void);
/** Does the dirty work. */
void (*assignRegisters) (struct ebbIndex *);
/** Returns the register name of a symbol.
- Used so that 'regs' can be an incomplete type. */
+ Used so that 'regs' can be an incomplete type. */
const char *(*getRegName) (struct regs * reg);
/* list of keywords that are used by this
void (*genInitStartup) (FILE * of);
/* parameter passing in register related functions */
- void (*reset_regparms) (void); /* reset the register count */
- int (*reg_parm) (struct sym_link *, bool reentrant); /* will return 1 if can be passed in register */
+ void (*reset_regparms) (void); /* reset the register count */
+ int (*reg_parm) (struct sym_link *, bool reentrant); /* will return 1 if can be passed in register */
/** Process the pragma string 'sz'. Returns 0 if recognised and
- processed, 1 otherwise. May be NULL.
+ processed, 1 otherwise. May be NULL.
*/
int (*process_pragma) (const char *sz);
bool little_endian;
/* condition transformations */
- bool lt_nge; /* transform (a < b) to !(a >= b) */
- bool gt_nle; /* transform (a > b) to !(a <= b) */
- bool le_ngt; /* transform (a <= b) to !(a > b) */
- bool ge_nlt; /* transform (a >= b) to !(a < b) */
- bool ne_neq; /* transform a != b --> ! (a == b) */
- bool eq_nne; /* transform a == b --> ! (a != b) */
+ bool lt_nge; /* transform (a < b) to !(a >= b) */
+ bool gt_nle; /* transform (a > b) to !(a <= b) */
+ bool le_ngt; /* transform (a <= b) to !(a > b) */
+ bool ge_nlt; /* transform (a >= b) to !(a < b) */
+ bool ne_neq; /* transform a != b --> ! (a == b) */
+ bool eq_nne; /* transform a == b --> ! (a != b) */
bool arrayInitializerSuppported;
bool (*cseOk) (iCode *ic, iCode *pdic);
builtins *builtintable; /* table of builtin functions */
- int unqualified_pointer; /* unqualified pointers type is */
- int reset_labelKey ; /* reset Label no 1 at the start of a function */
+ int unqualified_pointer; /* unqualified pointers type is */
+ int reset_labelKey ; /* reset Label no 1 at the start of a function */
int globals_allowed ; /* global & static locals not allowed ? 0 ONLY TININative*/
#define PORT_MAGIC 0xAC32
/** Used at runtime to detect if this structure has been completly filled in. */
}
}
}
+
+enum {
+ P_BANK = 1,
+ P_PORTMODE
+};
+
static int
-_process_pragma (const char *sz)
+do_pragma(int id, const char *name, const char *cp)
{
- if( startsWith( sz, "bank=" ) || startsWith( sz, "bank " ))
- {
- char buffer[128];
-
- if (sz[4]=='=')
- werror(W_DEPRECATED_PRAGMA, "bank=");
-
- strncpy (buffer, sz + 5, sizeof (buffer));
- buffer[sizeof (buffer) - 1 ] = '\0';
- chomp (buffer);
- if (isdigit ((unsigned char)buffer[0]))
- {
+ struct pragma_token_s token;
+ int err = 0;
+ int processed = 1;
- }
- else if (!strcmp (buffer, "BASE"))
- {
- strcpy (buffer, "HOME");
- }
- if (isdigit ((unsigned char)buffer[0]))
+ init_pragma_token(&token);
+
+ switch (id)
{
- /* Arg was a bank number. Handle in an ASM independent
- way. */
- char num[128];
- strncpy (num, sz + 5, sizeof (num));
- num[sizeof (num) -1] = '\0';
- chomp (num);
-
- switch (_G.asmType)
+ case P_BANK:
{
- case ASM_TYPE_ASXXXX:
- sprintf (buffer, "CODE_%s", num);
- break;
- case ASM_TYPE_RGBDS:
- sprintf (buffer, "CODE,BANK[%s]", num);
- break;
- case ASM_TYPE_ISAS:
- /* PENDING: what to use for ISAS? */
- sprintf (buffer, "CODE,BANK(%s)", num);
- break;
- default:
- wassert (0);
+ char buffer[128];
+
+ cp = get_pragma_token(cp, &token);
+
+ switch (token.type)
+ {
+ case TOKEN_EOL:
+ err = 1;
+ break;
+
+ case TOKEN_INT:
+ switch (_G.asmType)
+ {
+ case ASM_TYPE_ASXXXX:
+ sprintf(buffer, "CODE_%d", token.val.int_val);
+ break;
+
+ case ASM_TYPE_RGBDS:
+ sprintf(buffer, "CODE,BANK[%d]", token.val.int_val);
+ break;
+
+ case ASM_TYPE_ISAS:
+ /* PENDING: what to use for ISAS? */
+ sprintf (buffer, "CODE,BANK(%d)", token.val.int_val);
+ break;
+
+ default:
+ wassert (0);
+ }
+ break;
+
+ default:
+ {
+ const char *str = get_pragma_string(&token);
+
+ strcpy(buffer, (0 == strcmp("BASE", str)) ? "HOME" : str);
+ }
+ break;
+ }
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ gbz80_port.mem.code_name = Safe_strdup (buffer);
+ code->sname = gbz80_port.mem.code_name;
+ options.code_seg = gbz80_port.mem.code_name;
}
- }
- gbz80_port.mem.code_name = Safe_strdup (buffer);
- code->sname = gbz80_port.mem.code_name;
- options.code_seg = gbz80_port.mem.code_name;
- return 0;
- }
- else if( startsWith( sz, "portmode=" ) || startsWith( sz, "portmode " ))
- { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */
- char bfr[128];
+ break;
- if (sz[8]=='=')
- werror(W_DEPRECATED_PRAGMA, "portmode=");
+ case P_PORTMODE:
+ { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */
+ const char *str;
- strncpy( bfr, sz + 9, sizeof (bfr));
- bfr[sizeof (bfr) - 1] = '\0';
- chomp( bfr );
+ cp = get_pragma_token(cp, &token);
- if ( !strcmp( bfr, "z80" )){ z80_opts.port_mode = 80; }
- else if( !strcmp( bfr, "z180" )){ z80_opts.port_mode = 180; }
- else if( !strcmp( bfr, "save" )){ z80_opts.port_back = z80_opts.port_mode; }
- else if( !strcmp( bfr, "restore" )){ z80_opts.port_mode = z80_opts.port_back; }
- else return( 1 );
+ if (TOKEN_EOL == token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ str = get_pragma_string(&token);
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ if (!strcmp(str, "z80"))
+ { z80_opts.port_mode = 80; }
+ else if(!strcmp(str, "z180"))
+ { z80_opts.port_mode = 180; }
+ else if(!strcmp(str, "save"))
+ { z80_opts.port_back = z80_opts.port_mode; }
+ else if(!strcmp(str, "restore" ))
+ { z80_opts.port_mode = z80_opts.port_back; }
+ else
+ err = 1;
+ }
+ break;
- return( 0 );
+ default:
+ processed = 0;
+ break;
}
- return 1;
+ get_pragma_token(cp, &token);
+
+ if (1 == err)
+ werror(W_BAD_PRAGMA_ARGUMENTS, name);
+
+ free_pragma_token(&token);
+ return processed;
+}
+
+static struct pragma_s pragma_tbl[] = {
+ { "bank", P_BANK, 0, do_pragma },
+ { "portmode", P_PORTMODE, 0, do_pragma },
+ { NULL, 0, 0, NULL },
+ };
+
+static int
+_process_pragma(const char *s)
+{
+ return process_pragma_tbl(pragma_tbl, s);
}
static const char *_gbz80_rgbasmCmd[] =
"flexible array in otherwise empty struct" },
{ W_EMPTY_SOURCE_FILE, ERROR_LEVEL_WARNING,
"ISO C forbids an empty source file" },
+{ W_BAD_PRAGMA_ARGUMENTS, ERROR_LEVEL_WARNING,
+ "#pragma %s: bad argument(s); pragma ignored" },
};
/*
#define E_FLEXARRAY_NOTATEND 188 /* flexible array member not at end of struct */
#define E_FLEXARRAY_INEMPTYSTRCT 189 /* flexible array in otherwise empty struct */
#define W_EMPTY_SOURCE_FILE 190 /* ISO C forbids an empty source file */
+#define W_BAD_PRAGMA_ARGUMENTS 191 /* #pragma %s: bad argument(s); pragma ignored */
#define MAX_ERROR_WARNING 256 /* size of disable warnings array */
/*
dbuf.c - Dynamic buffer implementation
- version 1.1.2, May 22th, 2006
+ version 1.1.3, December 17th, 2006
Copyright (c) 2002-2006 Borut Razem
{
assert(dbuf != NULL);
assert(dbuf->alloc != 0);
- assert(size < dbuf->len);
+ assert(size <= dbuf->len);
if (size <= dbuf->len) {
dbuf->len = size;