git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4515 4a8a32a2...
authorborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 17 Dec 2006 17:47:57 +0000 (17:47 +0000)
committerborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 17 Dec 2006 17:47:57 +0000 (17:47 +0000)
12 files changed:
ChangeLog
doc/sdccman.lyx
src/SDCC.lex
src/SDCCutil.c
src/SDCCutil.h
src/pic/main.c
src/pic16/main.c
src/port.h
src/z80/main.c
support/Util/SDCCerr.c
support/Util/SDCCerr.h
support/Util/dbuf.c

index 014ca6b3d3b9b6a83d6b0d972e85bf5f0311128a..f22c517f5dff8f8087cafcefe2a4cfb7ff46b91b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,17 @@
+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,
index 8aba420659abb1241207cf4314a8321199b25141..c4ce3eba5665fbec3744787ae389bbd7b950254f 100644 (file)
@@ -10658,7 +10658,7 @@ portmode
 
 \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
@@ -19204,17 +19204,6 @@ If the stack_size field is omitted then a stack is created with the default
 \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}
 
@@ -20039,9 +20028,6 @@ void func_wparam(int a) wparam
 \layout LyX-Code
 
 }
-\layout Standard
-
-This keyword replaces the deprecated wparam pragma.
 \layout List
 \labelwidthstring 00.00.0000
 
index 4f9b51887143ffac7c794b995ac355ef74005628..41989a8545d052bf7ce0f6cc505acddc4b2e5e30 100644 (file)
@@ -2,24 +2,24 @@
   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]
@@ -58,7 +58,7 @@ static struct dbuf_s asmbuff;
 /* 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);
@@ -240,7 +240,7 @@ _?"_asm"         {
 "^"            { 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(); }
@@ -447,7 +447,7 @@ out:
 }
 
 
-enum pragma_id {
+enum {
      P_SAVE = 1,
      P_RESTORE,
      P_NOINDUCTION,
@@ -561,261 +561,474 @@ static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src)
   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
@@ -826,7 +1039,7 @@ static int isTargetKeyword(char *s)
 
   if (port->keywords == NULL)
     return 0;
-  
+
   if (s[0] == '_' && s[1] == '_')
     {
       /* Keywords in the port's array have either 0 or 1 underscore, */
@@ -864,16 +1077,13 @@ int yyerror(char *s)
 {
   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;
 }
index da0223f6f6b67c36715ac3f119ed2a4fefffd4d0..4fd505801e7b6e0c8fdee224fc870638c1488951 100644 (file)
@@ -23,9 +23,9 @@
 -------------------------------------------------------------------------*/
 
 #include <math.h>
+#include <ctype.h>
 
 #ifdef _WIN32
-#include <ctype.h>
 #include <windows.h>
 #endif
 #include <sys/stat.h>
@@ -325,5 +325,66 @@ size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...)
 
   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);
+}
index d8956d49322aa078b6daed1a9f4f3b7eb00b0eaf..6d5f75f92e529460dc66f3862d754e49639feb5c 100644 (file)
@@ -26,6 +26,7 @@
 #define SDCCUTIL_H
 
 #include "SDCChasht.h"
+#include "dbuf.h"
 #include <stdarg.h>
 
 /** Given an array of name, value string pairs creates a new hash
@@ -112,4 +113,21 @@ size_t SDCCsnprintf(char *, size_t, const char *, ...);
 #  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
index c194fbe3986a0041d60cba421aaf034545067cc2..ad5e3b300b01d21bc41ef22d04c4eccabd1ebc95 100644 (file)
@@ -99,16 +99,6 @@ _pic14_regparm (sym_link * l, bool reentrant)
        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
@@ -564,7 +554,7 @@ PORT pic_port =
        NULL,                           /* genInitStartup */
        _pic14_reset_regparm,
        _pic14_regparm,
-       _process_pragma,                                /* process a pragma */
+       NULL,                           /* process a pragma */
        NULL,
        _hasNativeMulFor,
        hasExtBitOp,                    /* hasExtBitOp */
index 7c9bb8312dd3207da693b26b233d667e5fe984d6..13f3bc47d2fe38050019a543ad4984f59885ca3c 100644 (file)
@@ -31,7 +31,6 @@
 #include "SDCCutil.h"
 #include "glue.h"
 #include "pcode.h"
-//#include "gen.h"
 
 
 static char _defaultRules[] =
@@ -161,258 +160,347 @@ struct {
 } 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(&sectSyms, ssym);
+          addSet(&sectSyms, 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(&sectNames, 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(&sectNames, 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="
index c980c6075a10a6681c614585f453aaf0e46bd4ab..0b0ae7580e45a6c8109c2a5807fe23508dc047e4 100644 (file)
@@ -15,9 +15,9 @@
 #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
   {
@@ -64,15 +76,15 @@ 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;
 
@@ -84,15 +96,15 @@ typedef struct
         /** 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;
 
@@ -100,41 +112,41 @@ typedef struct
     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;
 
@@ -147,37 +159,37 @@ typedef struct
         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;
 
@@ -185,18 +197,18 @@ typedef struct
     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;
 
@@ -212,19 +224,19 @@ typedef struct
 
     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;
 
@@ -243,8 +255,8 @@ typedef struct
     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 */
@@ -257,13 +269,13 @@ typedef struct
 /** 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
@@ -287,11 +299,11 @@ typedef struct
     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);
 
@@ -324,18 +336,18 @@ typedef struct
     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. */
index 88c6faa1f50fbc0c41b0ab992b156d4b244c981b..a5e840647a88fbfc47b797fe5d6486c4b0a54ae6 100644 (file)
@@ -138,78 +138,136 @@ _reg_parm (sym_link * l, bool reentrant)
         }
     }
 }
+
+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[] =
index 082400256f80cd2b4cffdba176a8aa1867518600..ef590fb99379d760410b432dad3e05373baacbb9 100644 (file)
@@ -434,6 +434,8 @@ struct
    "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" },
 };
 
 /*
index 927998ccc717d9e91a9dc1f5472e60335266a3ef..ba829ac09e9c9cf0fcc20b05fb36511031b2f9a5 100644 (file)
@@ -206,6 +206,7 @@ SDCCERR - SDCC Standard error handler
 #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 */
 
index 5ee200ac6d1400102670a6917eae005e30a0efa4..44762d8c3b8e63ff02efd8cddbfb769d7905a12a 100644 (file)
@@ -1,6 +1,6 @@
 /*
   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
 
@@ -105,7 +105,7 @@ int dbuf_set_size(struct dbuf_s *dbuf, size_t size)
 {
   assert(dbuf != NULL);
   assert(dbuf->alloc != 0);
-  assert(size < dbuf->len);
+  assert(size <= dbuf->len);
 
   if (size <= dbuf->len) {
     dbuf->len = size;