//
// aegis - project change supervisor
// Copyright (C) 2001, 2002, 2004-2008 Peter Miller
//
// 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 3 of the License, 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, see
// .
//
#include
#include
#include
#include
#include
#include
#include
#include
#include // must be after
static input ip;
static int keyword_expected;
static symtab_ty *stp;
static int error_count;
struct table_ty
{
const char *name;
int value;
};
static table_ty table[] =
{
{ "access", ACCESS, },
{ "author", AUTHOR, },
{ "branch", BRANCH, },
{ "branches", BRANCH, },
{ "comment", COMMENT, },
{ "date", DATE, },
{ "desc", DESC, },
{ "expand", EXPAND, },
{ "head", HEAD, },
{ "locks", LOCKS, },
{ "log", LOG, },
{ "next", NEXT, },
{ "state", STATE, },
{ "strict", STRICT, },
{ "suffix", SUFFIX, },
{ "symbols", SYMBOLS, },
{ "text", TEXT, },
};
void
rcs_lex_open(string_ty *fn)
{
if (!stp)
{
table_ty *tp;
stp = symtab_alloc(SIZEOF(table));
for (tp = table; tp < ENDOF(table); ++tp)
{
string_ty *name;
name = str_from_c(tp->name);
symtab_assign(stp, name, tp);
str_free(name);
}
}
//
// Open it as a binary file. The lexer will treat random CR
// characters as white space. This means that we can cope with
// binary files when they have been checked into RCS.
//
// Note that of there are errors, the error messages won't have
// line numbers, because binary files don't do line numbers.
//
ip = input_file_open(fn);
keyword_expected = 1;
}
void
rcs_lex_close(void)
{
if (error_count)
quit(1);
ip.close();
}
static void
rcs_lex_error(sub_context_ty *scp, const char *s)
{
string_ty *msg;
msg = subst_intl(scp, s);
// re-use substitution context
sub_var_set_string(scp, "MeSsaGe", msg);
sub_var_set_string(scp, "File_Name", ip->name());
error_intl(scp, i18n("$filename: $message"));
str_free(msg);
if (++error_count >= 20)
{
// re-use substitution context
sub_var_set_string(scp, "File_Name", ip->name());
fatal_intl(scp, i18n("$filename: too many errors"));
}
}
void
format_rcs_gram_error(const char *s)
{
sub_context_ty *scp;
scp = sub_context_new();
rcs_lex_error(scp, s);
sub_context_delete(scp);
}
//
// map of character types
// ISO 8859/1 (Latin-1)
//
enum ctab_ty
{
ctab_is_junk,
ctab_is_space,
ctab_is_string,
ctab_is_digit,
ctab_is_colon,
ctab_is_semi,
ctab_is_alpha
};
static ctab_ty ctab[] =
{
ctab_is_junk, // 000
ctab_is_junk, // 001
ctab_is_junk, // 002
ctab_is_junk, // 003
ctab_is_junk, // 004
ctab_is_junk, // 005
ctab_is_junk, // 006
ctab_is_junk, // 007
ctab_is_space, // 010
ctab_is_space, // 011
ctab_is_space, // 012
ctab_is_space, // 013
ctab_is_space, // 014
ctab_is_space, // 015
ctab_is_junk, // 016
ctab_is_junk, // 017
ctab_is_junk, // 020
ctab_is_junk, // 021
ctab_is_junk, // 022
ctab_is_junk, // 023
ctab_is_junk, // 024
ctab_is_junk, // 025
ctab_is_junk, // 026
ctab_is_junk, // 027
ctab_is_junk, // 030
ctab_is_junk, // 031
ctab_is_junk, // 032
ctab_is_junk, // 033
ctab_is_junk, // 034
ctab_is_junk, // 035
ctab_is_junk, // 036
ctab_is_junk, // 037
ctab_is_space, // ' '
ctab_is_alpha, // '!'
ctab_is_alpha, // '"'
ctab_is_alpha, // '#'
ctab_is_alpha, // '$'
ctab_is_alpha, // '%'
ctab_is_alpha, // '&'
ctab_is_alpha, // '''
ctab_is_alpha, // '('
ctab_is_alpha, // ')'
ctab_is_alpha, // '*'
ctab_is_alpha, // '+'
ctab_is_alpha, // ','
ctab_is_alpha, // '-'
ctab_is_digit, // '.'
ctab_is_alpha, // '/'
ctab_is_digit, // '0'
ctab_is_digit, // '1'
ctab_is_digit, // '2'
ctab_is_digit, // '3'
ctab_is_digit, // '4'
ctab_is_digit, // '5'
ctab_is_digit, // '6'
ctab_is_digit, // '7'
ctab_is_digit, // '8'
ctab_is_digit, // '9'
ctab_is_colon, // ':'
ctab_is_semi, // ';'
ctab_is_alpha, // '<'
ctab_is_alpha, // '='
ctab_is_alpha, // '>'
ctab_is_alpha, // '?'
ctab_is_string, // '@'
ctab_is_alpha, // 'A'
ctab_is_alpha, // 'B'
ctab_is_alpha, // 'C'
ctab_is_alpha, // 'D'
ctab_is_alpha, // 'E'
ctab_is_alpha, // 'F'
ctab_is_alpha, // 'G'
ctab_is_alpha, // 'H'
ctab_is_alpha, // 'I'
ctab_is_alpha, // 'J'
ctab_is_alpha, // 'K'
ctab_is_alpha, // 'L'
ctab_is_alpha, // 'M'
ctab_is_alpha, // 'N'
ctab_is_alpha, // 'O'
ctab_is_alpha, // 'P'
ctab_is_alpha, // 'Q'
ctab_is_alpha, // 'R'
ctab_is_alpha, // 'S'
ctab_is_alpha, // 'T'
ctab_is_alpha, // 'U'
ctab_is_alpha, // 'V'
ctab_is_alpha, // 'W'
ctab_is_alpha, // 'X'
ctab_is_alpha, // 'Y'
ctab_is_alpha, // 'Z'
ctab_is_alpha, // '['
ctab_is_alpha, // '\'
ctab_is_alpha, // ']'
ctab_is_alpha, // '^'
ctab_is_alpha, // '_'
ctab_is_alpha, // '`'
ctab_is_alpha, // 'a'
ctab_is_alpha, // 'b'
ctab_is_alpha, // 'c'
ctab_is_alpha, // 'd'
ctab_is_alpha, // 'e'
ctab_is_alpha, // 'f'
ctab_is_alpha, // 'g'
ctab_is_alpha, // 'h'
ctab_is_alpha, // 'i'
ctab_is_alpha, // 'j'
ctab_is_alpha, // 'k'
ctab_is_alpha, // 'l'
ctab_is_alpha, // 'm'
ctab_is_alpha, // 'n'
ctab_is_alpha, // 'o'
ctab_is_alpha, // 'p'
ctab_is_alpha, // 'q'
ctab_is_alpha, // 'r'
ctab_is_alpha, // 's'
ctab_is_alpha, // 't'
ctab_is_alpha, // 'u'
ctab_is_alpha, // 'v'
ctab_is_alpha, // 'w'
ctab_is_alpha, // 'x'
ctab_is_alpha, // 'y'
ctab_is_alpha, // 'z'
ctab_is_alpha, // '{'
ctab_is_alpha, // '|'
ctab_is_alpha, // '}'
ctab_is_alpha, // '~'
ctab_is_junk, // 177
ctab_is_junk, // 200
ctab_is_junk, // 201
ctab_is_junk, // 202
ctab_is_junk, // 203
ctab_is_junk, // 204
ctab_is_junk, // 205
ctab_is_junk, // 206
ctab_is_junk, // 207
ctab_is_junk, // 210
ctab_is_junk, // 211
ctab_is_junk, // 212
ctab_is_junk, // 213
ctab_is_junk, // 214
ctab_is_junk, // 215
ctab_is_junk, // 216
ctab_is_junk, // 217
ctab_is_junk, // 220
ctab_is_junk, // 221
ctab_is_junk, // 222
ctab_is_junk, // 223
ctab_is_junk, // 224
ctab_is_junk, // 225
ctab_is_junk, // 226
ctab_is_junk, // 227
ctab_is_junk, // 230
ctab_is_junk, // 231
ctab_is_junk, // 232
ctab_is_junk, // 233
ctab_is_junk, // 234
ctab_is_junk, // 235
ctab_is_junk, // 236
ctab_is_junk, // 237
ctab_is_alpha, // 240
ctab_is_alpha, // 241
ctab_is_alpha, // 242
ctab_is_alpha, // 243
ctab_is_alpha, // 244
ctab_is_alpha, // 245
ctab_is_alpha, // 246
ctab_is_alpha, // 247
ctab_is_alpha, // 250
ctab_is_alpha, // 251
ctab_is_alpha, // 252
ctab_is_alpha, // 253
ctab_is_alpha, // 254
ctab_is_alpha, // 255
ctab_is_alpha, // 256
ctab_is_alpha, // 257
ctab_is_alpha, // 260
ctab_is_alpha, // 261
ctab_is_alpha, // 262
ctab_is_alpha, // 263
ctab_is_alpha, // 264
ctab_is_alpha, // 265
ctab_is_alpha, // 266
ctab_is_alpha, // 267
ctab_is_alpha, // 270
ctab_is_alpha, // 271
ctab_is_alpha, // 272
ctab_is_alpha, // 273
ctab_is_alpha, // 274
ctab_is_alpha, // 275
ctab_is_alpha, // 276
ctab_is_alpha, // 277
ctab_is_alpha, // 300
ctab_is_alpha, // 301
ctab_is_alpha, // 302
ctab_is_alpha, // 303
ctab_is_alpha, // 304
ctab_is_alpha, // 305
ctab_is_alpha, // 306
ctab_is_alpha, // 307
ctab_is_alpha, // 310
ctab_is_alpha, // 311
ctab_is_alpha, // 312
ctab_is_alpha, // 313
ctab_is_alpha, // 314
ctab_is_alpha, // 315
ctab_is_alpha, // 316
ctab_is_alpha, // 317
ctab_is_alpha, // 320
ctab_is_alpha, // 321
ctab_is_alpha, // 322
ctab_is_alpha, // 323
ctab_is_alpha, // 324
ctab_is_alpha, // 325
ctab_is_alpha, // 326
ctab_is_alpha, // 327
ctab_is_alpha, // 330
ctab_is_alpha, // 331
ctab_is_alpha, // 332
ctab_is_alpha, // 333
ctab_is_alpha, // 334
ctab_is_alpha, // 335
ctab_is_alpha, // 336
ctab_is_alpha, // 337
ctab_is_alpha, // 340
ctab_is_alpha, // 341
ctab_is_alpha, // 342
ctab_is_alpha, // 343
ctab_is_alpha, // 344
ctab_is_alpha, // 345
ctab_is_alpha, // 346
ctab_is_alpha, // 347
ctab_is_alpha, // 350
ctab_is_alpha, // 351
ctab_is_alpha, // 352
ctab_is_alpha, // 353
ctab_is_alpha, // 354
ctab_is_alpha, // 355
ctab_is_alpha, // 356
ctab_is_alpha, // 357
ctab_is_alpha, // 360
ctab_is_alpha, // 361
ctab_is_alpha, // 362
ctab_is_alpha, // 363
ctab_is_alpha, // 364
ctab_is_alpha, // 365
ctab_is_alpha, // 366
ctab_is_alpha, // 367
ctab_is_alpha, // 370
ctab_is_alpha, // 371
ctab_is_alpha, // 372
ctab_is_alpha, // 373
ctab_is_alpha, // 374
ctab_is_alpha, // 375
ctab_is_alpha, // 376
ctab_is_alpha // 377
};
int
format_rcs_gram_lex(void)
{
static stracc_t buffer;
int c;
ctab_ty d;
for (;;)
{
c = ip->getch();
if (c < 0)
{
trace(("EOF\n"));
return 0;
}
d = ctab[c];
switch (d)
{
default:
trace(("JUNK\n"));
return JUNK;
case ctab_is_space:
break;
case ctab_is_alpha:
buffer.clear();
for (;;)
{
buffer.push_back(c);
c = ip->getch();
if (c < 0)
break;
d = ctab[c];
switch (d)
{
case ctab_is_alpha:
case ctab_is_digit:
continue;
default:
if (c >= 0)
ip->ungetc(c);
break;
}
break;
}
format_rcs_gram_lval.lv_string = buffer.mkstr();
if (keyword_expected)
{
table_ty *tp =
(table_ty *)
symtab_query(stp, format_rcs_gram_lval.lv_string);
if (tp)
{
str_free(format_rcs_gram_lval.lv_string);
format_rcs_gram_lval.lv_string = 0;
keyword_expected = 0;
trace(("%s\n", tp->name));
return tp->value;
}
}
trace(("IDENTIFIER \"%s\"\n",
format_rcs_gram_lval.lv_string->str_text));
return IDENTIFIER;
case ctab_is_digit:
buffer.clear();
for (;;)
{
buffer.push_back(c);
c = ip->getch();
if (c < 0)
break;
d = ctab[c];
switch (d)
{
case ctab_is_digit:
continue;
default:
if (c >= 0)
ip->ungetc(c);
break;
}
break;
}
format_rcs_gram_lval.lv_string = buffer.mkstr();
trace(("NUMBER \"%s\"\n",
format_rcs_gram_lval.lv_string->str_text));
return NUMBER;
case ctab_is_string:
buffer.clear();
for (;;)
{
c = ip->getch();
if (c < 0)
break;
d = ctab[c];
if (d == ctab_is_string)
{
c = ip->getch();
if (c < 0)
break;
d = ctab[c];
if (d != ctab_is_string)
{
ip->ungetc(c);
break;
}
}
buffer.push_back(c);
}
format_rcs_gram_lval.lv_string = buffer.mkstr();
trace(("STRING\n"));
return STRING;
case ctab_is_colon:
trace(("COLON\n"));
return COLON;
case ctab_is_semi:
keyword_expected = 1;
trace(("SEMI\n"));
return SEMI;
}
}
}
void
rcs_lex_keyword_expected(void)
{
keyword_expected = 1;
}