CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

MacroTags.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2009, 2010 by Ilya A. Volynets-Evenbakh                  *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include "StdTagBase.h"
00022 #include <ctype.h>
00023 #include <sstream>
00024 
00025 using namespace servlet::taglib;
00026 using namespace std;
00027 
00028 namespace csp
00029 {
00030 namespace tags
00031 {
00032 
00041 class DefineTag: public StdTagBase
00042 {
00043 protected:
00044     typedef set<string> deflist_t;
00045     static deflist_t m_defines;
00046     string m_defname;
00047     stringstream func_body;
00048     bool with_servlet;
00049 public:
00050     DefineTag(const string& name)
00051         : StdTagBase(name)
00052     {}
00053     virtual void doStartTag(const attribs_t& attribs);
00054     virtual void doEndTag();
00055     virtual void initChildBuffers();
00056 };
00057 
00058 DefineTag::deflist_t DefineTag::m_defines;
00059 
00060 void DefineTag::initChildBuffers()
00061 {
00062     StdTagBase::initChildBuffers();
00063     m_child_body=&func_body;
00064 }
00065 
00066 void DefineTag::doStartTag(const Generator::attribs_t& attribs)
00067 {
00068     get_attr(attribs, "name", m_defname, "csp:define");
00069     if(m_defines.find(m_defname)!=m_defines.end())
00070         throw runtime_error(m_defname+" is already defined");
00071     string params;
00072     get_attr(attribs, "params", params, "csp:define");
00073     with_servlet = get_bool_attr(attribs, "with_servlet", "csp:define");
00074     stringstream s;
00075     s<<"protected:"<<endl;
00076     s<<"struct "<<m_defname<<"_t"<<endl;
00077     s<<"{"<<endl;
00078     s<<"    servlet::HttpServletRequest& request;"<<endl;
00079     s<<"    servlet::HttpServletResponse& response;"<<endl;
00080     s<<"    std::ostream& out;"<<endl;
00081     if(with_servlet)
00082         s<<"    servlet::HttpServlet& servlet;"<<endl;
00083     s<<"    "<<m_defname<<"_t (servlet::HttpServletRequest& req, servlet::HttpServletResponse& resp, std::ostream& o";
00084     if(with_servlet)
00085         s<<", servlet::HttpServlet& s";
00086     s<<")"<<endl;
00087     s<<"        : request(req)"<<endl;
00088     s<<"        , response(resp)"<<endl;
00089     s<<"        , out(o)"<<endl;
00090     if(with_servlet)
00091         s<<"        , servlet(s)"<<endl;
00092     s<<"    {}"<<endl;
00093     s<<"    void operator()("<<params<<")"<<endl;
00094     s<<"    {"<<endl;
00095     *member<<s.str();
00096 }
00097 
00098 void DefineTag::doEndTag()
00099 {
00100     *member<<func_body.rdbuf()<<endl;
00101     *member<<"  }"<<endl;
00102     *member<<"};";
00103     *member<<"private:"<<endl;
00104     *body<<m_defname<<"_t "<<m_defname<<"(request, response, out";
00105     if(with_servlet)
00106         *body<<", *this";
00107     *body<<");"<<endl;
00108     *body<<"/* end csp:define "<<m_defname<<" */"<<endl;
00109     m_defines.insert(m_defname);
00110 }
00111 
00115 class UseDefTag: public DefineTag
00116 {
00117 private:
00118     bool with_servlet;
00119 public:
00120     UseDefTag(const string& name)
00121         : DefineTag(name)
00122     {}
00123     virtual void doStartTag(const attribs_t& attribs);
00124     virtual void doEndTag();
00125     virtual void initChildBuffers();
00126 };
00127 
00128 void UseDefTag::initChildBuffers()
00129 {
00130     m_child_header = m_child_member = m_child_body=&func_body;
00131 }
00132 
00133 void UseDefTag::doStartTag(const Generator::attribs_t& attribs)
00134 {
00135     get_attr(attribs, "name", m_defname, "csp:usedef");
00136     if(m_defines.find(m_defname)!=m_defines.end())
00137         throw runtime_error(m_defname+" is already imported (usedefed)");
00138     with_servlet = get_bool_attr(attribs, "with_servlet", "csp:define");
00139 }
00140 
00141 void UseDefTag::doEndTag()
00142 {
00143     /*if(!func_body.str().empty())
00144       throw(runtime_error("<csp:usedef name=\""+m_defname+"\"> tag cannot have a body. Body contents:\"\n"+func_body.str()+"\n"));*/
00145     *body<<m_defname<<"_t "<<m_defname<<"(request, response, out";
00146     if(with_servlet)
00147         *body<<", *this";
00148     *body<<");"<<endl;
00149     m_defines.insert(m_defname);
00150 }
00151 
00158 class DefunTag: public DefineTag
00159 {
00160 public:
00161     DefunTag(const string& name)
00162         : DefineTag(name)
00163     {}
00164     virtual void doStartTag(const attribs_t& attribs);
00165     virtual void doEndTag();
00166 };
00167 
00168 void DefunTag::doStartTag(const Generator::attribs_t& attribs)
00169 {
00170     get_attr(attribs, "name", m_defname, "csp:defun");
00171     if(m_defines.find(m_defname)!=m_defines.end())
00172         throw runtime_error(m_defname+" is already defined");
00173     string params;
00174     get_attr(attribs, "params", params, "csp:defun");
00175     stringstream s;
00176     s<<"protected:"<<endl;
00177     s<<"    void "<<m_defname<<"(servlet::HttpServletRequest& request, servlet::HttpServletResponse& response, std::ostream& out";
00178     if(!params.empty()) {s<<","<<params;}
00179     s<<")";
00180     s<<"    {"<<endl;
00181     *member<<s.str();
00182 }
00183 
00184 void DefunTag::doEndTag()
00185 {
00186     *member<<func_body.rdbuf()<<endl;
00187     *member<<"  } /* end csp:defun "<<m_defname<<" */"<<endl;
00188     m_defines.insert(m_defname);
00189 }
00194 class CallTag: public DefineTag
00195 {
00196 public:
00197     CallTag(const string& name)
00198         : DefineTag(name)
00199     {}
00200     virtual void doStartTag(const attribs_t& attribs);
00201     virtual void doEndTag(){}
00202 };
00203 
00204 void CallTag::doStartTag(const Generator::attribs_t& attribs)
00205 {
00206     get_attr(attribs, "name", m_defname, "csp:call");
00207     string params;
00208     get_attr(attribs, "params", params, "csp:call");
00209     stringstream s;
00210     *body<<"    "<<m_defname<<"(request, response, out";
00211     if(!params.empty()) {*body<<","<<params;}
00212     *body<<");"<<endl;
00213 }
00214 
00215 }
00216 }
00217 
00218 DECLARE_COMPILE_TIME_TAGLIB(csp)
00219 EXPORT_COMPILE_TIME_TAG(csp, define, csp::tags::DefineTag)
00220 EXPORT_COMPILE_TIME_TAG(csp, usedef, csp::tags::UseDefTag)
00221 EXPORT_COMPILE_TIME_TAG(csp, defun,  csp::tags::DefunTag)
00222 EXPORT_COMPILE_TIME_TAG(csp, call,   csp::tags::CallTag)

SourceForge.net Logo