%{ /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "mod_python", or "modpython", nor may these terms appear in their * name, without prior written permission of the Apache Software * Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * * $Id: psp_parser.l,v 1.15 2003/08/11 20:13:03 grisha Exp $ * * This file originally written by Sterling Hughes. * */ /* NOTE The seemingly unusual generated Python code (sometime using * ";" to separate statements, newline placement, etc) is such that * for vast majority of cases the line number of the input file will * match the line number of the output! */ #include "psp_parser.h" #define OUTPUT_WHITESPACE(__wsstring) \ psp_string_0((__wsstring)); \ psp_string_append(&PSP_PG(pycode), (__wsstring)->blob) #define CLEAR_WHITESPACE(__wsstring) psp_string_clear((__wsstring)); %} %option noyywrap nounistd %x TEXT %x PYCODE %x INDENT %x DIR %x COMMENT %% \r\n|\n { psp_string_appendl(&PSP_PG(pycode), STATIC_STR("req.write(\"\"\"")); yyless(0); BEGIN TEXT; } . { psp_string_appendl(&PSP_PG(pycode), STATIC_STR("req.write(\"\"\"")); yyless(0); BEGIN TEXT; } "<%=" { /* expression */ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\"); req.write(str(")); PSP_PG(is_psp_echo) = 1; BEGIN PYCODE; } "<%" { /* python code */ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\");")); CLEAR_WHITESPACE(&PSP_PG(whitespace)); PSP_PG(seen_newline) = 0; BEGIN PYCODE; } "<%@" { /* directive */ BEGIN DIR; } "<%--" { /* comment */ BEGIN COMMENT; } \r\n|\n { psp_string_appendc(&PSP_PG(pycode), '\n'); } . { if (yytext[0] == '"') { psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\\\"")); } else { psp_string_appendc(&PSP_PG(pycode), yytext[0]); } } <> { yypop_buffer_state(yyscanner); if (!YY_CURRENT_BUFFER) { /* this is really the end */ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\")\n")); yyterminate(); } else { /* we are inside include, continue scanning */ BEGIN DIR; } } \r\n|\n { psp_string_appendc(&PSP_PG(pycode), '\n'); PSP_PG(seen_newline) = 1; BEGIN INDENT; } "%>" { if (PSP_PG(is_psp_echo)) { psp_string_appendl(&PSP_PG(pycode), STATIC_STR(")); req.write(\"\"\"")); PSP_PG(is_psp_echo) = 0; } else { if (!PSP_PG(seen_newline)) { /* this will happen is you have <%%> */ psp_string_appendc(&PSP_PG(pycode), ';'); } if (PSP_PG(after_colon)) { /* this is dumb mistake-proof measure, if %> is immediately following where there should be an indent */ psp_string_appendc(&PSP_PG(whitespace), '\t'); PSP_PG(after_colon) = 0; } OUTPUT_WHITESPACE(&PSP_PG(whitespace)); psp_string_appendl(&PSP_PG(pycode), STATIC_STR("req.write(\"\"\"")); } BEGIN TEXT; } ":" { psp_string_appendc(&PSP_PG(pycode), yytext[0]); PSP_PG(after_colon) = 1; } . { psp_string_appendc(&PSP_PG(pycode), yytext[0]); PSP_PG(after_colon) = 0; } ^[\t ]* { CLEAR_WHITESPACE(&PSP_PG(whitespace)); psp_string_appendl(&PSP_PG(whitespace), yytext, yyleng); psp_string_appendl(&PSP_PG(pycode), yytext, yyleng); BEGIN PYCODE; } "%>" { yyless(0); BEGIN PYCODE; } \r\n|\n { CLEAR_WHITESPACE(&PSP_PG(whitespace)); yyless(0); BEGIN PYCODE; } . { CLEAR_WHITESPACE(&PSP_PG(whitespace)); yyless(0); BEGIN PYCODE; } "include"[ ]+"file"[ ]?=[ ]?"\""[^ ]+"\"" { char *filename; char *path; FILE *f; /* find a quote */ filename = strchr(yytext, '"') + 1; filename[strchr(filename, '"')-filename] = '\0'; if (PSP_PG(dir)) { path = malloc(strlen(filename)+strlen(PSP_PG(dir))+1); if (path == NULL) { PyErr_NoMemory(); yyterminate(); } strcpy(path, PSP_PG(dir)); strcat(path, filename); } else { path = filename; } Py_BEGIN_ALLOW_THREADS f = fopen(path, "rb"); Py_END_ALLOW_THREADS if (f == NULL) { PyErr_SetFromErrnoWithFilename(PyExc_IOError, path); } else { yypush_buffer_state(yy_create_buffer(f, YY_BUF_SIZE, yyscanner), yyscanner); BEGIN(TEXT); } if (PSP_PG(dir)) free(path); } "%>" { BEGIN TEXT; } "--%>" { BEGIN TEXT; } %% /* this is for emacs Local Variables: mode:C End: */