*** empty log message ***
[platform/upstream/binutils.git] / ld / ldlex.l
index 2651a05..7d50ccd 100644 (file)
@@ -46,8 +46,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define unput lex_unput
 int debug;
 
-extern boolean ldgram_in_expression;
-extern boolean ldgram_in_defsym;
+
+static boolean ldgram_in_defsym;
+static boolean ldgram_had_equals;
 extern boolean ldgram_in_script;
 static char *command_line;
 
@@ -61,17 +62,17 @@ int value;
 #define RTOKEN(x)  {  yylval.token = x; return x; }
 keyword_type keywords[] = 
 {
+"/", '/',
 "MEMORY",MEMORY,
 "ORIGIN",ORIGIN,
 "BLOCK",BLOCK,
 "LENGTH",LENGTH,
 "ALIGN",ALIGN_K,
-"SUBSECTION_ALIGN",SUBSECTION_ALIGN,
 "ADDR",ADDR,
 "ENTRY",ENTRY,
-"SCRIPT", SCRIPT,
-"ENDSCRIPT", ENDSCRIPT,
 "NEXT",NEXT,
+"sizeof_headers",SIZEOF_HEADERS,
+"SIZEOF_HEADERS",SIZEOF_HEADERS,
 "MAP",MAP,
 "SIZEOF",SIZEOF,
 "TARGET",TARGET_K,
@@ -80,9 +81,12 @@ keyword_type keywords[] =
 "INPUT",INPUT,
 "DEFINED",DEFINED,
 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
+"FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
 "SECTIONS",SECTIONS,
 "FILL",FILL,
 "STARTUP",STARTUP,
+"OUTPUT_FORMAT",OUTPUT_FORMAT,
+"OUTPUT_ARCH", OUTPUT_ARCH,
 "HLL",HLL,
 "SYSLIB",SYSLIB,
 "FLOAT",FLOAT,
@@ -99,6 +103,7 @@ unsigned int lineno;
 extern boolean hex_mode;
 FILE *ldlex_input_stack;
 static unsigned int have_pushback;
+
 #define NPUSHBACK 10
 int pushback[NPUSHBACK];
 int thischar;
@@ -120,7 +125,7 @@ lex_input()
       ldlex_input_stack = (FILE *)NULL;
       ldfile_input_filename = (char *)NULL;
       /* First char after script eof is a @ so that we can tell the grammer
-        that we've eft */
+        that we've left */
       thischar = '@';
 
     }
@@ -213,33 +218,46 @@ char **av;
 
 }
 
-long number(text, base)
-char *text;
-int base;
+static long 
+DEFUN(number,(default_if_zero,base),
+      int default_if_zero AND
+      int base)
 {
   unsigned  long l = 0;
-  char *p;
-  for (p = text; *p != 0; p++) {
-    if (*p == 'K') {
+  int ch = yytext[0];
+  if (ch == 0) {
+    base = default_if_zero;
+  }
+  while (1) {
+    switch (ch) {
+    case 'x':
+      base = 16;
+      break;
+    case 'k':
+    case 'K':
       l =l * 1024;
-    }
-    else if(*p== 'M') {
+      break;
+    case 'm':
+    case 'M':
       l =l * 1024 * 1024;
+      break;
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      l = l * base + ch - '0';
+      break;
+    case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
+      l =l *base + ch - 'a' + 10;
+      break;
+    case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
+      l =l *base + ch - 'A' + 10;
+      break;
+    default:
+      unput(ch);
+      yylval.integer = l;
+      return INT;
     }
-    else {
-      l =l * base;
-      if (isdigit(*p))  {
-       l += *p - '0';
-      }
-      else if (islower(*p)) {
-       l += *p - 'a' + 10;
-      }
-      else {
-       l += *p - 'A' + 10;
-      }
-    }
+ch = input();
   }
-  return l;
 }
 %}
 
@@ -247,18 +265,18 @@ int base;
 %o 5000
 FILENAMECHAR   [a-zA-Z0-9\/\.\-\_\+\=]
 FILENAME       {FILENAMECHAR}+
-
-
-WHITE          [ \t]+
+WHITE          [ \t]+ 
 
 %%
 
-"@" { return ENDSCRIPT; }
-"\ -defsym\ " { return OPTION_defsym; }
+"@" { return '}'; }
+"\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
 "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
+"\ -sort_common\ " { return OPTION_sort_common;}
 "\ -format\ " { return OPTION_format; }
 "\ -n\ "               { return OPTION_n; }
 "\ -r\ "               { return OPTION_r; }
+"\ -i\ "               { return OPTION_r; }
 "\ -Ur\ "              { return OPTION_Ur; }
 "\ -o\ "               { return OPTION_o; }
 "\ -g\ "               { return OPTION_g; }
@@ -277,6 +295,7 @@ WHITE               [ \t]+
 "\ -u\ "               { return OPTION_u; }
 "\ -s\ "            { return OPTION_s; }
 "\ -S\ "            { return OPTION_S; }
+"\ -B{FILENAME}\ "    { /* Ignored */ }
 "\ -l"{FILENAME} {
                yylval.name = buystring(yytext+3);
                return OPTION_l; 
@@ -318,7 +337,13 @@ WHITE              [ \t]+
                  yylval.name = buystring(yytext+3);
                 return OPTION_Aarch;
               }
-" " { }
+
+" "            {
+                if (ldgram_had_equals == true) {
+                         ldgram_in_defsym = false;
+                         ldgram_had_equals = false;
+                 }
+       }
 "<<="          { RTOKEN(LSHIFTEQ);}
 ">>="          { RTOKEN(RSHIFTEQ);}
 "||"           { RTOKEN(OROR);}
@@ -353,7 +378,7 @@ WHITE               [ \t]+
 "]"            { RTOKEN(']');}
 "["            { RTOKEN('[');}
 ":"            { RTOKEN(':'); }
-";"            { RTOKEN(';');}
+";"            { RTOKEN('\;');}
 "-"            { RTOKEN('-');}
 
 
@@ -381,126 +406,104 @@ WHITE           [ \t]+
   yylval.name[yyleng-2] = 0; /* Fry final quote */
   return NAME;
 }
-[0][0-7KM]* {
-
-  yylval.integer = number(yytext+1, 8);
- return INT;
-}
-
-[0-9]+[KM]? {
-  if (hex_mode == true) {
-    yylval.integer = number(yytext, 16);
-  }
-  else {
-    yylval.integer = number(yytext, 10);
-  }
-  return INT;
-}
 
-0[Xx][0-9a-fA-FKM]+ {
-  yylval.integer = number(yytext+2,16);        
-  return INT;
-}
-
-"\#"{WHITE}*{FILENAMECHAR}+ {
-  char *p = yytext+1;
-  while(*p ==' ' || *p == '\t') p++;
-  yylval.name = buystring(p);
-  return NAME;
-}
 {FILENAMECHAR} {
 
   boolean loop = false;
-  /*
-    Tokenize a name, this is really pain, since a name can be a
-    filename or a symbol name. filenames have slashes and stuff whist
-    in an expression those things are seperate tokens. We hack this by
-    setting ldlang_in_script when we are expecting a symbol, so that
-    [/+-] get taken to be seperate tokens. An extra gotcha is
-    expressions after defsyms, we only allow +s and -s in a defsym
-    expression, so -defsym foo=bar+9 /file.o is parsed ok.
-    
-    The more I think about this the more I hate it. I've got a problem
-    now with the = sign, what should I do ? imagine:
-    __start=.;
-    You'd think that was pretty unambiguous wouldn't you. Well it's
-    not since __start=. is (at the moment) a perfectly valid
-    filename. And in some cases we don't know what's going on. I'm
-    going to have to hack this. If we see a '/' before the = sign then
-    we say we've got an = in a filename, otherwise it's an operator.
-    (later)
-    That's it, I've had enough. From now on, an =s on a command line
-    will be taken to be part of a file name unless its in a defsym,
-    and an = in a file will be taken to be an operator.
-    */
   int ch;
   keyword_type *k;
 
-  if (hex_mode) {
-    ch = yytext[0];
-    /* Then always read a number */
-    while (isxdigit(ch)) {
-      yytext[yyleng++] = ch;
-      ch = input();
-    }
-    yytext[yyleng] = 0;
-    unput(ch);
+  /* If we're in hex mode (only after a -T) then all we can see are numbers
+     hex digit we see will be a number. */
 
-    yylval.integer = number(yytext,16);
-    return INT;
+  if (hex_mode) {      
+    return number(16, 16);
   }
 
-  if (ldfile_input_filename) {
-    /* We're inside a file */
-    if (yytext[0]== '=') {
-      RTOKEN('=');
-    }
+  /* If we're in a defsym then all things starting with a digit are in
+     hex */
+
+  if (isdigit(yytext[0]) && ldgram_in_defsym) {
+    return number(16,16);
+  }
+
+
+  /* Otherwise if we're in a script we will parse the numbers
+     normally */
+
+  if (ldgram_in_script == true && isdigit(yytext[0])) {
+    return number(8,10);
   }
 
-    
+  /* Anywhere not in a script or defsym, an opertor is part of a
+     filename, except / and, which is an operator when on its own */
+  if (ldgram_in_script == true|| ldgram_in_defsym == true) {
 
-    /* Otherwise we only notice special things if were in an
-       expression */
+    switch (yytext[0]) {
+      case '*': RTOKEN('*');
 
-  if (ldgram_in_expression) {
-    if (yytext[0] != '/' ||  ldgram_in_defsym == false)  {
-      switch (yytext[0]) {
-      case '/': RTOKEN('/');
-      case '=': RTOKEN('=');
+      case '=': {
+       ldgram_had_equals = true;
+       RTOKEN('=');
+      }
+       break;
+     case '/': {
+       if (ldgram_in_defsym) RTOKEN('/');
+     }
+       break;
       case '+': RTOKEN('+');
       case '-': RTOKEN('-');
+      case '!': RTOKEN('!');
+      case '~': RTOKEN('~');
       }
     }
-  }
 
+
+/* Otherwise this must be a file or a symbol name, and it will continue to be a
+   filename until we get to something strange. In scripts operator looking
+   things  are taken to be operators, except /, which will be left
+ */
   ch = input();
   while (true)
       {
-       if (isalpha(ch) || isdigit(ch) || ch == '.'  || ch == '_' ) {
-         yytext[yyleng++] = ch;
+       if (ldgram_in_defsym == true) {
+         switch (ch) {
+         case '*': 
+         case '=': 
+         case '+': 
+         case '/': 
+         case '-': 
+         case '!': 
+         case '~': 
+           goto quit;
+         }
+         
        }
-else if (ch == '=' && ldgram_in_script) {
-/* An = within a script is always taken to be an operator */
-break;
-}
-       else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') {
-         if (ldgram_in_expression) break;
+       if(ldgram_in_script == true) {
+         switch (ch) {
+         case '*': 
+         case '=': 
+         case '+': 
+         case '-': 
+         case '!': 
+         case '~': 
+           goto quit;
+         }
+        }
+
+       if (isalpha(ch) || isdigit(ch) || ch == '.'  || ch == '_'  ||
+           ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
          yytext[yyleng++] = ch;
        }
        else 
          break;
        ch = input();
       }
-
+ quit:;
   yytext[yyleng] = 0;
   unput(ch);
-  /* Filenames  of just =signs are tokens */
-  if (yyleng == 1 && yytext[0] == '=') {
-    RTOKEN('=');
-  }
-  for(k = keywords; k ->name != (char *)NULL; k++) {
 
+  for(k = keywords; k ->name != (char *)NULL; k++) {
     if (strcmp(k->name, yytext)==0) {
       yylval.token = k->value;
       return k->value;