%{ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include #include #include #include #include "iconv_tm.h" #include "itmcomp.h" #include "y.tab.h" static itm_data_t *hexadecimal_data(int, char *); static itm_data_t *name_data(int, char *); static void filename_lineno(void); static int at_name_to_token(char *); %} %start norm comment DECIMAL ([0-9]+) OCTAL (0[0-7][0-7]+) HEXADECIMAL (("0x"|"0X")([0-9A-Fa-f])+) ITMNAME (([^% \t\n\r])+"%"([^% \t\n\r])+) ATNAME "@"([0-9A-Za-z_]+) NAME ([A-Za-z_][A-Za-z0-9_]*) MAPTYPE_NAME (automatic|dense|index|hash|binary) %% [ \t\n]+ ; "//".*"\n" ; ^"#"[ \t]*{DECIMAL}[ \t]*"\"".*"\"".*"\n" { filename_lineno(); } ^"#".*"\n" { if (NULL == cmd_opt.preprocess) { itm_error( gettext("warning: " "preprocess may be required\n")); } } {DECIMAL} { yylval.num = strtoul(yytext, (char **)NULL, 10); return (DECIMAL); } {OCTAL} { yylval.num = strtoul(yytext, (char **)NULL, 8); return (DECIMAL); } {HEXADECIMAL} { yylval.data = hexadecimal_data(yyleng - 2, yytext + 2); return (HEXADECIMAL); } {ITMNAME} { yylval.data = str_to_data(yyleng, yytext); return (ITMNAME); } {ATNAME} { return at_name_to_token(yytext); } {MAPTYPE_NAME} { yylval.num = at_name_to_token(yytext); yylval.data = name_data(yyleng, yytext); return (MAPTYPE_NAME); } {NAME} { yylval.num = at_name_to_token(yytext); if (0 != yylval.num) { return (yylval.num); } else { yylval.data = name_data(yyleng, yytext); return (NAME); } } "{" {return (CBO);} "}" {return (CBC);} "[" {return (SBO);} "]" {return (SBC);} "(" {return (PO);} ")" {return (PC);} ";" {return (SC);} "," {return (COMMA);} ":" {return (COLON);} "..." {return (ELLIPSES);} "=" {return (ASSIGN);} "||" {return (LOR);} "&&" {return (LAND);} "|" {return (OR);} "^" {return (XOR);} "&" {return (AND);} "==" {return (EQ);} "!=" {return (NE);} "<" {return (LT);} "<=" {return (LE);} ">" {return (GT);} ">=" {return (GE);} "<<" {return (SHL);} ">>" {return (SHR);} "+" {return (PLUS);} "-" {return (MINUS);} "*" {return (MUL);} "/" {return (DIV);} "%" {return (MOD);} "!" {return (NOT);} "~" {return (NEG);} . { itm_error( gettext("Unrecognized token '%1$c' \n"), cmd_opt.my_name, yytext[0]); return (0); } %% /* * lexinit - starts the Lexical Analyzer off in the right start condition */ void lexinit() { BEGIN norm; } /* does this really need to be here? */ int yywrap() { return (1); } void yyerror(char *s) { extern int yylineno; itm_error( gettext("%1$s: file(%2$s) line(%3$d) last token(%4$s)\n"), s, itm_input_file, yylineno, yytext); exit(ITMC_STATUS_BT); } typedef struct { char *name; int token; } at_name_token_t; /* * NOT: This table must be sorted alphabetically. */ static at_name_token_t at_table[] = { "@automatic", MAPTYPE_AUTO, "@binary", MAPTYPE_BINARY, "@between", BETWEEN, "@condition", CONDITION, "@default", ITM_DEFAULT, "@dense", MAPTYPE_DENSE, "@direction", DIRECTION, "@discard", DISCARD, "@else", ITM_ELSE, "@error", ERROR, "@escapeseq", ESCAPESEQ, "@false", ITM_FALSE, "@hash", MAPTYPE_HASH, "@identical", ITM_IDENTICAL, "@if", ITM_IF, "@in", ITM_IN, "@index", MAPTYPE_INDEX, "@init", ITM_INIT, "@input", ITM_IN, "@inputsize", ITM_INSIZE, "@map", MAP, "@maptype", MAPTYPE, "@no_change_copy", ITM_IDENTICAL, "@nop", NOP, "@operation", OPERATION, "@out", ITM_OUT, "@output", ITM_OUT, "@output_byte_length", RESULTLEN, "@outputsize", ITM_OUTSIZE, "@printchr", PRINTCHR, "@printhd", PRINTHD, "@printint", PRINTINT, "@reset", RESET, "@resultlen", RESULTLEN, "@return", RETURN, "@true", ITM_TRUE, "automatic", MAPTYPE_AUTO, "between", BETWEEN, "binary", MAPTYPE_BINARY, "break", BREAK, "condition", CONDITION, "default", ITM_DEFAULT, "dense", MAPTYPE_DENSE, "direction", DIRECTION, "discard", DISCARD, "else", ITM_ELSE, "error", ERROR, "escapeseq", ESCAPESEQ, "false", ITM_FALSE, "hash", MAPTYPE_HASH, "if", ITM_IF, "index", MAPTYPE_INDEX, "init", ITM_INIT, "input", ITM_IN, "inputsize", ITM_INSIZE, "map", MAP, "maptype", MAPTYPE, "no_change_copy", ITM_IDENTICAL, "nop", NOP, "operation", OPERATION, "output", ITM_OUT, "output_byte_length", RESULTLEN, "outputsize", ITM_OUTSIZE, "printchr", PRINTCHR, "printhd", PRINTHD, "printint", PRINTINT, "reset", RESET, "return", RETURN, "true", ITM_TRUE, }; int at_name_to_token(char *s) { int high; int mid; int low; int result; TRACE_MESSAGE('l', ("at_name_to_token: %s", s)); for (low = 0, high = (sizeof (at_table) / sizeof (at_name_token_t)); low < high; /* NOP */) { mid = (low + high) / 2; result = strcmp(s, at_table[mid].name); if (result < 0) { high = mid; } else if (0 < result) { low = mid + 1; } else { /* 0 == result */ TRACE_MESSAGE('l', (" %d\n", at_table[mid].token)); return (at_table[mid].token); } } TRACE_MESSAGE('l', (" - not found\n")); return (0); } static itm_data_t * hexadecimal_data(int seqsize, char *seq) { itm_data_t *data; char *binary; int i, j; int val; int high; int low; int size; /* size is assured to be multiple of 2 */ assert(seqsize != 0); size = seqsize + 1; size /= 2; if (size > MAXSEQUENCE) { itm_error( gettext(" specified sequence must be less than %$1d\n"), MAXSEQUENCE); return (NULL); } binary = malloc_vital(size); i = j = 0; if (seqsize % 2 != 0) { low = *(seq); if (('0' <= low) && (low <= '9')) { val = (low - '0'); } else if (('a' <= low) && (low <= 'f')) { val = (low - 'a' + 10); } else if (('A' <= low) && (low <= 'F')) { val = (low - 'A' + 10); } *(binary + i) = val; i++; j++; } for (/* NOP */; i < size; i++, j += 2) { high = *(seq + j); low = *(seq + j + 1); if (('0' <= high) && (high <= '9')) { val = ((high - '0') << 4); } else if (('a' <= high) && (high <= 'f')) { val = ((high - 'a' + 10) << 4); } else if (('A' <= high) && (high <= 'F')) { val = ((high - 'A' + 10) << 4); } if (('0' <= low) && (low <= '9')) { val |= (low - '0'); } else if (('a' <= low) && (low <= 'f')) { val |= (low - 'a' + 10); } else if (('A' <= low) && (low <= 'F')) { val |= (low - 'A' + 10); } *(binary + i) = val; } data = malloc_vital(sizeof (itm_data_t)); data->size = size; if (size <= sizeof (data->place)) { (void) memmove(&(data->place), binary, size); free(binary); } else { data->place.itm_ptr = (itm_place2_t)binary; } return (data); } static itm_data_t * name_data(int size, char *seq) { itm_data_t *data; if (size > MAXNAMELENGTH) { itm_error(gettext("the length(%d) exceed limitation(%d)"), size, MAXNAMELENGTH); exit(ITMC_STATUS_BT2); } data = malloc_vital(sizeof (itm_data_t)); data->size = size; if (size <= sizeof (data->place)) { (void) memmove(&(data->place), seq, size); } else { data->place.itm_ptr = (itm_place2_t)malloc_vital(size); (void) memmove((char *)(data->place.itm_ptr), seq, size); } return (data); } static void filename_lineno(void) { static char *re; static char restr[] = "^#[ \t]*\\([0-9]\\{1,\\}\\)[ \t]*\"\\(.*\\)\".*"; int match; extern char *braslist[]; extern char *braelist[]; static char *filename; int len; int lineno; if (NULL == re) { re = compile(restr, NULL, NULL); if (NULL == re) { itm_error( gettext("REGEXP compile error\n")); exit(ITMC_STATUS_BT); } } match = step(yytext, re); if (0 != match) { lineno = atoi(braslist[0]); free(filename); len = braelist[1] - braslist[1]; filename = malloc_vital(len + 1); (void) memcpy(filename, braslist[1], len); *(filename + len) = '\0'; itm_input_file = filename; yylineno = lineno; } }