48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross/*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * This file and its contents are supplied under the terms of the
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * Common Development and Distribution License ("CDDL"), version 1.0.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * You may only use this file in accordance with the terms of version
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * 1.0 of the CDDL.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross *
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * A full copy of the text of the CDDL should have accompanied this
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * source. A copy of the CDDL is also available via the Internet at
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * http://www.illumos.org/license/CDDL.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross/*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross/*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * This file contains the "scanner", which tokenizes charmap files
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * for iconv for processing by the higher level grammar processor.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <stdio.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <stdlib.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <ctype.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <limits.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <string.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <widec.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <sys/types.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include <assert.h>
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include "charmap.h"
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#include "parser.tab.h"
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint com_char = '#';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint esc_char = '\\';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint mb_cur_min = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint mb_cur_max = MB_LEN_MAX;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint lineno = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint warnings = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int nextline;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic FILE *input = stdin;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic const char *filename = "<stdin>";
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int instring = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int escaped = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross/*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * Token space ... grows on demand.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic char *token = NULL;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int tokidx;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int toksz = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int hadtok = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross/*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * The last keyword seen. This is useful to trigger the special lexer rules
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * for "copy" and also collating symbols and elements.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint last_kw = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int category = T_END;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic struct token {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int id;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross const char *name;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross} keywords[] = {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_COM_CHAR, "comment_char" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_ESC_CHAR, "escape_char" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_END, "END" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * These are keywords used in the charmap file. Note that
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * Solaris orginally used angle brackets to wrap some of them,
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * but we removed that to simplify our parser. The first of these
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * items are "global items."
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_CHARMAP, "CHARMAP" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_WIDTH, "WIDTH" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_WIDTH_DEFAULT, "WIDTH_DEFAULT" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { -1, NULL },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross};
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross/*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * These special words are only used in a charmap file, enclosed in <>.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic struct token symwords[] = {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_COM_CHAR, "comment_char" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_ESC_CHAR, "escape_char" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_CODE_SET, "code_set_name" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_MB_CUR_MAX, "mb_cur_max" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { T_MB_CUR_MIN, "mb_cur_min" },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross { -1, NULL },
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross};
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int categories[] = {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross T_CHARMAP,
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross 0
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross};
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossvoid
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossreset_scanner(const char *fname)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (fname == NULL) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross filename = "<stdin>";
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross input = stdin;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross } else {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (input != stdin)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross (void) fclose(input);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if ((input = fopen(fname, "r")) == NULL) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross perror(fname);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross exit(1);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross filename = fname;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross com_char = '#';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross esc_char = '\\';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross instring = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross escaped = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross lineno = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross nextline = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross tokidx = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross last_kw = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross category = T_END;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#define hex(x) \
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross (isdigit(x) ? (x - '0') : ((islower(x) ? (x - 'a') : (x - 'A')) + 10))
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross#define isodigit(x) ((x >= '0') && (x <= '7'))
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossscanc(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c = getc(input);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross lineno = nextline;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == '\n') {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross nextline++;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic void
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossunscanc(int c)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == '\n') {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross nextline--;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (ungetc(c, input) < 0) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("ungetc failed"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossscan_hex_byte(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c1, c2;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int v;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c1 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isxdigit(c1)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("malformed hex digit"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (0);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c2 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isxdigit(c2)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("malformed hex digit"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (0);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross v = ((hex(c1) << 4) | hex(c2));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (v);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossscan_dec_byte(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c1, c2, c3;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int b;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c1 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isdigit(c1)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("malformed decimal digit"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (0);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b = c1 - '0';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c2 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isdigit(c2)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("malformed decimal digit"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (0);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b *= 10;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b += (c2 - '0');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c3 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isdigit(c3)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c3);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross } else {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b *= 10;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b += (c3 - '0');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (b);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossscan_oct_byte(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c1, c2, c3;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int b;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c1 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isodigit(c1)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("malformed octal digit"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (0);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b = c1 - '0';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c2 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isodigit(c2)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("malformed octal digit"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (0);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b *= 8;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b += (c2 - '0');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c3 = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!isodigit(c3)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c3);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross } else {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b *= 8;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross b += (c3 - '0');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (b);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossvoid
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossadd_tok(int c)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if ((tokidx + 1) >= toksz) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross toksz += 64;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if ((token = realloc(token, toksz)) == NULL) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("out of memory"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross tokidx = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross toksz = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross token[tokidx++] = (char)c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross token[tokidx] = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossget_byte(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if ((c = scanc()) != esc_char) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (EOF);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross c = scanc();
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross switch (c) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'd':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'D':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (scan_dec_byte());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'x':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'X':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (scan_hex_byte());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '0':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '1':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '2':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '3':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '4':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '5':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '6':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '7':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* put the character back so we can get it */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (scan_oct_byte());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross default:
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(esc_char);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (EOF);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossget_escaped(int c)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross switch (c) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'n':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return ('\n');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'r':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return ('\r');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 't':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return ('\t');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'f':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return ('\f');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'v':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return ('\v');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'b':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return ('\b');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case 'a':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return ('\a');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross default:
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossget_wide(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* NB: yylval.mbs[0] is the length */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross char *mbs = &yylval.mbs[1];
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int mbi = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross mbs[mbi] = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (mb_cur_max > MB_LEN_MAX) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("max multibyte character size too big"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NULL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross for (;;) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if ((c = get_byte()) == EOF)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross break;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (mbi == mb_cur_max) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("length > mb_cur_max"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NULL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross mbs[mbi++] = c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross mbs[mbi] = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* result in yylval.mbs */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross mbs[-1] = mbi;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_CHAR);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossget_symbol(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross while ((c = scanc()) != EOF) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (escaped) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross escaped = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == '\n')
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross add_tok(get_escaped(c));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == esc_char) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross escaped = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == '\n') { /* well that's strange! */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("unterminated symbolic name"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == '>') { /* end of symbol */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * This restarts the token from the beginning
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * the next time we scan a character. (This
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * token is complete.)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (token == NULL) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("missing symbolic name"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NULL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross tokidx = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * A few symbols are handled as keywords outside
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * of the normal categories.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (category == T_END) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int i;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross for (i = 0; symwords[i].name != 0; i++) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (strcmp(token, symwords[i].name) ==
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross 0) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross last_kw = symwords[i].id;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (last_kw);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* its an undefined symbol */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.token = strdup(token);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (yylval.token == NULL) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross perror("malloc");
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross exit(1);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross token = NULL;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross toksz = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross tokidx = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_SYMBOL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross add_tok(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("unterminated symbolic name"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (EOF);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossstatic int
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossconsume_token(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int len = tokidx;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int i;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross tokidx = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (token == NULL)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NULL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * this one is special, because we don't want it to alter the
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * last_kw field.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (strcmp(token, "...") == 0) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_ELLIPSIS);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* search for reserved words first */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross for (i = 0; keywords[i].name; i++) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int j;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (strcmp(keywords[i].name, token) != 0) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross last_kw = keywords[i].id;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* clear the top level category if we're done with it */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (last_kw == T_END) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross category = T_END;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* set the top level category if we're changing */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross for (j = 0; categories[j]; j++) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (categories[j] != last_kw)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross category = last_kw;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (keywords[i].id);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* maybe its a numeric constant? */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (isdigit(*token) || (*token == '-' && isdigit(token[1]))) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross char *eptr;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.num = strtol(token, &eptr, 10);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (*eptr != 0)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yyerror(_("malformed number"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NUMBER);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * A single lone character is treated as a character literal.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * To avoid duplication of effort, we stick in the charmap.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (len == 1) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[0] = 1; /* length */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[1] = token[0];
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[2] = '\0';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_CHAR);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* anything else is treated as a symbolic name */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.token = strdup(token);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross token = NULL;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross toksz = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross tokidx = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NAME);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossvoid
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossscan_to_eol(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross while ((c = scanc()) != '\n') {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == EOF) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* end of file without newline! */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross errf(_("missing newline"));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross assert(c == '\n');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossint
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossyylex(void)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross int c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross while ((c = scanc()) != EOF) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* special handling for quoted string */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (instring) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (escaped) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross escaped = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* if newline, just eat and forget it */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == '\n')
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (strchr("xXd01234567", c)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(esc_char);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (get_wide());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[0] = 1; /* length */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[1] = get_escaped(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[2] = '\0';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_CHAR);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == esc_char) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross escaped = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross switch (c) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '<':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (get_symbol());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '>':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* oops! should generate syntax error */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_GT);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '"':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross instring = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_QUOTE);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross default:
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[0] = 1; /* length */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[1] = c;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross yylval.mbs[2] = '\0';
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_CHAR);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* escaped characters first */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (escaped) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross escaped = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == '\n') {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* eat the newline */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (tokidx) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* an escape mid-token is nonsense */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NULL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* numeric escapes are treated as wide characters */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (strchr("xXd01234567", c)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(esc_char);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (get_wide());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross add_tok(get_escaped(c));
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* if it is the escape charter itself note it */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == esc_char) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross escaped = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* remove from the comment char to end of line */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (c == com_char) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross while (c != '\n') {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if ((c = scanc()) == EOF) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* end of file without newline! */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (EOF);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross assert(c == '\n');
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!hadtok) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * If there were no tokens on this line,
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * then just pretend it didn't exist at all.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (strchr(" \t\n;()<>,\"", c) && (tokidx != 0)) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * These are all token delimiters. If there
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * is a token already in progress, we need to
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * process it.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross unscanc(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (consume_token());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross switch (c) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '\n':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross if (!hadtok) {
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /*
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * If the line was completely devoid of tokens,
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross * then just ignore it.
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* we're starting a new line, reset the token state */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 0;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_NL);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case ',':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_COMMA);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case ';':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_SEMI);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '(':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_LPAREN);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case ')':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_RPAREN);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '>':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_GT);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '<':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* symbol start! */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (get_symbol());
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case ' ':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '\t':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross /* whitespace, just ignore it */
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross case '"':
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross instring = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (T_QUOTE);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross default:
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross hadtok = 1;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross add_tok(c);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross continue;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross }
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross return (EOF);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossvoid
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossyyerror(const char *msg)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross (void) fprintf(stderr, _("%s: %d: error: %s\n"),
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross filename, lineno, msg);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross exit(1);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossvoid
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rosserrf(const char *fmt, ...)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross char *msg;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross va_list va;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross va_start(va, fmt);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross (void) vasprintf(&msg, fmt, va);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross va_end(va);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross (void) fprintf(stderr, _("%s: %d: error: %s\n"),
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross filename, lineno, msg);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross free(msg);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross exit(1);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rossvoid
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Rosswarn(const char *fmt, ...)
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross{
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross char *msg;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross va_list va;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross va_start(va, fmt);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross (void) vasprintf(&msg, fmt, va);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross va_end(va);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross (void) fprintf(stderr, _("%s: %d: warning: %s\n"),
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross filename, lineno, msg);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross free(msg);
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross warnings++;
48edc7cf07b5dccc3ad84bf2dafe4150bd666d60Gordon Ross}