xref: /netbsd-src/external/gpl3/binutils.old/dist/binutils/mclex.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* mclex.c -- lexer for Windows mc files parser.
2*e992f068Schristos    Copyright (C) 2007-2022 Free Software Foundation, Inc.
375fd0b74Schristos 
475fd0b74Schristos    Written by Kai Tietz, Onevision.
575fd0b74Schristos 
675fd0b74Schristos    This file is part of GNU Binutils.
775fd0b74Schristos 
875fd0b74Schristos    This program is free software; you can redistribute it and/or modify
975fd0b74Schristos    it under the terms of the GNU General Public License as published by
1075fd0b74Schristos    the Free Software Foundation; either version 3 of the License, or
1175fd0b74Schristos    (at your option) any later version.
1275fd0b74Schristos 
1375fd0b74Schristos    This program is distributed in the hope that it will be useful,
1475fd0b74Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1575fd0b74Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1675fd0b74Schristos    GNU General Public License for more details.
1775fd0b74Schristos 
1875fd0b74Schristos    You should have received a copy of the GNU General Public License
1975fd0b74Schristos    along with this program; if not, write to the Free Software
2075fd0b74Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
2175fd0b74Schristos    02110-1301, USA.  */
2275fd0b74Schristos 
2375fd0b74Schristos /* This is a lexer used by the Windows rc file parser.
2475fd0b74Schristos    It basically just recognized a bunch of keywords.  */
2575fd0b74Schristos 
2675fd0b74Schristos #include "sysdep.h"
2775fd0b74Schristos #include "bfd.h"
2875fd0b74Schristos #include "bucomm.h"
2975fd0b74Schristos #include "libiberty.h"
3075fd0b74Schristos #include "safe-ctype.h"
3175fd0b74Schristos #include "windmc.h"
3275fd0b74Schristos #include "mcparse.h"
3375fd0b74Schristos 
3475fd0b74Schristos #include <assert.h>
3575fd0b74Schristos 
3675fd0b74Schristos /* Exported globals.  */
37*e992f068Schristos bool mclex_want_nl = false;
38*e992f068Schristos bool mclex_want_line = false;
39*e992f068Schristos bool mclex_want_filename = false;
4075fd0b74Schristos 
4175fd0b74Schristos /* Local globals.  */
4275fd0b74Schristos static unichar *input_stream = NULL;
4375fd0b74Schristos static unichar *input_stream_pos = NULL;
4475fd0b74Schristos static int input_line = 1;
4575fd0b74Schristos static const char *input_filename = NULL;
4675fd0b74Schristos 
4775fd0b74Schristos void
mc_set_content(const unichar * src)4875fd0b74Schristos mc_set_content (const unichar *src)
4975fd0b74Schristos {
5075fd0b74Schristos   if (!src)
5175fd0b74Schristos     return;
5275fd0b74Schristos   input_stream = input_stream_pos = unichar_dup (src);
5375fd0b74Schristos }
5475fd0b74Schristos 
5575fd0b74Schristos void
mc_set_inputfile(const char * name)5675fd0b74Schristos mc_set_inputfile (const char *name)
5775fd0b74Schristos {
5875fd0b74Schristos   if (! name || *name == 0)
5975fd0b74Schristos     input_filename = "-";
6075fd0b74Schristos   else
6175fd0b74Schristos     {
6275fd0b74Schristos       const char *s1 = strrchr (name, '/');
6375fd0b74Schristos       const char *s2 = strrchr (name, '\\');
6475fd0b74Schristos 
6575fd0b74Schristos       if (! s1)
6675fd0b74Schristos 	s1 = s2;
6775fd0b74Schristos       if (s1 && s2 && s1 < s2)
6875fd0b74Schristos 	s1 = s2;
6975fd0b74Schristos       if (! s1)
7075fd0b74Schristos 	s1 = name;
7175fd0b74Schristos       else
7275fd0b74Schristos 	s1++;
7375fd0b74Schristos       s1 = xstrdup (s1);
7475fd0b74Schristos       input_filename = s1;
7575fd0b74Schristos     }
7675fd0b74Schristos }
7775fd0b74Schristos 
7875fd0b74Schristos static void
show_msg(const char * kind,const char * msg,va_list argp)7975fd0b74Schristos show_msg (const char *kind, const char *msg, va_list argp)
8075fd0b74Schristos {
8175fd0b74Schristos   fprintf (stderr, "In %s at line %d: %s: ", input_filename, input_line, kind);
8275fd0b74Schristos   vfprintf (stderr, msg, argp);
8375fd0b74Schristos   fprintf (stderr, ".\n");
8475fd0b74Schristos }
8575fd0b74Schristos 
8675fd0b74Schristos void
mc_warn(const char * s,...)8775fd0b74Schristos mc_warn (const char *s, ...)
8875fd0b74Schristos {
8975fd0b74Schristos   va_list argp;
9075fd0b74Schristos   va_start (argp, s);
9175fd0b74Schristos   show_msg ("warning", s, argp);
9275fd0b74Schristos   va_end (argp);
9375fd0b74Schristos }
9475fd0b74Schristos 
9575fd0b74Schristos void
mc_fatal(const char * s,...)9675fd0b74Schristos mc_fatal (const char *s, ...)
9775fd0b74Schristos {
9875fd0b74Schristos   va_list argp;
9975fd0b74Schristos   va_start (argp, s);
10075fd0b74Schristos   show_msg ("fatal", s, argp);
10175fd0b74Schristos   va_end (argp);
10275fd0b74Schristos   xexit (1);
10375fd0b74Schristos }
10475fd0b74Schristos 
10575fd0b74Schristos 
106*e992f068Schristos static void
mc_error(const char * s,...)107*e992f068Schristos mc_error (const char *s, ...)
10875fd0b74Schristos {
10975fd0b74Schristos   va_list argp;
11075fd0b74Schristos   va_start (argp, s);
11175fd0b74Schristos   show_msg ("parser", s, argp);
11275fd0b74Schristos   va_end (argp);
113*e992f068Schristos }
114*e992f068Schristos 
115*e992f068Schristos void
yyerror(const char * s)116*e992f068Schristos yyerror (const char *s)
117*e992f068Schristos {
118*e992f068Schristos   mc_error (s);
11975fd0b74Schristos }
12075fd0b74Schristos 
12175fd0b74Schristos static unichar *
get_diff(unichar * end,unichar * start)12275fd0b74Schristos get_diff (unichar *end, unichar *start)
12375fd0b74Schristos {
12475fd0b74Schristos   unichar *ret;
12575fd0b74Schristos   unichar save = *end;
12675fd0b74Schristos 
12775fd0b74Schristos   *end = 0;
12875fd0b74Schristos   ret = unichar_dup (start);
12975fd0b74Schristos   *end = save;
13075fd0b74Schristos   return ret;
13175fd0b74Schristos }
13275fd0b74Schristos 
13375fd0b74Schristos static rc_uint_type
parse_digit(unichar ch)13475fd0b74Schristos parse_digit (unichar ch)
13575fd0b74Schristos {
13675fd0b74Schristos   rc_uint_type base = 10, v = 0, c;
13775fd0b74Schristos 
13875fd0b74Schristos   if (ch == '0')
13975fd0b74Schristos     {
14075fd0b74Schristos       base = 8;
14175fd0b74Schristos       switch (input_stream_pos[0])
14275fd0b74Schristos 	{
14375fd0b74Schristos 	case 'x': case 'X': base = 16; input_stream_pos++; break;
14475fd0b74Schristos 	case 'o': case 'O': base = 8; input_stream_pos++; break;
14575fd0b74Schristos 	case 'b': case 'B': base = 2; input_stream_pos++; break;
14675fd0b74Schristos 	}
14775fd0b74Schristos     }
14875fd0b74Schristos   else
14975fd0b74Schristos     v = (rc_uint_type) (ch - '0');
15075fd0b74Schristos 
15175fd0b74Schristos   while ((ch = input_stream_pos[0]) != 0)
15275fd0b74Schristos     {
15375fd0b74Schristos       if (ch >= 'A' && ch <= 'F')
15475fd0b74Schristos 	c = (rc_uint_type) (ch - 'A') + 10;
15575fd0b74Schristos       else if (ch >= 'a' && ch <= 'f')
15675fd0b74Schristos 	c = (rc_uint_type) (ch - 'a') + 10;
15775fd0b74Schristos       else if (ch >= '0' && ch <= '9')
15875fd0b74Schristos 	c = (rc_uint_type) (ch - '0');
15975fd0b74Schristos       else
16075fd0b74Schristos 	break;
16175fd0b74Schristos       v *= base;
16275fd0b74Schristos       v += c;
16375fd0b74Schristos       ++input_stream_pos;
16475fd0b74Schristos     }
16575fd0b74Schristos   if (input_stream_pos[0] == 'U' || input_stream_pos[0] == 'u')
16675fd0b74Schristos     input_stream_pos++;
16775fd0b74Schristos   if (input_stream_pos[0] == 'L' || input_stream_pos[0] == 'l')
16875fd0b74Schristos     input_stream_pos++;
16975fd0b74Schristos   if (input_stream_pos[0] == 'L' || input_stream_pos[0] == 'l')
17075fd0b74Schristos     input_stream_pos++;
17175fd0b74Schristos   return v;
17275fd0b74Schristos }
17375fd0b74Schristos 
17475fd0b74Schristos static mc_keyword *keyword_top = NULL;
17575fd0b74Schristos 
17675fd0b74Schristos const mc_keyword *
enum_facility(int e)17775fd0b74Schristos enum_facility (int e)
17875fd0b74Schristos {
17975fd0b74Schristos   mc_keyword *h = keyword_top;
18075fd0b74Schristos 
18175fd0b74Schristos   while (h != NULL)
18275fd0b74Schristos     {
18375fd0b74Schristos       while (h && strcmp (h->group_name, "facility") != 0)
18475fd0b74Schristos 	h = h->next;
18575fd0b74Schristos       if (e == 0)
18675fd0b74Schristos 	return h;
18775fd0b74Schristos       --e;
18875fd0b74Schristos       if (h)
18975fd0b74Schristos 	h = h->next;
19075fd0b74Schristos     }
19175fd0b74Schristos   return h;
19275fd0b74Schristos }
19375fd0b74Schristos 
19475fd0b74Schristos const mc_keyword *
enum_severity(int e)19575fd0b74Schristos enum_severity (int e)
19675fd0b74Schristos {
19775fd0b74Schristos   mc_keyword *h = keyword_top;
19875fd0b74Schristos 
19975fd0b74Schristos   while (h != NULL)
20075fd0b74Schristos     {
20175fd0b74Schristos       while (h && strcmp (h->group_name, "severity") != 0)
20275fd0b74Schristos 	h = h->next;
20375fd0b74Schristos       if (e == 0)
20475fd0b74Schristos 	return h;
20575fd0b74Schristos       --e;
20675fd0b74Schristos       if (h)
20775fd0b74Schristos 	h = h->next;
20875fd0b74Schristos     }
20975fd0b74Schristos   return h;
21075fd0b74Schristos }
21175fd0b74Schristos 
21275fd0b74Schristos static void
mc_add_keyword_ascii(const char * sz,int rid,const char * grp,rc_uint_type nv,const char * sv)21375fd0b74Schristos mc_add_keyword_ascii (const char *sz, int rid, const char *grp, rc_uint_type nv, const char *sv)
21475fd0b74Schristos {
215*e992f068Schristos   unichar *usz = NULL, *usv = NULL;
21675fd0b74Schristos   rc_uint_type usz_len;
21775fd0b74Schristos 
21875fd0b74Schristos   unicode_from_codepage (&usz_len, &usz, sz, CP_ACP);
21975fd0b74Schristos   if (sv)
22075fd0b74Schristos     unicode_from_codepage (&usz_len, &usv, sv, CP_ACP);
22175fd0b74Schristos   mc_add_keyword (usz, rid, grp, nv, usv);
22275fd0b74Schristos }
22375fd0b74Schristos 
22475fd0b74Schristos void
mc_add_keyword(unichar * usz,int rid,const char * grp,rc_uint_type nv,unichar * sv)22575fd0b74Schristos mc_add_keyword (unichar *usz, int rid, const char *grp, rc_uint_type nv, unichar *sv)
22675fd0b74Schristos {
22775fd0b74Schristos   mc_keyword *p, *c, *n;
22875fd0b74Schristos   size_t len = unichar_len (usz);
22975fd0b74Schristos 
23075fd0b74Schristos   c = keyword_top;
23175fd0b74Schristos   p = NULL;
23275fd0b74Schristos   while (c != NULL)
23375fd0b74Schristos     {
23475fd0b74Schristos       if (c->len > len)
23575fd0b74Schristos 	break;
23675fd0b74Schristos       if (c->len == len)
23775fd0b74Schristos 	{
23875fd0b74Schristos 	  int e = memcmp (usz, c->usz, len * sizeof (unichar));
23975fd0b74Schristos 
24075fd0b74Schristos 	  if (e < 0)
24175fd0b74Schristos 	    break;
24275fd0b74Schristos 	  if (! e)
24375fd0b74Schristos 	    {
24475fd0b74Schristos 	      if (! strcmp (grp, "keyword") || strcmp (c->group_name, grp) != 0)
24575fd0b74Schristos 		fatal (_("Duplicate symbol entered into keyword list."));
24675fd0b74Schristos 	      c->rid = rid;
24775fd0b74Schristos 	      c->nval = nv;
24875fd0b74Schristos 	      c->sval = (!sv ? NULL : unichar_dup (sv));
24975fd0b74Schristos 	      if (! strcmp (grp, "language"))
25075fd0b74Schristos 		{
25175fd0b74Schristos 		  const wind_language_t *lag = wind_find_language_by_id ((unsigned) nv);
25275fd0b74Schristos 
25375fd0b74Schristos 		  if (lag == NULL)
25475fd0b74Schristos 		    fatal ("Language ident 0x%lx is not resolvable.\n", (long) nv);
25575fd0b74Schristos 		  memcpy (&c->lang_info, lag, sizeof (*lag));
25675fd0b74Schristos 		}
25775fd0b74Schristos 	      return;
25875fd0b74Schristos 	    }
25975fd0b74Schristos 	}
26075fd0b74Schristos       c = (p = c)->next;
26175fd0b74Schristos     }
26275fd0b74Schristos   n = xmalloc (sizeof (mc_keyword));
26375fd0b74Schristos   n->next = c;
26475fd0b74Schristos   n->len = len;
26575fd0b74Schristos   n->group_name = grp;
26675fd0b74Schristos   n->usz = usz;
26775fd0b74Schristos   n->rid = rid;
26875fd0b74Schristos   n->nval = nv;
26975fd0b74Schristos   n->sval = (!sv ? NULL : unichar_dup (sv));
27075fd0b74Schristos   if (! strcmp (grp, "language"))
27175fd0b74Schristos     {
27275fd0b74Schristos       const wind_language_t *lag = wind_find_language_by_id ((unsigned) nv);
27375fd0b74Schristos       if (lag == NULL)
27475fd0b74Schristos 	fatal ("Language ident 0x%lx is not resolvable.\n", (long) nv);
27575fd0b74Schristos       memcpy (&n->lang_info, lag, sizeof (*lag));
27675fd0b74Schristos     }
27775fd0b74Schristos   if (! p)
27875fd0b74Schristos     keyword_top = n;
27975fd0b74Schristos   else
28075fd0b74Schristos     p->next = n;
28175fd0b74Schristos }
28275fd0b74Schristos 
28375fd0b74Schristos static int
mc_token(const unichar * t,size_t len)28475fd0b74Schristos mc_token (const unichar *t, size_t len)
28575fd0b74Schristos {
28675fd0b74Schristos   static int was_init = 0;
28775fd0b74Schristos   mc_keyword *k;
28875fd0b74Schristos 
28975fd0b74Schristos   if (! was_init)
29075fd0b74Schristos     {
29175fd0b74Schristos       was_init = 1;
29275fd0b74Schristos       mc_add_keyword_ascii ("OutputBase", MCOUTPUTBASE, "keyword", 0, NULL);
29375fd0b74Schristos       mc_add_keyword_ascii ("MessageIdTypedef", MCMESSAGEIDTYPEDEF, "keyword", 0, NULL);
29475fd0b74Schristos       mc_add_keyword_ascii ("SeverityNames", MCSEVERITYNAMES, "keyword", 0, NULL);
29575fd0b74Schristos       mc_add_keyword_ascii ("FacilityNames", MCFACILITYNAMES, "keyword", 0, NULL);
29675fd0b74Schristos       mc_add_keyword_ascii ("LanguageNames", MCLANGUAGENAMES, "keyword", 0, NULL);
29775fd0b74Schristos       mc_add_keyword_ascii ("MessageId", MCMESSAGEID, "keyword", 0, NULL);
29875fd0b74Schristos       mc_add_keyword_ascii ("Severity", MCSEVERITY, "keyword", 0, NULL);
29975fd0b74Schristos       mc_add_keyword_ascii ("Facility", MCFACILITY, "keyword", 0, NULL);
30075fd0b74Schristos       mc_add_keyword_ascii ("SymbolicName", MCSYMBOLICNAME, "keyword", 0, NULL);
30175fd0b74Schristos       mc_add_keyword_ascii ("Language", MCLANGUAGE, "keyword", 0, NULL);
30275fd0b74Schristos       mc_add_keyword_ascii ("Success", MCTOKEN, "severity", 0, NULL);
30375fd0b74Schristos       mc_add_keyword_ascii ("Informational", MCTOKEN, "severity", 1, NULL);
30475fd0b74Schristos       mc_add_keyword_ascii ("Warning", MCTOKEN, "severity", 2, NULL);
30575fd0b74Schristos       mc_add_keyword_ascii ("Error", MCTOKEN, "severity", 3, NULL);
30675fd0b74Schristos       mc_add_keyword_ascii ("System", MCTOKEN, "facility", 0xff, NULL);
30775fd0b74Schristos       mc_add_keyword_ascii ("Application", MCTOKEN, "facility", 0xfff, NULL);
30875fd0b74Schristos       mc_add_keyword_ascii ("English", MCTOKEN, "language", 0x409, "MSG00001");
30975fd0b74Schristos   }
31075fd0b74Schristos   k = keyword_top;
31175fd0b74Schristos   if (!len || !t || *t == 0)
31275fd0b74Schristos     return -1;
31375fd0b74Schristos   while (k != NULL)
31475fd0b74Schristos     {
31575fd0b74Schristos       if (k->len > len)
31675fd0b74Schristos 	break;
31775fd0b74Schristos       if (k->len == len)
31875fd0b74Schristos 	{
31975fd0b74Schristos 	  if (! memcmp (k->usz, t, len * sizeof (unichar)))
32075fd0b74Schristos 	    {
32175fd0b74Schristos 	      if (k->rid == MCTOKEN)
32275fd0b74Schristos 		yylval.tok = k;
32375fd0b74Schristos 	      return k->rid;
32475fd0b74Schristos 	    }
32575fd0b74Schristos 	}
32675fd0b74Schristos       k = k->next;
32775fd0b74Schristos     }
32875fd0b74Schristos   return -1;
32975fd0b74Schristos }
33075fd0b74Schristos 
331*e992f068Schristos /* Skip characters in input_stream_pos up to and including a newline
332*e992f068Schristos    character.  Returns non-zero if the newline was found, zero otherwise.  */
333*e992f068Schristos 
334*e992f068Schristos static int
skip_until_eol(void)335*e992f068Schristos skip_until_eol (void)
336*e992f068Schristos {
337*e992f068Schristos   while (input_stream_pos[0] != 0 && input_stream_pos[0] != '\n')
338*e992f068Schristos     ++input_stream_pos;
339*e992f068Schristos   if (input_stream_pos[0] == 0)
340*e992f068Schristos     return 0;
341*e992f068Schristos   if (input_stream_pos[0] == '\n')
342*e992f068Schristos     {
343*e992f068Schristos       ++input_stream_pos;
344*e992f068Schristos       input_line += 1;
345*e992f068Schristos     }
346*e992f068Schristos   return 1;
347*e992f068Schristos }
348*e992f068Schristos 
34975fd0b74Schristos int
yylex(void)35075fd0b74Schristos yylex (void)
35175fd0b74Schristos {
35275fd0b74Schristos   unichar *start_token;
35375fd0b74Schristos   unichar ch;
35475fd0b74Schristos 
35575fd0b74Schristos   if (! input_stream_pos)
35675fd0b74Schristos     {
35775fd0b74Schristos       fatal ("Input stream not setuped.\n");
35875fd0b74Schristos       return -1;
35975fd0b74Schristos     }
360*e992f068Schristos 
36175fd0b74Schristos   if (mclex_want_line)
36275fd0b74Schristos     {
36375fd0b74Schristos       start_token = input_stream_pos;
364*e992f068Schristos       if (input_stream_pos[0] == 0)
365*e992f068Schristos 	return -1;
366*e992f068Schristos       /* PR 26082: Reject a period followed by EOF.  */
367*e992f068Schristos       if (input_stream_pos[0] == '.' && input_stream_pos[1] == 0)
368*e992f068Schristos 	return -1;
36975fd0b74Schristos       if (input_stream_pos[0] == '.'
37075fd0b74Schristos 	  && (input_stream_pos[1] == '\n'
37175fd0b74Schristos 	      || (input_stream_pos[1] == '\r' && input_stream_pos[2] == '\n')))
37275fd0b74Schristos 	{
373*e992f068Schristos 	  mclex_want_line = false;
374*e992f068Schristos           return skip_until_eol () ? MCENDLINE : -1;
37575fd0b74Schristos 	}
376*e992f068Schristos       if (!skip_until_eol ())
377*e992f068Schristos 	return -1;
37875fd0b74Schristos       yylval.ustr = get_diff (input_stream_pos, start_token);
37975fd0b74Schristos       return MCLINE;
38075fd0b74Schristos     }
381*e992f068Schristos 
38275fd0b74Schristos   while ((ch = input_stream_pos[0]) <= 0x20)
38375fd0b74Schristos     {
38475fd0b74Schristos       if (ch == 0)
38575fd0b74Schristos 	return -1;
38675fd0b74Schristos       ++input_stream_pos;
38775fd0b74Schristos       if (ch == '\n')
38875fd0b74Schristos 	input_line += 1;
38975fd0b74Schristos       if (mclex_want_nl && ch == '\n')
39075fd0b74Schristos 	{
391*e992f068Schristos 	  mclex_want_nl = false;
39275fd0b74Schristos 	  return NL;
39375fd0b74Schristos 	}
39475fd0b74Schristos     }
39575fd0b74Schristos   start_token = input_stream_pos;
39675fd0b74Schristos   ++input_stream_pos;
39775fd0b74Schristos   if (mclex_want_filename)
39875fd0b74Schristos     {
399*e992f068Schristos       mclex_want_filename = false;
40075fd0b74Schristos       if (ch == '"')
40175fd0b74Schristos 	{
40275fd0b74Schristos 	  start_token++;
40375fd0b74Schristos 	  while ((ch = input_stream_pos[0]) != 0)
40475fd0b74Schristos 	    {
40575fd0b74Schristos 	      if (ch == '"')
40675fd0b74Schristos 		break;
40775fd0b74Schristos 	      ++input_stream_pos;
40875fd0b74Schristos 	    }
40975fd0b74Schristos 	  yylval.ustr = get_diff (input_stream_pos, start_token);
41075fd0b74Schristos 	  if (ch == '"')
41175fd0b74Schristos 	    ++input_stream_pos;
41275fd0b74Schristos 	}
41375fd0b74Schristos       else
41475fd0b74Schristos 	{
41575fd0b74Schristos 	  while ((ch = input_stream_pos[0]) != 0)
41675fd0b74Schristos 	    {
41775fd0b74Schristos 	      if (ch <= 0x20 || ch == ')')
41875fd0b74Schristos 		break;
41975fd0b74Schristos 	      ++input_stream_pos;
42075fd0b74Schristos 	    }
42175fd0b74Schristos 	  yylval.ustr = get_diff (input_stream_pos, start_token);
42275fd0b74Schristos 	}
42375fd0b74Schristos       return MCFILENAME;
42475fd0b74Schristos     }
42575fd0b74Schristos   switch (ch)
42675fd0b74Schristos   {
42775fd0b74Schristos   case ';':
42875fd0b74Schristos     ++start_token;
429*e992f068Schristos     if (!skip_until_eol ())
430*e992f068Schristos       return -1;
43175fd0b74Schristos     yylval.ustr = get_diff (input_stream_pos, start_token);
43275fd0b74Schristos     return MCCOMMENT;
43375fd0b74Schristos   case '=':
43475fd0b74Schristos     return '=';
43575fd0b74Schristos   case '(':
43675fd0b74Schristos     return '(';
43775fd0b74Schristos   case ')':
43875fd0b74Schristos     return ')';
43975fd0b74Schristos   case '+':
44075fd0b74Schristos     return '+';
44175fd0b74Schristos   case ':':
44275fd0b74Schristos     return ':';
44375fd0b74Schristos   case '0': case '1': case '2': case '3': case '4':
44475fd0b74Schristos   case '5': case '6': case '7': case '8': case '9':
44575fd0b74Schristos     yylval.ival = parse_digit (ch);
44675fd0b74Schristos     return MCNUMBER;
44775fd0b74Schristos   default:
44875fd0b74Schristos     if (ch >= 0x40)
44975fd0b74Schristos       {
45075fd0b74Schristos 	int ret;
45175fd0b74Schristos 	while (input_stream_pos[0] >= 0x40 || (input_stream_pos[0] >= '0' && input_stream_pos[0] <= '9'))
45275fd0b74Schristos 	  ++input_stream_pos;
45375fd0b74Schristos 	ret = mc_token (start_token, (size_t) (input_stream_pos - start_token));
45475fd0b74Schristos 	if (ret != -1)
45575fd0b74Schristos 	  return ret;
45675fd0b74Schristos 	yylval.ustr = get_diff (input_stream_pos, start_token);
45775fd0b74Schristos 	return MCIDENT;
45875fd0b74Schristos       }
459*e992f068Schristos     mc_error ("illegal character 0x%x.", ch);
46075fd0b74Schristos   }
46175fd0b74Schristos   return -1;
46275fd0b74Schristos }
463