/* --------------------------------------------------------------------- * File: exp.l * (input file for flex - read config files for Eis/Fair) * * Copyright (C) 2006 * Daniel Vogel, * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * --------------------------------------------------------------------- */ %{ #include "global.h" #include "exp.h" #ifndef FALSE #define FALSE 0 #define TRUE !FALSE #endif #ifdef ECHO #undef ECHO #endif #define YY_NO_UNPUT #define STRING_BLOCK 128 ErrorCallback ExpError = NULL; int ExpCurrentLine; char* ExpInputFile = NULL; char* ExpStringBuf = NULL; int ExpStringBufLen = 0; int ExpStringBufPos = 0; int ExpStringML = FALSE; int ExpStringNL = FALSE; void ExpAddString(const char* text,int len); %} COND_IDENTIFIER [A-Z][A-Z0-9_]*\([A-Z][A-Z0-9_%]*(=~\'[^\']*\')?\) IDENTIFIER [A-Z][A-Z0-9_]* STR_ELEM \\\\|\\\'|[^'\n] STRING \'{STR_ELEM}*\' MLSTR_ELEM \\\\|\\\'|[^'] MLSTRING \'({MLSTR_ELEM}*[\n])*\' NL [\n] COLON [:] EQUAL [=] ADD [+] SPACE [ ]+ CR [\r] TAB [\t] COMMENT [#] ANYCHAR . %x COMMENT %x SQSTRING %x DQSTRING %% {COMMENT} { BEGIN(COMMENT); } {NL} { ExpCurrentLine++; BEGIN(INITIAL); } {ANYCHAR} /* */ \' { BEGIN(SQSTRING); ExpStringBuf[0] = 0; ExpStringBufPos = 0; ExpStringML = FALSE; ExpStringNL = FALSE; } \' { BEGIN(INITIAL); return ExpStringML ? EXP_MLSTRING : EXP_STRING; } {CR} /* */ {NL} { ExpCurrentLine++; ExpStringML = TRUE; ExpStringNL = TRUE; ExpAddString(" ",1); } {SPACE}|{TAB} { if (!ExpStringNL) { ExpAddString(exptext,expleng); } } [^'\n\r\t ]+ { ExpAddString(exptext,expleng); ExpStringNL = FALSE; } <> { BEGIN(INITIAL); if (ExpError) { ExpError( "Unterminated string constant!", ExpInputFile, ExpCurrentLine, FALSE ); } return EXP_EOF; } \" { BEGIN(DQSTRING); ExpStringBuf[0] = 0; ExpStringBufPos = 0; ExpStringML = FALSE; ExpStringNL = FALSE; } \" { BEGIN(INITIAL); return ExpStringML ? EXP_MLSTRING : EXP_STRING; } {CR} /* */ {NL} { ExpCurrentLine++; ExpStringML = TRUE; ExpStringNL = TRUE; ExpAddString(" ",1); } {SPACE}|{TAB} { if (!ExpStringNL) { ExpAddString(exptext,expleng); } } \\. { ExpAddString(exptext,expleng); ExpStringNL = FALSE; } [^"\\\n\r\t ]+ { ExpAddString(exptext,expleng); ExpStringNL = FALSE; } <> { BEGIN(INITIAL); if (ExpError) { ExpError( "Unterminated string constant!", ExpInputFile, ExpCurrentLine, FALSE ); } return EXP_EOF; } {COLON} { return EXP_COLON; } {EQUAL} { return EXP_EQUAL; } {ADD} { return EXP_ADD; } {IDENTIFIER} { return EXP_IDENT; } {COND_IDENTIFIER} { char * p = strchr(exptext, '('); if (p) *p = 0; return EXP_IDENT; } {NL} { ExpCurrentLine++; /* return EXP_NL;*/ } {CR} /* */ {SPACE}|{TAB} /* */ {ANYCHAR} { if (ExpError) { ExpError( "Unrecognised input!", ExpInputFile, ExpCurrentLine, FALSE ); } } <> { return EXP_EOF; } %% /* ----------------------------------------------------------------------- * ExpFileOpen * Open a file for reading and prepare the scanner * ----------------------------------------------------------------------- */ int ExpFileOpen(const char* filename, ErrorCallback errout) { expin = fopen(filename, "rt"); if (expin) { ExpInputFile = strdup(filename); ExpCurrentLine = 1; ExpError = errout; ExpStringBuf = (char*) malloc(STRING_BLOCK + 1); ExpStringBufLen = STRING_BLOCK; ExpStringBufPos = 0; } return expin != NULL; } /* ----------------------------------------------------------------------- * ExpRead * Read the next token from the file input * ----------------------------------------------------------------------- */ int ExpRead(void) { return yylex(); } /* ----------------------------------------------------------------------- * ExpClose * Close the file input * ----------------------------------------------------------------------- */ void ExpClose() { if (ExpInputFile) { free(ExpInputFile); ExpInputFile = NULL; } if (ExpStringBuf) { free(ExpStringBuf); ExpStringBuf = NULL; ExpStringBufLen = 0; } ExpError = NULL; fclose(expin); } /* ----------------------------------------------------------------------- * ExpGetText * Return the text read by the scanner. This can be an idetifier or an * regular expression * ----------------------------------------------------------------------- */ const char* ExpGetText(void) { return exptext; } /* ----------------------------------------------------------------------- * ExpGetString * Return the text read by the scanner yust after removing the quotes. * ----------------------------------------------------------------------- */ const char* ExpGetString(void) { if (ExpStringBufLen > 0) { return ExpStringBuf; } else { return ""; } } /* ----------------------------------------------------------------------- * ExpGetFileName * Return the name of the file the scanner is processing * ----------------------------------------------------------------------- */ const char* ExpGetFileName(void) { return ExpInputFile; } /* ----------------------------------------------------------------------- * ExpGetLineNumber * Return the current line number, the scanner input currently is on. * ----------------------------------------------------------------------- */ int ExpGetLineNumber(void) { return ExpCurrentLine; } /* ----------------------------------------------------------------------- * ExpRecoverFromError * Recover from a read error be consuming the rest of the line without * further action * ----------------------------------------------------------------------- */ int ExpRecoverFromError(void) { int sym = ExpRead(); while ((sym != EXP_IDENT)&&(sym != EXP_EOF)) { sym = ExpRead(); } return sym; } /* ----------------------------------------------------------------------- * expwrap * Is called when the scanner reaches the end of the input stream. * To activate the standard procedure it is necessary to return a value * != 0 * ----------------------------------------------------------------------- */ int expwrap () { return 1; } /* ----------------------------------------------------------------------- * CfgAddString * Add a character or string to the string buffer. Reallocate if the * buffer is not large enought. * ----------------------------------------------------------------------- */ void ExpAddString(const char* text,int len) { if (ExpStringBufPos + len >= ExpStringBufLen) { int newlen = ((ExpStringBufPos + len) / STRING_BLOCK + 1) * STRING_BLOCK; char* newstr = (char*) malloc(newlen + 1); if (newstr) { strcpy(newstr, ExpStringBuf); free(ExpStringBuf); ExpStringBuf = newstr; ExpStringBufLen = newlen; } else { return; } } strncpy(&ExpStringBuf[ExpStringBufPos],text,len); ExpStringBufPos += len; ExpStringBuf[ExpStringBufPos] = 0; }