/* --------------------------------------------------------------------- * File: exp.l * (input file for flex - read config files for Eis/Fair) * * Copyright (C) 2006 * Daniel Vogel, * * Last Update: $Id$ * * 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 "xml.h" #ifndef FALSE #define FALSE 0 #define TRUE !FALSE #endif #ifdef ECHO #undef ECHO #endif #define YY_NO_UNPUT #define DATA_BLOCK 128 ErrorCallback XmlErrorHook = NULL; int XmlCurrentLine; char* XmlInputFile = NULL; char* XmlDataBuf = NULL; int XmlDataBufLen = 0; int XmlDataBufPos = 0; int XmlSpace = FALSE; int XmlProcessNL = FALSE; void XmlAddData(const char* text,int len); void XmlAddEntity(const char* text,int len); %} IDENTIFIER [A-Za-z][A-Za-z0-9_-]* STR_ELEM \\\\|\\\"|[^"\n] STRING \"{STR_ELEM}*\" ENTITY \&[a-zA-Z]+\; COMMENTOPEN TAGOPEN [<] TAGCLOSE [>] NL [\n] EQUAL [=] AMPERSAND [&] DIVIDE [/] DASH [-] SPACE [ ]+ CR [\r] TAB [\t] LINE_COMMENT ^[#] DATA [^ \n\r\t<&]+ COMMENTDATA [^ \n\r\t-] ANYCHAR . %x LCOMMENT %x COMMENT %x TAG %% {LINE_COMMENT} { BEGIN(LCOMMENT); } {NL} { XmlCurrentLine++; BEGIN(INITIAL); } {ANYCHAR} /* */ {COMMENTOPEN} { BEGIN(COMMENT); return XML_COMMENTOPEN; } {COMMENTCLOSE} { BEGIN(INITIAL); return XML_COMMENTCLOSE; } {CR} /* ignore CR's in DOS files */ {NL} { XmlCurrentLine++; XmlAddData("\n",1); XmlSpace = FALSE; } {SPACE}|{TAB} { if (!XmlSpace && (XmlDataBufPos != 0)) { XmlSpace = TRUE; } } {COMMENTDATA} { if (XmlSpace) { XmlAddData(" ",1); XmlSpace = FALSE; } XmlAddData(xmltext,xmlleng); } {DASH} { if (XmlSpace) { XmlAddData(" ",1); XmlSpace = FALSE; } XmlAddData("-",1); } <> { XmlErrorHook( "Unterminated comment block!", XmlInputFile, XmlCurrentLine, FALSE ); } {TAGOPEN} { BEGIN(TAG); return XML_TAGOPEN; } {IDENTIFIER} { return XML_IDENT; } {TAGCLOSE} { BEGIN(INITIAL); return XML_TAGCLOSE; } {EQUAL} { return XML_EQUAL; } {DIVIDE} { return XML_DIVIDE; } {STRING} { return XML_STRING; } {NL} { XmlCurrentLine++; } {CR} /* */ {SPACE}|{TAB} /* */ {ANYCHAR} { if (XmlErrorHook) { XmlErrorHook( "Unrecognised input within tag definition!", XmlInputFile, XmlCurrentLine, FALSE ); } } <> { XmlErrorHook( "Unclosed tag!", XmlInputFile, XmlCurrentLine, FALSE ); } {CR} /* ignore CR's in DOS files */ {NL} { XmlCurrentLine++; if (XmlProcessNL) { XmlAddData("\n",1); XmlSpace = FALSE; } else if (XmlDataBufPos != 0) { XmlSpace = TRUE; } } {SPACE}|{TAB} { if (!XmlSpace && (XmlDataBufPos != 0)) { XmlSpace = TRUE; } } {ENTITY} { if (XmlSpace) { XmlAddData(" ",1); XmlSpace = FALSE; } XmlAddEntity(xmltext,xmlleng); } {DATA} { if (XmlSpace) { XmlAddData(" ",1); XmlSpace = FALSE; } XmlAddData(xmltext,xmlleng); } {AMPERSAND} { if (XmlSpace) { XmlAddData(" ",1); XmlSpace = FALSE; } XmlAddData("&",1); } <> { return XML_EOF; } %% /* ----------------------------------------------------------------------- * XmlFileOpen * Open a file for reading and prepare the scanner * ----------------------------------------------------------------------- */ int XmlFileOpen(const char* filename, ErrorCallback errout) { xmlin = fopen(filename, "rt"); if (xmlin) { XmlInputFile = strdup(filename); XmlCurrentLine = 1; XmlErrorHook = errout; XmlDataBuf = (char*) malloc(DATA_BLOCK + 1); XmlDataBufLen = DATA_BLOCK; XmlDataBufPos = 0; XmlClearData(); } return xmlin != NULL; } /* ----------------------------------------------------------------------- * XmlRead * Read the next token from the file input * ----------------------------------------------------------------------- */ int XmlRead(void) { return yylex(); } /* ----------------------------------------------------------------------- * XmlClose * Close the file input * ----------------------------------------------------------------------- */ void XmlClose() { if (XmlInputFile) { free(XmlInputFile); XmlInputFile = NULL; } if (XmlDataBuf) { free(XmlDataBuf); XmlDataBuf = NULL; XmlDataBufLen = 0; } XmlErrorHook = NULL; fclose(xmlin); } /* ----------------------------------------------------------------------- * XmlParseNL * Return the text read by the scanner. This can be an idetifier or an * regular expression * ----------------------------------------------------------------------- */ void XmlParseNL(int state) { XmlProcessNL = state; } /* ----------------------------------------------------------------------- * XmlGetText * Return the text read by the scanner. This can be an idetifier or an * regular expression * ----------------------------------------------------------------------- */ const char* XmlGetText(void) { return xmltext; } /* ----------------------------------------------------------------------- * XmlGetString * Return the text read by the scanner yust after removing the quotes. * ----------------------------------------------------------------------- */ const char* XmlGetString(void) { int len = strlen(xmltext); if (len > 2) { xmltext[len - 1] = 0; return &xmltext[1]; } else { return ""; } } /* ----------------------------------------------------------------------- * ExpGetData * Return the data read by the scanner. * ----------------------------------------------------------------------- */ const char* XmlGetData(void) { if (XmlDataBufLen > 0) { return XmlDataBuf; } else { return ""; } } /* ----------------------------------------------------------------------- * XmlClearData * Clear the data buffer * ----------------------------------------------------------------------- */ void XmlClearData(void) { XmlSpace = FALSE; XmlDataBuf[0] = 0; XmlDataBufPos = 0; } /* ----------------------------------------------------------------------- * XmlGetFileName * Return the name of the file the scanner is processing * ----------------------------------------------------------------------- */ const char* XmlGetFileName(void) { return XmlInputFile; } /* ----------------------------------------------------------------------- * XmlGetLineNumber * Return the current line number, the scanner input currently is on. * ----------------------------------------------------------------------- */ int XmlGetLineNumber(void) { return XmlCurrentLine; } /* ----------------------------------------------------------------------- * XmlRecoverFromError * Recover from a read error be consuming the rest of the line without * further action * ----------------------------------------------------------------------- */ int XmlRecoverFromError(int nextsym) { int sym = XmlRead(); while ((sym != nextsym)&&(sym != XML_EOF)) { sym = XmlRead(); } return sym; } /* ----------------------------------------------------------------------- * xmlwrap * 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 xmlwrap () { return 1; } /* ----------------------------------------------------------------------- * XmlAddData * Add a character or string to the data buffer. Reallocate if the * buffer is not large enought. * ----------------------------------------------------------------------- */ void XmlAddData(const char* text,int len) { if (XmlDataBufPos + len >= XmlDataBufLen) { int newlen = ((XmlDataBufPos + len) / DATA_BLOCK + 1) * DATA_BLOCK; char* newstr = (char*) malloc(newlen + 1); if (newstr) { strcpy(newstr, XmlDataBuf); free(XmlDataBuf); XmlDataBuf = newstr; XmlDataBufLen = newlen; } else { return; } } strncpy(&XmlDataBuf[XmlDataBufPos],text,len); XmlDataBufPos += len; XmlDataBuf[XmlDataBufPos] = 0; } /* ----------------------------------------------------------------------- * XmlAddEntity * Add a xml entity to the current data block * ----------------------------------------------------------------------- */ void XmlAddEntity(const char* text,int len) { if (strncmp(text,"ä",len)==0) { XmlAddData("ä",1); } else if (strncmp(text,"Ä",len)==0) { XmlAddData("Ä",1); } else if (strncmp(text,"ö",len)==0) { XmlAddData("ö",1); } else if (strncmp(text,"Ö",len)==0) { XmlAddData("Ö",1); } else if (strncmp(text,"ü",len)==0) { XmlAddData("ü",1); } else if (strncmp(text,"Ü",len)==0) { XmlAddData("Ü",1); } else if (strncmp(text,"ßl;",len)==0) { XmlAddData("ß",1); } else if (strncmp(text,"<",len)==0) { XmlAddData("<",1); } else if (strncmp(text,">",len)==0) { XmlAddData(">",1); } else if (strncmp(text,"&",len)==0) { XmlAddData("&",1); } else if (strncmp(text,""",len)==0) { XmlAddData("\"",1); } else if (strncmp(text," ",len)==0) { XmlAddData(" ",1); } else { XmlAddData(text, len); } }