%{ /* * Copyright 1991 Klaus Zitzmann, 1993-1996 Johannes Sixt * * Permission to use, copy, modify and distribute this software and its * documentation for any purpose other than its commercial exploitation * is hereby granted without fee, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation. The authors * make no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied warranty. * * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Klaus Zitzmann * Johannes Sixt */ #include /* need FILE */ #ifndef SYSV #include #else #include #endif #include #include /* atof */ #include /* needed for X stuff in objects.h */ #include "objects.h" #include "yyscan.h" #define yywrap() 1 float yyfloatval; /* value of a TOK_FLOAT */ char yystrval[MAX_TEXT_LEN+1]; /* text of a text argument or align argument */ Unit yyunit; /* value of a TOK_UNIT */ /* these are prototypes of functions defined by lex */ int yylook(void); int yyback(int *p, int m); /* we do the line counting ourselves */ int lineno = 1; static enum {gtNo,gtNext,gtForceNext,gtForceNext2} getText; /* specifies if text argument is possible or not: gtNo not possible gtNext possible after next { gtForceNext must come after next { gtForceNext2 must come after second next { */ #define TRUE 1 #define FALSE 0 static int getUnitLen; /* TRUE if \unitlength is read */ static int getUnit; /* TRUE if unit of \unitlength is read */ static char *readText(unsigned numBr); %} %s inPictEnv inPut lookOut white [ \t] digit [0-9] letter [A-Za-z] sign [+-] %% {white}+ { /* ignore */ } "%".*\n { /* ignore LaTeX comments */ ++lineno; } \n { ++lineno; } \\unitlength= | \\setlength\{\\unitlength\} { getUnitLen = TRUE; } {sign}?{digit}+ | {sign}?{digit}*"."{digit}* { if(getUnitLen) { yyfloatval = (float) atof(yytext); getUnitLen = FALSE; getUnit = TRUE; return TOK_UNITLENGTH; } } [Pp][Tt] {if(getUnit) { getUnit = FALSE; yyunit = UnitPT; return TOK_UNIT; } } [Cc][Mm] {if(getUnit) { getUnit = FALSE; yyunit = UnitCM; return TOK_UNIT; } } [Mm][Mm] {if(getUnit) { getUnit = FALSE; yyunit = UnitMM; return TOK_UNIT; } } [Pp][Cc] {if(getUnit) { getUnit = FALSE; yyunit = UnitPC; return TOK_UNIT; } } [Ii][Nn] {if(getUnit) { getUnit = FALSE; yyunit = UnitIN; return TOK_UNIT; } } [Bb][Pp] {if(getUnit) { getUnit = FALSE; yyunit = UnitBP; return TOK_UNIT; } } [Dd][Dd] {if(getUnit) { getUnit = FALSE; yyunit = UnitDD; return TOK_UNIT; } } [Cc][Cc] {if(getUnit) { getUnit = FALSE; yyunit = UnitCC; return TOK_UNIT; } } [Ss][Pp] {if(getUnit) { getUnit = FALSE; yyunit = UnitSP; return TOK_UNIT; } } [Ee][Mm] {if(getUnit) { getUnit = FALSE; yyunit = UnitEM; return TOK_UNIT; } } \\begin\{picture\} {BEGIN inPictEnv; return TOK_BEGIN;} . {if (yytext[0] == '\n') ++lineno; } \\bezier | \\qbezier{white}*\[ {return TOK_BEZIER;} \\qbezier {return TOK_QBEZIER;} \\put {BEGIN inPut; return TOK_PUT;} \\framebox {getText = gtForceNext; BEGIN inPictEnv; return TOK_FRAMEBOX;} \\makebox {getText = gtForceNext; BEGIN inPictEnv; return TOK_MAKEBOX;} \\dashbox {getText = gtForceNext2; BEGIN inPictEnv; return TOK_DASHBOX;} \\line {BEGIN inPictEnv; return TOK_LINE;} \\vector {BEGIN inPictEnv; return TOK_VECTOR;} \\circle {BEGIN inPictEnv; return TOK_CIRCLE;} \\circle\* {BEGIN inPictEnv; return TOK_CIRCLE_AST;} \\oval {BEGIN inPictEnv; return TOK_OVAL;} \\rule {BEGIN inPictEnv; return TOK_RULE;} \} {/* empty text */ yystrval[0] = '\0'; BEGIN inPictEnv; return TOK_TEXT;} . {/* non-empty text */ yystrval[0] = yytext[0]; if (yytext[0] == '\n') ++lineno; strcpy(&yystrval[1], readText(yytext[0] == '{')); BEGIN inPictEnv; return TOK_TEXT;} \\unitlength { return TOK_DIM_UNITLENGTH; } [Pp][Tt] { yyunit = UnitPT; return TOK_UNIT; } [Cc][Mm] { yyunit = UnitCM; return TOK_UNIT; } [Mm][Mm] { yyunit = UnitMM; return TOK_UNIT; } [Pp][Cc] { yyunit = UnitPC; return TOK_UNIT; } [Ii][Nn] { yyunit = UnitIN; return TOK_UNIT; } [Bb][Pp] { yyunit = UnitBP; return TOK_UNIT; } [Dd][Dd] { yyunit = UnitDD; return TOK_UNIT; } [Cc][Cc] { yyunit = UnitCC; return TOK_UNIT; } [Ss][Pp] { yyunit = UnitSP; return TOK_UNIT; } [Ee][Mm] { yyunit = UnitEM; return TOK_UNIT; } {sign}?{digit}+ | {sign}?{digit}*"."{digit}* {yyfloatval = (float) atof(yytext); return TOK_FLOAT;} \{ { if(getText == gtForceNext) { (void) strcpy(yystrval,readText(0)); getText = gtNo; return TOK_TEXT; } else if(getText == gtForceNext2) getText = gtForceNext;} \{ BEGIN lookOut; \} {/* ignore */} [(),\[\]] {/* ignore */} \\end\{picture\} {return TOK_END;} \[{letter}+\] { strcpy(yystrval,&yytext[1]); yystrval[yyleng - 1] = '\0'; return TOK_LETTERS_OPT;} \\thicklines {return TOK_THICKLINE;} \\thinlines {return TOK_THINLINE;} . {fprintf(stderr, "yylex: unrecognized char '%c' (%#X) in line %d\n", yytext[0], yytext[0], lineno); if (yytext[0] == '\n') ++lineno; } %% /* * Initializes the input file. The file must already be open! */ void yyinitscan(FILE *fp) { yyin = fp; lineno = 1; BEGIN INITIAL; getUnitLen = FALSE; getUnit = FALSE; } /* yyinitscan */ /* * Reads in text which comes as argument to a command up to the closing * brace. Copes with nested { and }. The returned value does NOT include * the delimiting braces. * THE RESULT IS ONLY VALID UNTIL THE NEXT CALL!! */ char *readText(unsigned numBr) { static char text[MAX_TEXT_LEN+1]; unsigned i = 0; char ch; unsigned numBraces = numBr + 1; int start_line = lineno; /* pre: (numBr + 1) '{' is already read */ while (numBraces > 0) { text[i++] = ch = input(); if (ch == '\0') { /* end of file */ (void) fprintf(stderr, "end of file in text on line %d\n", start_line); return text; } switch (ch) { case '{': numBraces++; break; case '}': numBraces--; break; case '\n': ++lineno; break; } if (i >= MAX_TEXT_LEN) { (void) fprintf(stderr, "text argument on line %d too long\n", lineno); break; } } /* if numBraces > 0, then text arg was too long; skip to end of text arg */ while (numBraces > 0 && (ch = input()) != '\0') { switch (ch) { case '{': numBraces++; break; case '}': numBraces--; break; case '\n': ++lineno; break; } } text[--i] = '\0'; return text; }