HTML-Template-Pro-0.9510/0000755000076400007640000000000012144122665013360 5ustar igorigorHTML-Template-Pro-0.9510/TODO0000644000076400007640000000356611302530536014055 0ustar igorigorHTML-Template-Pro TODO. ======================= 1. A few wrappers for languages other then perl and mono (php, java, maybe high-level C/glib and C++ wrappers) to prove the API is designed good enough to fit a vast majority of languages. 2. query() support. 3. Parsing of variable contents as well, allowing truly dynamic template generation. Example: $t->register_function( f1 => sub { return $filename ? "" : "some text"} ); Variants of proposed syntax: This change will require the change of C library API. It requires either callback for (add name/value pair to a current scope) or built-in json-c or libjson or both, as in case of assignments like someVAR=someNativeLOOPorOBJECT. something like scope -2 for built-in json root -1 for wrapper-dependent set root 0 for wrapper-dependent param root Proscope: add is_scope_writeable flag. 5. add Pro::Compat (Compat::Pro??) 1) Compat inherits most of its code from Pro 1) Compat is_a HTML::Template, HTML::Template::Expr. 2) use old param_to_lowercase 3) has default case_sensitive=0 4) has option html_template_strict_mode=1 (enables use of perl _find_file); 6. add option expr: logical should return one of args 7. C htmltmplpro C API: add interface call ABSTRACT_MAP* get_root_scope (param, int POS); FLAGS can be user-provided SET scope, main root scope, case_transform flags etc. 8. Rewrite documentation - split C API documentation or merge perl and C docs. Find a place to document template_root hack. 10. rewrite scanner using re2c HTML-Template-Pro-0.9510/pstring.h0000644000076400007640000000304011251467341015215 0ustar igorigor/*! \file pstring.h * \brief string type. * * \author Igor Vlasenko * \warning This header file should never be included directly. * Include instead. */ #ifndef _PSTRING_H #define _PSTRING_H 1 /** \struct PSTRING \brief string type used in htmltmplpro. \code typedef struct PSTRING { const char* begin; const char* endnext; } PSTRING; \endcode The string is delimited by two pointers, begin and endnext. The length of the string is calculated as endnext - begin. The empty string has begin == endnext. \warning It is possible for empty string to have begin == endnext == NULL. \warning Contents of the memory area, passed as PSTRING, should always be treated as const. \warning Contents of the memory area, passed as PSTRING, can be destroyed after the callback function completed. To be used afterwards the string content should be copied. */ typedef struct PSTRING { const char* begin; /*!< pointer to begin of the string. */ const char* endnext; /*!< pointer to the byte next to the last char of the string. */ } PSTRING; /** \struct MPSTRING \brief Modifiable PSTRING. \code typedef struct MPSTRING { char* begin; char* endnext; } PSTRING; \endcode The same as PSTING, but in non-constant memory. */ typedef struct MPSTRING { char* begin; /*!< pointer to begin of the string. */ char* endnext; /*!< pointer to the byte next to the last char of the string. */ } MPSTRING; #endif /* pstring.h */ HTML-Template-Pro-0.9510/pabidecl.h0000644000076400007640000000256211237574706015312 0ustar igorigor/*! \file pabidecl.h \brief calling conventions. * APICALL and BACKCALL can be something like __stdcall or __cdecl (compiler-specific). * APICALL set the calling convention for exported symbols. * BACKCALL set the calling convention for callback pointers. * By default, the code uses C standard (Cdecl) calling conventions. * One can override the calling conventions by defining their own * APICALL and BACKCALL macro. */ #ifndef _PABIDECL_H #define _PABIDECL_H 1 #ifdef __cplusplus #define TMPLPRO_EXTERN_C extern "C" #else #define TMPLPRO_EXTERN_C #endif #if defined( __WIN32__ ) || defined( _WIN32 ) || defined __CYGWIN__ # define TMPLPRO_HIDDEN_SYM # if defined(HTMLTMPLPRO_STATIC) # define TMPLPRO_EXPORT_SYM # else # if defined( htmltmplpro_EXPORTS ) || defined (DLL_EXPORT) # define TMPLPRO_EXPORT_SYM __declspec(dllexport) # else # define TMPLPRO_EXPORT_SYM __declspec(dllimport) # endif # endif #elif __GNUC__ >= 4 # define TMPLPRO_EXPORT_SYM __attribute__ ((visibility("default"))) # define TMPLPRO_HIDDEN_SYM __attribute__ ((visibility("hidden"))) #else # define TMPLPRO_EXPORT_SYM # define TMPLPRO_HIDDEN_SYM #endif #ifndef APICALL #define APICALL #endif #ifndef BACKCALL #define BACKCALL #endif #define TMPLPRO_API TMPLPRO_EXTERN_C TMPLPRO_EXPORT_SYM #define API_IMPL TMPLPRO_EXPORT_SYM #define TMPLPRO_LOCAL TMPLPRO_HIDDEN_SYM #endif /* pabidecl.h */ HTML-Template-Pro-0.9510/ARTISTIC0000644000076400007640000001373710724553105014537 0ustar igorigor The "Artistic License" Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. "Copyright Holder" is whoever is named in the copyright or copyrights for the package. "You" is you, if you're thinking about copying or distributing this Package. "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. 7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. 8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End HTML-Template-Pro-0.9510/builtin_findfile.inc0000644000076400007640000003215211436234014017357 0ustar igorigor/* * File: builtin_findfile.c * Author: Igor Vlasenko * Created: Tue Jul 14 22:47:11 2009 */ #include /* for isalpha */ #include /* for getenv */ /* TODO: support CYGWIN * see * http://sourceware.org/autobook/autobook/autobook_249.html */ #if defined __CYGWIN32__ && !defined __CYGWIN__ /* For backwards compatibility with Cygwin b19 and earlier, we define __CYGWIN__ here, so that we can rely on checking just for that macro. */ # define __CYGWIN__ __CYGWIN32__ #endif #if defined _WIN32 && !defined __CYGWIN__ /* Use Windows separators on all _WIN32 defining environments, except Cygwin. */ # define DIR_SEPARATOR_CHAR '\\' #endif #if defined (DIR_SEPARATOR_CHAR) # define IS_FILE_SEP(X) ((X=='/') || (X==DIR_SEPARATOR_CHAR)) #else # define IS_FILE_SEP(X) (X=='/') #endif static int _ff_exists(const char* path) { FILE *file_p = fopen(path, "r"); if (file_p) { fclose(file_p); if (debuglevel>=TMPL_LOG_DEBUG2) tmpl_log(TMPL_LOG_DEBUG2,"_ff_exists: found [%s]\n",path); return 1; } if (debuglevel>=TMPL_LOG_DEBUG2) tmpl_log(TMPL_LOG_ERROR,"_ff_exists: not found [%s]\n",path); return 0; } /* lame dirname implementation */ static PSTRING _ff_dirname(const char* path) { PSTRING retval={(char*)path,(char*)path}; char c=0; if (path!=NULL) retval.endnext += strlen(path); else return retval; while (retval.endnext > retval.begin && (c=*(--retval.endnext)) && ! IS_FILE_SEP(c)); /*fprintf(stderr,"built-in _ff_dirname: dir = %.*s\n",(int)(retval.endnext-retval.begin),retval.begin);*/ return retval; } /* Windows Relative Paths For functions that manipulate files, the file names can be relative to the current directory. A file name is relative to the current directory if it does not begin with one of the following: * A UNC name of any format. * A disk designator with a backslash, for example "C:\". * A backslash, for example, "\directory"). */ /* remember about \\?\ and \\?\UNC\ prefixes on WIN platform. * see "File Names, Paths, and Namespaces" * http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx */ int _ff_is_absolute(const char * filename) { unsigned char c0 = *filename; #if defined _WIN32 || defined __CYGWIN__ unsigned char c1; unsigned char c2; #endif if ('\0' == c0) return 0; /* \\?\ and \\?\UNC\ prefixes are included too */ if (IS_FILE_SEP(c0)) return 1; #if defined _WIN32 || defined __CYGWIN__ c1 = *(++filename); if ('\0' == c1) return 0; c2 = *(++filename); if (isalpha(c0) && ':'==c1 && IS_FILE_SEP(c2)) return 1; #endif return 0; } #if defined _WIN32 || defined __CYGWIN__ int _ff_is_win_fully_qualified_path(const char * filename) { unsigned char c0 = *filename; unsigned char c1; unsigned char c2; if ('\0' == c0) return 0; c1 = *(++filename); if ('\0' == c1) return 0; c2 = *(++filename); /* \\?\ and \\?\UNC\ prefixes are included too */ if (isalpha(c0) && ':'==c1 && IS_FILE_SEP(c2)) return 1; if ('\\'==c0 && '\\'==c1 && '?'==c2 && '\\'==*filename) return 1; return 0; } #endif #define _ff_canonical_path(X) (X) static MPSTRING _shift_back_pstring_at(MPSTRING buf, char* pos, long shift) { if (pos >= buf.begin && (pos+shift) <=buf.endnext) { buf.endnext -= shift; while (pos1) && ('\\'==*pos && '\\'==*(pos+1))) pos += 2; #endif while (pos1) && isalpha((unsigned char) *pos) && ':'==*(pos+1)) { pos += 2; slash_begin += 2; } #endif prev_slash_next = slash_begin; while (pos leave one slash */ buf=_shift_back_pstring_at(buf, prev_slash_next, pos-prev_slash_next+3); pos=prev_slash_next-1;/* 1 to compensate pos++ */ } else { buf=_shift_back_pstring_at(buf, prev_slash_next, pos-prev_slash_next+4); pos=prev_slash_next-2;/* 2 to compensate / and pos++ */ /* 2 to step back slashnext char and 'slash' char, if any */ if (prev_slash_next>slash_begin) prev_slash_next--; if (prev_slash_next>slash_begin) prev_slash_next--; } /* old prev_slash_next now current, so we need to recalculate it */ /* first find a 'slash' char */ while (prev_slash_next>=slash_begin && !IS_FILE_SEP(*prev_slash_next)) prev_slash_next--; if (prev_slash_next>slash_begin) prev_slash_next++;/* step next to slash */ } else { prev_slash_next=pos+1; } } pos++; } /* // <-- shift -1 */ buf=_filepath_remove_multiple_slashes(buf); /* offset 0: if ./ shift -2 */ if ((buf.endnext-buf.begin)<2) return buf.begin; pos = buf.begin; if (('.'==*pos) && IS_FILE_SEP(*(pos+1))) buf=_shift_back_pstring_at(buf, pos, 2); return buf.begin; } static MPSTRING _ff_add_pstr_to_buffer(MPSTRING buf, PSTRING pstr) { MPSTRING ret = buf; const char* s; //tmpl_log(TMPL_LOG_ERROR,"_ff_add_pstr_to_buffer: called as [%p,%p]+[%p,%p]\n",buf.begin,buf.endnext, pstr.begin,pstr.endnext); for (s=pstr.begin;sret.begin && IS_FILE_SEP(*(ret.endnext-1))) return ret; #ifdef DIR_SEPARATOR_CHAR *(ret.endnext++)=DIR_SEPARATOR_CHAR; #else *(ret.endnext++)='/'; #endif return ret; } static MPSTRING _ff_add_0_to_buffer(MPSTRING buf) { *(buf.endnext++)='\0'; return buf; } static const char* get_template_root(struct tmplpro_param* param) { const char* retval = param->template_root; if (NULL==retval) retval = getenv("HTML_TEMPLATE_ROOT"); return retval; } static const char* _find_file (struct tmplpro_param* param, const char* filename, PSTRING extra_dir) { // TODO: finish it const char* HTML_TEMPLATE_ROOT = get_template_root(param); size_t HTML_TEMPLATE_ROOT_length=0; size_t buffsize=0; char** pathlist=param->path; MPSTRING pbuf_begin, filepath; if (param->debug >= TMPL_LOG_DEBUG2) { tmpl_log(TMPL_LOG_DEBUG2,"built-in _find_file: looking for %s extra dir = %.*s\n",filename, (int)(extra_dir.endnext-extra_dir.begin),extra_dir.begin); if (HTML_TEMPLATE_ROOT) tmpl_log(TMPL_LOG_DEBUG2,"built-in _find_file: HTML_TEMPLATE_ROOT = %s\n",HTML_TEMPLATE_ROOT); } /* first check for a full path */ if (_ff_is_absolute(filename) && _ff_exists(filename)) return _ff_canonical_path(filename); #if defined _WIN32 || defined __CYGWIN__ /* no sense of prefixing C:\ or \\?\ */ if (_ff_is_win_fully_qualified_path(filename)) { tmpl_log(TMPL_LOG_DEBUG2,"built-in _ff_is_win_fully_qualified_path: rejected %s: is_absolute=%d exists=%d\n",filename,_ff_is_absolute(filename),_ff_exists(filename)); return NULL; } #endif if (HTML_TEMPLATE_ROOT!=NULL) HTML_TEMPLATE_ROOT_length=strlen(HTML_TEMPLATE_ROOT); if (pathlist!=NULL) { while (NULL!=*pathlist) { size_t pathentrylen=strlen(*pathlist); if (buffsizebuiltin_findfile_buffer, buffsize); pbuf_begin.begin=pbuffer_string(¶m->builtin_findfile_buffer); pbuf_begin.endnext=pbuf_begin.begin; /* try the extra_path if one was specified */ if (extra_dir.begin!=NULL) { filepath=_ff_add_pstr_to_buffer(pbuf_begin,extra_dir); if (extra_dir.endnext-extra_dir.begin >0) filepath=_ff_add_sep_to_buffer(filepath); filepath=_ff_add_str_to_buffer(filepath,filename); filepath=_ff_add_0_to_buffer(filepath); if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath); } /* try pre-prending HTML_Template_Root */ if (HTML_TEMPLATE_ROOT!=NULL) { filepath=_ff_add_str_to_buffer(pbuf_begin,HTML_TEMPLATE_ROOT); if (HTML_TEMPLATE_ROOT_length >0) filepath=_ff_add_sep_to_buffer(filepath); filepath=_ff_add_str_to_buffer(filepath,filename); filepath=_ff_add_0_to_buffer(filepath); if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath); } /* try "path" option list.. */ pathlist=param->path; if (pathlist!=NULL) { while (NULL!=*pathlist) { //tmpl_log(TMPL_LOG_ERROR,"try 'path' option list..: looking in [%s]\n",*pathlist); filepath=_ff_add_str_to_buffer(pbuf_begin,*pathlist); /* add separator only if *pathlist non-empty */ if (0!=**pathlist) filepath=_ff_add_sep_to_buffer(filepath); filepath=_ff_add_str_to_buffer(filepath,filename); filepath=_ff_add_0_to_buffer(filepath); if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath); pathlist++; } } /* try even a relative path from the current directory...*/ if (_ff_exists(filename)) return _ff_canonical_path(filename); /* try "path" option list with HTML_TEMPLATE_ROOT prepended... */ if (HTML_TEMPLATE_ROOT!=NULL) { pathlist=param->path; if (pathlist!=NULL) { while (NULL!=*pathlist) { filepath=_ff_add_str_to_buffer(pbuf_begin,HTML_TEMPLATE_ROOT); if (HTML_TEMPLATE_ROOT_length >0) filepath=_ff_add_sep_to_buffer(filepath); filepath=_ff_add_str_to_buffer(filepath,*pathlist); /* add separator only if *pathlist non-empty */ if (0!=**pathlist) filepath=_ff_add_sep_to_buffer(filepath); filepath=_ff_add_str_to_buffer(filepath,filename); filepath=_ff_add_0_to_buffer(filepath); if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath); pathlist++; } } } return NULL; } static const char* BACKCALL stub_find_file_func(ABSTRACT_FINDFILE* param,const char* filename, const char* last_visited_file) { const char* filepath; PSTRING extra_path ={NULL,NULL}; if (filename == last_visited_file) tmpl_log(TMPL_LOG_ERROR,"built-in find_file: internal error: buffer clash for %s\n",filename); if (((struct tmplpro_param*)param)->debug>= TMPL_LOG_DEBUG) tmpl_log(TMPL_LOG_DEBUG,"built-in find_file: looking for %s last_visited_file = %s\n",filename, last_visited_file); // look for the included file... if (last_visited_file!=NULL && ! ((struct tmplpro_param*) param)->search_path_on_include) { extra_path = _ff_dirname(last_visited_file); } filepath = _find_file((struct tmplpro_param*)param,filename,extra_path); if (filepath==NULL) { char** path=((struct tmplpro_param*)param)->path; const char* HTML_TEMPLATE_ROOT = get_template_root((struct tmplpro_param*)param); tmpl_log(TMPL_LOG_ERROR,"built-in find_file: can't find file %s", filename); if (NULL!=last_visited_file) tmpl_log(TMPL_LOG_ERROR," (included from %s)", last_visited_file); if(HTML_TEMPLATE_ROOT!=NULL) { tmpl_log(TMPL_LOG_ERROR," with HTML_TEMPLATE_ROOT = '%s'",HTML_TEMPLATE_ROOT); } if (NULL!=path) { tmpl_log(TMPL_LOG_ERROR," with path = ["); while (NULL!=*path) { tmpl_log(TMPL_LOG_ERROR," '%s'",*path); path++; } tmpl_log(TMPL_LOG_ERROR," ]"); } else { tmpl_log(TMPL_LOG_ERROR," with empty path list"); } tmpl_log(TMPL_LOG_ERROR,"\n"); return NULL; } else { return filepath; } } /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/pstrutils.h0000644000076400007640000000073111245553124015602 0ustar igorigor/* -*- c -*- * File: pstring.h * Author: Igor Vlasenko * Created: Fri Jul 1 20:11:51 2005 * * $Id$ */ #ifndef _PSTRUTILS_H #define _PSTRUTILS_H 1 #include "pbuffer.h" static PSTRING lowercase_pstring (pbuffer*, PSTRING); static int is_pstring_true (PSTRING s); static PSTRING escape_pstring (pbuffer* StrBuffer, PSTRING pstring, int escapeopt); /* static void lowercase_pstring_inplace (PSTRING pstring); */ #endif /* pstrutils.h */ HTML-Template-Pro-0.9510/pabstract.h0000644000076400007640000004425611255623456015535 0ustar igorigor/*! \file pabstract.h \brief description of callbacks. In order to interact with core library a wrapper should provide some callback functions. This file specifies which callbacks can be provided. \author Igor Vlasenko \warning This header file should never be included directly. Include instead. */ #ifndef _PROABSTRACT_H #define _PROABSTRACT_H 1 #include "pstring.h" #include "pabidecl.h" struct tmplpro_param; struct exprval; typedef void ABSTRACT_WRITER; typedef void ABSTRACT_FINDFILE; typedef void ABSTRACT_FILTER; typedef void ABSTRACT_CALLER; typedef void ABSTRACT_DATASTATE; typedef void ABSTRACT_ARRAY; typedef void ABSTRACT_MAP; typedef void ABSTRACT_VALUE; typedef void ABSTRACT_FUNCMAP; typedef void ABSTRACT_ARGLIST; typedef void ABSTRACT_USERFUNC; typedef struct exprval ABSTRACT_EXPRVAL; typedef void BACKCALL (*writer_functype) (ABSTRACT_WRITER*,const char* begin, const char* endnext); typedef ABSTRACT_VALUE* BACKCALL (*get_ABSTRACT_VALUE_functype) (ABSTRACT_DATASTATE*, ABSTRACT_MAP*, PSTRING name); typedef PSTRING BACKCALL (*ABSTRACT_VALUE2PSTRING_functype) (ABSTRACT_DATASTATE*, ABSTRACT_VALUE*); /* optional */ typedef int BACKCALL (*is_ABSTRACT_VALUE_true_functype) (ABSTRACT_DATASTATE*, ABSTRACT_VALUE*); typedef ABSTRACT_ARRAY* BACKCALL (*ABSTRACT_VALUE2ABSTRACT_ARRAY_functype) (ABSTRACT_DATASTATE*, ABSTRACT_VALUE*); typedef int BACKCALL (*get_ABSTRACT_ARRAY_length_functype) (ABSTRACT_DATASTATE*, ABSTRACT_ARRAY*); typedef ABSTRACT_MAP* BACKCALL (*get_ABSTRACT_MAP_functype) (ABSTRACT_DATASTATE*, ABSTRACT_ARRAY*,int); /* optional notifier */ typedef void BACKCALL (*exit_loop_scope_functype) (ABSTRACT_DATASTATE*, ABSTRACT_ARRAY*); typedef const char* BACKCALL (*find_file_functype) (ABSTRACT_FINDFILE*, const char* filename, const char* prevfilename); /* optional; we can use wrapper to load file and apply its filters before running itself */ /* note that this function should allocate region 1 byte nore than the file size */ typedef PSTRING BACKCALL (*load_file_functype) (ABSTRACT_FILTER*, const char* filename); typedef int BACKCALL (*unload_file_functype) (ABSTRACT_FILTER*, PSTRING memarea); /* -------- Expr extension------------ */ /* those are needed for EXPR= extension */ typedef ABSTRACT_USERFUNC* BACKCALL (*is_expr_userfnc_functype) (ABSTRACT_FUNCMAP*, PSTRING name); typedef ABSTRACT_ARGLIST* BACKCALL (*init_expr_arglist_functype) (ABSTRACT_CALLER*); typedef void BACKCALL (*push_expr_arglist_functype) (ABSTRACT_ARGLIST*, ABSTRACT_EXPRVAL*); typedef void BACKCALL (*free_expr_arglist_functype) (ABSTRACT_ARGLIST*); typedef void BACKCALL (*call_expr_userfnc_functype) (ABSTRACT_CALLER*, ABSTRACT_ARGLIST*, ABSTRACT_USERFUNC*, ABSTRACT_EXPRVAL* return_value); /* ------- end Expr extension -------- */ #endif /* _PROABSTRACT_H */ /** \typedef typedef void (*writer_functype) (ABSTRACT_WRITER*,const char* begin, const char* endnext); \brief optional callback for writing or accumulating a piece of generated text. \param begin, endnext - pointers to memory area containing the output string. \param ABSTRACT_WRITER* - pointer stored by tmplpro_set_option_ext_writer_state() or NULL if nothing was stored. Note that outpot string is NOT 0-terminated. Instead, 2 pointers are used, as in PSTRING. This callback is called multiple times. This callback is optional: if not provided, a built-in stub will output to STDOUT. @see tmplpro_set_option_WriterFuncPtr @see tmplpro_set_option_ext_writer_state */ /** \typedef typedef ABSTRACT_VALUE* (*get_ABSTRACT_VALUE_functype) (ABSTRACT_MAP*, PSTRING name); \brief required callback to get a variable value. \param PSTRING name - a name as in <TMPL_VAR NAME="var1"> \param ABSTRACT_MAP* pointer returned by callback of get_ABSTRACT_MAP_functype. \return NULL if NAME not found or a non-null pointer to be passed to callback of ABSTRACT_VALUE2PSTRING_functype or ABSTRACT_VALUE2ABSTRACT_ARRAY_functype. @see tmplpro_set_option_GetAbstractValFuncPtr */ /** \typedef typedef PSTRING (*ABSTRACT_VALUE2PSTRING_functype) (ABSTRACT_VALUE*); \brief required callback to transform into PSTRING a variable name passed to callback of get_ABSTRACT_VALUE_functype. \param ABSTRACT_VALUE* optional pointer returned by callback of get_ABSTRACT_VALUE_functype. \return PSTRING to a memory area. The memery area can be safely freed in the next call to ABSTRACT_VALUE2PSTRING_functype. @see tmplpro_set_option_AbstractVal2pstringFuncPtr */ /** \typedef typedef int (*is_ABSTRACT_VALUE_true_functype) (ABSTRACT_VALUE*); \brief optional callback to fine-tune is ABSTRACT_VALUE* is true or false. \param ABSTRACT_VALUE* optional pointer returned by callback of get_ABSTRACT_VALUE_functype. \return 0(false) or 1(true). By default a stub is used that guesses true or false according to PSTRING form of ABSTRACT_VALUE. @see tmplpro_set_option_IsAbstractValTrueFuncPtr */ /** \typedef typedef ABSTRACT_ARRAY* (*ABSTRACT_VALUE2ABSTRACT_ARRAY_functype) (ABSTRACT_VALUE*); \brief required callback to transform into ABSTRACT_ARRAY a variable name passed to callback of get_ABSTRACT_VALUE_functype. \param ABSTRACT_VALUE* optional pointer returned by callback of get_ABSTRACT_VALUE_functype. \return NULL if NAME can not be converted to ABSTRACT_ARRAY or a non-null pointer that will be passed then to callbacks of get_ABSTRACT_ARRAY_length_functype and get_ABSTRACT_MAP_functype. @see tmplpro_set_option_AbstractVal2abstractArrayFuncPtr */ /** \typedef typedef int (*get_ABSTRACT_ARRAY_length_functype) (ABSTRACT_ARRAY*); \brief optional callback to specify a length of the loop. \param ABSTRACT_ARRAY* optional pointer returned by callback of ABSTRACT_VALUE2ABSTRACT_ARRAY_functype. \return the length of the loop or a special value of -1 that indicates that loop has an undefined length (useful when one need to iterate over large number of records in database or lines in a file). By default a stub is used that returns -1. @see tmplpro_set_option_GetAbstractArrayLengthFuncPtr */ /** \typedef typedef ABSTRACT_MAP* (*get_ABSTRACT_MAP_functype) (ABSTRACT_ARRAY*,int n); \brief required callback to transform into ABSTRACT_ARRAY a variable name passed to callback of get_ABSTRACT_VALUE_functype. \param ABSTRACT_ARRAY* optional pointer returned by callback of ABSTRACT_VALUE2ABSTRACT_ARRAY_functype. \param n - number of current loop iteration. \return NULL if loop can no nore be iterated or a non-null pointer that will be passed to callback of get_ABSTRACT_VALUE_functype. @see tmplpro_set_option_GetAbstractMapFuncPtr */ /** \typedef typedef void (*end_loop_functype) (ABSTRACT_MAP* root_param_map, int newlevel); \brief optional callback to notify a front-end that the current loop is exited. \param ABSTRACT_MAP* optional pointer stored by tmplpro_set_option_root_param_map(). \param newlevel current depth of nested loops (0 means a root scope). This callback is useful for front-end implementations which does not return pointers to real objects. In that case the corresponding ABSTRACT_MAP*, ABSTRACT_ARRAY*, and ABSTRACT_VALUE* pointers are fake non-null values, so instead of those pointers this callback can be used. @see tmplpro_set_option_EndLoopFuncPtr */ /** \typedef typedef void (*select_loop_scope_functype) (ABSTRACT_MAP* root_param_map, int level); \brief optional callback to select a loop. \param ABSTRACT_MAP* optional pointer stored by tmplpro_set_option_root_param_map(). \param int level level at which a loop will be selected. This callback is useful for front-end implementations which does not return pointers to real objects. In that case the corresponding ABSTRACT_MAP*, ABSTRACT_ARRAY*, and ABSTRACT_VALUE* pointers are fake non-null values, so instead of those pointers this callback can be used. @see tmplpro_set_option_SelectLoopScopeFuncPtr */ /** \typedef typedef const char* (*find_file_functype) (ABSTRACT_FINDFILE*, const char* filename, const char* prevfilename); \brief optional callback to fine-tune the algorythm of finding template file by name. \param ABSTRACT_FINDFILE* optional pointer stored by tmplpro_set_option_ext_writer_state(). \param filename file to be found. \param prevfilename fully qualified path to containing file, if any. \return fully qualified path to a file to be loaded. By default a stub is used (as of 0.82, with limited functionality). @see tmplpro_set_option_FindFileFuncPtr */ /** \typedef typedef PSTRING (*load_file_functype) (ABSTRACT_FILTER*, const char* filename); \brief optional callback to load and preprocess (filter) files. Only called if filters option is true (set by tmplpro_set_option_filters() ). \param ABSTRACT_FILTER* optional pointer stored by tmplpro_set_option_ext_filter_state(). \param filename fully qualified path to a file to be loaded (as returned by callback of find_file_functype). \return PSTRING of memory area loaded. @see tmplpro_set_option_filters @see tmplpro_set_option_LoadFileFuncPtr */ /** \typedef typedef int (*unload_file_functype) (ABSTRACT_FILTER*, PSTRING memarea); \brief optional callback to free memory accuired by a callback of load_file_functype. Only called if filters option is true (set by tmplpro_set_option_filters() ). \param ABSTRACT_FILTER* optional pointer stored by tmplpro_set_option_ext_filter_state(). \param memarea pointers to loaded area (as returned by callback of load_file_functype). \return 0 on success, non-zero otherwise. @see tmplpro_set_option_filters @see tmplpro_set_option_UnloadFileFuncPtr */ /** \typedef typedef ABSTRACT_USERFUNC* (*is_expr_userfnc_functype) (ABSTRACT_FUNCMAP*, PSTRING name); \brief optional callback for support of user-provided functions. \param ABSTRACT_FUNCMAP* optional pointer stored by tmplpro_set_option_expr_func_map(). \param name name of function \return NULL if there is no user function with such a name or non-null value to be passed to callback of call_expr_userfnc_functype. \warning if is_expr_userfnc_functype callback is set, then callbacks of init_expr_arglist_functype, push_expr_arglist_functype, free_expr_arglist_functype and call_expr_userfnc_functype also should be set. @see tmplpro_set_option_IsExprUserfncFuncPtr */ /** \typedef typedef ABSTRACT_ARGLIST* (*init_expr_arglist_functype) (ABSTRACT_CALLER*); \brief optional callback to initialize the list of arguments for a user-provided function. Note that if function calls are nested, then the calls to a callbacks of ::init_expr_arglist_functype, ::push_expr_arglist_functype, ::free_expr_arglist_functype will also be nested. \param ABSTRACT_CALLER* optional pointer stored by tmplpro_set_option_ext_calluserfunc_state(). \return value to be passed to callbacks of push_expr_arglist_functype, free_expr_arglist_functype and call_expr_userfnc_functype. @see tmplpro_set_option_InitExprArglistFuncPtr */ /** \typedef typedef void (*free_expr_arglist_functype) (ABSTRACT_ARGLIST*); \brief optional callback to release the list of arguments for a user-provided function. Note that if function calls are nested, then the calls to a callbacks of ::init_expr_arglist_functype, ::push_expr_arglist_functype, ::free_expr_arglist_functype will also be nested. \param ABSTRACT_ARGLIST* optional pointer returned by callback of init_expr_arglist_functype. @see tmplpro_set_option_FreeExprArglistFuncPtr */ /** \typedef typedef void (*push_expr_arglist_functype) (ABSTRACT_ARGLIST*, ABSTRACT_EXPRVAL*); \brief optional callback to add new value to the list of arguments for a user-provided function. Note that if function calls are nested, then the calls to a callbacks of ::init_expr_arglist_functype, ::push_expr_arglist_functype, ::free_expr_arglist_functype will also be nested. \param ABSTRACT_ARGLIST* optional pointer returned by callback of init_expr_arglist_functype. \param ABSTRACT_EXPRVAL* pointer required by tmplpro_get_expr_* functions to retrieve the value (a place the pushed value is stored). A value to be added to the list of arguments for a user-provided function is not passed as argument to a callback of push_expr_arglist_functype. Instead, a pointer to struct tmplpro_param is passed, and the callback function should discover the value's type using tmplpro_get_expr_type() function, and then should retrieve the value using one of the functions \li tmplpro_get_expr_as_int64() \li tmplpro_get_expr_as_double() \li tmplpro_get_expr_as_pstring() @see tmplpro_set_option_PushExprArglistFuncPtr */ /** \typedef typedef void (*call_expr_userfnc_functype) (ABSTRACT_CALLER*, ABSTRACT_ARGLIST*, ABSTRACT_USERFUNC*, ABSTRACT_EXPRVAL*); \brief optional callback to call a user-provided function with a current list of arguments. \param ABSTRACT_CALLER* optional pointer stored by tmplpro_set_option_ext_calluserfunc_state(). \param ABSTRACT_ARGLIST* optional pointer returned by callback of init_expr_arglist_functype. \param ABSTRACT_USERFUNC* optional pointer returned by callback of is_expr_userfnc_functype. \param ABSTRACT_EXPRVAL* pointer required by tmplpro_set_expr_as_* functions (a place the return value will be stored). To return the result user function returned the callback of call_expr_userfnc_functype should call one of the functions \li tmplpro_set_expr_as_null() \li tmplpro_set_expr_as_int64() \li tmplpro_set_expr_as_double() \li tmplpro_set_expr_as_string() \li tmplpro_set_expr_as_pstring() passing them the ABSTRACT_EXPRVAL* as argument. @see tmplpro_set_option_CallExprUserfncFuncPtr */ /** \typedef typedef void ABSTRACT_WRITER \brief optional pointer to be passed to a callback of ::writer_functype. Optional pointer to store internal state for a callback of ::writer_functype. If used, it should be stored beforehand with tmplpro_set_option_ext_writer_state(). @see tmplpro_set_option_ext_writer_state */ /** \typedef typedef void ABSTRACT_FINDFILE \brief optional pointer to be passed to a callback of ::find_file_functype. Optional pointer to store internal state for a callback of ::find_file_functype. If used, it should be stored beforehand with tmplpro_set_option_ext_findfile_state(). @see tmplpro_set_option_ext_findfile_state */ /** \typedef typedef void ABSTRACT_FILTER \brief optional pointer to be passed to a callback of ::load_file_functype / ::unload_file_functype. Optional pointer to store internal state for a callback of ::load_file_functype / ::unload_file_functype. If used, it should be stored beforehand with tmplpro_set_option_ext_filter_state(). @see tmplpro_set_option_ext_filter_state */ /** \typedef typedef void ABSTRACT_CALLER \brief optional pointer to be passed to a callback of ::call_expr_userfnc_functype. Optional pointer to store internal state for a callback of ::call_expr_userfnc_functype. If used, it should be stored beforehand with tmplpro_set_option_ext_calluserfunc_state(). @see tmplpro_set_option_ext_calluserfunc_state */ /** \typedef typedef void ABSTRACT_DATASTATE \brief optional pointer to be passed to data manipulation callbacks of ::get_ABSTRACT_VALUE_functype, ::ABSTRACT_VALUE2ABSTRACT_ARRAY_functype, ::get_ABSTRACT_ARRAY_length_functype, ::is_ABSTRACT_VALUE_true_functype, ::get_ABSTRACT_MAP_functype, exit_loop_scope_functype. Optional pointer to store internal state for a callback of ::get_ABSTRACT_VALUE_functype, ::ABSTRACT_VALUE2ABSTRACT_ARRAY_functype, ::get_ABSTRACT_ARRAY_length_functype, ::is_ABSTRACT_VALUE_true_functype, ::get_ABSTRACT_MAP_functype, exit_loop_scope_functype. If used, it should be stored beforehand with tmplpro_set_option_ext_data_state(). @see tmplpro_set_option_ext_data_state */ /** \typedef typedef void ABSTRACT_ARRAY \brief optional pointer representing a loop. It is returned from a callback of ::ABSTRACT_VALUE2ABSTRACT_ARRAY_functype and is passed to callbacks of ::get_ABSTRACT_ARRAY_length_functype and ::get_ABSTRACT_MAP_functype. */ /** \typedef typedef void ABSTRACT_MAP \brief optional pointer representing a root scope or a loop scope. Pointer for the loop scope is returned from a callback of ::get_ABSTRACT_MAP_functype. Pointer of the root scope should be stored beforehead using tmplpro_set_option_root_param_map(). Both types of pointers are passed to callback of ::get_ABSTRACT_VALUE_functype. Also, root scope pointer is passed to callbacks of ::end_loop_functype and ::select_loop_scope_functype. @see tmplpro_set_option_root_param_map */ /** \typedef typedef void ABSTRACT_VALUE \brief optional pointer representing an abstract value that can be converted to a sting or loop. It is returned from callback of ::get_ABSTRACT_VALUE_functype and passed to callbacks of ::ABSTRACT_VALUE2ABSTRACT_ARRAY_functype and ::ABSTRACT_VALUE2PSTRING_functype. */ /** \typedef typedef void ABSTRACT_FUNCMAP \brief optional pointer to be passed to a callback of ::is_expr_userfnc_functype. If used, it should be stored beforehand with tmplpro_set_option_expr_func_map(). @see tmplpro_set_option_expr_func_map */ /** \typedef typedef void ABSTRACT_ARGLIST \brief optional pointer representing a list accumulating arguments to user function call. It is returned from a callback of ::init_expr_arglist_functype and is passed to callbacks of ::push_expr_arglist_functype, ::call_expr_userfnc_functype and ::free_expr_arglist_functype. */ /** \typedef typedef void ABSTRACT_USERFUNC \brief optional pointer representing user function. It is returned from a callback of ::is_expr_userfnc_functype and is passed to callback of ::call_expr_userfnc_functype. */ /** \typedef typedef void ABSTRACT_EXPRVAL \brief optional pointer representing user function argument or return value. It is passed to callbacks of ::push_expr_arglist_functype and ::call_expr_userfnc_functype. */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/perl-HTML-Template-Pro.spec0000644000076400007640000001733712144122203020246 0ustar igorigor#################### WARNING! ###################### # this spec file is for ALT Linux distro only. # # other distro may have problems with rpm macro!!! # #################################################### %define module HTML-Template-Pro Name: perl-%module Version: 0.9510 Release: alt1 Packager: Igor Yu. Vlasenko Summary: Perl+C/XS module to produce HTML from HTML Template files. Group: Development/Perl License: LGPL2+ or Artistic #Source: http://www.cpan.org/modules/by-module/HTML/%module-%version.tar.gz Source: %module-%version.tar.gz Url: http://sourceforge.net/projects/html-tmpl-pro/ # Automatically added by buildreq on Wed Nov 06 2002 BuildRequires: perl-devel pcre libpcre-devel perl-JSON perl-JSON-XS perl-Test-Pod %description HTML::Template::Pro is a fast lightweight C/Perl+XS reimplementation of HTML::Template and HTML::Template::Expr. It is not intended to be a complete replacement, but to be a fast implementation of HTML::Template if you don't need quering, the extended facility of HTML::Template. Designed for heavy upload, resource limitations, abcence of mod_perl. HTML::Template module attempts make using HTML templates simple and natural. It extends standard HTML with a few new HTML-esque tags - , , , and . The file written with HTML and these new tags is called a template. It is usually saved separate from your script - possibly even created by someone else! Using this module you fill in the values for the variables, loops and branches declared in the template. This allows you to seperate design - the HTML - from the data, which you generate in the Perl script. %prep %setup -q -n %module-%version %build %perl_vendor_build %install %perl_vendor_install %files %doc README Changes README.ru FAQ TODO %perl_vendor_archlib/* #perl_vendor_man3dir/* %changelog * Mon May 13 2013 Igor Vlasenko 0.9510-alt1 - new version; see Changes * Tue Feb 28 2012 Igor Vlasenko 0.9509-alt1 - new version; see Changes * Mon Dec 26 2011 Igor Vlasenko 0.9508-alt1 - new version; see Changes * Fri Dec 09 2011 Igor Vlasenko 0.9507-alt1 - new version; see Changes * Wed Oct 19 2011 Alexey Tourbin 0.9506-alt2 - rebilt for perl-5.14 * Tue Oct 04 2011 Igor Vlasenko 0.9506-alt1 - new version; see Changes * Fri Jul 01 2011 Igor Vlasenko 0.9505-alt1 - new version; see Changes * Mon Nov 08 2010 Vladimir Lettiev 0.9504-alt1.1 - rebuilt with perl 5.12 * Tue Sep 28 2010 Igor Vlasenko 0.9504-alt1 - new version; see Changes * Sat Aug 28 2010 Igor Vlasenko 0.9503-alt1 - new version; see Changes * Thu Jun 17 2010 Igor Vlasenko 0.9502-alt1 - new version; see Changes * Wed Jun 09 2010 Igor Vlasenko 0.9501-alt1 - new version; see Changes * Fri May 21 2010 Igor Vlasenko 0.95-alt1 - new version; see Changes * Tue Feb 16 2010 Igor Vlasenko 0.94-alt1 - new version; see Changes * Sun Nov 15 2009 Igor Vlasenko 0.93-alt1 - new version; see Changes * Tue Sep 29 2009 Igor Vlasenko 0.92-alt1 - new version; see Changes * Tue Sep 22 2009 Igor Vlasenko 0.91-alt1 - new version; see Changes * Sat Sep 12 2009 Igor Vlasenko 0.90-alt3 - release * Fri Sep 11 2009 Igor Vlasenko 0.90-alt2 - rc2 * Mon Aug 31 2009 Igor Vlasenko 0.90-alt1 - rc1 * Sat Aug 29 2009 Igor Vlasenko 0.87-alt1 - new version; see Changes * Sat Aug 22 2009 Igor Vlasenko 0.86-alt1 - new version; see Changes * Sun Aug 09 2009 Igor Vlasenko 0.85-alt1 - new version; see Changes * Fri Aug 07 2009 Igor Vlasenko 0.84-alt1 - new version; see Changes * Wed Aug 05 2009 Igor Vlasenko 0.83-alt1 - new version; see Changes * Wed Jul 29 2009 Igor Vlasenko 0.82-alt1 - new version; see Changes * Tue Jul 28 2009 Igor Vlasenko 0.81-alt1 - new version; see Changes * Thu Jul 23 2009 Igor Vlasenko 0.80-alt1 - new version; see Changes * Tue Jul 21 2009 Igor Vlasenko 0.78-alt1 - new version; see Changes * Sat Jul 11 2009 Igor Vlasenko 0.76-alt1 - new version; see Changes * Wed Jul 01 2009 Igor Vlasenko 0.75-alt1 - new version; see Changes * Fri Apr 03 2009 Igor Vlasenko 0.74-alt1 - new version; see Changes * Thu Apr 02 2009 Igor Vlasenko 0.73-alt1 - new version; see Changes * Thu Dec 18 2008 Igor Vlasenko 0.72-alt1 - new version; see Changes * Sat Aug 16 2008 Igor Vlasenko 0.71-alt1 - new version; see Changes * Thu Apr 03 2008 Igor Vlasenko 0.70-alt1 - new version; see Changes * Thu Feb 28 2008 Igor Vlasenko 0.69-alt1 - new version; see Changes * Tue Jan 08 2008 Igor Vlasenko 0.68-alt2 - fix for ix86 * Tue Jan 08 2008 Igor Vlasenko 0.68-alt1 - new version; see Changes * Sun Dec 02 2007 Igor Vlasenko 0.67-alt1 - new version; see Changes * Thu Oct 04 2007 Igor Vlasenko 0.66-alt1 - new version; see Changes * Fri Jun 01 2007 Igor Vlasenko 0.65-alt1 - new version * Tue Apr 18 2006 Igor Vlasenko 0.64-alt1 - new version * Mon Apr 17 2006 Igor Vlasenko 0.63-alt1 - new version * Tue Feb 21 2006 Igor Vlasenko 0.62-alt1 - new version * Sat Feb 04 2006 Igor Vlasenko 0.61-alt1 - new version * Thu Feb 02 2006 Igor Vlasenko 0.60-alt1 - new version * Sun Jan 22 2006 Igor Vlasenko 0.59-alt1 - new version * Fri Dec 02 2005 Igor Vlasenko 0.58-alt1 - new version * Tue Nov 08 2005 Igor Vlasenko 0.57-alt1 - new version * Tue Nov 01 2005 Igor Vlasenko 0.56-alt1 - new version * Mon Oct 24 2005 Igor Vlasenko 0.55-alt1 - new version * Mon Oct 17 2005 Igor Vlasenko 0.54-alt1 - new version * Thu Oct 06 2005 Igor Vlasenko 0.53-alt1 - new version * Fri Sep 30 2005 Igor Vlasenko 0.52-alt1 - new version * Thu Sep 15 2005 Igor Vlasenko 0.51-alt1 - new version * Thu Sep 01 2005 Igor Vlasenko 0.49-alt1 - new version * Wed Aug 31 2005 Igor Vlasenko 0.48-alt1 - new version * Wed Aug 31 2005 Igor Vlasenko 0.47-alt1 - new version * Sat Aug 20 2005 Igor Vlasenko 0.46-alt1 - new version * Fri Aug 19 2005 Igor Vlasenko 0.45-alt1 - new version * Fri Aug 12 2005 Igor Vlasenko 0.44-alt1 - new version * Thu Aug 04 2005 Igor Vlasenko 0.43-alt1 - new version * Thu Aug 04 2005 Igor Vlasenko 0.42-alt1 - new version * Tue Jul 26 2005 Igor Vlasenko 0.41-alt1 - new version * Fri Jul 01 2005 Igor Vlasenko 0.40-alt1 - basic support for string comparing (HTML::Template::Expr) * Thu Jun 22 2005 Igor Vlasenko 0.39-alt1 - new version * Thu Jun 09 2005 Igor Vlasenko 0.38-alt1 - new version, basic support for HTML::Template::Expr * Thu Jun 02 2005 Igor Vlasenko 0.37-alt1 - new version * Mon May 23 2005 Igor Vlasenko 0.36-alt1 - new version * Thu May 19 2005 Igor Vlasenko 0.35-alt1 - First build for Sisyphus. * Sun May 15 2005 Igor Vlasenko 0.34-alt1.1 - First build for Daedalus. HTML-Template-Pro-0.9510/pconst.h0000644000076400007640000000047011436231734015041 0ustar igorigor#ifndef _PCONST_H #define _PCONST_H 1 /* internal constants */ #define ERR_PRO_INVALID_ARGUMENT 1 #define ERR_PRO_FILE_NOT_FOUND 2 #define ERR_PRO_CANT_OPEN_FILE 3 #define ERR_PRO_TEMPLATE_SYNTAX_ERROR 4 #define ERR_PRO_NOT_ENOUGH_MEMORY 5 #endif /* pconst.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/optint.h0000644000076400007640000000023711300025002015024 0ustar igorigor#include "pparam.h" extern TMPLPRO_LOCAL void _reset_int_options_set_nonzero_defaults(struct tmplpro_param* param); /* Local Variables: mode: c End: */ HTML-Template-Pro-0.9510/pstrutils.inc0000644000076400007640000001303611676075413016136 0ustar igorigor/* -*- c -*- * File: pstring.h * Author: Igor Vlasenko * Created: Fri Jul 1 20:11:51 2005 * * $Id$ */ #include #include #include #include "pbuffer.h" #include "pstring.h" static PSTRING lowercase_pstring (pbuffer* pBuffer ,PSTRING pstring) { const size_t size=pstring.endnext-pstring.begin; char* buf=pbuffer_resize(pBuffer, size+1); char* inbuf=buf; const char* i=pstring.begin; PSTRING retval; while (i=buflen-MAX_ESCAPE_SEQ) { buf=pbuffer_resize(StrBuffer, 2*(offset+MAX_ESCAPE_SEQ)); buflen=pbuffer_size(StrBuffer); } switch (curchar) { /* straight from the CGI.pm bible. (HTML::Template) */ case '&' : bufdelta=5; strncpy(buf+offset, "&", bufdelta);break; case '"' : bufdelta=6; strncpy(buf+offset, """,bufdelta);break; case '>' : bufdelta=4; strncpy(buf+offset, ">", bufdelta);break; case '<' : bufdelta=4; strncpy(buf+offset, "<", bufdelta);break; case '\'': bufdelta=5; strncpy(buf+offset, "'", bufdelta);break; default: *(buf+offset)=curchar; } offset+=bufdelta; } retval.begin=buf; retval.endnext=buf+offset; return retval; } static PSTRING jsencode_pstring (pbuffer* StrBuffer, PSTRING pstring) { char* buf=pbuffer_resize(StrBuffer, pstring.endnext-pstring.begin+1+MAX_ESCAPE_SEQ); const char* curpos=pstring.begin; size_t offset=0; size_t buflen=pbuffer_size(StrBuffer); PSTRING retval; while (curpos=buflen-MAX_ESCAPE_SEQ) { buf=pbuffer_resize(StrBuffer, 2*(offset+MAX_ESCAPE_SEQ)); buflen=pbuffer_size(StrBuffer); } switch (curchar) { case '\\' : bufdelta=6; strncpy(buf+offset, "\\u005c", bufdelta);break; case '"' : bufdelta=6; strncpy(buf+offset, "\\u0022",bufdelta);break; case '\'' : bufdelta=6; strncpy(buf+offset, "\\u0027",bufdelta);break; case '\n' : bufdelta=6; strncpy(buf+offset, "\\u000a",bufdelta);break; case '\r' : bufdelta=6; strncpy(buf+offset, "\\u000d",bufdelta);break; case '>' : bufdelta=6; strncpy(buf+offset, "\\u003e;", bufdelta);break; case '<' : bufdelta=6; strncpy(buf+offset, "\\u003c;", bufdelta);break; case '&' : bufdelta=6; strncpy(buf+offset, "\\u0026;", bufdelta);break; case '=' : bufdelta=6; strncpy(buf+offset, "\\u003d;", bufdelta);break; case '-' : bufdelta=6; strncpy(buf+offset, "\\u002d;", bufdelta);break; case ';' : bufdelta=6; strncpy(buf+offset, "\\u003b;", bufdelta);break; case '+' : bufdelta=6; strncpy(buf+offset, "\\u002b;", bufdelta);break; default: *(buf+offset)=curchar; } offset+=bufdelta; } retval.begin=buf; retval.endnext=buf+offset; return retval; } static PSTRING urlencode_pstring (pbuffer* StrBuffer, PSTRING pstring) { char* buf=pbuffer_resize(StrBuffer, pstring.endnext-pstring.begin+1+MAX_ESCAPE_SEQ); const char* curpos=pstring.begin; size_t offset=0; size_t buflen=pbuffer_size(StrBuffer); PSTRING retval; while (curpos=buflen-MAX_ESCAPE_SEQ) { buf=pbuffer_resize(StrBuffer, 2*(offset+MAX_ESCAPE_SEQ)); buflen=pbuffer_size(StrBuffer); } /* * # do the translation (RFC 2396 ^uric) * s!([^a-zA-Z0-9_.\-])!sprintf('%%%02X', $_) */ if ((curchar>='a' && curchar<='z') || (curchar>='A' && curchar<='Z') || (curchar>='0' && curchar<='9') || curchar=='_' || curchar=='.' || curchar=='\\' || curchar=='-' ) *(buf+offset)=curchar; else { bufdelta=3; sprintf(buf+offset,"%%%.2X",(int) curchar); } offset+=bufdelta; } retval.begin=buf; retval.endnext=buf+offset; return retval; } static PSTRING escape_pstring (pbuffer* strBuffer, PSTRING pstring, const int escapeopt) { switch (escapeopt) { case HTML_TEMPLATE_OPT_ESCAPE_HTML: return htmlencode_pstring(strBuffer, pstring); case HTML_TEMPLATE_OPT_ESCAPE_JS: return jsencode_pstring(strBuffer, pstring); case HTML_TEMPLATE_OPT_ESCAPE_URL: return urlencode_pstring(strBuffer, pstring); default : return pstring; } } HTML-Template-Pro-0.9510/lib/0000755000076400007640000000000012144122665014126 5ustar igorigorHTML-Template-Pro-0.9510/lib/HTML/0000755000076400007640000000000012144122665014672 5ustar igorigorHTML-Template-Pro-0.9510/lib/HTML/Template/0000755000076400007640000000000012144122665016445 5ustar igorigorHTML-Template-Pro-0.9510/lib/HTML/Template/SYNTAX.pod0000644000076400007640000013654311441152634020211 0ustar igorigor=head1 NAME HTML::Template::SYNTAX - syntax of html template language for HTML::Template =head1 SYNOPSIS This help is only on syntax of html template files. For perl interface of HTML::Template::Pro you should see L. First you make a template - this is just a normal HTML file with a few extra tags, the simplest being For example, test.tmpl: Test Template My Home Directory is

My Path is set to Now define the value for HOME and PATH, for example, in perl it will look like $template->param(HOME => $ENV{HOME}); $template->param(PATH => $ENV{PATH}); and process the template. If all is well in the universe this should show something like this in your browser: My Home Directory is /home/some/directory My Path is set to /bin;/usr/bin =head1 DESCRIPTION This module attempts to make using HTML templates simple and natural. It extends standard HTML with a few new HTML-esque tags - , , , , and . (HTML::Template::Pro also supports tag.) The file written with HTML and these new tags is called a template. It is usually saved separate from your script - possibly even created by someone else! Using this module you fill in the values for the variables, loops and branches declared in the template. This allows you to separate design - the HTML - from the data, which you generate in the Perl script. This module is licensed under the (L)GPL or perl license. See the LICENSE section below for more details. =head1 TUTORIAL If you're new to HTML::Template, I suggest you start with the introductory article available on the HTML::Template website: http://html-template.sourceforge.net =head1 MOTIVATION It is true that there are a number of packages out there to do HTML templates. On the one hand you have things like HTML::Embperl which allows you freely mix Perl with HTML. On the other hand lie home-grown variable substitution solutions. Hopefully the module can find a place between the two. One advantage of this module over a full HTML::Embperl-esque solution is that it enforces an important divide - design and programming. By limiting the programmer to just using simple variables and loops in the HTML, the template remains accessible to designers and other non-perl people. The use of HTML-esque syntax goes further to make the format understandable to others. In the future this similarity could be used to extend existing HTML editors/analyzers to support HTML::Template. An advantage of this module over home-grown tag-replacement schemes is the support for loops. In my work I am often called on to produce tables of data in html. Producing them using simplistic HTML templates results in CGIs containing lots of HTML since the HTML itself cannot represent loops. The introduction of loop statements in the HTML simplifies this situation considerably. The designer can layout a single row and the programmer can fill it in as many times as necessary - all they must agree on is the parameter names. For all that, I think the best thing about this module is that it does just one thing and it does it quickly and carefully. It doesn't try to replace Perl and HTML, it just augments them to interact a little better. And it's pretty fast. =head1 THE TAGS =head2 GENERAL TAG SYNTAX A generic HTML::Template tag that is supported by HTML::Template::Pro looks like . Tags are case-insensitve: is acceptable. Single quotes can be used, quotes can be omitted, and option name could be often guessed as in . template tags could be decorated as html comments Also, as HTML::Template::Pro extension (starting from version 0.90), template tags could also be decorated as xml See L. =head2 TMPL_VAR The tag is very simple. For each tag in the template you call $template->param(PARAMETER_NAME => "VALUE"). When the template is output the is replaced with the VALUE text you specified. If you don't set a parameter it just gets skipped in the output. Optionally you can use the "ESCAPE=HTML" option in the tag to indicate that you want the value to be HTML-escaped before being returned from output (the old ESCAPE=1 syntax is still supported). This means that the ", <, >, and & characters get translated into ", <, > and & respectively. This is useful when you want to use a TMPL_VAR in a context where those characters would cause trouble. Example: "> If you called C with a value like sam"my you'll get in trouble with HTML's idea of a double-quote. On the other hand, if you use ESCAPE=HTML, like this: "> You'll get what you wanted no matter what value happens to be passed in for param. You can also write ESCAPE="HTML", ESCAPE='HTML' and ESCAPE='1'. "ESCAPE=0" and "ESCAPE=NONE" turn off escaping, which is the default behavior. There is also the "ESCAPE=URL" option which may be used for VARs that populate a URL. It will do URL escaping, like replacing ' ' with '+' and '/' with '%2F'. There is also the "ESCAPE=JS" option which may be used for VARs that need to be placed within a Javascript string. All \n, \r, ' and " characters are escaped. You can assign a default value to a variable with the DEFAULT attribute. For example, this will output "the devil gave me a taco" if the "who" variable is not set. The gave me a taco. =head2 TMPL_LOOP ... The tag is a bit more complicated than . The tag allows you to delimit a section of text and give it a name. Inside this named loop you place s. Now you pass to C a list (an array ref) of parameter assignments (hash refs) for this loop. The loop iterates over the list and produces output from the text block for each pass. Unset parameters are skipped. Here's an example: In the template: Name:
Job:

In the script: $template->param(EMPLOYEE_INFO => [ { name => 'Sam', job => 'programmer' }, { name => 'Steve', job => 'soda jerk' }, ] ); print $template->output(); The output in a browser: Name: Sam Job: programmer Name: Steve Job: soda jerk As you can see above the takes a list of variable assignments and then iterates over the loop body producing output. Often you'll want to generate a 's contents programmatically. Here's an example of how this can be done (many other ways are possible!): # a couple of arrays of data to put in a loop: my @words = qw(I Am Cool); my @numbers = qw(1 2 3); my @loop_data = (); # initialize an array to hold your loop while (@words and @numbers) { my %row_data; # get a fresh hash for the row data # fill in this row $row_data{WORD} = shift @words; $row_data{NUMBER} = shift @numbers; # the crucial step - push a reference to this row into the loop! push(@loop_data, \%row_data); } # finally, assign the loop data to the loop param, again with a # reference: $template->param(THIS_LOOP => \@loop_data); The above example would work with a template like: Word:
Number:

It would produce output like: Word: I Number: 1 Word: Am Number: 2 Word: Cool Number: 3 s within s are fine and work as you would expect. If the syntax for the C call has you stumped, here's an example of a param call with one nested loop: $template->param(LOOP => [ { name => 'Bobby', nicknames => [ { name => 'the big bad wolf' }, { name => 'He-Man' }, ], }, ], ); Basically, each gets an array reference. Inside the array are any number of hash references. These hashes contain the name=>value pairs for a single pass over the loop template. Inside a , the only variables that are usable are the ones from the . The variables in the outer blocks are not visible within a template loop. For the computer-science geeks among you, a introduces a new scope much like a perl subroutine call. If you want your variables to be global you can use 'global_vars' option to new() described below. =head2 TMPL_INCLUDE This tag includes a template directly into the current template at the point where the tag is found. The included template contents are used exactly as if its contents were physically included in the master template. The file specified can be an absolute path (beginning with a '/' under Unix, for example). If it isn't absolute, the path to the enclosing file is tried first. After that the path in the environment variable HTML_TEMPLATE_ROOT is tried, if it exists. Next, the "path" option is consulted, first as-is and then with HTML_TEMPLATE_ROOT prepended if available. As a final attempt, the filename is passed to open() directly. See below for more information on HTML_TEMPLATE_ROOT and the "path" option to new(). As a protection against infinitly recursive includes, an arbitrary limit of 10 levels deep is imposed. You can alter this limit with the "max_includes" option. See the entry for the "max_includes" option below for more details. For the see L for more details. =head2 TMPL_IF ... The tag allows you to include or not include a block of the template based on the value of a given parameter name. If the parameter is given a value that is true for Perl - like '1' - then the block is included in the output. If it is not defined, or given a false value - like '0' - then it is skipped. The parameters are specified the same way as with TMPL_VAR. Example Template: Some text that only gets displayed if BOOL is true! Now if you call $template->param(BOOL => 1) then the above block will be included by output. blocks can include any valid HTML::Template construct - VARs and LOOPs and other IF/ELSE blocks. Note, however, that intersecting a and a is invalid. Not going to work: If the name of a TMPL_LOOP is used in a TMPL_IF, the IF block will output if the loop has at least one row. Example: This will output if the loop is not empty. .... WARNING: Much of the benefit of HTML::Template is in decoupling your Perl and HTML. If you introduce numerous cases where you have TMPL_IFs and matching Perl if()s, you will create a maintenance problem in keeping the two synchronized. I suggest you adopt the practice of only using TMPL_IF if you can do so without requiring a matching if() in your Perl code. =head2 TMPL_ELSIF ... ... ... ... WARNING: TMPL_ELSIF is a HTML::Template::Pro extension! It is not supported in HTML::Template (as of 2.9). =head2 TMPL_ELSE ... ... You can include an alternate block in your TMPL_IF block by using TMPL_ELSE. NOTE: You still end the block with , not ! Example: Some text that is included only if BOOL is true Some text that is included only if BOOL is false =head2 TMPL_UNLESS ... This tag is the opposite of . The block is output if the CONTROL_PARAMETER is set false or not defined. You can use with just as you can with . Example: Some text that is output only if BOOL is FALSE. Some text that is output only if BOOL is TRUE. If the name of a TMPL_LOOP is used in a TMPL_UNLESS, the UNLESS block output if the loop has zero rows. This will output if the loop is empty. .... =head2 NOTES HTML::Template's tags are meant to mimic normal HTML tags. However, they are allowed to "break the rules". Something like: is not really valid HTML, but it is a perfectly valid use and will work as planned. The "NAME=" in the tag is optional, although for extensibility's sake I recommend using it. Example - "" is acceptable. If you're a fanatic about valid HTML and would like your templates to conform to valid HTML syntax, you may optionally type template tags in the form of HTML comments. This may be of use to HTML authors who would like to validate their templates' HTML syntax prior to HTML::Template processing, or who use DTD-savvy editing tools. In order to realize a dramatic savings in bandwidth, the standard (non-comment) tags will be used throughout this documentation. =head1 EXPR EXTENSION This module supports an extension to HTML::Template which allows expressions in the template syntax which was implemented in HTML::Template::Expr. See L for details. Expression support includes comparisons, math operations, string operations and a mechanism to allow you add your own functions at runtime. The basic syntax is: I've got a lot of bananas. This will output "I've got a lot of bananas" if you call: $template->param(banana_count => 100); In your script. s also work with expressions: I'd like to have bananas. This will output "I'd like to have 200 bananas." with the same param() call as above. =head1 BASIC SYNTAX =head2 Variables Variables are unquoted alphanumeric strings with the same restrictions as variable names in HTML::Template. Their values are set through param(), just like normal HTML::Template variables. For example, these two lines are equivalent: =head2 Emiliano Bruni extension to Expr original HTML::Template allows almost arbitrary chars in parameter names, but original HTML::Template::Expr (as to 0.04) allows variables in the 'EXPR' tag to be only m![A-Za-z_][A-Za-z0-9_]*!. With this extension, arbitrary chars can be used in variable name inside the 'EXPR' tag if bracketed in ${}, as, for example, EXPR="${foo.bar} eq 'a'". Note that old bracketing into {} is considered obsolete, as it will clash with JSON assignments like A = { "key" => "val" }. COMPATIBILITY WARNING. Currently, this extension is not present in HTML::Template::Expr (as of 0.04). =head2 INCLUDE extension to Expr With this extension, you can write something like or , or even SECURITY WARNING. Using of this extension with untrasted values of variables is a potential security leak (as in with USER_INPUT='/etc/passwd'). Omit it unless you know what you are doing. COMPATIBILITY WARNING. Currently, this extension is not present in HTML::Template::Expr (as of 0.04). =head2 Constants Numbers are unquoted strings of numbers and may have a single "." to indicate a floating point number. For example: String constants must be enclosed in quotes, single or double. For example: Note that the original parser of HTML::Template::Expr is currently (0.04) rather simple, so if you need backward compatibility all compound expressions must be parenthesized. Backward compatible examples: Nevertheless, in HTML::Template::Pro, you can safely write things like with proper priority of operations. Pattern in a regular expression must be enclosed with "/": =head1 COMPARISON Here's a list of supported comparison operators: =over 4 =item * Numeric Comparisons =over 4 =item * E =item * E =item * == =item * != =item * E= =item * E= =item * E=E =back =item * String Comparisons =over 4 =item * gt =item * lt =item * eq =item * ne =item * ge =item * le =item * cmp =back =back =head1 MATHEMATICS The basic operators are supported: =over 4 =item * + =item * - =item * * =item * / =item * % =item * ^ (not supported in HTML::Template::Expr) =back There are also some mathy functions. See the FUNCTIONS section below. =head1 LOGIC Boolean logic is available: =over 4 =item * && (synonym: and) =item * || (synonym: or) =back =head1 REGULAR EXPRESSION SUPPORT regexp support is added to HTML::Template::Expr and HTML::Template::Pro by Stanislav Yadykin . Currently it is not included in official distribution of HTML::Template::Expr. Standard regexp syntax: =over 4 =item * =~ =item * !~ =back =head1 FUNCTIONS The following functions are available to be used in expressions. See perldoc perlfunc for details. =over 4 =item * sprintf =item * substr (2 and 3 arg versions only) =item * lc =item * lcfirst =item * uc =item * ucfirst =item * length =item * defined =item * abs =item * atan2 =item * cos =item * exp =item * hex =item * int =item * log =item * oct =item * rand =item * sin =item * sqrt =item * srand =back All functions must be called using full parenthesis. For example, this is a syntax error: But this is good: =head1 EXPR: DEFINING NEW FUNCTIONS You may also define functions of your own. See L for details. =begin comment =head1 METHODS =head2 new() Call new() to create a new Template object: my $template = HTML::Template->new( filename => 'file.tmpl', option => 'value' ); You must call new() with at least one name => value pair specifying how to access the template text. You can use C<< filename => 'file.tmpl' >> to specify a filename to be opened as the template. Alternately you can use: my $t = HTML::Template->new( scalarref => $ref_to_template_text, option => 'value' ); and my $t = HTML::Template->new( arrayref => $ref_to_array_of_lines , option => 'value' ); These initialize the template from in-memory resources. In almost every case you'll want to use the filename parameter. If you're worried about all the disk access from reading a template file just use mod_perl and the cache option detailed below. You can also read the template from an already opened filehandle, either traditionally as a glob or as a FileHandle: my $t = HTML::Template->new( filehandle => *FH, option => 'value'); The four new() calling methods can also be accessed as below, if you prefer. my $t = HTML::Template->new_file('file.tmpl', option => 'value'); my $t = HTML::Template->new_scalar_ref($ref_to_template_text, option => 'value'); my $t = HTML::Template->new_array_ref($ref_to_array_of_lines, option => 'value'); my $t = HTML::Template->new_filehandle($fh, option => 'value'); And as a final option, for those that might prefer it, you can call new as: my $t = HTML::Template->new(type => 'filename', source => 'file.tmpl'); Which works for all three of the source types. If the environment variable HTML_TEMPLATE_ROOT is set and your filename doesn't begin with /, then the path will be relative to the value of $HTML_TEMPLATE_ROOT. Example - if the environment variable HTML_TEMPLATE_ROOT is set to "/home/sam" and I call HTML::Template->new() with filename set to "sam.tmpl", the HTML::Template will try to open "/home/sam/sam.tmpl" to access the template file. You can also affect the search path for files with the "path" option to new() - see below for more information. You can modify the Template object's behavior with new(). The options are available: =over 4 =item Error Detection Options =over 4 =item * die_on_bad_params - if set to 0 the module will let you call $template->param(param_name => 'value') even if 'param_name' doesn't exist in the template body. Defaults to 1. =item * strict - if set to 0 the module will allow things that look like they might be TMPL_* tags to get by without dieing. Example: Would normally cause an error, but if you call new with strict => 0, HTML::Template will ignore it. Defaults to 1. HTML::Template::Pro always use strict => 0. =item * vanguard_compatibility_mode - if set to 1 the module will expect to see s that look like %NAME% in addition to the standard syntax. Also sets die_on_bad_params => 0. If you're not at Vanguard Media trying to use an old format template don't worry about this one. Defaults to 0. vanguard_compatibility_mode is not supported in HTML::Template::Pro. =back =item Caching Options HTML::Template use many caching options such as cache, shared_cache, double_cache, blind_cache, file_cache, file_cache_dir, file_cache_dir_mode, double_file_cache to cache preparsed html templates. Since HTML::Template::Pro parses and outputs templates at once, it silently ignores those options. =back =item Filesystem Options =over 4 =item * path - you can set this variable with a list of paths to search for files specified with the "filename" option to new() and for files included with the tag. This list is only consulted when the filename is relative. The HTML_TEMPLATE_ROOT environment variable is always tried first if it exists. Also, if HTML_TEMPLATE_ROOT is set then an attempt will be made to prepend HTML_TEMPLATE_ROOT onto paths in the path array. In the case of a file, the path to the including file is also tried before path is consulted. Example: my $template = HTML::Template->new( filename => 'file.tmpl', path => [ '/path/to/templates', '/alternate/path' ] ); NOTE: the paths in the path list must be expressed as UNIX paths, separated by the forward-slash character ('/'). =item * search_path_on_include - if set to a true value the module will search from the top of the array of paths specified by the path option on every and use the first matching template found. The normal behavior is to look only in the current directory for a template to include. Defaults to 0. =back =item Debugging Options =over 4 =item * debug - if set to 1 the module will write random debugging information to STDERR. Defaults to 0. =item * HTML::Template use many cache debug options such as stack_debug, cache_debug, shared_cache_debug, memory_debug. Since HTML::Template::Pro parses and outputs templates at once, it silently ignores those options. =back =item Miscellaneous Options =over 4 =item * associate - this option allows you to inherit the parameter values from other objects. The only requirement for the other object is that it have a C method that works like HTML::Template's C. A good candidate would be a CGI.pm query object. Example: my $query = new CGI; my $template = HTML::Template->new(filename => 'template.tmpl', associate => $query); Now, C<< $template->output() >> will act as though $template->param('FormField', $cgi->param('FormField')); had been specified for each key/value pair that would be provided by the C<< $cgi->param() >> method. Parameters you set directly take precedence over associated parameters. You can specify multiple objects to associate by passing an anonymous array to the associate option. They are searched for parameters in the order they appear: my $template = HTML::Template->new(filename => 'template.tmpl', associate => [$query, $other_obj]); The old associateCGI() call is still supported, but should be considered obsolete. NOTE: The parameter names are matched in a case-insensitve manner. If you have two parameters in a CGI object like 'NAME' and 'Name' one will be chosen randomly by associate. This behavior can be changed by the following option. =item * case_sensitive - setting this option to true causes HTML::Template to treat template variable names case-sensitively. The following example would only set one parameter without the "case_sensitive" option: my $template = HTML::Template->new(filename => 'template.tmpl', case_sensitive => 1); $template->param( FieldA => 'foo', fIELDa => 'bar', ); This option defaults to off. NOTE: with case_sensitive and loop_context_vars the special loop variables are available in lower-case only. =item * loop_context_vars - when this parameter is set to true (it is false by default) four loop context variables are made available inside a loop: __first__, __last__, __inner__, __odd__. They can be used with , and to control how a loop is output. In addition to the above, a __counter__ var is also made available when loop context variables are turned on. Example: This only outputs on the first pass. This outputs every other pass, on the odd passes. This outputs every other pass, on the even passes. This outputs on passes that are neither first nor last. This is pass number . This only outputs on the last pass. One use of this feature is to provide a "separator" similar in effect to the perl function join(). Example: and , . Would output (in a browser) something like: Apples, Oranges, Brains, Toes, and Kiwi. Given an appropriate C call, of course. NOTE: A loop with only a single pass will get both __first__ and __last__ set to true, but not __inner__. =item * no_includes - set this option to 1 to disallow the tag in the template file. This can be used to make opening untrusted templates B less dangerous. Defaults to 0. =item * max_includes - set this variable to determine the maximum depth that includes can reach. Set to 10 by default. Including files to a depth greater than this value causes an error message to be displayed. Set to 0 to disable this protection. =item * global_vars - normally variables declared outside a loop are not available inside a loop. This option makes s like global variables in Perl - they have unlimited scope. This option also affects and . Example: This is a normal variable: .

Here it is inside the loop:

Normally this wouldn't work as expected, since 's value outside the loop is not available inside the loop. The global_vars option also allows you to access the values of an enclosing loop within an inner loop. For example, in this loop the inner loop will have access to the value of OUTER_VAR in the correct iteration: OUTER: INNER: INSIDE OUT: B: C is not C (which does not exist). That means that loops you declare at one scope are not available inside other loops even when C is on. =item * path_like_variable_scope - this option switches on a Shigeki Morimoto extension to HTML::Template::Pro that allows access to variables that are outside the current loop scope using path-like expressions. Example: {{{ }}} =item * filter - this option allows you to specify a filter for your template files. A filter is a subroutine that will be called after HTML::Template reads your template file but before it starts parsing template tags. In the most simple usage, you simply assign a code reference to the filter parameter. This subroutine will recieve a single argument - a reference to a string containing the template file text. Here is an example that accepts templates with tags that look like "!!!ZAP_VAR FOO!!!" and transforms them into HTML::Template tags: my $filter = sub { my $text_ref = shift; $$text_ref =~ s/!!!ZAP_(.*?)!!!//g; }; # open zap.tmpl using the above filter my $template = HTML::Template->new(filename => 'zap.tmpl', filter => $filter); More complicated usages are possible. You can request that your filter receieve the template text as an array of lines rather than as a single scalar. To do that you need to specify your filter using a hash-ref. In this form you specify the filter using the C key and the desired argument format using the C key. The available formats are C and C. Using the C format will incur a performance penalty but may be more convenient in some situations. my $template = HTML::Template->new(filename => 'zap.tmpl', filter => { sub => $filter, format => 'array' }); You may also have multiple filters. This allows simple filters to be combined for more elaborate functionality. To do this you specify an array of filters. The filters are applied in the order they are specified. my $template = HTML::Template->new(filename => 'zap.tmpl', filter => [ { sub => \&decompress, format => 'scalar' }, { sub => \&remove_spaces, format => 'array' } ]); The specified filters will be called for any TMPL_INCLUDEed files just as they are for the main template file. =item * default_escape - Set this parameter to "HTML", "URL" or "JS" and HTML::Template will apply the specified escaping to all variables unless they declare a different escape in the template. =back =cut =head2 param() C can be called in a number of ways 1) To return a list of parameters in the template : my @parameter_names = $self->param(); 2) To return the value set to a param : my $value = $self->param('PARAM'); 3) To set the value of a parameter : # For simple TMPL_VARs: $self->param(PARAM => 'value'); # with a subroutine reference that gets called to get the value # of the scalar. The sub will recieve the template object as a # parameter. $self->param(PARAM => sub { return 'value' }); # And TMPL_LOOPs: $self->param(LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ] ); 4) To set the value of a a number of parameters : # For simple TMPL_VARs: $self->param(PARAM => 'value', PARAM2 => 'value' ); # And with some TMPL_LOOPs: $self->param(PARAM => 'value', PARAM2 => 'value', LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ], ANOTHER_LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ] ); 5) To set the value of a a number of parameters using a hash-ref : $self->param( { PARAM => 'value', PARAM2 => 'value', LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ], ANOTHER_LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ] } ); =head2 clear_params() Sets all the parameters to undef. Useful internally, if nowhere else! =head2 output() output() returns the final result of the template. In most situations you'll want to print this, like: print $template->output(); When output is called each occurrence of is replaced with the value assigned to "name" via C. If a named parameter is unset it is simply replaced with ''. are evaluated once per parameter set, accumlating output on each pass. Calling output() is guaranteed not to change the state of the Template object, in case you were wondering. This property is mostly important for the internal implementation of loops. You may optionally supply a filehandle to print to automatically as the template is generated. This may improve performance and lower memory consumption. Example: $template->output(print_to => *STDOUT); The return value is undefined when using the C option. =head2 query() This method allow you to get information about the template structure. It can be called in a number of ways. The simplest usage of query is simply to check whether a parameter name exists in the template, using the C option: if ($template->query(name => 'foo')) { # do something if a varaible of any type # named FOO is in the template } This same usage returns the type of the parameter. The type is the same as the tag minus the leading 'TMPL_'. So, for example, a TMPL_VAR parameter returns 'VAR' from C. if ($template->query(name => 'foo') eq 'VAR') { # do something if FOO exists and is a TMPL_VAR } Note that the variables associated with TMPL_IFs and TMPL_UNLESSs will be identified as 'VAR' unless they are also used in a TMPL_LOOP, in which case they will return 'LOOP'. C also allows you to get a list of parameters inside a loop (and inside loops inside loops). Example loop: And some query calls: # returns 'LOOP' $type = $template->query(name => 'EXAMPLE_LOOP'); # returns ('bop', 'bee', 'example_inner_loop') @param_names = $template->query(loop => 'EXAMPLE_LOOP'); # both return 'VAR' $type = $template->query(name => ['EXAMPLE_LOOP', 'BEE']); $type = $template->query(name => ['EXAMPLE_LOOP', 'BOP']); # and this one returns 'LOOP' $type = $template->query(name => ['EXAMPLE_LOOP', 'EXAMPLE_INNER_LOOP']); # and finally, this returns ('inner_bee', 'inner_bop') @inner_param_names = $template->query(loop => ['EXAMPLE_LOOP', 'EXAMPLE_INNER_LOOP']); # for non existent parameter names you get undef # this returns undef. $type = $template->query(name => 'DWEAZLE_ZAPPA'); # calling loop on a non-loop parameter name will cause an error. # this dies: $type = $template->query(loop => 'DWEAZLE_ZAPPA'); As you can see above the C option returns a list of parameter names and both C and C take array refs in order to refer to parameters inside loops. It is an error to use C with a parameter that is not a loop. Note that all the names are returned in lowercase and the types are uppercase. Just like C, C with no arguments returns all the parameter names in the template at the top level. =head1 FREQUENTLY ASKED QUESTIONS In the interest of greater understanding I've started a FAQ section of the perldocs. Please look in here before you send me email. =over 4 =item 1 Q: Is there a place to go to discuss HTML::Template and/or get help? A: There's a mailing-list for discussing HTML::Template at html-template-users@lists.sourceforge.net. To join: http://lists.sourceforge.net/lists/listinfo/html-template-users If you just want to get email when new releases are available you can join the announcements mailing-list here: http://lists.sourceforge.net/lists/listinfo/html-template-announce =item 2 Q: Is there a searchable archive for the mailing-list? A: Yes, you can find an archive of the SourceForge list here: http://www.geocrawler.com/lists/3/SourceForge/23294/0/ For an archive of the old vm.com list, setup by Sean P. Scanlon, see: http://bluedot.net/mail/archive/ =item 3 Q: I want support for ! How about it? A: Maybe. I definitely encourage people to discuss their ideas for HTML::Template on the mailing list. Please be ready to explain to me how the new tag fits in with HTML::Template's mission to provide a fast, lightweight system for using HTML templates. NOTE: Offering to program said addition and provide it in the form of a patch to the most recent version of HTML::Template will definitely have a softening effect on potential opponents! =item 4 Q: I found a bug, can you fix it? A: That depends. Did you send me the VERSION of HTML::Template, a test script and a test template? If so, then almost certainly. If you're feeling really adventurous, HTML::Template has a publically available Subversion server. See below for more information in the PUBLIC SUBVERSION SERVER section. =item 5 Q: s from the main template aren't working inside a ! Why? A: This is the intended behavior. introduces a separate scope for s much like a subroutine call in Perl introduces a separate scope for "my" variables. If you want your s to be global you can set the 'global_vars' option when you call new(). See above for documentation of the 'global_vars' new() option. =item 6 Q: Why do you use /[Tt]/ instead of /t/i? It's so ugly! A: Simple - the case-insensitive match switch is very inefficient. According to _Mastering_Regular_Expressions_ from O'Reilly Press, /[Tt]/ is faster and more space efficient than /t/i - by as much as double against long strings. //i essentially does a lc() on the string and keeps a temporary copy in memory. When this changes, and it is in the 5.6 development series, I will gladly use //i. Believe me, I realize [Tt] is hideously ugly. =item 7 Q: How can I pre-load my templates using cache-mode and mod_perl? A: Add something like this to your startup.pl: use HTML::Template; use File::Find; print STDERR "Pre-loading HTML Templates...\n"; find( sub { return unless /\.tmpl$/; HTML::Template->new( filename => "$File::Find::dir/$_", cache => 1, ); }, '/path/to/templates', '/another/path/to/templates/' ); Note that you'll need to modify the "return unless" line to specify the extension you use for your template files - I use .tmpl, as you can see. You'll also need to specify the path to your template files. One potential problem: the "/path/to/templates/" must be EXACTLY the same path you use when you call HTML::Template->new(). Otherwise the cache won't know they're the same file and will load a new copy - instead getting a speed increase, you'll double your memory usage. To find out if this is happening set cache_debug => 1 in your application code and look for "CACHE MISS" messages in the logs. =item 8 Q: What characters are allowed in TMPL_* NAMEs? A: Numbers, letters, '.', '/', '+', '-' and '_'. =item 9 Q: How can I execute a program from inside my template? A: Short answer: you can't. Longer answer: you shouldn't since this violates the fundamental concept behind HTML::Template - that design and code should be seperate. But, inevitably some people still want to do it. If that describes you then you should take a look at L. Using HTML::Template::Expr it should be easy to write a run_program() function. Then you can do awful stuff like: Just, please, don't tell me about it. I'm feeling guilty enough just for writing HTML::Template::Expr in the first place. =item 10 Q: Can I get a copy of these docs in Japanese? A: Yes you can. See Kawai Takanori's translation at: http://member.nifty.ne.jp/hippo2000/perltips/html/template.htm =item 11 Q: What's the best way to create a element entirely inside the template. What you end up with is a rat's nest of loops and conditionals. Alternately you can give up a certain amount of flexibility in return for vastly simplifying your templates. I generally choose the latter. Another option is to investigate HTML::FillInForm which some have reported success using to solve this problem. =back =head1 BUGS I am aware of no bugs - if you find one, join the mailing list and tell us about it. You can join the HTML::Template mailing-list by visiting: http://lists.sourceforge.net/lists/listinfo/html-template-users Of course, you can still email me directly (sam@tregar.com) with bugs, but I reserve the right to forward bug reports to the mailing list. When submitting bug reports, be sure to include full details, including the VERSION of the module, a test script and a test template demonstrating the problem! If you're feeling really adventurous, HTML::Template has a publically available Subversion server. See below for more information in the PUBLIC SUBVERSION SERVER section. =head1 CREDITS This module was the brain child of my boss, Jesse Erlbaum ( jesse@vm.com ) at Vanguard Media ( http://vm.com ) . The most original idea in this module - the - was entirely his. Fixes, Bug Reports, Optimizations and Ideas have been generously provided by: Richard Chen Mike Blazer Adriano Nagelschmidt Rodrigues Andrej Mikus Ilya Obshadko Kevin Puetz Steve Reppucci Richard Dice Tom Hukins Eric Zylberstejn David Glasser Peter Marelas James William Carlson Frank D. Cringle Winfried Koenig Matthew Wickline Doug Steinwand Drew Taylor Tobias Brox Michael Lloyd Simran Gambhir Chris Houser Larry Moore Todd Larason Jody Biggs T.J. Mather Martin Schroth Dave Wolfe uchum Kawai Takanori Peter Guelich Chris Nokleberg Ralph Corderoy William Ward Ade Olonoh Mark Stosberg Lance Thomas Roland Giersig Jere Julian Peter Leonard Kenny Smith Sean P. Scanlon Martin Pfeffer David Ferrance Gyepi Sam Darren Chamberlain Paul Baker Gabor Szabo Craig Manley Richard Fein The Phalanx Project Sven Neuhaus Thanks! =head1 WEBSITE You can find information about HTML::Template and other related modules at: http://html-template.sourceforge.net =head1 PUBLIC SUBVERSION SERVER HTML::Template now has a publicly accessible Subversion server provided by SourceForge (www.sourceforge.net). You can access it by going to http://sourceforge.net/svn/?group_id=1075. Give it a try! =end comment =head1 AUTHOR Sam Tregar, sam@tregar.com (Main text) I. Vlasenko, Eviy@altlinux.orgE (Pecularities of HTML::Template::Pro) =head1 LICENSE HTML::Template : A module for using HTML Templates with Perl Copyright (C) 2000-2008 Sam Tregar (sam@tregar.com) This module is free software; you can redistribute it and/or modify it under the terms of either: a) the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version, or b) the "Artistic License" which comes with this module. 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 either the GNU General Public License or the Artistic License for more details. You should have received a copy of the Artistic License with this module, in the file ARTISTIC. If not, I'll be glad to provide one. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA =cut HTML-Template-Pro-0.9510/lib/HTML/Template/Pro.pm0000644000076400007640000004122512144122140017533 0ustar igorigorpackage HTML::Template::Pro; use 5.005; use strict; use integer; # no floating point math so far! use HTML::Template::Pro::WrapAssociate; use File::Spec; # generate paths that work on all platforms use Scalar::Util qw(tainted); use Carp; require DynaLoader; require Exporter; use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS); @ISA = qw(DynaLoader Exporter); $VERSION = '0.9510'; @EXPORT_OK = qw/ASK_NAME_DEFAULT ASK_NAME_AS_IS ASK_NAME_LOWERCASE ASK_NAME_UPPERCASE ASK_NAME_MASK/; %EXPORT_TAGS = (const => [qw/ASK_NAME_DEFAULT ASK_NAME_AS_IS ASK_NAME_LOWERCASE ASK_NAME_UPPERCASE ASK_NAME_MASK/]); # constants for tmpl_var_case use constant { ASK_NAME_DEFAULT => 0, ASK_NAME_AS_IS => 1, ASK_NAME_LOWERCASE => 2, ASK_NAME_UPPERCASE => 4, }; use constant ASK_NAME_MASK => ASK_NAME_AS_IS | ASK_NAME_LOWERCASE | ASK_NAME_UPPERCASE; bootstrap HTML::Template::Pro $VERSION; ## when HTML::Template is not loaded, ## all calls to HTML::Template will be sent to HTML::Template::Pro, ## otherwise native HTML::Template will be used push @HTML::Template::ISA, qw/HTML::Template::Pro/; push @HTML::Template::Expr::ISA, qw/HTML::Template::Pro/; # Preloaded methods go here. # internal C library init -- required _init(); # internal C library unload -- it is better to comment it: # when process terminates, memory is freed anyway # but END {} can be called between calls (as SpeedyCGI does) # END {_done()} # initialize preset function table use vars qw(%FUNC); %FUNC = ( # note that length,defined,sin,cos,log,tan,... are built-in 'sprintf' => sub { sprintf(shift, @_); }, 'substr' => sub { return substr($_[0], $_[1]) if @_ == 2; return substr($_[0], $_[1], $_[2]); }, 'lc' => sub { lc($_[0]); }, 'lcfirst' => sub { lcfirst($_[0]); }, 'uc' => sub { uc($_[0]); }, 'ucfirst' => sub { ucfirst($_[0]); }, # 'length' => sub { length($_[0]); }, # 'defined' => sub { defined($_[0]); }, # 'abs' => sub { abs($_[0]); }, # 'hex' => sub { hex($_[0]); }, # 'oct' => sub { oct($_[0]); }, 'rand' => sub { rand($_[0]); }, 'srand' => sub { srand($_[0]); }, ); sub new { my $class=shift; my %param; my $options={param_map=>\%param, functions => {}, filter => [], # ---- supported ------- debug => 0, max_includes => 10, global_vars => 0, no_includes => 0, search_path_on_include => 0, loop_context_vars => 0, path => [], associate => [], case_sensitive => 0, __strict_compatibility => 1, force_untaint => 0, # ---- unsupported distinct ------- die_on_bad_params => 0, strict => 0, # ---- unsupported ------- # vanguard_compatibility_mode => 0, #============================================= # The following options are harmless caching-specific. # They are ignored silently because there is nothing to cache. #============================================= # stack_debug => 0, # timing => 0, # cache => 0, # blind_cache => 0, # file_cache => 0, # file_cache_dir => '', # file_cache_dir_mode => 0700, # cache_debug => 0, # shared_cache_debug => 0, # memory_debug => 0, # shared_cache => 0, # double_cache => 0, # double_file_cache => 0, # ipc_key => 'TMPL', # ipc_mode => 0666, # ipc_segment_size => 65536, # ipc_max_size => 0, #============================================ @_}; # make sure taint mode is on if force_untaint flag is set if ($options->{force_untaint} && ! ${^TAINT}) { croak("HTML::Template->new() : 'force_untaint' option set but perl does not run in taint mode!"); } # associate should be an array if it's not already if (ref($options->{associate}) ne 'ARRAY') { $options->{associate} = [ $options->{associate} ]; } # path should be an array if it's not already if (ref($options->{path}) ne 'ARRAY') { $options->{path} = [ $options->{path} ]; } # filter should be an array if it's not already if (ref($options->{filter}) ne 'ARRAY') { $options->{filter} = [ $options->{filter} ]; } my $case_sensitive = $options->{case_sensitive}; my $__strict_compatibility = $options->{__strict_compatibility}; # wrap associated objects into tied hash and # make sure objects in associate are support param() $options->{associate} = [ map {HTML::Template::Pro::WrapAssociate->_wrap($_, $case_sensitive, $__strict_compatibility)} @{$options->{associate}} ]; # check for syntax errors: my $source_count = 0; exists($options->{filename}) and $source_count++; exists($options->{filehandle}) and $source_count++; exists($options->{arrayref}) and $source_count++; exists($options->{scalarref}) and $source_count++; if ($source_count != 1) { croak("HTML::Template->new called with multiple (or no) template sources specified! A valid call to new() has exactly one filename => 'file' OR exactly one scalarref => \\\$scalar OR exactly one arrayref => \\\@array OR exactly one filehandle => \*FH"); } if ($options->{arrayref}) { die "bad value of arrayref" unless UNIVERSAL::isa($_[0], 'ARRAY'); my $template=join('',@{$options->{arrayref}}); $options->{scalarref}=\$template; } if ($options->{filehandle}) { local $/; # enable "slurp" mode local *FH=$options->{filehandle}; my $template=; $options->{scalarref}=\$template; } # merging built_in funcs with user-defined funcs $options->{expr_func}={%FUNC, %{$options->{functions}}}; # hack to be fully compatible with HTML::Template; # caused serious memory leak. it should be done on XS level, if needed. # &safe_circular_reference($options,'options') ??? #$options->{options}=$options; bless $options,$class; $options->_call_filters($options->{scalarref}) if $options->{scalarref} and @{$options->{filter}}; return $options; # == $self } # a few shortcuts to new(), of possible use... sub new_file { my $pkg = shift; return $pkg->new('filename', @_); } sub new_filehandle { my $pkg = shift; return $pkg->new('filehandle', @_); } sub new_array_ref { my $pkg = shift; return $pkg->new('arrayref', @_); } sub new_scalar_ref { my $pkg = shift; return $pkg->new('scalarref', @_); } sub output { my $self=shift; my %oparam=(@_); my $print_to = $oparam{print_to}; if (defined wantarray && ! $print_to) { return exec_tmpl_string($self); } else { exec_tmpl($self,$print_to); } } sub clear_params { my $self = shift; %{$self->{param_map}}=(); } sub param { my $self = shift; #my $options = $self->{options}; my $param_map = $self->{param_map}; # compatibility with HTML::Template # the one-parameter case - could be a parameter value request or a # hash-ref. if (scalar @_==0) { return keys (%$param_map); } elsif (scalar @_==1) { if (ref($_[0]) and UNIVERSAL::isa($_[0], 'HASH')) { # ref to hash of params --- simply dereference it return $self->param(%{$_[0]}); } else { my $key=$self->{case_sensitive} ? $_[0] : lc($_[0]); return $param_map->{$key} || $param_map->{$_[0]}; } } # loop below is obvious but wrong for perl # while (@_) {$param_map->{shift(@_)}=shift(@_);} if ($self->{case_sensitive}) { while (@_) { my $key=shift; my $val=shift; $param_map->{$key}=$val; } } else { while (@_) { my $key=shift; my $val=shift; if (ref($val)) { if (UNIVERSAL::isa($val, 'ARRAY')) { $param_map->{lc($key)}=[map {_lowercase_keys($_)} @$val]; } else { $param_map->{lc($key)}=$val; } } else { $param_map->{lc($key)}=$val; } } } } sub register_function { my($self, $name, $sub) = @_; if ( ref($sub) eq 'CODE' ) { if (ref $self) { # per object call $self->{expr_func}->{$name} = $sub; $self->{expr_func_user_list}->{$name} = 1; } else { # per class call $FUNC{$name} = $sub; } } elsif ( defined $sub ) { croak("HTML::Template::Pro : last arg of register_function must be subroutine reference\n") } else { if (ref $self) { if ( defined $name ) { return $self->{expr_func}->{$name}; } else { return keys %{ $self->{expr_func_user_list} }; } } else { return keys %FUNC; } } } sub _lowercase_keys { my $orighash=shift; my $newhash={}; my ($key,$val); unless (UNIVERSAL::isa($orighash, 'HASH')) { Carp::carp "HTML::Template::Pro:_lowercase_keys:in param_tree: found strange parameter $orighash while hash was expected"; return; } while (($key,$val)=each %$orighash) { if (ref($val)) { if (UNIVERSAL::isa($val, 'ARRAY')) { $newhash->{lc($key)}=[map {_lowercase_keys($_)} @$val]; } else { $newhash->{lc($key)}=$val; } } else { $newhash->{lc($key)}=$val; } } return $newhash; } # sub _load_file { # my $filepath=shift; # open my $fh, $filepath or die $!; # local $/; # enable localized slurp mode # my $content = <$fh>; # close $fh; # return $content; # } ## HTML::Template based #### callback function called from C library ############## # Note that this _get_filepath perl code is deprecated; ## # by default built-in find_file implementation is used. ## # use magic option __use_perl_find_file => 1 to re-enable it. ########################################################### sub _get_filepath { my ($self, $filename, $last_visited_file) = @_; # look for the included file... my $filepath; if ((not defined $last_visited_file) or $self->{search_path_on_include}) { $filepath = $self->_find_file($filename); } else { $filepath = $self->_find_file($filename, [File::Spec->splitdir($last_visited_file)] ); } carp "HTML::Template::Pro (using callback): template $filename not found!" unless $filepath; return $filepath; } sub _find_file { my ($options, $filename, $extra_path) = @_; my $filepath; # first check for a full path return File::Spec->canonpath($filename) if (File::Spec->file_name_is_absolute($filename) and (-e $filename)); # try the extra_path if one was specified if (defined($extra_path)) { $extra_path->[$#{$extra_path}] = $filename; $filepath = File::Spec->canonpath(File::Spec->catfile(@$extra_path)); return File::Spec->canonpath($filepath) if -e $filepath; } # try pre-prending HTML_Template_Root if (defined($ENV{HTML_TEMPLATE_ROOT})) { $filepath = File::Spec->catfile($ENV{HTML_TEMPLATE_ROOT}, $filename); return File::Spec->canonpath($filepath) if -e $filepath; } # try "path" option list.. foreach my $path (@{$options->{path}}) { $filepath = File::Spec->catfile($path, $filename); return File::Spec->canonpath($filepath) if -e $filepath; } # try even a relative path from the current directory... return File::Spec->canonpath($filename) if -e $filename; # try "path" option list with HTML_TEMPLATE_ROOT prepended... if (defined($ENV{HTML_TEMPLATE_ROOT})) { foreach my $path (@{$options->{path}}) { $filepath = File::Spec->catfile($ENV{HTML_TEMPLATE_ROOT}, $path, $filename); return File::Spec->canonpath($filepath) if -e $filepath; } } return undef; } sub _load_template { my $self = shift; my $filepath=shift; my $template = ""; confess("HTML::Template->new() : Cannot open file $filepath : $!") unless defined(open(TEMPLATE, $filepath)); # read into scalar while (read(TEMPLATE, $template, 10240, length($template))) {} close(TEMPLATE); $self->_call_filters(\$template) if @{$self->{filter}}; return \$template; } # handle calling user defined filters sub _call_filters { my $self = shift; my $template_ref = shift; my $options = $self;#->{options}; my ($format, $sub); foreach my $filter (@{$options->{filter}}) { croak("HTML::Template->new() : bad value set for filter parameter - must be a code ref or a hash ref.") unless ref $filter; # translate into CODE->HASH $filter = { 'format' => 'scalar', 'sub' => $filter } if (ref $filter eq 'CODE'); if (ref $filter eq 'HASH') { $format = $filter->{'format'}; $sub = $filter->{'sub'}; # check types and values croak("HTML::Template->new() : bad value set for filter parameter - hash must contain \"format\" key and \"sub\" key.") unless defined $format and defined $sub; croak("HTML::Template->new() : bad value set for filter parameter - \"format\" must be either 'array' or 'scalar'") unless $format eq 'array' or $format eq 'scalar'; croak("HTML::Template->new() : bad value set for filter parameter - \"sub\" must be a code ref") unless ref $sub and ref $sub eq 'CODE'; # catch errors eval { if ($format eq 'scalar') { # call $sub->($template_ref); } else { # modulate my @array = map { $_."\n" } split("\n", $$template_ref); # call $sub->(\@array); # demodulate $$template_ref = join("", @array); } }; croak("HTML::Template->new() : fatal error occured during filter call: $@") if $@; } else { croak("HTML::Template->new() : bad value set for filter parameter - must be code ref or hash ref"); } } # all done return $template_ref; } 1; __END__ =head1 NAME HTML::Template::Pro - Perl/XS module to use HTML Templates from CGI scripts =head1 SYNOPSIS It is moved out and split. See L for introduction to HTML::Template and syntax of template files. See L for perl interface of HTML::Template, HTML::Template::Expr and HTML::Template::Pro. =head1 DESCRIPTION Original HTML::Template is written by Sam Tregar, sam@tregar.com with contributions of many people mentioned there. Their efforts caused HTML::Template to be mature html tempate engine which separate perl code and html design. Yet powerful, HTML::Template is slow, especially if mod_perl isn't available or in case of disk usage and memory limitations. HTML::Template::Pro is a fast lightweight C/Perl+XS reimplementation of HTML::Template (as of 2.9) and HTML::Template::Expr (as of 0.0.7). It is not intended to be a complete replacement, but to be a fast implementation of HTML::Template if you don't need querying, the extended facility of HTML::Template. Designed for heavy upload, resource limitations, abcence of mod_perl. HTML::Template::Pro has complete support of filters and HTML::Template::Expr's tag EXPR="", including user-defined functions and construction . HTML::Template work cycle uses 2 steps. First, it loads and parse template. Then it accepts param() calls until you call output(). output() is its second phase where it produces a page from the parsed tree of template, obtained in the 1st step. HTML::Template::Pro loads, parse and outputs template on fly, when you call $tmpl->output(), in one pass. The corresponding code is written in C and glued to Perl using Perl+XS. As a result, comparing to HTML::Template in ordinary calls, it runs 10-25 times faster. Comparing to HTML::Template with all caching enabled under mod_perl, it still 1-3 times faster. At that HTML::Template caching requires considerable amount of memory (per process, shareable, or on disk) to be permanently filled with parsed trees, whereas HTML::Template::Pro don't consumes memory for caches and use mmap() for reading templates on disk. Introduction to HTML::Template and syntax of template files is described in L. Perl interface of HTML::Template and HTML::Template::Pro is described in L. =head1 SEE ALSO L, L. Progect page is http://html-tmpl-pro.sourceforge.net (and http://sourceforge.net/projects/html-tmpl-pro) Original modules are L, L. Their progect page is http://html-template.sourceforge.net =head1 BUGS See L =head1 AUTHOR I. Vlasenko, Eviy@altlinux.orgE with contributions of Bruni Emiliano, Einfo at ebruni.itE Stanislav Yadykin, Etosick at altlinux.ruE Viacheslav Sheveliov Eslavash at aha.ruE Shigeki Morimoto Eshigeki.morimoto at mixi.co.jpE Kirill Rebenok Ekirill at rebenok.plE =head1 COPYRIGHT AND LICENSE Copyright (C) 2005-2009 by I. Yu. Vlasenko. Pieces of code in Pro.pm and documentation of HTML::Template are copyright (C) 2000-2002 Sam Tregar (sam@tregar.com) The template syntax, interface conventions and a large piece of documentation of HTML::Template::Pro are based on CPAN module HTML::Template by Sam Tregar, sam@tregar.com. This library is free software; you can redistribute it and/or modify it under either the LGPL2+ or under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available. =cut HTML-Template-Pro-0.9510/lib/HTML/Template/PerlInterface.pod0000644000076400007640000010371212144121772021676 0ustar igorigor=head1 NAME HTML::Template::PerlInterface - perl interface of HTML::Template::Pro =head1 SYNOPSIS This help is only on perl interface of HTML::Template::Pro. For syntax of html template files you should see L. First you make a template - this is just a normal HTML file with a few extra tags, the simplest being For example, test.tmpl: Test Template My Home Directory is

My Path is set to See L for their syntax. Now create a small CGI program: #!/usr/bin/perl -w use HTML::Template::Pro; # open the html template my $template = HTML::Template::Pro->new( filename => 'test.tmpl', case_sensitive=> 1); # fill in some parameters $template->param(HOME => $ENV{HOME}); $template->param(PATH => $ENV{PATH}); # send the obligatory Content-Type and print the template output print "Content-Type: text/html\n\n"; # print output $template->output(print_to=>\*STDOUT); # this would also work. # print $template->output(); # this would also work. It is faster, # but (WARNING!) not compatible with original HTML::Template. # $template->output(); If all is well in the universe this should show something like this in your browser when visiting the CGI: My Home Directory is /home/some/directory My Path is set to /bin;/usr/bin For the best performance it is recommended to use case_sensitive=>1 in new() and print_to=>\*STDOUT in output(). Note that (HTML::Template::Pro version 0.90+) output(), called in void context, also prints to stdout using built-in htmltmplpro C library calls, so the last call "$template->output();" might be, in fact, the fastest way to call output(). IMPORTANT NOTE: you can safely write my $template = HTML::Template->new( ... options ...) or even my $template = HTML::Template::Expr->new( ... options ...) with HTML::Template::Pro, because in absence of original HTML::Template and HTML::Template::Expr HTML::Template::Pro intercepts their calls. You can also use all three modules and safely mix their calls (benchmarking may be the only reason for it). In case you want to mix calls to HTML::Template::Expr and HTML::Template::Pro, the only proper usage of their load is use HTML::Template; use HTML::Template::Expr; use HTML::Template::Pro; Of course, if you don't plan to mix them (in most cases) it is enough to simply write use HTML::Template::Pro; Simply use HTML::Template::Pro, it supports all functions of HTML::Template::Expr. =head1 DESCRIPTION HTML::Template::Pro is a fast C/perl+XS implementation of HTML::Template and HTML::Template::Expr. See L for details. It fully supports template language of HTML::Template as described in L. Briefly, "This module attempts to make using HTML templates simple and natural. It extends standard HTML with a few new HTML-esque tags - , , , , and . The file written with HTML and these new tags is called a template. It is usually saved separate from your script - possibly even created by someone else! Using this module you fill in the values for the variables, loops and branches declared in the template. This allows you to separate design - the HTML - from the data, which you generate in the Perl script." Here is described a perl interface of HTML::Template::Pro and HTML::Template + HTML::Template::Expr. See B for brief summary of distinctions between HTML::Template::Pro and HTML::Template. =head1 METHODS =head2 new() Call new() to create a new Template object: my $template = HTML::Template->new( filename => 'file.tmpl', option => 'value' ); You must call new() with at least one name => value pair specifying how to access the template text. You can use C<< filename => 'file.tmpl' >> to specify a filename to be opened as the template. Alternately you can use: my $t = HTML::Template->new( scalarref => $ref_to_template_text, option => 'value' ); and my $t = HTML::Template->new( arrayref => $ref_to_array_of_lines , option => 'value' ); These initialize the template from in-memory resources. In almost every case you'll want to use the filename parameter. If you're worried about all the disk access from reading a template file just use mod_perl and the cache option detailed below. You can also read the template from an already opened filehandle, either traditionally as a glob or as a FileHandle: my $t = HTML::Template->new( filehandle => *FH, option => 'value'); The four new() calling methods can also be accessed as below, if you prefer. my $t = HTML::Template->new_file('file.tmpl', option => 'value'); my $t = HTML::Template->new_scalar_ref($ref_to_template_text, option => 'value'); my $t = HTML::Template->new_array_ref($ref_to_array_of_lines, option => 'value'); my $t = HTML::Template->new_filehandle($fh, option => 'value'); And as a final option, for those that might prefer it, you can call new as: my $t = HTML::Template->new(type => 'filename', source => 'file.tmpl'); Which works for all three of the source types. If the environment variable HTML_TEMPLATE_ROOT is set and your filename doesn't begin with /, then the path will be relative to the value of $HTML_TEMPLATE_ROOT. Example - if the environment variable HTML_TEMPLATE_ROOT is set to "/home/sam" and I call HTML::Template->new() with filename set to "sam.tmpl", the HTML::Template will try to open "/home/sam/sam.tmpl" to access the template file. You can also affect the search path for files with the "path" option to new() - see below for more information. You can modify the Template object's behavior with new(). The options are available: =over 4 =item Error Detection Options =over 4 =item * die_on_bad_params - if set to 0 the module will let you call $template->param(param_name => 'value') even if 'param_name' doesn't exist in the template body. Defaults to 1 in HTML::Template. HTML::Template::Pro always use die_on_bad_params => 0. It currently can't be changed, because HTML::Template::Pro can't know whether a parameter is bad until it finishes output. Note that it is wrapper-only option: it is not implemented in the htmltmplpro C library. =item * force_untaint - if set to 1 the module will not allow you to set unescaped parameters with tainted values. If set to 2 you will have to untaint all parameters, including ones with the escape attribute. This option makes sure you untaint everything so you don't accidentally introduce e.g. cross-site-scripting (CSS) vulnerabilities. Requires taint mode. Defaults to 0. In the original HTML::Template, if the "force_untaint" option is set an error occurs if you try to set a value that is tainted in the param() call. In HTML::Template::Pro, an error occurs when output is called. Note that the tainted value will never be printed; but, to completely suppress output, one should use call to output() that returns string, like print $tmpl->output(); Then output() will die before it returns the string to print. Note that it is wrapper-only perl-specific option: it is not implemented in the htmltmplpro C library. =item * strict - if set to 0 the module will allow things that look like they might be TMPL_* tags to get by without dieing. Example: Would normally cause an error, but if you call new with strict => 0, HTML::Template will ignore it. Defaults to 1. HTML::Template::Pro always implies strict => 0. =begin comment =item * vanguard_compatibility_mode - if set to 1 the module will expect to see s that look like %NAME% in addition to the standard syntax. Also sets die_on_bad_params => 0. If you're not at Vanguard Media trying to use an old format template don't worry about this one. Defaults to 0. vanguard_compatibility_mode is not supported in HTML::Template::Pro. =end comment =back =item Caching Options HTML::Template use many caching options such as cache, shared_cache, double_cache, blind_cache, file_cache, file_cache_dir, file_cache_dir_mode, double_file_cache to cache preparsed html templates. Since HTML::Template::Pro parses and outputs templates at once, it silently ignores those options. =item Filesystem Options =over 4 =item * path - you can set this variable with a list of paths to search for files specified with the "filename" option to new() and for files included with the tag. This list is only consulted when the filename is relative. The HTML_TEMPLATE_ROOT environment variable is always tried first if it exists. Also, if HTML_TEMPLATE_ROOT is set then an attempt will be made to prepend HTML_TEMPLATE_ROOT onto paths in the path array. In the case of a file, the path to the including file is also tried before path is consulted. Example: my $template = HTML::Template->new( filename => 'file.tmpl', path => [ '/path/to/templates', '/alternate/path' ] ); NOTE: the paths in the path list must be expressed as UNIX paths, separated by the forward-slash character ('/'). =item * search_path_on_include - if set to a true value the module will search from the top of the array of paths specified by the path option on every and use the first matching template found. The normal behavior is to look only in the current directory for a template to include. Defaults to 0. =back =item Debugging Options =over 4 =item * debug - if set to 1 the module will write random debugging information to STDERR. Defaults to 0. =item * HTML::Template use many cache debug options such as stack_debug, cache_debug, shared_cache_debug, memory_debug. Since HTML::Template::Pro parses and outputs templates at once, it silently ignores those options. =back =item Miscellaneous Options =over 4 =item * associate - this option allows you to inherit the parameter values from other objects. The only requirement for the other object is that it have a C method that works like HTML::Template's C. A good candidate would be a CGI.pm query object. Example: my $query = new CGI; my $template = HTML::Template->new(filename => 'template.tmpl', associate => $query); Now, C<< $template->output() >> will act as though $template->param('FormField', $cgi->param('FormField')); had been specified for each key/value pair that would be provided by the C<< $cgi->param() >> method. Parameters you set directly take precedence over associated parameters. You can specify multiple objects to associate by passing an anonymous array to the associate option. They are searched for parameters in the order they appear: my $template = HTML::Template->new(filename => 'template.tmpl', associate => [$query, $other_obj]); =begin comment The old associateCGI() call is still supported, but should be considered obsolete. =end comment NOTE: If the option case_sensitive => 0, the parameter names are matched in a case-insensitive manner. If you have two parameters in a CGI object like 'NAME' and 'Name' one will be chosen randomly by associate. This behavior can be changed by setting option case_sensitive to 1. =item * case_sensitive - setting this option to true causes HTML::Template to treat template variable names case-sensitively. The following example would only set one parameter without the "case_sensitive" option: my $template = HTML::Template->new(filename => 'template.tmpl', case_sensitive => 1); $template->param( FieldA => 'foo', fIELDa => 'bar', ); This option defaults to off to keep compatibility with HTML::Template. Nevertheless, setting case_sensitive => 1 is encouraged, because it significantly improves performance. If case_sensitive is set to 0, the perl wrapper is forced to lowercase keys in every hash it will find in "param" tree, which is sometimes an expensive operation. To avoid this, set case_sensitive => 1. If case conversion is necessary, there is an alternative lightweight option tmpl_var_case, which is HTML::Template::Pro specific. Note that case_sensitive is wrapper-only option: it is not implemented in the htmltmplpro C library. =item * tmpl_var_case - this option is similar to case_sensitive, but is implemented directly in the htmltmplpro C library. Instead of converting keys in every hash of "param" tree, it converts the name of variable. For example, in case of setting tmpl_var_case = ASK_NAME_AS_IS | ASK_NAME_LOWERCASE | ASK_NAME_UPPERCASE will cause HTML::Template::Pro to look into "param" tree for 3 names: CamelCaseName, camelcasename, and CAMELCASENAME. By default, the name is asked "as is". =item * loop_context_vars - when this parameter is set to true (it is false by default) four loop context variables are made available inside a loop: __first__, __last__, __inner__, __odd__. They can be used with , and to control how a loop is output. In addition to the above, a __counter__ var is also made available when loop context variables are turned on. Example: This only outputs on the first pass. This outputs every other pass, on the odd passes. This outputs every other pass, on the even passes. This outputs on passes that are neither first nor last. This is pass number . This only outputs on the last pass. One use of this feature is to provide a "separator" similar in effect to the perl function join(). Example: and , . Would output (in a browser) something like: Apples, Oranges, Brains, Toes, and Kiwi. Given an appropriate C call, of course. NOTE: A loop with only a single pass will get both __first__ and __last__ set to true, but not __inner__. NOTE: in the original HTML::Template with case_sensitive = 1 and loop_context_vars the special loop variables are available in lower-case only. In HTML::Template::Pro they are recognized regardless of case. =item * no_includes - set this option to 1 to disallow the tag in the template file. This can be used to make opening untrusted templates B less dangerous. Defaults to 0. =item * max_includes - set this variable to determine the maximum depth that includes can reach. Set to 10 by default. Including files to a depth greater than this value causes an error message to be displayed. Set to 0 to disable this protection. =item * global_vars - normally variables declared outside a loop are not available inside a loop. This option makes s like global variables in Perl - they have unlimited scope. This option also affects and . Example: This is a normal variable: .

Here it is inside the loop:

Normally this wouldn't work as expected, since 's value outside the loop is not available inside the loop. The global_vars option also allows you to access the values of an enclosing loop within an inner loop. For example, in this loop the inner loop will have access to the value of OUTER_VAR in the correct iteration: OUTER: INNER: INSIDE OUT: B: C is not C (which does not exist). That means that loops you declare at one scope are not available inside other loops even when C is on. =item * path_like_variable_scope - this option switches on a Shigeki Morimoto extension to HTML::Template::Pro that allows access to variables that are outside the current loop scope using path-like expressions. Example: {{{ }}} =item * filter - this option allows you to specify a filter for your template files. A filter is a subroutine that will be called after HTML::Template reads your template file but before it starts parsing template tags. In the most simple usage, you simply assign a code reference to the filter parameter. This subroutine will receive a single argument - a reference to a string containing the template file text. Here is an example that accepts templates with tags that look like "!!!ZAP_VAR FOO!!!" and transforms them into HTML::Template tags: my $filter = sub { my $text_ref = shift; $$text_ref =~ s/!!!ZAP_(.*?)!!!//g; }; # open zap.tmpl using the above filter my $template = HTML::Template->new(filename => 'zap.tmpl', filter => $filter); More complicated usages are possible. You can request that your filter receive the template text as an array of lines rather than as a single scalar. To do that you need to specify your filter using a hash-ref. In this form you specify the filter using the C key and the desired argument format using the C key. The available formats are C and C. Using the C format will incur a performance penalty but may be more convenient in some situations. my $template = HTML::Template->new(filename => 'zap.tmpl', filter => { sub => $filter, format => 'array' }); You may also have multiple filters. This allows simple filters to be combined for more elaborate functionality. To do this you specify an array of filters. The filters are applied in the order they are specified. my $template = HTML::Template->new(filename => 'zap.tmpl', filter => [ { sub => \&decompress, format => 'scalar' }, { sub => \&remove_spaces, format => 'array' } ]); The specified filters will be called for any TMPL_INCLUDEed files just as they are for the main template file. =item * default_escape - Set this parameter to "HTML", "URL" or "JS" and HTML::Template will apply the specified escaping to all variables unless they declare a different escape in the template. =back =back =cut =head2 param() C can be called in a number of ways 1) To return a list of parameters in the template : ( this features is distinct in HTML::Template::Pro: it returns a list of parameters _SET_ after new() ) my @parameter_names = $self->param(); 2) To return the value set to a param : my $value = $self->param('PARAM'); 3) To set the value of a parameter : # For simple TMPL_VARs: $self->param(PARAM => 'value'); # with a subroutine reference that gets called to get the value # of the scalar. The sub will receive the template object as a # parameter. $self->param(PARAM => sub { return 'value' }); # And TMPL_LOOPs: $self->param(LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ] ); 4) To set the value of a a number of parameters : # For simple TMPL_VARs: $self->param(PARAM => 'value', PARAM2 => 'value' ); # And with some TMPL_LOOPs: $self->param(PARAM => 'value', PARAM2 => 'value', LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ], ANOTHER_LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ] ); 5) To set the value of a a number of parameters using a hash-ref : $self->param( { PARAM => 'value', PARAM2 => 'value', LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ], ANOTHER_LOOP_PARAM => [ { PARAM => VALUE_FOR_FIRST_PASS, ... }, { PARAM => VALUE_FOR_SECOND_PASS, ... } ... ] } ); =cut =pod =head2 clear_params() Sets all the parameters to undef. Useful internally, if nowhere else! =head2 output() output() returns the final result of the template. In most situations you'll want to print this, like: print $template->output(); When output is called each occurrence of is replaced with the value assigned to "name" via C. If a named parameter is unset it is simply replaced with ''. are evaluated once per parameter set, accumulating output on each pass. Calling output() is guaranteed not to change the state of the Template object, in case you were wondering. This property is mostly important for the internal implementation of loops. You may optionally supply a filehandle to print to automatically as the template is generated. This may improve performance and lower memory consumption. Example: $template->output(print_to => *STDOUT); The return value is undefined when using the C option. =head2 query() This method is not supported in HTML::Template::Pro. =begin comment This method allow you to get information about the template structure. It can be called in a number of ways. The simplest usage of query is simply to check whether a parameter name exists in the template, using the C option: if ($template->query(name => 'foo')) { # do something if a varaible of any type # named FOO is in the template } This same usage returns the type of the parameter. The type is the same as the tag minus the leading 'TMPL_'. So, for example, a TMPL_VAR parameter returns 'VAR' from C. if ($template->query(name => 'foo') eq 'VAR') { # do something if FOO exists and is a TMPL_VAR } Note that the variables associated with TMPL_IFs and TMPL_UNLESSs will be identified as 'VAR' unless they are also used in a TMPL_LOOP, in which case they will return 'LOOP'. C also allows you to get a list of parameters inside a loop (and inside loops inside loops). Example loop: And some query calls: # returns 'LOOP' $type = $template->query(name => 'EXAMPLE_LOOP'); # returns ('bop', 'bee', 'example_inner_loop') @param_names = $template->query(loop => 'EXAMPLE_LOOP'); # both return 'VAR' $type = $template->query(name => ['EXAMPLE_LOOP', 'BEE']); $type = $template->query(name => ['EXAMPLE_LOOP', 'BOP']); # and this one returns 'LOOP' $type = $template->query(name => ['EXAMPLE_LOOP', 'EXAMPLE_INNER_LOOP']); # and finally, this returns ('inner_bee', 'inner_bop') @inner_param_names = $template->query(loop => ['EXAMPLE_LOOP', 'EXAMPLE_INNER_LOOP']); # for non existent parameter names you get undef # this returns undef. $type = $template->query(name => 'DWEAZLE_ZAPPA'); # calling loop on a non-loop parameter name will cause an error. # this dies: $type = $template->query(loop => 'DWEAZLE_ZAPPA'); As you can see above the C option returns a list of parameter names and both C and C take array refs in order to refer to parameters inside loops. It is an error to use C with a parameter that is not a loop. Note that all the names are returned in lowercase and the types are uppercase. Just like C, C with no arguments returns all the parameter names in the template at the top level. =end comment =cut =head1 DISTINCTIONS AND INCOMPATIBILITIES The main reason for small incompatibilities between HTML::Template and HTML::Template::Pro is the fact that HTML::Template builds parsed tree of template before anything else. So it has an additional information which HTML::Template::Pro obtains during output. In cases when HTML::Template dies, such as no_includes, bad syntax of template, max_includes and so on, HTML::Template::Pro issues warning to STDERR and continue. =head2 new() the following options are not supported in HTML::Template::Pro: vanguard_compatibility_mode. The options die_on_bad_params and strict are ignored. HTML::Template::Pro behaves itself as HTML::Template called with die_on_bad_params => 0, strict => 0. It currently can't be changed, because HTML::Template::Pro can't know whether a parameter is bad before it start output. This may change in future releases. To keep backward compatibility with HTML::Template, you should explicitly call its new() with die_on_bad_params => 0, strict => 0. =head2 query() This method is not supported in HTML::Template::Pro. =head2 param() param() without arguments should return a list of parameters in the template. In HTML::Template::Pro it returns a list of parameters set after new(). =head1 BUGS With I and I the special loop variables should be available in lower-case only. I is case_sensitive inside loops. =begin comment I am aware of no bugs - if you find one, join the mailing list and tell us about it. You can join the HTML::Template mailing-list by visiting: http://lists.sourceforge.net/lists/listinfo/html-template-users Of course, you can still email me directly (sam@tregar.com) with bugs, but I reserve the right to forward bug reports to the mailing list. =end comment When submitting bug reports, be sure to include full details, including the VERSION of the module, a test script and a test template demonstrating the problem! =begin comment If you're feeling really adventurous, HTML::Template has a publically available Subversion server. See below for more information in the PUBLIC SUBVERSION SERVER section. =end comment =head1 EXPR: DEFINING NEW FUNCTIONS To define a new function, pass a C option to new: $t = HTML::Template::Pro->new(filename => 'foo.tmpl', functions => { func_name => \&func_handler }); or $t = HTML::Template::Expr->new(filename => 'foo.tmpl', functions => { func_name => \&func_handler }); Or, you can use C class method to register the function globally: HTML::Template::Pro->register_function(func_name => \&func_handler); or HTML::Template::Expr->register_function(func_name => \&func_handler); You provide a subroutine reference that will be called during output. It will receive as arguments the parameters specified in the template. For example, here's a function that checks if a directory exists: sub directory_exists { my $dir_name = shift; return 1 if -d $dir_name; return 0; } If you call HTML::Template::Expr->new() with a C arg: $t = HTML::Template::Expr->new(filename => 'foo.tmpl', functions => { directory_exists => \&directory_exists }); Then you can use it in your template: This can be abused in ways that make my teeth hurt. =head2 register_function() extended usage (HTML::Template::Pro specific) C can be called in a number of ways 1) To fetch the names of registered functions in the template: =over 4 =item * if C was called in a newly created object it returns a list of function's that set _after_ or _in_ new(): my @registered_functions_names = $self->register_function(); =item * in global context C will return a list of _ALL_ avalible function's my @all_avalible_functions_names = HTML::Template::Pro->register_function(); 2) To fetching the function by name: my $function = $self->register_function('FUNCTION_NAME'); 3) To set a new function: # Set function, that can be called in templates, wich are processed # by the current object: $self->register_function(foozicate => sub { ... }); # Set global function: HTML::Template::Pro->register_function(barify => sub { ... }); =back for details of "how to defined a function" see in L. =head1 EXPR MOD_PERL TIP C class method can be called in mod_perl's startup.pl to define widely used common functions to HTML::Template::Expr. Add something like this to your startup.pl: use HTML::Template::Pro; HTML::Template::Pro->register_function(foozicate => sub { ... }); HTML::Template::Pro->register_function(barify => sub { ... }); HTML::Template::Pro->register_function(baznate => sub { ... }); =head1 EXPR CAVEATS HTML::Template::Pro does not forces the HTML::Template global_vars option to be set, whereas currently HTML::Template::Expr does. Anyway, this also will hopefully go away in a future version of HTML::Template::Expr, so if you need global_vars in your templates then you should set it explicitly. =head1 CREDITS to Sam Tregar, sam@tregar.com Original credits of HTML::Template: This module was the brain child of my boss, Jesse Erlbaum ( jesse@vm.com ) at Vanguard Media ( http://vm.com ) . The most original idea in this module - the - was entirely his. Fixes, Bug Reports, Optimizations and Ideas have been generously provided by: Richard Chen Mike Blazer Adriano Nagelschmidt Rodrigues Andrej Mikus Ilya Obshadko Kevin Puetz Steve Reppucci Richard Dice Tom Hukins Eric Zylberstejn David Glasser Peter Marelas James William Carlson Frank D. Cringle Winfried Koenig Matthew Wickline Doug Steinwand Drew Taylor Tobias Brox Michael Lloyd Simran Gambhir Chris Houser Larry Moore Todd Larason Jody Biggs T.J. Mather Martin Schroth Dave Wolfe uchum Kawai Takanori Peter Guelich Chris Nokleberg Ralph Corderoy William Ward Ade Olonoh Mark Stosberg Lance Thomas Roland Giersig Jere Julian Peter Leonard Kenny Smith Sean P. Scanlon Martin Pfeffer David Ferrance Gyepi Sam Darren Chamberlain Paul Baker Gabor Szabo Craig Manley Richard Fein The Phalanx Project Sven Neuhaus Thanks! Original credits of HTML::Template::Expr: The following people have generously submitted bug reports, patches and ideas: Peter Leonard Tatsuhiko Miyagawa Thanks! =head1 WEBSITE You can find information about HTML::Template::Pro at: http://html-tmpl-pro.sourceforge.net You can find information about HTML::Template and other related modules at: http://html-template.sourceforge.net =begin comment =head1 PUBLIC SUBVERSION SERVER HTML::Template now has a publicly accessible Subversion server provided by SourceForge (www.sourceforge.net). You can access it by going to http://sourceforge.net/svn/?group_id=1075. Give it a try! =end comment =head1 AUTHOR Sam Tregar, sam@tregar.com (Main text) I. Vlasenko, Eviy@altlinux.orgE (Pecularities of HTML::Template::Pro) =head1 LICENSE HTML::Template : A module for using HTML Templates with Perl Copyright (C) 2000-2002 Sam Tregar (sam@tregar.com) This module is free software; you can redistribute it and/or modify it under the terms of either: a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" which comes with this module. 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 either the GNU General Public License or the Artistic License for more details. You should have received a copy of the Artistic License with this module, in the file ARTISTIC. If not, I'll be glad to provide one. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA =cut HTML-Template-Pro-0.9510/lib/HTML/Template/Pro/0000755000076400007640000000000012144122665017205 5ustar igorigorHTML-Template-Pro-0.9510/lib/HTML/Template/Pro/WrapAssociate.pm0000644000076400007640000000535711603320007022307 0ustar igorigorpackage HTML::Template::Pro::WrapAssociate; use strict; use Carp; use vars qw($VERSION @ISA); sub _wrap { my ($class, $associate_object, $is_case_sensitive, $is_strict_compatibility) = @_; if (ref($associate_object) && UNIVERSAL::can($associate_object,'param')) { my %hash; if ($is_case_sensitive) { tie %hash, $class, $associate_object; } else { foreach my $key ($associate_object->param()) { $hash{lc($key)} = $associate_object->param($key); } } return \%hash; } elsif (!$is_strict_compatibility && UNIVERSAL::isa($associate_object,'HASH')) { if ($is_case_sensitive) { return $associate_object; } else { my %hash; foreach my $key (keys(%$associate_object)) { $hash{lc($key)} = $associate_object->{$key}; } return \%hash; } } else { Carp::croak "bad value for associate: HTML::Template::Pro->new called with associate option, containing object of type " . ref($associate_object) . " which lacks a param() method and does not look like a hash!"; } } sub param { my $this = shift; return $this->[0]->param(@_); } sub TIEHASH { my ($class, $associate) = @_; my $self=[$associate,[]]; return bless $self, $class; }; sub FETCH { my ($this, $key) = @_; return $this->[0]->param($key); } sub EXISTS { my ($this, $key) = @_; return defined($this->[0]->param($key)); } sub FIRSTKEY{ my ($this) = @_; my @param=$this->[0]->param(); $this->[1]=\@param; return shift @{$this->[1]}; } sub NEXTKEY{ my ($this) = @_; return shift @{$this->[1]}; } sub STORE{} sub DELETE{} sub CLEAR{} sub SCALAR{} 1; __END__ #head1 NAME HTML::Template::Pro::WrapAssociate - internal wrapper for associated objects #head1 DESCRIPTION Original HTML::Template has an 'associate' option, that allows to specify an extra places whare to look for a variable value. They should have custom 'param' interface method, see L for details. This module wraps an object with custom 'param' interface method into a magic tied hash. Note that this module is for internal use only. #head1 AUTHOR I. Vlasenko, Eviy@altlinux.orgE #head1 COPYRIGHT AND LICENSE Copyright (C) 2005-2009 by I. Yu. Vlasenko. Pieces of code in Pro.pm and documentation of HTML::Template are copyright (C) 2000-2002 Sam Tregar (sam@tregar.com) The template syntax, interface conventions and a large piece of documentation of HTML::Template::AssociateProWrapper are based on CPAN module HTML::Template by Sam Tregar, sam@tregar.com. This library is free software; you can redistribute it and/or modify it under either the LGPL2+ or under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available. #cut HTML-Template-Pro-0.9510/templates-Pro/0000755000076400007640000000000012144122665016114 5ustar igorigorHTML-Template-Pro-0.9510/templates-Pro/test_esc2.out0000644000076400007640000000017711676075515020557 0ustar igorigor

test_esc2

%26foo%22bar%27%3C%2Fscript%3E%3D-%3B%2B%20\%3C%3E%22%3B%20%25FAhidden%3A%0D%0Aend Some%22%27%20Txt%27 HTML-Template-Pro-0.9510/templates-Pro/test_expr9.tmpl0000644000076400007640000000011111353202174021104 0ustar igorigor

test lex bug

n= HTML-Template-Pro-0.9510/templates-Pro/test_expr2.tmpl0000644000076400007640000000251611353202212021101 0ustar igorigor

test string expr

ONE lt THREE= ONE gt THREE= ONE ne THREE= ONE eq THREE= '1' lt '3'= '1' gt '3'= '1' ne '3'= '1' eq '3'= '1' lt THREE= '1' gt THREE= '1' ne THREE= '1' eq THREE= ONE lt '3'= ONE gt '3'= ONE ne '3'= ONE eq '3'= '100' lt '3'= '100' lt '30'= '100' le '30'= '100' gt '30'= '100' ge '30'= 100 lt '30'= 100 lt 30= 'aaa' le 'b'= 'aaa' ge 'b'= 'bbb' le 'a'= 'bbb' ge 'a'= 'bbb' cmp 'a'= 'aaa' cmp 'b'= ONE= foo= HTML-Template-Pro-0.9510/templates-Pro/test_expr4.out0000644000076400007640000000016511247777752020770 0ustar igorigor

test expr with var quote extension of Emiliano Bruno

${foo.bar}= HTML-Template-Pro-0.9510/templates-Pro/test_userfunc3.out0000644000076400007640000000012010617575046021622 0ustar igorigor

test_expr6 (per_object_call)

Z-arg Z-arg HTML-Template-Pro-0.9510/templates-Pro/test_include1.out0000644000076400007640000000062010617575362021417 0ustar igorigor

test_include1

undefined (TRUE), so including test_if2 ...

test_if2

undefined (TRUE) (if test 1) VAR2 defined (TRUE) (if test 2) defined (if test 3 level 1) VISIBLE VAR2 VISIBLE (if test 3 level 2) VAR2 defined VISIBLE (if test 3 level 3) --- visible ---

END test_if2

(include test 1) HTML-Template-Pro-0.9510/templates-Pro/test_expr9.out0000644000076400007640000000006711353202230020742 0ustar igorigor

test lex bug

n=2 HTML-Template-Pro-0.9510/templates-Pro/test_esc3.tmpl0000644000076400007640000000027010617575362020716 0ustar igorigor

test_esc3

HTML-Template-Pro-0.9510/templates-Pro/test_loop4.tmpl0000644000076400007640000000055510630015117021102 0ustar igorigor

test_loop4

We test inner loop variables
first: last: odd: inner: count:
HTML-Template-Pro-0.9510/templates-Pro/test_loop4.out0000644000076400007640000000074710630015427020744 0ustar igorigor

test_loop4

We test inner loop variables
first:1 last: 0 odd:1 inner:0 count:1
first:0 last: 0 odd:0 inner:1 count:2
first:0 last: 0 odd:1 inner:1 count:3
first:0 last: 1 odd:0 inner:0 count:4
HTML-Template-Pro-0.9510/templates-Pro/test_loop2.tmpl0000644000076400007640000000044011247207133021077 0ustar igorigor

test_loop2

We test simple loop
HTML-Template-Pro-0.9510/templates-Pro/test_userfunc6.tmpl0000644000076400007640000000014511237237607021776 0ustar igorigor

test on nested functions

HTML-Template-Pro-0.9510/templates-Pro/test_if5.tmpl0000644000076400007640000000100610617575362020542 0ustar igorigor HTML::Template::Pro test template TMPL_IF in "<>":
Variable 1 set!Variable 1 not set!
TMPL_IF in "<!-- -->":
Variable 1 set!Variable 1 not set!
HTML-Template-Pro-0.9510/templates-Pro/test_esc1.tmpl0000644000076400007640000000025610617575362020720 0ustar igorigor

test_esc1

HTML-Template-Pro-0.9510/templates-Pro/test_var3.out0000644000076400007640000000064211676076065020574 0ustar igorigor

test_var3

&foo"bar'=-;+ \<>"; %FAhidden: end %26foo%22bar%27%3C%2Fscript%3E%3D-%3B%2B%20\%3C%3E%22%3B%20%25FAhidden%3A%0D%0Aend &foo"bar'</script>=-;+ \<>"; %FAhidden: end \u0026foo\u0022bar\u0027\u003c/script\u003e\u003d\u002d\u003b\u002b \u005c\u003c\u003e\u0022\u003b %FAhidden:\u000d\u000aend

END test_var3

HTML-Template-Pro-0.9510/templates-Pro/empty.incl0000644000076400007640000000000010617575362020120 0ustar igorigorHTML-Template-Pro-0.9510/templates-Pro/test_loop6.out0000644000076400007640000000022011252243660020733 0ustar igorigor

test_loop6: global vars inside a loop

Inside a Loop 1 A B 2 A B 3 A B Outside a Loop A B

end test_loop6

HTML-Template-Pro-0.9510/templates-Pro/test_userfunc2.out0000644000076400007640000000055110617575362021632 0ustar igorigor

test_expr5 (include)

test_if2

undefined (TRUE) (if test 1) undefined (FALSE) (if test 2) defined (if test 3 level 1) HIDDEN

END test_if2

test_if1

------------------
defined (TRUE) (if test 1) defined (FALSE) (if test 2) HTML-Template-Pro-0.9510/templates-Pro/test_include3.tmpl0000644000076400007640000000022010617575362021562 0ustar igorigor

test_include3

including empty template After including empty template HTML-Template-Pro-0.9510/templates-Pro/test_loop2.out0000644000076400007640000000065211247207142020737 0ustar igorigor

test_loop2

We test simple loop
LOOP1-VAR1 LOOP1-VAR2 LOOP1-VAR3
LOOP2-VAR1 LOOP2-VAR2 LOOP2-VAR3
LOOP3-VAR1 LOOP3-VAR2 LOOP3-VAR3
LOOP4-VAR1 LOOP4-VAR2 LOOP4-VAR3
HTML-Template-Pro-0.9510/templates-Pro/test_userfunc1.out0000644000076400007640000000050510617575362021630 0ustar igorigor

test expr with perl-supplied functions

hello('dad')=hi, dad! lc('DAD')=dad lc(ONE)=1 sprintf('1+1=%d', TWO)=1+1=2

test expr with user-defined functions

registered_func('self')=self hello_string()=hello! arglist()=[] arglist('')=[] arglist('','')=[][] arglist('a','b')=[a][b] HTML-Template-Pro-0.9510/templates-Pro/test_include4.out0000644000076400007640000000013011252364033021401 0ustar igorigor

test_include path with default options

A-ROOT HTML-Template-Pro-0.9510/templates-Pro/test_if2.tmpl0000644000076400007640000000170110617575362020541 0ustar igorigor

test_if2

defined (FALSE) undefined (TRUE) (if test 1) defined (TRUE) undefined (FALSE) (if test 2) defined (if test 3 level 1) HIDDEN defined TRUE HIDDEN (if test 2) defined (if test 3 level 1) VISIBLE VISIBLE (if test 3 level 2) defined VISIBLE (if test 3 level 3) defined (if test 3 level 4 FALSE) HIDDEN --- visible --- (if test 3 level 3) HIDDEN (if test 3 level 2) HIDDEN

END test_if2

HTML-Template-Pro-0.9510/templates-Pro/test_include2.out0000644000076400007640000000240410617575362021422 0ustar igorigor

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include

test_include2

Before recursive include After recursive include After recursive include After recursive include After recursive include After recursive include After recursive include After recursive include After recursive include After recursive include After recursive include After recursive include After recursive include HTML-Template-Pro-0.9510/templates-Pro/test_esc4.tmpl0000644000076400007640000000040011433713764020707 0ustar igorigor

test_esc4

HTML-Template-Pro-0.9510/templates-Pro/test_if6.tmpl0000644000076400007640000000151310775214411020534 0ustar igorigor

test_if6 -- if enambled COMPAT_ALLOW_NAME_IN_CLOSING_TAG

we test that tmpl_else should be invisible in invisible context failed 1-0 failed 1-1 failed 1-2 failed 2-0 failed 2-1 failed 2-2 failed 3-0 failed 3-1 failed 3-2 failed 4-0 failed 4-1 failed 4-2

END test_if6

HTML-Template-Pro-0.9510/templates-Pro/test_expr8.out0000644000076400007640000000021510775214411020747 0ustar igorigor

test_expr8

We test addition 70 70 200001000000 70 70 1 HTML-Template-Pro-0.9510/templates-Pro/test_userfunc3.tmpl0000644000076400007640000000022110617575046021771 0ustar igorigor

test_expr6 (per_object_call)

HTML-Template-Pro-0.9510/templates-Pro/test_broken1.tmpl0000644000076400007640000000002510617575362021420 0ustar igorigor=-;+ \<>"; %FAhidden: end HTML-Template-Pro-0.9510/templates-Pro/test_loop5.tmpl0000644000076400007640000000023410617575362021117 0ustar igorigor

test_loop5

should be VAR1 should be VAR1

end test_loop5

HTML-Template-Pro-0.9510/templates-Pro/test_expr1.out0000644000076400007640000000057611265056256020760 0ustar igorigor

test numeric expr

ok true true ok true ok 2+2=4 ONE+2=3 ONE + TWO=3 THREE=3 (ONE+TWO)==THREE=1 ONE+TWO == THREE=1 (ONE+TWO == THREE) and (THREE && TWO) and sin(ONE)=1 sin(ONE)=0.841471 111.111 + 222.333555=333.444555 7%3=1 (70*5)%33-20=0 7 && 3=1 strings are true: 'aaa' && 'bbb'=1 'aaa' || 0=1 minus is handled properly: MINUSTEN+8=-2 HTML-Template-Pro-0.9510/templates-Pro/test_expr5.tmpl0000644000076400007640000000135011450360617021113 0ustar igorigor

test on string compare

true: false: false: false: false: false: false: false: testing unescape string false: true: badgood goodbad true: true: true: false: HTML-Template-Pro-0.9510/templates-Pro/test_broken.tmpl0000644000076400007640000000042110617575362021337 0ustar igorigor
HTML-Template-Pro-0.9510/templates-Pro/test_include5.tmpl0000644000076400007640000000016511252364275021567 0ustar igorigor

test_include: path with search_path_on_include

HTML-Template-Pro-0.9510/templates-Pro/test_var3.tmpl0000644000076400007640000000130610617575362020735 0ustar igorigor

test_var3

END test_var3

HTML-Template-Pro-0.9510/templates-Pro/test_expr7.out0000644000076400007640000000074710630025405020751 0ustar igorigor

test_expr7

We test inner loop variables
first:1 last: 0 odd:1 inner:0 count:1
first:0 last: 0 odd:0 inner:1 count:2
first:0 last: 0 odd:1 inner:1 count:3
first:0 last: 1 odd:0 inner:0 count:4
HTML-Template-Pro-0.9510/templates-Pro/test_if7.tmpl0000644000076400007640000000072210775214411020536 0ustar igorigor

test_if7

we test elsif here. test 1 var4 defined (FALSE) var2 defined (TRUE) else (FALSE) end if test 1. test 2 var4 undefined (TRUE) var2 defined (should be skipped) else (FALSE) end if test 2.

END test_if7

HTML-Template-Pro-0.9510/templates-Pro/test_var1.out0000644000076400007640000000063411247705032020556 0ustar igorigor

test_var1

------------------
VAR1 step1 VAR1 VAR1 step3 VAR1 VAR2 step5 VAR3 step6 VAR10 step7
VAR10 step8 VAR10 step9 VAR1 step10 test 1 passed. ':) template tags could be decorated as html comments test 2 passed. ':) template tags could also be decorated as xml (starting from version 0.90) VAR1 no trailing slash here. ----- end -------

end test_var1

HTML-Template-Pro-0.9510/templates-Pro/test_malloc.tmpl0000644000076400007640000000004110617575362021324 0ustar igorigor HTML-Template-Pro-0.9510/templates-Pro/test_var2.tmpl0000644000076400007640000000031510617575362020733 0ustar igorigor

test_var2

END test_var2

HTML-Template-Pro-0.9510/templates-Pro/test_var1.tmpl0000644000076400007640000000127411247704757020741 0ustar igorigor

test_var1

------------------
step1 step3 step5 step6 step7
step8 step9 step10 template tags could be decorated as html comments template tags could also be decorated as xml (starting from version 0.90) no trailing slash here. ----- end -------

end test_var1

HTML-Template-Pro-0.9510/templates-Pro/test_expr7.tmpl0000644000076400007640000000055510714321277021124 0ustar igorigor

test_expr7

We test inner loop variables
first: last: odd: inner: count:
HTML-Template-Pro-0.9510/templates-Pro/test_if5.out0000644000076400007640000000060510617575362020401 0ustar igorigor HTML::Template::Pro test template TMPL_IF in "<>":
Variable 1 set!
TMPL_IF in "<!-- -->":
Variable 1 set!
HTML-Template-Pro-0.9510/templates-Pro/test_loop3.tmpl0000644000076400007640000000164310617575362021122 0ustar igorigor

test_loop3

We test loops and nesting test failed test failed test failed test failed
test failed test failed
test passed test failed test failed HTML-Template-Pro-0.9510/templates-Pro/test_userfunc5.tmpl0000644000076400007640000000015211236341530021761 0ustar igorigor

test on nested functions

HTML-Template-Pro-0.9510/templates-Pro/test_expr6.out0000644000076400007640000000040711250506557020754 0ustar igorigor

test_expr14 (built-in functions)

int(5.1)=5 abs(-2)=2 abs(-2.0)=2 defined(0)=1 length(1)=1 length('abc')=3 length('ab\'c')=4 hex(123)=291 oct(123)=83 allowed by current rules - but should not crash int()=0 oct()=0 hex()=0 HTML-Template-Pro-0.9510/templates-Pro/test_userfunc4.out0000644000076400007640000000035610775214411021625 0ustar igorigor

test unescape in func args

arglist('\'','s\a\\nki')=['][sa\nki] arglist('\'','\a\\n')=['][a\n] arglist('\'','\a\\')=['][a\] arglist('\a\\')=[a\] arglist('\a')=[a] arglist('\\')=[\] arglist('\'')=['] HTML-Template-Pro-0.9510/templates-Pro/test_expr2.out0000644000076400007640000000075410617575362020763 0ustar igorigor

test string expr

ONE lt THREE=1 ONE gt THREE=0 ONE ne THREE=1 ONE eq THREE=0 '1' lt '3'=1 '1' gt '3'=0 '1' ne '3'=1 '1' eq '3'=0 '1' lt THREE=1 '1' gt THREE=0 '1' ne THREE=1 '1' eq THREE=0 ONE lt '3'=1 ONE gt '3'=0 ONE ne '3'=1 ONE eq '3'=0 '100' lt '3'=1 '100' lt '30'=1 '100' le '30'=1 '100' gt '30'=0 '100' ge '30'=0 100 lt '30'=1 100 lt 30=1 'aaa' le 'b'=1 'aaa' ge 'b'=0 'bbb' le 'a'=0 'bbb' ge 'a'=1 'bbb' cmp 'a'=1 'aaa' cmp 'b'=-1 ONE=1 foo=foo HTML-Template-Pro-0.9510/templates-Pro/test_loop1.out0000644000076400007640000000013610617575362020747 0ustar igorigor

test_loop1

We test empty and undefined loops HTML-Template-Pro-0.9510/templates-Pro/test_if4.out0000644000076400007640000000022310617575362020374 0ustar igorigor

test_if4

we test that tmpl_else should be invisible in invisible context

END test_if4

HTML-Template-Pro-0.9510/templates-Pro/test_expr3.tmpl0000644000076400007640000000021111230140653021074 0ustar igorigor

test nt aryphmetics

1+1= 2*2= 4/2= HTML-Template-Pro-0.9510/templates-Pro/test_esc4.out0000644000076400007640000000026411676075515020556 0ustar igorigor

test_esc4

\u0026foo\u0022bar\u0027\u003c/script\u003e\u003d\u002d\u003b\u002b \u005c\u003c\u003e\u0022\u003b %FAhidden:\u000d\u000aend VAR1 Some"' Txt' HTML-Template-Pro-0.9510/templates-Pro/test_include4.tmpl0000644000076400007640000000015511252363330021554 0ustar igorigor

test_include path with default options

HTML-Template-Pro-0.9510/templates-Pro/test_include1.tmpl0000644000076400007640000000044010617575362021564 0ustar igorigor

test_include1

defined (FALSE) undefined (TRUE), so including test_if2 ... (include test 1) HTML-Template-Pro-0.9510/templates-Pro/test_expr6.tmpl0000644000076400007640000000106611250506551021115 0ustar igorigor

test_expr14 (built-in functions)

int(5.1)= abs(-2)= abs(-2.0)= defined(0)= length(1)= length('abc')= length('ab\'c')= hex(123)= oct(123)= allowed by current rules - but should not crash int()= oct()= hex()= HTML-Template-Pro-0.9510/templates-Pro/test_include5.out0000644000076400007640000000013511252364314021411 0ustar igorigor

test_include: path with search_path_on_include

A-1 HTML-Template-Pro-0.9510/templates-Pro/test_loop6.tmpl0000644000076400007640000000043711252243650021111 0ustar igorigor

test_loop6: global vars inside a loop

Inside a Loop Outside a Loop

end test_loop6

HTML-Template-Pro-0.9510/templates-Pro/test_expr1.tmpl0000644000076400007640000000207510617575362021125 0ustar igorigor

test numeric expr

not okok truefalse truefalse not okok truefalse not okok 2+2= ONE+2= ONE + TWO= THREE= (ONE+TWO)==THREE= ONE+TWO == THREE= (ONE+TWO == THREE) and (THREE && TWO) and sin(ONE)= sin(ONE)= 111.111 + 222.333555= 7%3= (70*5)%33-20= 7 && 3= strings are true: 'aaa' && 'bbb'= 'aaa' || 0= minus is handled properly: MINUSTEN+8= HTML-Template-Pro-0.9510/templates-Pro/test_if3.tmpl0000644000076400007640000000031110617575362020536 0ustar igorigor

test_if3

We test that hash/array ref should be true test passed test failed HTML-Template-Pro-0.9510/templates-Pro/test_expr8.tmpl0000644000076400007640000000046110775214411021117 0ustar igorigor

test_expr8

We test addition HTML-Template-Pro-0.9510/templates-Pro/a.incl0000644000076400007640000000000711252363021017170 0ustar igorigorA-ROOT HTML-Template-Pro-0.9510/templates-Pro/test_if1.tmpl0000644000076400007640000000175610617575362020552 0ustar igorigor

test_if1

defined (FALSE) (if test 1) defined (TRUE) (if test 2) defined (if test 3 level 1) defined (if test 3 level 2) defined (if test 3 level 3) defined (if test 3 level 4 FALSE) ------------------
defined (TRUE) (if test 1) defined (FALSE) (if test 2) defined (if test 3 level 1) defined (if test 3 level 2) defined (if test 3 level 3) defined (if test 3 level 4) HTML-Template-Pro-0.9510/templates-Pro/test_if2.out0000644000076400007640000000043110617575362020373 0ustar igorigor

test_if2

undefined (TRUE) (if test 1) VAR2 defined (TRUE) (if test 2) defined (if test 3 level 1) VISIBLE VAR2 VISIBLE (if test 3 level 2) VAR2 defined VISIBLE (if test 3 level 3) --- visible ---

END test_if2

HTML-Template-Pro-0.9510/templates-Pro/test_userfunc1.tmpl0000644000076400007640000000113110617575362021771 0ustar igorigor

test expr with perl-supplied functions

hello('dad')= lc('DAD')= lc(ONE)= sprintf('1+1=%d', TWO)=

test expr with user-defined functions

registered_func('self')= hello_string()= arglist()= arglist('')= arglist('','')= arglist('a','b')= HTML-Template-Pro-0.9510/templates-Pro/test_loop1.tmpl0000644000076400007640000000041410617575362021113 0ustar igorigor

test_loop1

We test empty and undefined loops test failed test failed test failed test failed HTML-Template-Pro-0.9510/templates-Pro/test_if1.out0000644000076400007640000000055010617575362020374 0ustar igorigor

test_if1

VAR2 defined (TRUE) (if test 2) VAR1 defined (if test 3 level 1) VAR2 defined (if test 3 level 2) VAR2 defined (if test 3 level 3) ------------------
defined (TRUE) (if test 1) VAR1 defined (if test 3 level 1) VAR2 defined (if test 3 level 2) VAR2 defined (if test 3 level 3) defined (if test 3 level 4) HTML-Template-Pro-0.9510/templates-Pro/test_if3.out0000644000076400007640000000016010617575362020373 0ustar igorigor

test_if3

We test that hash/array ref should be true test passed HTML-Template-Pro-0.9510/templates-Pro/test_expr5.out0000644000076400007640000000032011450360734020742 0ustar igorigor

test on string compare

true:1 false:0 false:0 false:0 false:0 false:0 false:0 false:0 testing unescape string false:0 true:1 good good true:1 true:1 true:1 false:0 HTML-Template-Pro-0.9510/templates-Pro/test_if4.tmpl0000644000076400007640000000141210617575362020542 0ustar igorigor

test_if4

we test that tmpl_else should be invisible in invisible context failed 1-0 failed 1-1 failed 1-2 failed 2-0 failed 2-1 failed 2-2 failed 3-0 failed 3-1 failed 3-2 failed 4-0 failed 4-1 failed 4-2

END test_if4

HTML-Template-Pro-0.9510/templates-Pro/test_loop3.out0000644000076400007640000000076110617575362020755 0ustar igorigor

test_loop3

We test loops and nesting
LOOP1-VAR1 LOOP1-VAR2 LOOP1-VAR3
LOOP2-VAR1 LOOP2-VAR2 LOOP2-VAR3
LOOP3-VAR1 LOOP3-VAR2 LOOP3-VAR3
LOOP4-VAR1 LOOP4-VAR2 LOOP4-VAR3
VAR2 test passed HTML-Template-Pro-0.9510/templates-Pro/test_if7.out0000644000076400007640000000027410775214411020373 0ustar igorigor

test_if7

we test elsif here. test 1 VAR2 var2 defined (TRUE) end if test 1. test 2 var4 undefined (TRUE) end if test 2.

END test_if7

HTML-Template-Pro-0.9510/templates-Pro/test_userfunc5.out0000644000076400007640000000011611236341535021621 0ustar igorigor

test on nested functions

F1: 1 F2: 2 3 HTML-Template-Pro-0.9510/templates-Pro/test_userfunc6.out0000644000076400007640000000010211236753501021615 0ustar igorigor

test on nested functions

1 HTML-Template-Pro-0.9510/templates-Pro/test_if6.out0000644000076400007640000000030310775214411020363 0ustar igorigor

test_if6 -- if enambled COMPAT_ALLOW_NAME_IN_CLOSING_TAG

we test that tmpl_else should be invisible in invisible context

END test_if6

HTML-Template-Pro-0.9510/templates-Pro/test_expr3.out0000644000076400007640000000011511230140744020733 0ustar igorigor

test nt aryphmetics

1+1=2 2*2=4 4/2=2 HTML-Template-Pro-0.9510/templates-Pro/test_broken1.out0000644000076400007640000000000610617575362021252 0ustar igorigor'ONE> HTML-Template-Pro-0.9510/templates-Pro/test_loop5.out0000644000076400007640000000016710617575362020757 0ustar igorigor

test_loop5

should be VAR1 should be VAR1 should be VAR1 should be VAR1

end test_loop5

HTML-Template-Pro-0.9510/templates-Pro/test_userfunc2.tmpl0000644000076400007640000000021310617575362021772 0ustar igorigor

test_expr5 (include)

HTML-Template-Pro-0.9510/templates-Pro/test_esc2.tmpl0000644000076400007640000000033211251221506020673 0ustar igorigor

test_esc2

HTML-Template-Pro-0.9510/templates-Pro/test_esc3.out0000644000076400007640000000014411676076065020553 0ustar igorigor

test_esc3

&foo"bar'</script>=-;+ \<>"; %FAhidden: end HTML-Template-Pro-0.9510/templates-Pro/test_userfunc4.tmpl0000644000076400007640000000067410775214411021775 0ustar igorigor

test unescape in func args

arglist('\'','s\a\\nki')= arglist('\'','\a\\n')= arglist('\'','\a\\')= arglist('\a\\')= arglist('\a')= arglist('\\')= arglist('\'')= HTML-Template-Pro-0.9510/templates-Pro/test_expr4.tmpl0000644000076400007640000000020411247777751021126 0ustar igorigor

test expr with var quote extension of Emiliano Bruno

${foo.bar}= HTML-Template-Pro-0.9510/templates-Pro/test_include3.out0000644000076400007640000000016010617575362021420 0ustar igorigor

test_include3

including empty template After including empty template HTML-Template-Pro-0.9510/Pro.xs0000644000076400007640000005157112144122512014474 0ustar igorigor#define PERLIO_NOT_STDIO 0 /* For co-existence with stdio only */ #define PERL_NO_GET_CONTEXT /* we want efficiency */ #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif #include #include #include "ppport.h" #ifdef USE_SYSTEM_HTP_HEADER #include #else #include "tmplpro.h" #endif typedef PerlIO * OutputStream; struct perl_callback_state { SV* perl_obj_self_ptr; AV* filtered_tmpl_array; AV* pool_for_perl_vars; int force_untaint; }; static int debuglevel=0; /* endnext points on next character to end of interval as in c++ */ static void write_chars_to_file (ABSTRACT_WRITER* OutputFile, const char* begin, const char* endnext) { dTHX; /* fetch context */ PerlIO_write((PerlIO*)OutputFile,begin, endnext-begin); } /* endnext points on next to end character of the interval */ static void write_chars_to_string (ABSTRACT_WRITER* OutputString, const char* begin, const char* endnext) { dTHX; /* fetch context */ sv_catpvn((SV*)OutputString, begin, endnext-begin); } static ABSTRACT_VALUE* get_ABSTRACT_VALUE_impl (ABSTRACT_DATASTATE* none, ABSTRACT_MAP* ptr_HV, PSTRING name) { dTHX; /* fetch context */ return hv_fetch((HV*) ptr_HV,name.begin, name.endnext-name.begin, 0); } static SV* call_coderef (SV* coderef) { SV* SVretval; I32 count; dTHX; /* fetch context */ /* TODO: G_EVAL and error handler */ dSP; /* let perl clean up mortals after the end of output() call ENTER; SAVETMPS;*/ PUSHMARK(SP); PUTBACK; /* in fact, isn't needed -- nothing is pushed and G_NOARGS is used */ count = call_sv(coderef, G_EVAL|G_SCALAR|G_NOARGS); SPAGAIN; /* Check the eval first */ if (SvTRUE(ERRSV)) { STRLEN n_a; printf ("Pro.xs: param tree code reference exited abnormally - %s\n", SvPV(ERRSV, n_a)); SVretval=POPs; /* undef */ } else { if (count != 1) croak("Pro.xs: internal context error (got %d) while calling CODE reference\n", (int)count); SVretval=POPs; } PUTBACK; /* let perl clean up mortals after the end of output() call FREETMPS; LEAVE;*/ return SVretval; } static PSTRING ABSTRACT_VALUE2PSTRING_impl (ABSTRACT_DATASTATE* callback_state, ABSTRACT_VALUE* valptr) { STRLEN len=0; PSTRING retval={NULL,NULL}; SV* SVval; dTHX; /* fetch context */ if (valptr==NULL) return retval; SVval = *((SV**) valptr); SvGETMAGIC(SVval); if (SvOK(SVval) && SvROK(SVval)) { if (SvTYPE(SvRV(SVval))==SVt_PVCV) { SVval = call_coderef(SVval); } else if(SvTYPE(SvRV(SVval))==SVt_PV) { SVval = SvRV(SVval); } SvGETMAGIC(SVval); } if (!SvOK(SVval)) return retval; /* TODO param resource deallocation */ if (((struct perl_callback_state*) callback_state)->force_untaint && SVval && SvTAINTED(SVval)) croak("force_untaint: got tainted value %" SVf, SVval); retval.begin=SvPV(SVval, len); retval.endnext=retval.begin+len; return retval; } static int is_ABSTRACT_VALUE_true_impl (ABSTRACT_DATASTATE* none, ABSTRACT_VALUE* valptr) { SV* SVval; dTHX; /* fetch context */ if (valptr==NULL) return 0; SVval = *((SV**) valptr); if (SvROK(SVval)) { if ((SvTYPE(SvRV(SVval)) == SVt_PVCV)) { SVval = call_coderef(SVval); } else /* arrayptr : in HTML::Template, true if len(array)>0 */ if ((SvTYPE(SvRV(SVval)) == SVt_PVAV) && (av_len((AV *)SvRV(SVval))<0)) { return 0; } else return 1; } /* in any place where I receive a value of which I don't know the origin, I should call SvGETMAGIC first. */ SvGETMAGIC(SVval); if(SvTRUE(SVval)) return 1; return 0; } static ABSTRACT_ARRAY* ABSTRACT_VALUE2ABSTRACT_ARRAY_impl (ABSTRACT_DATASTATE* none, ABSTRACT_VALUE* abstrvalptr) { SV* val = *((SV**) abstrvalptr); dTHX; /* fetch context */ SvGETMAGIC(val); if ((!SvROK(val)) || (SvTYPE(SvRV(val)) != SVt_PVAV)) return 0; return (ABSTRACT_ARRAY*) SvRV(val); } static int get_ABSTRACT_ARRAY_length_impl (ABSTRACT_DATASTATE* none, ABSTRACT_ARRAY* loops_AV) { dTHX; /* fetch context */ SvGETMAGIC((SV *)loops_AV); return av_len((AV *)loops_AV)+1; } static ABSTRACT_MAP* get_ABSTRACT_MAP_impl (ABSTRACT_DATASTATE* none, ABSTRACT_ARRAY* loops_AV, int loop) { dTHX; /* fetch context */ SV* val; SV** arrayvalptr = av_fetch((AV*)loops_AV, loop, 0); if (arrayvalptr==NULL) return NULL; val = *arrayvalptr; SvGETMAGIC(val); if ((!SvROK(val)) || (SvTYPE(SvRV(val)) != SVt_PVHV)) { return NULL; } else { return (ABSTRACT_MAP *)SvRV(*arrayvalptr); } } static const char* get_filepath (ABSTRACT_FINDFILE* callback_state, const char* filename, const char* prevfilename) { dTHX; /* fetch context */ dSP ; int count ; STRLEN len; char* filepath; SV* perlprevfile; SV* PerlSelfHTMLTemplatePro = ((struct perl_callback_state*)callback_state)->perl_obj_self_ptr; SV* perlretval = sv_2mortal(newSVpv(filename,0)); if (prevfilename) { perlprevfile=sv_2mortal(newSVpv(prevfilename,0)); } else { perlprevfile=sv_2mortal(newSV(0)); } ENTER ; SAVETMPS; PUSHMARK(SP) ; XPUSHs((SV*)PerlSelfHTMLTemplatePro); XPUSHs(perlretval); XPUSHs(perlprevfile); PUTBACK ; count = call_pv("_get_filepath", G_SCALAR); SPAGAIN ; if (count != 1) croak("Big troublen") ; perlretval=POPs; /* any memory leaks??? */ if (SvOK(perlretval)) { filepath = SvPV(perlretval, len); av_push(((struct perl_callback_state*)callback_state)->pool_for_perl_vars,perlretval); SvREFCNT_inc(perlretval); } else { filepath = NULL; } PUTBACK ; FREETMPS ; LEAVE ; return filepath; } static PSTRING load_file (ABSTRACT_FILTER* callback_state, const char* filepath) { dTHX; /* fetch context */ dSP ; int count ; STRLEN len; PSTRING tmpl; SV* templateptr; SV* perlretval = sv_2mortal(newSVpv(filepath,0)); ENTER ; SAVETMPS; PUSHMARK(SP) ; XPUSHs(((struct perl_callback_state*)callback_state)->perl_obj_self_ptr); XPUSHs(perlretval); PUTBACK ; count = call_pv("_load_template", G_SCALAR); SPAGAIN ; if (count != 1) croak("Big troublen") ; templateptr=POPs; /* any memory leaks??? */ if (SvOK(templateptr) && SvROK(templateptr)) { tmpl.begin = SvPV(SvRV(templateptr), len); tmpl.endnext=tmpl.begin+len; av_push(((struct perl_callback_state*)callback_state)->filtered_tmpl_array,templateptr); SvREFCNT_inc(templateptr); } else { croak("Big trouble! _load_template internal fatal error\n") ; } PUTBACK ; FREETMPS ; LEAVE ; return tmpl; } static int unload_file(ABSTRACT_FILTER* callback_state, PSTRING memarea) { dTHX; /* fetch context */ SvREFCNT_dec(av_pop(((struct perl_callback_state*)callback_state)->filtered_tmpl_array)); return 0; } static ABSTRACT_USERFUNC* is_expr_userfnc (ABSTRACT_FUNCMAP* FuncHash, PSTRING name) { dTHX; /* fetch context */ SV** hashvalptr=hv_fetch((HV *) FuncHash, name.begin, name.endnext-name.begin, 0); return hashvalptr; } static void free_expr_arglist(ABSTRACT_ARGLIST* arglist) { dTHX; /* fetch context */ if (NULL!=arglist) { av_undef((AV*) arglist); SvREFCNT_dec(arglist); } } static ABSTRACT_ARGLIST* init_expr_arglist(ABSTRACT_CALLER* none) { dTHX; /* fetch context */ return newAV(); } static void push_expr_arglist(ABSTRACT_ARGLIST* arglist, ABSTRACT_EXPRVAL* exprval) { dTHX; /* fetch context */ SV* val=NULL; int exprval_type=tmplpro_get_expr_type(exprval); PSTRING parg; switch (exprval_type) { case EXPR_TYPE_NULL: val=newSV(0);break; case EXPR_TYPE_INT: val=newSViv(tmplpro_get_expr_as_int64(exprval));break; case EXPR_TYPE_DBL: val=newSVnv(tmplpro_get_expr_as_double(exprval));break; case EXPR_TYPE_PSTR: parg=tmplpro_get_expr_as_pstring(exprval); val=newSVpvn(parg.begin, parg.endnext-parg.begin);break; default: die ("Perl wrapper: FATAL INTERNAL ERROR:Unsupported type %d in exprval", exprval_type); } av_push ((AV*) arglist, val); } static void call_expr_userfnc (ABSTRACT_CALLER* callback_state, ABSTRACT_ARGLIST* arglist, ABSTRACT_USERFUNC* hashvalptr, ABSTRACT_EXPRVAL* exprval) { dTHX; /* fetch context */ dSP ; char* empty=""; char* strval; SV ** arrval; SV * svretval; I32 i; I32 numretval; I32 arrlen=av_len((AV *) arglist); PSTRING retvalpstr = { empty, empty }; retvalpstr.begin=empty; retvalpstr.endnext=empty; if (hashvalptr==NULL) { die ("FATAL INTERNAL ERROR:Call_EXPR:function called but not exists"); tmplpro_set_expr_as_pstring(exprval,retvalpstr); return; } else if (! SvROK(*((SV**) hashvalptr)) || (SvTYPE(SvRV(*((SV**) hashvalptr))) != SVt_PVCV)) { die ("FATAL INTERNAL ERROR:Call_EXPR:not a function reference"); tmplpro_set_expr_as_pstring(exprval,retvalpstr); return; } ENTER ; SAVETMPS ; PUSHMARK(SP) ; for (i=0;i<=arrlen;i++) { arrval=av_fetch((AV *) arglist,i,0); if (arrval) XPUSHs(*arrval); else warn("INTERNAL: call: strange arrval"); } PUTBACK ; numretval=call_sv(*((SV**) hashvalptr), G_SCALAR); SPAGAIN ; if (numretval) { svretval=POPs; SvGETMAGIC(svretval); if (SvOK(svretval)) { if (SvIOK(svretval)) { tmplpro_set_expr_as_int64(exprval,SvIV(svretval)); } else if (SvNOK(svretval)) { tmplpro_set_expr_as_double(exprval,SvNV(svretval)); } else { STRLEN len=0; strval =SvPV(svretval, len); /* hack !!! */ av_push(((struct perl_callback_state*)callback_state)->pool_for_perl_vars,svretval); SvREFCNT_inc(svretval); retvalpstr.begin=strval; retvalpstr.endnext=strval +len; tmplpro_set_expr_as_pstring(exprval,retvalpstr); } } else { if (debuglevel>1) warn ("user defined function returned undef\n"); } } else { if (debuglevel) warn ("user defined function returned nothing\n"); } FREETMPS ; LEAVE ; return; } typedef void (*set_int_option_functype) (struct tmplpro_param*, int); static void set_integer_from_hash(pTHX_ HV* TheHash, char* key, struct tmplpro_param* param, set_int_option_functype setfunc) { SV** hashvalptr=hv_fetch(TheHash, key, strlen(key), 0); if (hashvalptr==NULL) return; setfunc(param,SvIV(*hashvalptr)); } static int get_integer_from_hash(pTHX_ HV* TheHash, char* key) { SV** hashvalptr=hv_fetch(TheHash, key, strlen(key), 0); if (hashvalptr==NULL) return 0; return SvIV(*hashvalptr); } static PSTRING get_string_from_hash(pTHX_ HV* TheHash, char* key) { SV** hashvalptr=hv_fetch(TheHash, key, strlen(key), 0); STRLEN len=0; char * begin; PSTRING retval={NULL,NULL}; if (hashvalptr==NULL) return retval; if (SvROK(*hashvalptr)) { /* if (SvTYPE(SvRV(*hashvalptr))!=SVt_PV) return (PSTRING) {NULL,NULL}; */ begin=SvPV(SvRV(*hashvalptr),len); } else { if (! SvPOK(*hashvalptr)) return retval; begin=SvPV(*hashvalptr,len); } retval.begin=begin; retval.endnext=begin+len; return retval; } static char** get_array_of_strings_from_hash(pTHX_ HV* TheHash, char* key, struct perl_callback_state* callback_state) { SV** valptr=hv_fetch(TheHash, key, strlen(key), 0); int amax; char** path=NULL; AV* pathAV; int i =0; char** j; SV* store; if (valptr!=NULL && SvROK(*valptr) && (SvTYPE(SvRV(*valptr)) == SVt_PVAV) ) { pathAV=(AV *)SvRV(*valptr); amax=av_len(pathAV); if (amax<0) { return NULL; } else { store = newSV(sizeof(char*)*(amax+2)); path = (char**) SvGROW(store, sizeof(char*)*(amax+2)); av_push(((struct perl_callback_state*)callback_state)->pool_for_perl_vars,store); SvREFCNT_inc(store); //path=(char**) malloc(sizeof(char*)*(amax+2)); j=path; for (i=0; i<=amax;i++) { valptr = av_fetch(pathAV,i,0); if (valptr!=NULL) { *j=SvPV_nolen(*valptr); j++; } *j=NULL; } } } else { warn ("get_array_of_strings:option %s not found :(\n", key); } return path; } static struct tmplpro_param* process_tmplpro_options (struct perl_callback_state* callback_state) { dTHX; /* fetch context */ HV* SelfHash; SV** hashvalptr; const char* tmpstring; SV* PerlSelfPtr=callback_state->perl_obj_self_ptr; int default_escape=HTML_TEMPLATE_OPT_ESCAPE_NO; /* main arguments */ PSTRING filename; PSTRING scalarref; /* internal initialization */ struct tmplpro_param* param=tmplpro_param_init(); /* setting initial hooks */ tmplpro_set_option_WriterFuncPtr(param, &write_chars_to_string); tmplpro_set_option_GetAbstractValFuncPtr(param, &get_ABSTRACT_VALUE_impl); tmplpro_set_option_AbstractVal2pstringFuncPtr(param, &ABSTRACT_VALUE2PSTRING_impl); tmplpro_set_option_AbstractVal2abstractArrayFuncPtr(param, &ABSTRACT_VALUE2ABSTRACT_ARRAY_impl); tmplpro_set_option_GetAbstractArrayLengthFuncPtr(param, &get_ABSTRACT_ARRAY_length_impl); tmplpro_set_option_IsAbstractValTrueFuncPtr(param, &is_ABSTRACT_VALUE_true_impl); tmplpro_set_option_GetAbstractMapFuncPtr(param, &get_ABSTRACT_MAP_impl); tmplpro_set_option_LoadFileFuncPtr(param, &load_file); tmplpro_set_option_UnloadFileFuncPtr(param, &unload_file); /* setting initial Expr hooks */ tmplpro_set_option_InitExprArglistFuncPtr(param, &init_expr_arglist); tmplpro_set_option_FreeExprArglistFuncPtr(param, &free_expr_arglist); tmplpro_set_option_PushExprArglistFuncPtr(param, &push_expr_arglist); tmplpro_set_option_CallExprUserfncFuncPtr(param, &call_expr_userfnc); tmplpro_set_option_IsExprUserfncFuncPtr(param, &is_expr_userfnc); /* end setting initial hooks */ /* setting perl globals */ tmplpro_set_option_ext_findfile_state(param,callback_state); tmplpro_set_option_ext_filter_state(param,callback_state); tmplpro_set_option_ext_calluserfunc_state(param,callback_state); tmplpro_set_option_ext_data_state(param,callback_state); /* end setting perl globals */ if ((!SvROK(PerlSelfPtr)) || (SvTYPE(SvRV(PerlSelfPtr)) != SVt_PVHV)) { die("FATAL:SELF:hash pointer was expected but not found"); } SelfHash=(HV *)SvRV(PerlSelfPtr); /* checking main arguments */ filename=get_string_from_hash(aTHX_ SelfHash,"filename"); scalarref=get_string_from_hash(aTHX_ SelfHash,"scalarref"); tmplpro_set_option_filename(param, filename.begin); tmplpro_set_option_scalarref(param, scalarref); if (filename.begin==NULL && scalarref.begin==NULL) { die ("bad arguments: expected filename or scalarref"); } /* setting expr_func */ hashvalptr=hv_fetch(SelfHash, "expr_func", 9, 0); /* 9=strlen("expr_func") */ if (!hashvalptr || !SvROK(*hashvalptr) || (SvTYPE(SvRV(*hashvalptr)) != SVt_PVHV)) die("FATAL:output:EXPR user functions not found"); tmplpro_set_option_expr_func_map(param, (HV *) SvRV(*hashvalptr)); /* end setting expr_func */ /* setting param_map */ tmplpro_clear_option_param_map(param); hashvalptr=hv_fetch(SelfHash, "associate", 9, 0); /* 9=strlen("associate") */ if (hashvalptr!=NULL && SvROK(*hashvalptr) && (SvTYPE(SvRV(*hashvalptr)) == SVt_PVAV)) { AV* associate = (AV*) SvRV(*hashvalptr); I32 i = av_len(associate); SV** arrayvalptr; while (i>=0) { arrayvalptr = av_fetch(associate, i, 0); if (arrayvalptr!=NULL && SvROK(*arrayvalptr)) tmplpro_push_option_param_map(param, (ABSTRACT_MAP *)SvRV(*arrayvalptr), 0); i--; } } hashvalptr=hv_fetch(SelfHash, "param_map", 9, 0); /* 9=strlen("param_map") */ /* TODO param deallocation on warn/die */ if (!hashvalptr || !SvROK(*hashvalptr) || (SvTYPE(SvRV(*hashvalptr)) != SVt_PVHV)) die("FATAL:output:param_map not found"); tmplpro_push_option_param_map(param, (ABSTRACT_MAP *)SvRV(*hashvalptr), 0); /* end setting param_map */ /* setting filter */ hashvalptr=hv_fetch(SelfHash, "filter", 6, 0); /* 6=strlen("filter") */ if (!hashvalptr || !SvROK(*hashvalptr) || (SvTYPE(SvRV(*hashvalptr)) != SVt_PVAV)) die("FATAL:output:filter not found"); if (av_len((AV*)SvRV(*hashvalptr))>=0) tmplpro_set_option_filters(param, 1); /* end setting param_map */ if (!get_integer_from_hash(aTHX_ SelfHash,"case_sensitive")) { tmplpro_set_option_tmpl_var_case(param, ASK_NAME_LOWERCASE); } set_integer_from_hash(aTHX_ SelfHash,"tmpl_var_case",param,tmplpro_set_option_tmpl_var_case); set_integer_from_hash(aTHX_ SelfHash,"max_includes",param,tmplpro_set_option_max_includes); set_integer_from_hash(aTHX_ SelfHash,"no_includes",param,tmplpro_set_option_no_includes); set_integer_from_hash(aTHX_ SelfHash,"search_path_on_include",param,tmplpro_set_option_search_path_on_include); set_integer_from_hash(aTHX_ SelfHash,"global_vars",param,tmplpro_set_option_global_vars); set_integer_from_hash(aTHX_ SelfHash,"debug",param,tmplpro_set_option_debug); debuglevel = tmplpro_get_option_debug(param); set_integer_from_hash(aTHX_ SelfHash,"loop_context_vars",param,tmplpro_set_option_loop_context_vars); set_integer_from_hash(aTHX_ SelfHash,"path_like_variable_scope",param,tmplpro_set_option_path_like_variable_scope); /* still unsupported */ set_integer_from_hash(aTHX_ SelfHash,"strict",param,tmplpro_set_option_strict); tmpstring=get_string_from_hash(aTHX_ SelfHash,"default_escape").begin; if (tmpstring && *tmpstring) { switch (*tmpstring) { case '1': case 'H': case 'h': /* HTML*/ default_escape = HTML_TEMPLATE_OPT_ESCAPE_HTML; break; case 'U': case 'u': /* URL */ default_escape = HTML_TEMPLATE_OPT_ESCAPE_URL; break; case 'J': case 'j': /* JS */ default_escape = HTML_TEMPLATE_OPT_ESCAPE_JS; break; case '0': case 'N': case 'n': /* 0 or NONE */ default_escape = HTML_TEMPLATE_OPT_ESCAPE_NO; break; default: warn("unsupported value of default_escape=%s. Valid values are HTML, URL or JS.\n",tmpstring); } tmplpro_set_option_default_escape(param, default_escape); } /* setting callback_state */ callback_state->force_untaint=get_integer_from_hash(aTHX_ SelfHash,"force_untaint"); /* end setting callback_state */ if (get_integer_from_hash(aTHX_ SelfHash,"__use_perl_find_file")) { tmplpro_set_option_FindFileFuncPtr(param, &get_filepath); } else { tmplpro_set_option_path(param, get_array_of_strings_from_hash(aTHX_ SelfHash, "path", callback_state)); tmplpro_set_option_FindFileFuncPtr(param, NULL); } #if defined _WIN32 /* hack; see https://rt.cpan.org/Public/Bug/Display.html?id=51218 */ tmplpro_set_option_template_root(param, getenv("HTML_TEMPLATE_ROOT")); #endif return param; } static void release_tmplpro_options(struct tmplpro_param* param, struct perl_callback_state callback_state) { dTHX; /* fetch context */ av_undef(callback_state.filtered_tmpl_array); av_undef(callback_state.pool_for_perl_vars); tmplpro_param_free(param); } MODULE = HTML::Template::Pro PACKAGE = HTML::Template::Pro void _init() CODE: tmplpro_procore_init(); void _done() CODE: tmplpro_procore_done(); int exec_tmpl(self_ptr,possible_output) SV* self_ptr; SV* possible_output; PREINIT: struct perl_callback_state callback_state = {self_ptr,newAV(),newAV(),0}; struct tmplpro_param* proparam=process_tmplpro_options(&callback_state); CODE: OutputStream output_stream; SvGETMAGIC(possible_output); if (!SvOK(possible_output)) { tmplpro_set_option_WriterFuncPtr(proparam,NULL); } else { output_stream = IoOFP(sv_2io(possible_output)); if (output_stream == NULL){ warn("Pro.xs:output: bad file descriptor in print_to option. Use stdout\n"); tmplpro_set_option_WriterFuncPtr(proparam,NULL); } else { tmplpro_set_option_ext_writer_state(proparam,output_stream); tmplpro_set_option_WriterFuncPtr(proparam,&write_chars_to_file); } } RETVAL = tmplpro_exec_tmpl(proparam); release_tmplpro_options(proparam,callback_state); if (RETVAL!=0) warn ("Pro.xs: non-zero exit code %d",RETVAL); OUTPUT: RETVAL SV* exec_tmpl_string(self_ptr) SV* self_ptr; PREINIT: int retstate; /* made mortal automatically */ SV* outputString; struct perl_callback_state callback_state = {self_ptr,newAV(),newAV(),0}; struct tmplpro_param* proparam=process_tmplpro_options(&callback_state); CODE: outputString=newSV(4000); /* 4000 allocated bytes -- should be approx. filesize*/ sv_setpvn(outputString, "", 0); tmplpro_set_option_WriterFuncPtr(proparam,&write_chars_to_string); tmplpro_set_option_ext_writer_state(proparam,outputString); retstate = tmplpro_exec_tmpl(proparam); release_tmplpro_options(proparam,callback_state); if (retstate!=0) warn ("Pro.xs: non-zero exit code %d",retstate); RETVAL = outputString; OUTPUT: RETVAL SV* exec_tmpl_string_builtin(self_ptr) SV* self_ptr; PREINIT: int retstate; SV* outputString; PSTRING inString; struct perl_callback_state callback_state = {self_ptr,newAV(),newAV(),0}; struct tmplpro_param* proparam=process_tmplpro_options(&callback_state); CODE: inString = tmplpro_tmpl2pstring(proparam, &retstate); outputString=newSV(inString.endnext-inString.begin+2); sv_setpvn(outputString, inString.begin, inString.endnext-inString.begin); release_tmplpro_options(proparam,callback_state); if (retstate!=0) warn ("Pro.xs: non-zero exit code %d",retstate); RETVAL = outputString; OUTPUT: RETVAL HTML-Template-Pro-0.9510/tmplpro_version.c0000644000076400007640000000160311450366440016766 0ustar igorigor/* -*- c -*- * File: tmplpro_version.c * Author: Igor Vlasenko * Created: Mon Jul 13 21:24:55 2009 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef PACKAGE_VERSION #ifdef VERSION #define PACKAGE_VERSION VERSION #else #define PACKAGE_VERSION "0.0(not defined)" #endif #endif /************************************************* * Return version string * *************************************************/ /* These macros are the standard way of turning unquoted text into C strings. They allow macros like PCRE_MAJOR to be defined without quotes, which is convenient for user programs that want to test its value. */ #define STRING(a) # a #define XSTRING(s) STRING(s) const char* tmplpro_version(void) { //return "" XSTRING(PACKAGE_VERSION) ; return "" PACKAGE_VERSION ; } /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/FAQ0000644000076400007640000000325611233510023013703 0ustar igorigorQ: > I have one quick question. I am unclear > how Template and Template::Pro interact. > > For instance, If I use the following code: > > use HTML::Template; > > my $template = HTML::Template->( filename => $tmp_file ); > > .. > $emplate->output(); > > With Template::Pro installed, will this code actually use Template::Pro > to parse and output the HTML? Or do I need to change the code to: > > use HTML::Template::Pro; > my $template = HTML::Template::Pro->new( filename => $tmp_file ) > A: use HTML::Template::Pro; then, if you don't 'use HTML::Template;' both are equivalent. so call my $template = HTML::Template->new( filename => $tmp_file ) also uses Pro. It is better to develop code with HTML::Template, because its debug facilities currently much better, but to swich ready code to HTML::Template::Pro (replacing use HTML::Template with HTML::Template::Pro) because it faster, lighter and so on. On the other hand, it is useful for writing scripts which works with both modules. in case when both modules are loaded use HTML::Template::Pro; use HTML::Template; my $template = HTML::Template::Pro->new( filename => $tmp_file ) uses Pro, but my $template = HTML::Template->new( filename => $tmp_file ) uses HTML::Template. > As I read the docs, the only reason to mix Template and Template::Pro > would be that you needed query support from HTML::Template? Maybe. I also used mixing it in the same file for benchmark.pl.t :) Q: > I am considering using your html::template::pro and I have a question > about the tmpl_include tag. Is it possible to put a template variable > inside the file tag? A: It is possible through EXPR="", for example, . HTML-Template-Pro-0.9510/MANIFEST0000644000076400007640000001215712144122665014517 0ustar igorigor.gitignore ARTISTIC Changes FAQ LGPL MANIFEST Makefile.PL Pro.xs README README.ru README.win32 TODO benchmark.pl.t builtin_findfile.inc calc.h calc.inc callback_stubs.inc cmp_expr.t expr.c expr.y expr_iface.c exprpstr.h exprpstr.inc exprtool.h exprtool.inc exprtype.h exprval.h lib/HTML/Template/PerlInterface.pod lib/HTML/Template/Pro.pm lib/HTML/Template/Pro/WrapAssociate.pm lib/HTML/Template/SYNTAX.pod loadfile.h loadfile.inc loopvar.inc optint.c optint.h pabidecl.h pabstract.h parse_expr.h pbuffer.c pbuffer.h pconst.h perl-HTML-Template-Pro.spec pmiscdef.h pparam.h pparam2proparam ppport.h procore.c procore.h proparam.c proparam.h proscope.h proscope.inc prostate.h prostate.inc provalue.h pstring.h pstrutils.h pstrutils.inc t/01coderefs.t t/02basic.t t/02random.t t/03complex.t t/04register.t t/05path_like_variable_scope.t t/06loop_var.t t/error_output.t t/HTML-Template-Expr.t t/HTML-Template-Pro.t t/HTML-Template.t t/HTML/Template/Pro/CommonTest.pm t/htp_version.t t/magic.t t/pod.t t/realloc.t t/templates/complex.tmpl t/templates/foo.tmpl t/templates/func.tmpl t/templates/loop.tmpl t/templates/negative.tmpl t/templates/numerics.tmpl t/templates/register.tmpl tags.inc tagstack.h tagstack.inc templates-Pro/a.incl templates-Pro/empty.incl templates-Pro/include/1/a.incl templates-Pro/include/2.out templates-Pro/include/2.tmpl templates-Pro/include/2/a.incl templates-Pro/include/3.tmpl templates-Pro/include/4.tmpl templates-Pro/include/a.incl templates-Pro/test_broken.tmpl templates-Pro/test_broken1.out templates-Pro/test_broken1.tmpl templates-Pro/test_esc1.out templates-Pro/test_esc1.tmpl templates-Pro/test_esc2.out templates-Pro/test_esc2.tmpl templates-Pro/test_esc3.out templates-Pro/test_esc3.tmpl templates-Pro/test_esc4.out templates-Pro/test_esc4.tmpl templates-Pro/test_expr1.out templates-Pro/test_expr1.tmpl templates-Pro/test_expr2.out templates-Pro/test_expr2.tmpl templates-Pro/test_expr3.out templates-Pro/test_expr3.tmpl templates-Pro/test_expr4.out templates-Pro/test_expr4.tmpl templates-Pro/test_expr5.out templates-Pro/test_expr5.tmpl templates-Pro/test_expr6.out templates-Pro/test_expr6.tmpl templates-Pro/test_expr7.out templates-Pro/test_expr7.tmpl templates-Pro/test_expr8.out templates-Pro/test_expr8.tmpl templates-Pro/test_expr9.out templates-Pro/test_expr9.tmpl templates-Pro/test_if1.out templates-Pro/test_if1.tmpl templates-Pro/test_if2.out templates-Pro/test_if2.tmpl templates-Pro/test_if3.out templates-Pro/test_if3.tmpl templates-Pro/test_if4.out templates-Pro/test_if4.tmpl templates-Pro/test_if5.out templates-Pro/test_if5.tmpl templates-Pro/test_if6.out templates-Pro/test_if6.tmpl templates-Pro/test_if7.out templates-Pro/test_if7.tmpl templates-Pro/test_include1.out templates-Pro/test_include1.tmpl templates-Pro/test_include2.out templates-Pro/test_include2.tmpl templates-Pro/test_include3.out templates-Pro/test_include3.tmpl templates-Pro/test_include4.out templates-Pro/test_include4.tmpl templates-Pro/test_include5.out templates-Pro/test_include5.tmpl templates-Pro/test_loop1.out templates-Pro/test_loop1.tmpl templates-Pro/test_loop2.out templates-Pro/test_loop2.tmpl templates-Pro/test_loop3.out templates-Pro/test_loop3.tmpl templates-Pro/test_loop4.out templates-Pro/test_loop4.tmpl templates-Pro/test_loop5.out templates-Pro/test_loop5.tmpl templates-Pro/test_loop6.out templates-Pro/test_loop6.tmpl templates-Pro/test_malloc.tmpl templates-Pro/test_userfunc1.out templates-Pro/test_userfunc1.tmpl templates-Pro/test_userfunc2.out templates-Pro/test_userfunc2.tmpl templates-Pro/test_userfunc3.out templates-Pro/test_userfunc3.tmpl templates-Pro/test_userfunc4.out templates-Pro/test_userfunc4.tmpl templates-Pro/test_userfunc5.out templates-Pro/test_userfunc5.tmpl templates-Pro/test_userfunc6.out templates-Pro/test_userfunc6.tmpl templates-Pro/test_var1.out templates-Pro/test_var1.tmpl templates-Pro/test_var2.out templates-Pro/test_var2.tmpl templates-Pro/test_var3.out templates-Pro/test_var3.tmpl templates/case_loop.tmpl templates/context.tmpl templates/counter.tmpl templates/default.tmpl templates/default_escape.tmpl templates/double_loop.tmpl templates/escape.tmpl templates/global-loops.tmpl templates/globals.tmpl templates/if.tmpl templates/ifelse.tmpl templates/include.tmpl templates/include_path/a.tmpl templates/include_path/b.tmpl templates/include_path/inner.tmpl templates/include_path/one.tmpl templates/include_path2/inner.tmpl templates/included.tmpl templates/included2.tmpl templates/js.tmpl templates/long_loops.tmpl templates/loop-context.tmpl templates/loop-if.tmpl templates/medium.tmpl templates/multiline_tags.tmpl templates/newline_test1.tmpl templates/newline_test2.tmpl templates/other-loop.tmpl templates/outer.tmpl templates/query-test.tmpl templates/query-test2.tmpl templates/recursive.tmpl templates/searchpath/included.tmpl templates/searchpath/three.tmpl templates/searchpath/two.tmpl templates/simple-loop-nonames.tmpl templates/simple-loop.tmpl templates/simple.tmpl templates/unless.tmpl templates/urlescape.tmpl templates/vanguard1.tmpl templates/vanguard2.tmpl test_crlf.out tmpllog.c tmpllog.h tmplpro.h tmplpro_version.c META.yml Module meta-data (added by MakeMaker) HTML-Template-Pro-0.9510/Changes0000644000076400007640000002567512144122276014670 0ustar igorigorRevision history for Perl extension HTML::Template::Pro. 0.01 Thu Feb 24 17:20:58 2005 - original version; created by h2xs 1.23 with options -A -O -b 5.5.0 -c -n HTML::Template::Pro --skip-exporter *.h 0.17 Tue Mar 8 10:19:28 2005 - First stable release. 0.26 Tue Mar 28 23:05:00 2005 - Full support of template syntax. 0.34 Mon Apr 11 16:31:36 2005 - First public release. - Distinctions from original HTML::Template: * No support for querying of templates, filter * No support for die_on_bad_params=1, strict=1: warn but not die issued when one tries to include template with no_includes=1 or exceeded max_includes. 0.35 Thu May 19 19:10:38 2005 - added warnings on incorrect tags like /tmpl_else 0.36 Thu May 23 19:10:38 2005 - merged HTML::Template 2.7 - added escape=js modifier from 2.7 0.37 Thu June 2 11:22:38 2005 - internal refactoring 0.38 Thu June 9 13:39:24 2005 - added basic support for EXPR="expr" from HTML::Template::Expr. it includes numeric arithmetic and comparisons. 0.40 Thu July 7 12:18:22 2005 - added support for string comparisions in EXPR="... " tags 0.41 Thu Jul 26 12:18:22 2005 - EXPR="... " tags: string type comparisions now support digits - grammar is improved - bug fixes 0.42 Thu Aug 2 16:26:35 2005 - complete support of EXPR="... " tags 0.43 Thu Aug 2 19:26:35 2005 - added documentation of EXPR="... " tags 0.44 Thu Aug 12 19:03:05 2005 - underquoted string fix (thanks to Christopher Pryce) 0.45 Thu Aug 19 21:17:01 2005 - merged patch of Emiliano Bruni With this extension, arbitrary chars can be used in variable name inside the 'EXPR' tag if bracketed in {}, as, for example, EXPR="{foo.bar} eq 'a'". 0.47 Wed Aug 31 19:29:31 2005 - merged patch of Stanislav Yadykin (implemented his regexp extension) 0.48 Wed Aug 31 20:31:41 2005 - added support for cmp in Expr - minor bugfixes in string comparison 0.50 Thu Sep 8 12:34:56 2005 - added new debug subsystem 0.51 Thu Sep 15 19:37:13 2005 - compatibility fixes in Expr 0.52 Thu Sep 30 14:39:00 2005 - Expr: fixed bug with empty string passed (thanks to Stanislav Yadykin) - added filters support 0.53 Tue Oct 5 20:02:15 2005 - fixed realloc bug (thanks to Stanislav Yadykin) - fixed comment-like tag bug (thanks to Niklas Bichinger) - fixed incorrect params processing (thanks to Jim Spath) 0.54 Mon Oct 17 10:08:14 2005 - portability fixes 0.55 Mon Oct 23 00:02:16 2005 - added IMITATE build option (imitate behavior of HTML::Template even on broken templates) requested by Jim Spath 0.56 Tue Nov 1 21:45:52 2005 - fixed memory leak (thanks to Jim Spath) - ELF symbols cleanup 0.57 Tue Nov 8 22:57:02 2005 - fixed bug in Expr with negative variables (thanks to Stanislav Yadykin) 0.58 Wed Nov 30 23:56:36 2005 - added support for Expr and Default in Include tag (thanks to Mike Greenish) - improvements in portability 0.59 Sun Jan 22 21:46:23 EET 2006 - improvements in portability 0.60 Thu Feb 2 14:36:26 EET 2006 - portability changes for Win32 (thanks to Viacheslav Sheveliov) - portability changes for hpux-pa-risc - tests data integrity test in Makefile.PL 0.61 Sat Feb 4 21:34:56 EET 2006 - Win32 support (thanks to Viacheslav Sheveliov) now HTML::Template::Pro should work on Win32. 0.62 Tue Feb 21 21:56:58 EET 2006 - added support for absence of mmap - extra compatibility mode for Win32. 0.63 Thu Apr 13 23:10:34 EEST 2006 - fixed bug in escape=url (thanks to Naoya Ito) - ABI design start 0.64 Tue Apr 18 22:42:08 EEST 2006 - synced with HTML::Template 2.8. - New: added default_escape option from HTML::Template 2.8 0.65 Fri May 4 10:58:59 EEST 2007 - added per-object register_function (thanks to Mike Greenish) Expr: fixed CPAN bugs (thanks to YORHEL for report) - numeric division now always return double (due to compains 1/3==0) - variables with _leading_underscore are allowed too - now expr supports inner_loop_variable 0.66 Sat Jun 2 14:49:07 2007 +0300 - added compatibility mode for closing tags. (thanks to Ton Hospel) - code cleanup - now library is reentrant: reentrant Scope() reentrant tagstack reentrant pbuffer 0.67 Sun Dec 2 16:47:15 EET 2007 - used long ariphmetics in EXPR instead of int one - fix in clear_params() thanks to Sergey Konovalov - fixed string escaping (see test_expr9) 0.68 Tue Jan 8 19:59:12 EET 2008 - fixed Windows compilation thanks to Vyacheslav Shevelyov 0.69 Thu Feb 28 06:46:17 EET 2008 - added elsif tag (requested by koha.org project) 0.70 Thu Apr 3 22:12:33 EEST 2008 - fixed regression in include scope (reported by Naxim Babych) 0.71 Sat Aug 16 15:05:01 EEST 2008 - fixed evaluation of variables in 'if' even in shadow context - fixed misconfig on Darvin (CPAN #38013) 0.72 Thu Dec 18 21:22:45 EET 2008 - added support of path through variable scope (by Shigeki Morimoto ) 0.73 Thu Apr 2 22:45:47 EEST 2009 - multiple memory leaks fixed (by Shigeki Morimoto ) 0.74 Fri Apr 3 20:19:32 EEST 2009 - merges from HTML::Template 2.9 - memory leaks fix (by Shigeki Morimoto ) 0.75 Wed Jul 1 23:23:36 EEST 2009 - pos value in log message. (Shigeki Morimoto ). - fixed cpan rt #38486 (mixed loops && global_var=1) 0.76 Sat Jul 11 10:46:27 EEST 2009 - work towards stable backend API. Current perl wrapper (Pro.xs) had to communicate with c backend using the param {...} struct(ure). That's still bearable if library is statically built in wrapper but unacceptable for public library that can be used by third-pary software (the layout of the structure is not a public API. It is not meant to be and is subject to change without prior notice). Instead, param structure is hidden behind the stable public library API getter and setter functions. tmplpro.h is now the API header. 0,77 Tue Jul 21 20:45:48 EEST 2009 - major API cleanups - concept mono wrapper (requested by Robert Henniger) 0.80 Thu Jul 23 20:08:47 EEST 2009 - added sypport for dynamically-linked perl wrapper. - C library is clearly separated from perl The main idea is following: Core C library should be as language neutral and portable as possible. As ANSI C lack standard map types, the code was designed so that wrapper should use its own language spacific (as Perl built-in hash) or library specific (C+glib, for example) HashOfHash type, and should provide abstract HashOfHash getters to the core C library as well as some other system specific calls. - released separate public backend library. (libhtmltmplpro.so.0.0.0, htmltmplpro.dll). - explicitly stated "LGPL or Artistic" license for the library. 0.81 Tue Jul 28 14:26:01 EEST 2009 - maintainance release, no API/ABI/behaviour changes - support for mingw 0.82 Thu Jul 30 11:56:16 EEST 2009 - maintainance release, no API/behaviour changes - CMake fixes - added library documentation - ABI: removed 2 garbage symbols - ABI is officially released as 0:0:0. - library default case-sensitive = 1 (Note: perl module dedault is 0). 0.83 Wed Aug 5 20:42:28 EEST 2009 - bugfix release: fixed nested functions bug thanks to Rebenok Kirill - added ABSTRACT_EXPRVAL to hide 0.82 implementation details. 0.84 Thu Aug 6 13:03:23 EEST 2009 - perl: register_function (name), register_function() calls thanks to Rebenok Kirill - bugfix: fixed function returned undef crush bug thanks to Rebenok Kirill 0.85 Sun Aug 9 19:31:26 EEST 2009 - windows specific fixes 0.86 Sat Aug 22 13:49:10 EEST 2009 - bugfix(expr): both strings should be unescaped. - bugfix(built-in find_file). - defined future NULL expr type. - added buit-in funcs: atan2, int, abs, defined, length. - mono: bugfix for case_sensitive=0 root keys. 0.87 Wed Aug 26 22:08:41 EEST 2009 - bugfix(expr): fixed memory leak. - perl: by default, built-in find_file implementation is used. the old perl find_file implementation can be re-enabled with __use_perl_find_file option. Please, report any misbehavior of built-in find_file implementation. 0.90 Mon Aug 31 18:44:39 EEST 2009 - perl: added force_untaint option - perl: bugfix: code references are now treated properly (evaluated dynamically). - perl: bugfix: support for magic arrays and hashes. - perl: now in void context output use built-in stdout. - perl: support for associate on library level. case_sensitive option removed from the C library. from now on it is wrapper-level option. - template syntax: added support for template tags decorated as xml like (thanks to Alberto Simaes). - C lib: added tmpl_var_case option. - C lib: tmplpro_get_expr_type has new return value EXPR_TYPE_NULL - expr: Modified Bruni extension: now recommended bracketing is ${} change {NAME} -> ${NAME} in Expr compatibility warning is ifdefed. - C lib: 1.0 ABI (see htmltmplpro/API for details) 0.92 Wed Oct 7 21:41:21 EEST 2009 - C lib: 1.1 (2:0:1) ABI (see htmltmplpro/API for details) - C lib: bugfix: memory corruption in ESCAPE=(html|js) bug seems to be very old, everyone is recommended to update. - php interface first release candidate. 0.93 Sun Nov 22 19:33:06 EET 2009 - C lib: bugfix: builtin_find_file on WIN32 does not work properly with absolute path names. - C lib: 1.2 (3:0:2) ABI (see htmltmplpro/API for details) added API call for alternate HTML_TEMPLATE_ROOT setup (hack around %ENV on WIN32). 0.94 Tue Feb 16 16:58:39 EET 2010 - c lib 1.3 (4:0:3) ABI (see htmltmplpro/API for details) - fixed lexer bug (thanks to Svetlana Safronova) 0.95 Fri May 21 22:25:10 EEST 2010 - perl specific: fixed bug in perl wrapper (list evaluated to false). thanks to Shigeki Morimoto for bugreport and patch. 0.9501 Wed Jun 9 10:36:07 EEST 2010 - bugfix release: segfault in EXPR log subroutine. thanks to Robert Hanniger and Mike Shogin 0.9502 Fri Jun 18 18:02:28 EEST 2010 - bugfix release: segfault for string operetions with undefined variables. Thanks to Mike Shogin. 0.9503 Sat Aug 28 18:00:49 EEST 2010 - log file is not truncated now in tmplpro_set_log_file. - freed memory access error fixed. - perl: CommonTest.pm hidden from installation - tests: added generic json-packed test data 0.9504 Tue Sep 28 17:16:55 EEST 2010 - bugfix in string comparision - spelling fix by gregor herrmann 0.9505 Fri Jul 1 13:27:10 EEST 2011 - bugfix in perl wrapper: fix in WrapAssociate.pm thanks to Viktor Bukhtoyarov 0.9506 Tue Oct 4 22:55:35 EEST 2011 - file name in logs 0.9507 Fri Dec 9 09:44:49 EET 2011 - patch for XSS vulnerability in HTML::Template::Pro thanks to Shigeki Morimoto shigeki.morimoto mixi.co.jp 0.9508 Mon Dec 26 16:13:37 EET 2011 - use unicode quoting in XSS vulnerability patch (more portable) thanks to Shigeki Morimoto shigeki.morimoto mixi.co.jp 0.9509 Tue Feb 28 21:15:28 EET 2012 - more verbose messages for tag stack underflow 0.9510 Mon May 13 11:30:15 EEST 2013 - rt.cpan.org #85211 - pod fix HTML-Template-Pro-0.9510/expr.y0000644000076400007640000004163611406441065014540 0ustar igorigor%pure-parser %lex-param {struct tmplpro_state* state} %lex-param {struct expr_parser* exprobj} %parse-param {struct tmplpro_state* state} %parse-param {struct expr_parser* exprobj} %parse-param {PSTRING* expr_retval_ptr} %{ #include /* For math functions, cos(), sin(), etc. */ #include /* for printf */ #include /* for malloc */ #include /* for yylex alnum */ #include "calc.h" /* Contains definition of `symrec'. */ #include "tmpllog.h" #include "pabstract.h" #include "prostate.h" #include "provalue.h" #include "pparam.h" #include "pmiscdef.h" /* for expr-specific only */ #include "exprtool.h" #include "exprpstr.h" #include "parse_expr.h" /* Remember unsigned char assert on win32 Debug Assertion Failed! f:\dd\vctools\crt_bld\self_x86\crt\src \isctype.c Expression:(unsigned)(c + 1) <= 256 */ %} %union { struct exprval numval; /* For returning numbers. */ const symrec_const *tptr; /* For returning symbol-table pointers. */ struct user_func_call extfunc; /* for user-defined function name */ PSTRING uservar; } %{ /* the second section is required as we use YYSTYPE here */ static void yyerror (struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr, char const *); static int yylex (YYSTYPE *lvalp, struct tmplpro_state* state, struct expr_parser* exprobj); %} %start line %token NUM /* poly type. */ %token EXTFUNC /* user-defined function */ %token BUILTIN_VAR /* built-in Variable */ %token BUILTIN_FNC_DD /* built-in D Function (D). */ %token BUILTIN_FNC_DDD /* built-in D Function (D,D). */ %token BUILTIN_FNC_EE /* built-in E Function (E). */ %token VAR /* user-supplied variable. */ %type numEXP %type arglist /*%right '='*/ %left OR %left AND %nonassoc strGT strGE strLT strLE strEQ strNE strCMP %nonassoc numGT numGE numLT numLE numEQ numNE '<' '>' %nonassoc reLIKE reNOTLIKE %left '-' '+' %left '*' '/' '%' %left '!' NOT NEG /* negation--unary minus */ %right '^' /* exponentiation */ %% /* The grammar follows. */ line: numEXP { expr_to_str1(state, &$1); *expr_retval_ptr=$1.val.strval; } ; /* | error { yyerrok; } */ numEXP: NUM { $$ = $1; } | BUILTIN_VAR { $$.type=EXPR_TYPE_DBL; $$.val.dblval = $1->var; } /*| BUILTIN_VAR '=' numEXP { $$ = $3; $1->value.var = $3; } */ | VAR { PSTRING varvalue=_get_variable_value(state->param, $1); if (varvalue.begin==NULL) { int loglevel = state->param->warn_unused ? TMPL_LOG_ERROR : TMPL_LOG_INFO; log_expr(exprobj,loglevel, "non-initialized variable %.*s\n",(int)($1.endnext-$1.begin),$1.begin); } $$.type=EXPR_TYPE_PSTR; $$.val.strval=varvalue; } | arglist ')' { $$ = call_expr_userfunc(exprobj, state->param, $1); } | EXTFUNC '(' ')' { $1.arglist=state->param->InitExprArglistFuncPtr(state->param->ext_calluserfunc_state); $$ = call_expr_userfunc(exprobj, state->param, $1); } | BUILTIN_FNC_EE '(' ')' { struct exprval e = NEW_EXPRVAL(EXPR_TYPE_PSTR); e.val.strval.begin = NULL; e.val.strval.endnext = NULL; $$ = (*((func_t_ee)$1->fnctptr))(exprobj, e); } | BUILTIN_FNC_DD '(' numEXP ')' { $$.type=EXPR_TYPE_DBL; expr_to_dbl1(exprobj, &$3); $$.val.dblval = (*((func_t_dd)$1->fnctptr))($3.val.dblval); } | BUILTIN_FNC_DDD '(' numEXP ',' numEXP ')' { $$.type=EXPR_TYPE_DBL; expr_to_dbl(exprobj, &$3, &$5); $$.val.dblval = (*((func_t_ddd)$1->fnctptr))($3.val.dblval,$5.val.dblval); } | BUILTIN_FNC_EE '(' numEXP ')' { $$ = (*((func_t_ee)$1->fnctptr))(exprobj,$3); } | numEXP '+' numEXP { DO_MATHOP(exprobj, $$,+,$1,$3); } | numEXP '-' numEXP { DO_MATHOP(exprobj, $$,-,$1,$3); } | numEXP '*' numEXP { DO_MATHOP(exprobj, $$,*,$1,$3); } | numEXP '%' numEXP { $$.type=EXPR_TYPE_INT; expr_to_int(exprobj, &$1,&$3); $$.val.intval = $1.val.intval % $3.val.intval; } /* old division; now always return double (due to compains 1/3==0) | numEXP '/' numEXP { switch ($$.type=expr_to_int_or_dbl(&$1,&$3)) { case EXPR_TYPE_INT: if ($3.val.intval) $$.val.intval = $1.val.intval / $3.val.intval; else { $$.val.intval = 0; log_expr(exprobj, TMPL_LOG_ERROR, "%s\n", "division by zero"); } ;break; case EXPR_TYPE_DBL: if ($3.val.dblval) $$.val.dblval = $1.val.dblval / $3.val.dblval; else { $$.val.dblval = 0; log_expr(exprobj, TMPL_LOG_ERROR, "%s\n", "division by zero"); } } ;break; } */ | numEXP '/' numEXP { $$.type=EXPR_TYPE_DBL; expr_to_dbl(exprobj, &$1,&$3); if ($3.val.dblval) $$.val.dblval = $1.val.dblval / $3.val.dblval; else { $$.val.dblval = 0; log_expr(exprobj, TMPL_LOG_ERROR, "%s\n", "division by zero"); } } | '-' numEXP %prec NEG { switch ($$.type=$2.type) { case EXPR_TYPE_INT: $$.val.intval = -$2.val.intval; ;break; case EXPR_TYPE_DBL: $$.val.dblval = -$2.val.dblval; ;break; } } | numEXP '^' numEXP { $$.type=EXPR_TYPE_DBL; expr_to_dbl(exprobj, &$1,&$3); $$.val.dblval = pow ($1.val.dblval, $3.val.dblval); } | numEXP OR numEXP { if (exprobj->is_tt_like_logical) { $$=$1; switch (expr_to_int_or_dbl_logop1(exprobj, &$$)) { case EXPR_TYPE_INT: $$= ($1.val.intval ? $1 : $3); break; case EXPR_TYPE_DBL: $$= ($1.val.dblval ? $1 : $3); break; } } else { DO_LOGOP(exprobj, $$,||,$1,$3); } } | numEXP AND numEXP { if (exprobj->is_tt_like_logical) { $$=$1; switch (expr_to_int_or_dbl_logop1(exprobj, &$$)) { case EXPR_TYPE_INT: $$= ($1.val.intval ? $3 : $1); break; case EXPR_TYPE_DBL: $$= ($1.val.dblval ? $3 : $1); break; } } else { DO_LOGOP(exprobj, $$,&&,$1,$3); } } | numEXP numGE numEXP { DO_CMPOP(exprobj, $$,>=,$1,$3); } | numEXP numLE numEXP { DO_CMPOP(exprobj, $$,<=,$1,$3); } | numEXP numNE numEXP { DO_CMPOP(exprobj, $$,!=,$1,$3); } | numEXP numEQ numEXP { DO_CMPOP(exprobj, $$,==,$1,$3); } | numEXP '>' numEXP %prec numGT { DO_CMPOP(exprobj, $$,>,$1,$3); } | numEXP '<' numEXP %prec numLT { DO_CMPOP(exprobj, $$,<,$1,$3); } | '!' numEXP %prec NOT { DO_LOGOP1(exprobj, $$,!,$2); } | NOT numEXP { DO_LOGOP1(exprobj, $$,!,$2); } | '(' numEXP ')' { $$ = $2; } | numEXP strCMP numEXP { expr_to_str(state, &$1,&$3); $$.type=EXPR_TYPE_INT; $$.val.intval = pstring_ge ($1.val.strval,$3.val.strval)-pstring_le ($1.val.strval,$3.val.strval); } | numEXP strGE numEXP { DO_TXTOP($$,pstring_ge,$1,$3,state);} | numEXP strLE numEXP { DO_TXTOP($$,pstring_le,$1,$3,state);} | numEXP strNE numEXP { DO_TXTOP($$,pstring_ne,$1,$3,state);} | numEXP strEQ numEXP { DO_TXTOP($$,pstring_eq,$1,$3,state);} | numEXP strGT numEXP { DO_TXTOP($$,pstring_gt,$1,$3,state);} | numEXP strLT numEXP { DO_TXTOP($$,pstring_lt,$1,$3,state);} | numEXP reLIKE numEXP { DO_TXTOPLOG($$,re_like,$1,$3,exprobj);} | numEXP reNOTLIKE numEXP { DO_TXTOPLOG($$,re_notlike,$1,$3,exprobj);} ; arglist: EXTFUNC '(' numEXP { $1.arglist=state->param->InitExprArglistFuncPtr(state->param->expr_func_map); pusharg_expr_userfunc(exprobj,state->param,$1,$3); $$ = $1; } | arglist ',' numEXP { pusharg_expr_userfunc(exprobj,state->param,$1,$3); $$ = $1; } ; /* End of grammar. */ %% /* Called by yyparse on error. */ static void yyerror (struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr, char const *s) { log_expr(exprobj, TMPL_LOG_ERROR, "not a valid expression: %s\n", s); } #include "calc.inc" static const symrec_const #ifndef __cplusplus const #endif builtin_funcs_symrec[] = { /* built-in funcs */ {SYMREC("sin"), BUILTIN_FNC_DD, 0, sin}, {SYMREC("cos"), BUILTIN_FNC_DD, 0, cos}, {SYMREC("atan"), BUILTIN_FNC_DD, 0, atan}, {SYMREC("log"), BUILTIN_FNC_DD, 0, log}, {SYMREC("exp"), BUILTIN_FNC_DD, 0, exp}, {SYMREC("sqrt"), BUILTIN_FNC_DD, 0, sqrt}, {SYMREC("atan2"), BUILTIN_FNC_DDD, 0, atan2}, {SYMREC("abs"), BUILTIN_FNC_EE, 0, builtin_abs}, {SYMREC("defined"), BUILTIN_FNC_EE, 0, builtin_defined}, {SYMREC("int"), BUILTIN_FNC_EE, 0, builtin_int}, {SYMREC("hex"), BUILTIN_FNC_EE, 0, builtin_hex}, {SYMREC("length"), BUILTIN_FNC_EE, 0, builtin_length}, {SYMREC("oct"), BUILTIN_FNC_EE, 0, builtin_oct}, {SYMREC("rand"), BUILTIN_FNC_EE, 0, builtin_rand}, {SYMREC("srand"), BUILTIN_FNC_EE, 0, builtin_srand}, {SYMREC("version"), BUILTIN_FNC_EE, 0, builtin_version}, /* end mark */ {0, 0, 0} }; static const symrec_const #ifndef __cplusplus const #endif builtin_ops_symrec[] = { /* built-in ops */ {SYMREC("eq"), strEQ, 0, NULL}, {SYMREC("ne"), strNE, 0, NULL}, {SYMREC("gt"), strGT, 0, NULL}, {SYMREC("ge"), strGE, 0, NULL}, {SYMREC("lt"), strLT, 0, NULL}, {SYMREC("le"), strLE, 0, NULL}, {SYMREC("cmp"), strCMP, 0, NULL}, {SYMREC("or"), OR, 0, NULL}, {SYMREC("and"),AND, 0, NULL}, {SYMREC("not"),NOT, 0, NULL}, /* end mark */ {0, 0, 0} }; TMPLPRO_LOCAL PSTRING parse_expr(PSTRING expression, struct tmplpro_state* state) { PSTRING expr_retval; struct expr_parser exprobj; expr_retval.begin=expression.begin; expr_retval.endnext=expression.begin; exprobj.expr_curpos=expression.begin; exprobj.exprarea=expression; exprobj.state = state; exprobj.is_expect_quote_like=1; // TODO!! exprobj.is_tt_like_logical=0; yyparse (state, &exprobj, &expr_retval); if (NULL!=expr_retval.begin && NULL==expr_retval.endnext) log_expr(&exprobj, TMPL_LOG_ERROR, "parse_expr internal warning: %s\n", "endnext is null pointer"); return expr_retval; } static void log_expr(struct expr_parser* exprobj, int loglevel, const char* fmt, ...) { va_list vl; va_start(vl, fmt); log_state(exprobj->state, loglevel, "in EXPR:at pos " MOD_TD " [" MOD_TD "]: ", TO_PTRDIFF_T((exprobj->expr_curpos)-(exprobj->state->top)), TO_PTRDIFF_T((exprobj->expr_curpos)-(exprobj->exprarea).begin)); tmpl_vlog(loglevel, fmt, vl); va_end(vl); } static PSTRING fill_symbuf (struct expr_parser* exprobj, int is_accepted(unsigned char)) { /* skip first char, already tested */ PSTRING retval = {exprobj->expr_curpos++}; while (exprobj->expr_curpos < (exprobj->exprarea).endnext && is_accepted(*exprobj->expr_curpos)) exprobj->expr_curpos++; retval.endnext= exprobj->expr_curpos; return retval; } static int is_alnum_lex (unsigned char c) { return (c == '_' || isalnum (c)); } static int is_not_identifier_ext_end (unsigned char c) { return (c != '}'); } #define TESTOP(c1,c2,z) if (c1 == c) { char d=*++(exprobj->expr_curpos); if (c2 != d) return c; else (exprobj->expr_curpos)++; return z; } #define TESTOP3(c1,c2,c3,num2,str3) if (c1 == c) { char d=*++(exprobj->expr_curpos); if (c2 == d) {(exprobj->expr_curpos)++; return num2;} else if (c3 == d) {(exprobj->expr_curpos)++; exprobj->is_expect_quote_like=1; return str3;} else return c; } static int yylex (YYSTYPE *lvalp, struct tmplpro_state* state, struct expr_parser* exprobj) { register unsigned char c = 0; int is_identifier_ext; /* TODO: newline? */ /* Ignore white space, get first nonwhite character. */ while ((exprobj->expr_curpos)<(exprobj->exprarea).endnext && ((c = *(exprobj->expr_curpos)) == ' ' || c == '\t')) (exprobj->expr_curpos)++; if ((exprobj->expr_curpos)>=(exprobj->exprarea).endnext) return 0; /* Char starts a quote => read a string */ if ('\''==c || '"'==c || (exprobj->is_expect_quote_like && '/'==c) ) { PSTRING strvalue; unsigned char terminal_quote=c; int escape_flag = 0; c =* ++(exprobj->expr_curpos); strvalue.begin = exprobj->expr_curpos; strvalue.endnext = exprobj->expr_curpos; while ((exprobj->expr_curpos)<(exprobj->exprarea).endnext && c != terminal_quote) { /* any escaped char with \ , incl. quote */ if ('\\' == c) { escape_flag = 1; exprobj->expr_curpos+=2; c =*(exprobj->expr_curpos); } else { c = * ++(exprobj->expr_curpos); } } strvalue.endnext = exprobj->expr_curpos; if ((exprobj->expr_curpos)<(exprobj->exprarea).endnext && ((c = *(exprobj->expr_curpos)) == terminal_quote)) (exprobj->expr_curpos)++; if (escape_flag) { (*lvalp).numval.type=EXPR_TYPE_UPSTR; } else { (*lvalp).numval.type=EXPR_TYPE_PSTR; } (*lvalp).numval.val.strval=strvalue; exprobj->is_expect_quote_like=0; return NUM; } exprobj->is_expect_quote_like=0; /* Char starts a number => parse the number. */ if (c == '.' || isdigit (c)) { (*lvalp).numval=exp_read_number (exprobj, &(exprobj->expr_curpos), (exprobj->exprarea).endnext); return NUM; } /* * Emiliano Bruni extension to Expr: * original HTML::Template allows almost arbitrary chars in parameter names, * but original HTML::Template::Expr (as to 0.04) allows only * var to be m![A-Za-z_][A-Za-z0-9_]*!. * with this extension, arbitrary chars can be used * if bracketed in ${}, as, for example, EXPR="${foo.bar} eq 'a'". * first it was bracketing in {}, but it is changed * * COMPATIBILITY WARNING. * Currently, this extension is not present in HTML::Template::Expr (as of 0.04). */ /* Let's try to see if this is an identifier between two { } - Emiliano */ is_identifier_ext = (int) (c == '{' || c == '$'); /* Char starts an identifier => read the name. */ /* variables with _leading_underscore are allowed too */ if (isalpha (c) || c=='_' || is_identifier_ext) { const symrec_const *s; PSTRING name; if (is_identifier_ext) { (exprobj->expr_curpos)++; /* jump over $ or { */ if ('$' == c && '{' == *(exprobj->expr_curpos)) { (exprobj->expr_curpos)++; /* jump over { */ #ifndef ALLOW_OLD_BRACKETING_IN_EXPR } else { log_expr(exprobj, TMPL_LOG_ERROR, "{} bracketing is deprecated. Use ${} bracketing.\n"); #endif } name=fill_symbuf(exprobj, is_not_identifier_ext_end); if ((exprobj->expr_curpos)<(exprobj->exprarea).endnext) (exprobj->expr_curpos)++; /* Jump the last } - Emiliano */ } else { name=fill_symbuf(exprobj, is_alnum_lex); } s = getsym (builtin_ops_symrec, name); if (s != 0) { (*lvalp).tptr = s; return s->type; } { const char* next_char= exprobj->expr_curpos; /* optimization: funcs is always followed by ( */ while ((next_char<(exprobj->exprarea).endnext) && isspace(*next_char)) next_char++; if ((*next_char)=='(') { /* user-defined functions have precedence over buit-in */ if (((*lvalp).extfunc.func=(state->param->IsExprUserfncFuncPtr)(state->param->expr_func_map, name))) { return EXTFUNC; } s = getsym (builtin_funcs_symrec, name); if (s != 0) { (*lvalp).tptr = s; return s->type; } } (*lvalp).uservar=name; /*log_expr(exprobj,TMPL_LOG_DEBUG2, "yylex: returned variable name %.*s\n",(int)(name.endnext-name.begin),name.begin);*/ return VAR; } } TESTOP3('=','=','~',numEQ,reLIKE) TESTOP3('!','=','~',numNE,reNOTLIKE) TESTOP('>','=',numGE) TESTOP('<','=',numLE) TESTOP('&','&',AND) TESTOP('|','|',OR) /* Any other character is a token by itself. */ (exprobj->expr_curpos)++; return c; } static struct exprval call_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call USERFUNC) { struct exprval emptyval = {EXPR_TYPE_PSTR}; emptyval.val.strval.begin=NULL; emptyval.val.strval.endnext=NULL; exprobj->userfunc_call = emptyval; param->CallExprUserfncFuncPtr(param->ext_calluserfunc_state, USERFUNC.arglist, USERFUNC.func, &(exprobj->userfunc_call)); if (param->debug>6) _tmplpro_expnum_debug (exprobj->userfunc_call, "EXPR: function call: returned "); param->FreeExprArglistFuncPtr(USERFUNC.arglist); USERFUNC.arglist = NULL; /* never happen; tmplpro_set_expr_as_* never set EXPR_TYPE_NULL * * if (exprobj->userfunc_call.type == EXPR_TYPE_NULL) exprobj->userfunc_call.type = EXPR_TYPE_PSTR; */ return exprobj->userfunc_call; } static void pusharg_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call USERFUNC, struct exprval arg) { if (arg.type == EXPR_TYPE_UPSTR) { arg.val.strval=expr_unescape_pstring_val(&(exprobj->state->expr_left_pbuffer),arg.val.strval); arg.type=EXPR_TYPE_PSTR; } exprobj->userfunc_call = arg; param->PushExprArglistFuncPtr(USERFUNC.arglist,&(exprobj->userfunc_call)); if (param->debug>6) _tmplpro_expnum_debug (arg, "EXPR: arglist: pushed "); } #include "exprtool.inc" #include "exprpstr.inc" HTML-Template-Pro-0.9510/tmpllog.c0000644000076400007640000000237311337026730015206 0ustar igorigor/* -*- c -*- * File: log.c * Author: Igor Vlasenko * Created: Thu Sep 1 17:18:16 2005 * * $Id$ */ /* based on FFmpeg av_log API */ #include #include #include "tmpllog.h" static int tmpl_log_level = TMPL_LOG_ERROR; TMPLPRO_LOCAL FILE* tmpl_log_stream = NULL; TMPLPRO_LOCAL void tmpl_log_default_callback(int level, const char* fmt, va_list vl) { vfprintf(stderr, fmt, vl); } TMPLPRO_LOCAL void tmpl_log_stream_callback(int level, const char* fmt, va_list vl) { vfprintf(tmpl_log_stream, fmt, vl); fflush(tmpl_log_stream); } static void (*tmpl_log_callback)(int, const char*, va_list) = tmpl_log_default_callback; TMPLPRO_LOCAL void tmpl_log(int level, const char *fmt, ...) { va_list vl; va_start(vl, fmt); tmpl_vlog(level, fmt, vl); va_end(vl); } TMPLPRO_LOCAL void tmpl_vlog(int level, const char *fmt, va_list vl) { if(level>tmpl_log_level) return; tmpl_log_callback(level, fmt, vl); } TMPLPRO_LOCAL int tmpl_log_get_level(void) { return tmpl_log_level; } TMPLPRO_LOCAL void tmpl_log_set_level(int level) { tmpl_log_level = level; } TMPLPRO_LOCAL void tmpl_log_set_callback(void (*callback)(int, const char*, va_list)) { tmpl_log_callback = callback; } HTML-Template-Pro-0.9510/expr.c0000644000076400007640000021652311450352117014507 0ustar igorigor /* A Bison parser, made by GNU Bison 2.4.1. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Copy the first part of user declarations. */ /* Line 189 of yacc.c */ #line 7 "expr.y" #include /* For math functions, cos(), sin(), etc. */ #include /* for printf */ #include /* for malloc */ #include /* for yylex alnum */ #include "calc.h" /* Contains definition of `symrec'. */ #include "tmpllog.h" #include "pabstract.h" #include "prostate.h" #include "provalue.h" #include "pparam.h" #include "pmiscdef.h" /* for expr-specific only */ #include "exprtool.h" #include "exprpstr.h" #include "parse_expr.h" /* Remember unsigned char assert on win32 Debug Assertion Failed! f:\dd\vctools\crt_bld\self_x86\crt\src \isctype.c Expression:(unsigned)(c + 1) <= 256 */ /* Line 189 of yacc.c */ #line 95 "y.tab.c" /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { NUM = 258, EXTFUNC = 259, BUILTIN_VAR = 260, BUILTIN_FNC_DD = 261, BUILTIN_FNC_DDD = 262, BUILTIN_FNC_EE = 263, VAR = 264, OR = 265, AND = 266, strCMP = 267, strNE = 268, strEQ = 269, strLE = 270, strLT = 271, strGE = 272, strGT = 273, numNE = 274, numEQ = 275, numLE = 276, numLT = 277, numGE = 278, numGT = 279, reNOTLIKE = 280, reLIKE = 281, NEG = 282, NOT = 283 }; #endif /* Tokens. */ #define NUM 258 #define EXTFUNC 259 #define BUILTIN_VAR 260 #define BUILTIN_FNC_DD 261 #define BUILTIN_FNC_DDD 262 #define BUILTIN_FNC_EE 263 #define VAR 264 #define OR 265 #define AND 266 #define strCMP 267 #define strNE 268 #define strEQ 269 #define strLE 270 #define strLT 271 #define strGE 272 #define strGT 273 #define numNE 274 #define numEQ 275 #define numLE 276 #define numLT 277 #define numGE 278 #define numGT 279 #define reNOTLIKE 280 #define reLIKE 281 #define NEG 282 #define NOT 283 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { /* Line 214 of yacc.c */ #line 27 "expr.y" struct exprval numval; /* For returning numbers. */ const symrec_const *tptr; /* For returning symbol-table pointers. */ struct user_func_call extfunc; /* for user-defined function name */ PSTRING uservar; /* Line 214 of yacc.c */ #line 196 "y.tab.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif /* Copy the second part of user declarations. */ /* Line 264 of yacc.c */ #line 33 "expr.y" /* the second section is required as we use YYSTYPE here */ static void yyerror (struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr, char const *); static int yylex (YYSTYPE *lvalp, struct tmplpro_state* state, struct expr_parser* exprobj); /* Line 264 of yacc.c */ #line 215 "y.tab.c" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int yyi) #else static int YYID (yyi) int yyi; #endif { return yyi; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 23 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 377 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 41 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 4 /* YYNRULES -- Number of rules. */ #define YYNRULES 40 /* YYNRULES -- Number of states. */ #define YYNSTATES 85 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 283 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 2, 2, 2, 33, 2, 2, 39, 38, 31, 30, 40, 29, 2, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 2, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28, 35, 36 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 7, 9, 11, 14, 18, 22, 27, 34, 39, 43, 47, 51, 55, 59, 62, 66, 70, 74, 78, 82, 86, 90, 94, 98, 101, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 42, 0, -1, 43, -1, 3, -1, 5, -1, 9, -1, 44, 38, -1, 4, 39, 38, -1, 8, 39, 38, -1, 6, 39, 43, 38, -1, 7, 39, 43, 40, 43, 38, -1, 8, 39, 43, 38, -1, 43, 30, 43, -1, 43, 29, 43, -1, 43, 31, 43, -1, 43, 33, 43, -1, 43, 32, 43, -1, 29, 43, -1, 43, 37, 43, -1, 43, 10, 43, -1, 43, 11, 43, -1, 43, 25, 43, -1, 43, 23, 43, -1, 43, 21, 43, -1, 43, 22, 43, -1, 43, 20, 43, -1, 43, 19, 43, -1, 34, 43, -1, 36, 43, -1, 39, 43, 38, -1, 43, 12, 43, -1, 43, 17, 43, -1, 43, 15, 43, -1, 43, 13, 43, -1, 43, 14, 43, -1, 43, 18, 43, -1, 43, 16, 43, -1, 43, 28, 43, -1, 43, 27, 43, -1, 4, 39, 43, -1, 44, 40, 43, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 61, 61, 69, 70, 72, 81, 85, 90, 97, 103, 109, 113, 114, 115, 116, 147, 159, 170, 176, 188, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 213, 214, 215, 216, 217, 218, 219, 220, 223, 228 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "NUM", "EXTFUNC", "BUILTIN_VAR", "BUILTIN_FNC_DD", "BUILTIN_FNC_DDD", "BUILTIN_FNC_EE", "VAR", "OR", "AND", "strCMP", "strNE", "strEQ", "strLE", "strLT", "strGE", "strGT", "'<'", "'>'", "numNE", "numEQ", "numLE", "numLT", "numGE", "numGT", "reNOTLIKE", "reLIKE", "'-'", "'+'", "'*'", "'/'", "'%'", "'!'", "NEG", "NOT", "'^'", "')'", "'('", "','", "$accept", "line", "numEXP", "arglist", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 60, 62, 274, 275, 276, 277, 278, 279, 280, 281, 45, 43, 42, 47, 37, 33, 282, 283, 94, 41, 40, 44 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 41, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 1, 1, 2, 3, 3, 4, 6, 4, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 3, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 17, 27, 28, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 39, 0, 0, 8, 0, 29, 19, 20, 30, 33, 34, 32, 36, 31, 35, 26, 25, 23, 24, 22, 21, 38, 37, 13, 12, 14, 16, 15, 18, 40, 9, 0, 11, 0, 10 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 12, 13, 14 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -35 static const yytype_int16 yypact[] = { 54, -35, -28, -35, -27, -26, -25, -35, 54, 54, 54, 54, 5, 231, -34, 38, 54, 54, 46, -22, -22, -22, 115, -35, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -35, 54, -35, 231, 144, 84, -35, 173, -35, 258, 284, 310, 310, 310, 310, 310, 310, 310, 329, 329, 329, 329, 329, 329, 340, 340, 33, 33, -22, -22, -22, -22, 231, -35, 54, -35, 202, -35 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -35, -35, -8, -35 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_int8 yytable[] = { 19, 20, 21, 22, 47, 23, 48, 50, 51, 52, 54, 15, 16, 17, 18, 46, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 0, 79, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 43, 44, 45, 8, 0, 0, 46, 0, 9, 83, 10, 8, 49, 11, 0, 0, 9, 0, 10, 8, 53, 11, 0, 0, 9, 0, 10, 0, 0, 11, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, 0, 0, 81, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, 55, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, 80, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, 82, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, 84, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, -1, -1, -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, 0, 38, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, -1, -1, -1, -1, -1, 0, -1, 0, 39, 40, 41, 42, 43, 44, 45, 0, 0, 0, 46, -1, -1, 41, 42, 43, 44, 45, 0, 0, 0, 46 }; static const yytype_int8 yycheck[] = { 8, 9, 10, 11, 38, 0, 40, 15, 16, 17, 18, 39, 39, 39, 39, 37, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, -1, 48, 3, 4, 5, 6, 7, 8, 9, -1, 3, 4, 5, 6, 7, 8, 9, -1, 3, 4, 5, 6, 7, 8, 9, 31, 32, 33, 29, -1, -1, 37, -1, 34, 81, 36, 29, 38, 39, -1, -1, 34, -1, 36, 29, 38, 39, -1, -1, 34, -1, 36, -1, -1, 39, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, -1, -1, 40, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 38, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 38, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 38, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 38, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 19, 20, 21, 22, 23, -1, 25, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, 37 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 9, 29, 34, 36, 39, 42, 43, 44, 39, 39, 39, 39, 43, 43, 43, 43, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 28, 29, 30, 31, 32, 33, 37, 38, 40, 38, 43, 43, 43, 38, 43, 38, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 38, 40, 38, 43, 38 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (state, exprobj, expr_retval_ptr, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, state, exprobj) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, state, exprobj, expr_retval_ptr); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, state, exprobj, expr_retval_ptr) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; struct tmplpro_state* state; struct expr_parser* exprobj; PSTRING* expr_retval_ptr; #endif { if (!yyvaluep) return; YYUSE (state); YYUSE (exprobj); YYUSE (expr_retval_ptr); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, state, exprobj, expr_retval_ptr) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; struct tmplpro_state* state; struct expr_parser* exprobj; PSTRING* expr_retval_ptr; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, state, exprobj, expr_retval_ptr); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void yy_stack_print (yybottom, yytop) yytype_int16 *yybottom; yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr) #else static void yy_reduce_print (yyvsp, yyrule, state, exprobj, expr_retval_ptr) YYSTYPE *yyvsp; int yyrule; struct tmplpro_state* state; struct expr_parser* exprobj; PSTRING* expr_retval_ptr; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , state, exprobj, expr_retval_ptr); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, state, exprobj, expr_retval_ptr); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr) #else static void yydestruct (yymsg, yytype, yyvaluep, state, exprobj, expr_retval_ptr) const char *yymsg; int yytype; YYSTYPE *yyvaluep; struct tmplpro_state* state; struct expr_parser* exprobj; PSTRING* expr_retval_ptr; #endif { YYUSE (yyvaluep); YYUSE (state); YYUSE (exprobj); YYUSE (expr_retval_ptr); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*-------------------------. | yyparse or yypush_parse. | `-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr) #else int yyparse (state, exprobj, expr_retval_ptr) struct tmplpro_state* state; struct expr_parser* exprobj; PSTRING* expr_retval_ptr; #endif #endif { /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: `yyss': related to states. `yyvs': related to semantic values. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yytoken = 0; yyss = yyssa; yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: /* Line 1455 of yacc.c */ #line 62 "expr.y" { expr_to_str1(state, &(yyvsp[(1) - (1)].numval)); *expr_retval_ptr=(yyvsp[(1) - (1)].numval).val.strval; } break; case 3: /* Line 1455 of yacc.c */ #line 69 "expr.y" { (yyval.numval) = (yyvsp[(1) - (1)].numval); } break; case 4: /* Line 1455 of yacc.c */ #line 70 "expr.y" { (yyval.numval).type=EXPR_TYPE_DBL; (yyval.numval).val.dblval = (yyvsp[(1) - (1)].tptr)->var; } break; case 5: /* Line 1455 of yacc.c */ #line 72 "expr.y" { PSTRING varvalue=_get_variable_value(state->param, (yyvsp[(1) - (1)].uservar)); if (varvalue.begin==NULL) { int loglevel = state->param->warn_unused ? TMPL_LOG_ERROR : TMPL_LOG_INFO; log_expr(exprobj,loglevel, "non-initialized variable %.*s\n",(int)((yyvsp[(1) - (1)].uservar).endnext-(yyvsp[(1) - (1)].uservar).begin),(yyvsp[(1) - (1)].uservar).begin); } (yyval.numval).type=EXPR_TYPE_PSTR; (yyval.numval).val.strval=varvalue; } break; case 6: /* Line 1455 of yacc.c */ #line 82 "expr.y" { (yyval.numval) = call_expr_userfunc(exprobj, state->param, (yyvsp[(1) - (2)].extfunc)); } break; case 7: /* Line 1455 of yacc.c */ #line 86 "expr.y" { (yyvsp[(1) - (3)].extfunc).arglist=state->param->InitExprArglistFuncPtr(state->param->ext_calluserfunc_state); (yyval.numval) = call_expr_userfunc(exprobj, state->param, (yyvsp[(1) - (3)].extfunc)); } break; case 8: /* Line 1455 of yacc.c */ #line 91 "expr.y" { struct exprval e = NEW_EXPRVAL(EXPR_TYPE_PSTR); e.val.strval.begin = NULL; e.val.strval.endnext = NULL; (yyval.numval) = (*((func_t_ee)(yyvsp[(1) - (3)].tptr)->fnctptr))(exprobj, e); } break; case 9: /* Line 1455 of yacc.c */ #line 98 "expr.y" { (yyval.numval).type=EXPR_TYPE_DBL; expr_to_dbl1(exprobj, &(yyvsp[(3) - (4)].numval)); (yyval.numval).val.dblval = (*((func_t_dd)(yyvsp[(1) - (4)].tptr)->fnctptr))((yyvsp[(3) - (4)].numval).val.dblval); } break; case 10: /* Line 1455 of yacc.c */ #line 104 "expr.y" { (yyval.numval).type=EXPR_TYPE_DBL; expr_to_dbl(exprobj, &(yyvsp[(3) - (6)].numval), &(yyvsp[(5) - (6)].numval)); (yyval.numval).val.dblval = (*((func_t_ddd)(yyvsp[(1) - (6)].tptr)->fnctptr))((yyvsp[(3) - (6)].numval).val.dblval,(yyvsp[(5) - (6)].numval).val.dblval); } break; case 11: /* Line 1455 of yacc.c */ #line 110 "expr.y" { (yyval.numval) = (*((func_t_ee)(yyvsp[(1) - (4)].tptr)->fnctptr))(exprobj,(yyvsp[(3) - (4)].numval)); } break; case 12: /* Line 1455 of yacc.c */ #line 113 "expr.y" { DO_MATHOP(exprobj, (yyval.numval),+,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 13: /* Line 1455 of yacc.c */ #line 114 "expr.y" { DO_MATHOP(exprobj, (yyval.numval),-,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 14: /* Line 1455 of yacc.c */ #line 115 "expr.y" { DO_MATHOP(exprobj, (yyval.numval),*,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 15: /* Line 1455 of yacc.c */ #line 117 "expr.y" { (yyval.numval).type=EXPR_TYPE_INT; expr_to_int(exprobj, &(yyvsp[(1) - (3)].numval),&(yyvsp[(3) - (3)].numval)); (yyval.numval).val.intval = (yyvsp[(1) - (3)].numval).val.intval % (yyvsp[(3) - (3)].numval).val.intval; } break; case 16: /* Line 1455 of yacc.c */ #line 148 "expr.y" { (yyval.numval).type=EXPR_TYPE_DBL; expr_to_dbl(exprobj, &(yyvsp[(1) - (3)].numval),&(yyvsp[(3) - (3)].numval)); if ((yyvsp[(3) - (3)].numval).val.dblval) (yyval.numval).val.dblval = (yyvsp[(1) - (3)].numval).val.dblval / (yyvsp[(3) - (3)].numval).val.dblval; else { (yyval.numval).val.dblval = 0; log_expr(exprobj, TMPL_LOG_ERROR, "%s\n", "division by zero"); } } break; case 17: /* Line 1455 of yacc.c */ #line 160 "expr.y" { switch ((yyval.numval).type=(yyvsp[(2) - (2)].numval).type) { case EXPR_TYPE_INT: (yyval.numval).val.intval = -(yyvsp[(2) - (2)].numval).val.intval; ;break; case EXPR_TYPE_DBL: (yyval.numval).val.dblval = -(yyvsp[(2) - (2)].numval).val.dblval; ;break; } } break; case 18: /* Line 1455 of yacc.c */ #line 171 "expr.y" { (yyval.numval).type=EXPR_TYPE_DBL; expr_to_dbl(exprobj, &(yyvsp[(1) - (3)].numval),&(yyvsp[(3) - (3)].numval)); (yyval.numval).val.dblval = pow ((yyvsp[(1) - (3)].numval).val.dblval, (yyvsp[(3) - (3)].numval).val.dblval); } break; case 19: /* Line 1455 of yacc.c */ #line 177 "expr.y" { if (exprobj->is_tt_like_logical) { (yyval.numval)=(yyvsp[(1) - (3)].numval); switch (expr_to_int_or_dbl_logop1(exprobj, &(yyval.numval))) { case EXPR_TYPE_INT: (yyval.numval)= ((yyvsp[(1) - (3)].numval).val.intval ? (yyvsp[(1) - (3)].numval) : (yyvsp[(3) - (3)].numval)); break; case EXPR_TYPE_DBL: (yyval.numval)= ((yyvsp[(1) - (3)].numval).val.dblval ? (yyvsp[(1) - (3)].numval) : (yyvsp[(3) - (3)].numval)); break; } } else { DO_LOGOP(exprobj, (yyval.numval),||,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } } break; case 20: /* Line 1455 of yacc.c */ #line 189 "expr.y" { if (exprobj->is_tt_like_logical) { (yyval.numval)=(yyvsp[(1) - (3)].numval); switch (expr_to_int_or_dbl_logop1(exprobj, &(yyval.numval))) { case EXPR_TYPE_INT: (yyval.numval)= ((yyvsp[(1) - (3)].numval).val.intval ? (yyvsp[(3) - (3)].numval) : (yyvsp[(1) - (3)].numval)); break; case EXPR_TYPE_DBL: (yyval.numval)= ((yyvsp[(1) - (3)].numval).val.dblval ? (yyvsp[(3) - (3)].numval) : (yyvsp[(1) - (3)].numval)); break; } } else { DO_LOGOP(exprobj, (yyval.numval),&&,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } } break; case 21: /* Line 1455 of yacc.c */ #line 200 "expr.y" { DO_CMPOP(exprobj, (yyval.numval),>=,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 22: /* Line 1455 of yacc.c */ #line 201 "expr.y" { DO_CMPOP(exprobj, (yyval.numval),<=,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 23: /* Line 1455 of yacc.c */ #line 202 "expr.y" { DO_CMPOP(exprobj, (yyval.numval),!=,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 24: /* Line 1455 of yacc.c */ #line 203 "expr.y" { DO_CMPOP(exprobj, (yyval.numval),==,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 25: /* Line 1455 of yacc.c */ #line 204 "expr.y" { DO_CMPOP(exprobj, (yyval.numval),>,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 26: /* Line 1455 of yacc.c */ #line 205 "expr.y" { DO_CMPOP(exprobj, (yyval.numval),<,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval)); } break; case 27: /* Line 1455 of yacc.c */ #line 206 "expr.y" { DO_LOGOP1(exprobj, (yyval.numval),!,(yyvsp[(2) - (2)].numval)); } break; case 28: /* Line 1455 of yacc.c */ #line 207 "expr.y" { DO_LOGOP1(exprobj, (yyval.numval),!,(yyvsp[(2) - (2)].numval)); } break; case 29: /* Line 1455 of yacc.c */ #line 208 "expr.y" { (yyval.numval) = (yyvsp[(2) - (3)].numval); } break; case 30: /* Line 1455 of yacc.c */ #line 209 "expr.y" { expr_to_str(state, &(yyvsp[(1) - (3)].numval),&(yyvsp[(3) - (3)].numval)); (yyval.numval).type=EXPR_TYPE_INT; (yyval.numval).val.intval = pstring_ge ((yyvsp[(1) - (3)].numval).val.strval,(yyvsp[(3) - (3)].numval).val.strval)-pstring_le ((yyvsp[(1) - (3)].numval).val.strval,(yyvsp[(3) - (3)].numval).val.strval); } break; case 31: /* Line 1455 of yacc.c */ #line 213 "expr.y" { DO_TXTOP((yyval.numval),pstring_ge,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),state);} break; case 32: /* Line 1455 of yacc.c */ #line 214 "expr.y" { DO_TXTOP((yyval.numval),pstring_le,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),state);} break; case 33: /* Line 1455 of yacc.c */ #line 215 "expr.y" { DO_TXTOP((yyval.numval),pstring_ne,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),state);} break; case 34: /* Line 1455 of yacc.c */ #line 216 "expr.y" { DO_TXTOP((yyval.numval),pstring_eq,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),state);} break; case 35: /* Line 1455 of yacc.c */ #line 217 "expr.y" { DO_TXTOP((yyval.numval),pstring_gt,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),state);} break; case 36: /* Line 1455 of yacc.c */ #line 218 "expr.y" { DO_TXTOP((yyval.numval),pstring_lt,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),state);} break; case 37: /* Line 1455 of yacc.c */ #line 219 "expr.y" { DO_TXTOPLOG((yyval.numval),re_like,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),exprobj);} break; case 38: /* Line 1455 of yacc.c */ #line 220 "expr.y" { DO_TXTOPLOG((yyval.numval),re_notlike,(yyvsp[(1) - (3)].numval),(yyvsp[(3) - (3)].numval),exprobj);} break; case 39: /* Line 1455 of yacc.c */ #line 223 "expr.y" { (yyvsp[(1) - (3)].extfunc).arglist=state->param->InitExprArglistFuncPtr(state->param->expr_func_map); pusharg_expr_userfunc(exprobj,state->param,(yyvsp[(1) - (3)].extfunc),(yyvsp[(3) - (3)].numval)); (yyval.extfunc) = (yyvsp[(1) - (3)].extfunc); } break; case 40: /* Line 1455 of yacc.c */ #line 228 "expr.y" { pusharg_expr_userfunc(exprobj,state->param,(yyvsp[(1) - (3)].extfunc),(yyvsp[(3) - (3)].numval)); (yyval.extfunc) = (yyvsp[(1) - (3)].extfunc); } break; /* Line 1455 of yacc.c */ #line 1910 "y.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (state, exprobj, expr_retval_ptr, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (state, exprobj, expr_retval_ptr, yymsg); } else { yyerror (state, exprobj, expr_retval_ptr, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, state, exprobj, expr_retval_ptr); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, state, exprobj, expr_retval_ptr); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (state, exprobj, expr_retval_ptr, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, state, exprobj, expr_retval_ptr); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, state, exprobj, expr_retval_ptr); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } /* Line 1675 of yacc.c */ #line 232 "expr.y" /* Called by yyparse on error. */ static void yyerror (struct tmplpro_state* state, struct expr_parser* exprobj, PSTRING* expr_retval_ptr, char const *s) { log_expr(exprobj, TMPL_LOG_ERROR, "not a valid expression: %s\n", s); } #include "calc.inc" static const symrec_const #ifndef __cplusplus const #endif builtin_funcs_symrec[] = { /* built-in funcs */ {SYMREC("sin"), BUILTIN_FNC_DD, 0, sin}, {SYMREC("cos"), BUILTIN_FNC_DD, 0, cos}, {SYMREC("atan"), BUILTIN_FNC_DD, 0, atan}, {SYMREC("log"), BUILTIN_FNC_DD, 0, log}, {SYMREC("exp"), BUILTIN_FNC_DD, 0, exp}, {SYMREC("sqrt"), BUILTIN_FNC_DD, 0, sqrt}, {SYMREC("atan2"), BUILTIN_FNC_DDD, 0, atan2}, {SYMREC("abs"), BUILTIN_FNC_EE, 0, builtin_abs}, {SYMREC("defined"), BUILTIN_FNC_EE, 0, builtin_defined}, {SYMREC("int"), BUILTIN_FNC_EE, 0, builtin_int}, {SYMREC("hex"), BUILTIN_FNC_EE, 0, builtin_hex}, {SYMREC("length"), BUILTIN_FNC_EE, 0, builtin_length}, {SYMREC("oct"), BUILTIN_FNC_EE, 0, builtin_oct}, {SYMREC("rand"), BUILTIN_FNC_EE, 0, builtin_rand}, {SYMREC("srand"), BUILTIN_FNC_EE, 0, builtin_srand}, {SYMREC("version"), BUILTIN_FNC_EE, 0, builtin_version}, /* end mark */ {0, 0, 0} }; static const symrec_const #ifndef __cplusplus const #endif builtin_ops_symrec[] = { /* built-in ops */ {SYMREC("eq"), strEQ, 0, NULL}, {SYMREC("ne"), strNE, 0, NULL}, {SYMREC("gt"), strGT, 0, NULL}, {SYMREC("ge"), strGE, 0, NULL}, {SYMREC("lt"), strLT, 0, NULL}, {SYMREC("le"), strLE, 0, NULL}, {SYMREC("cmp"), strCMP, 0, NULL}, {SYMREC("or"), OR, 0, NULL}, {SYMREC("and"),AND, 0, NULL}, {SYMREC("not"),NOT, 0, NULL}, /* end mark */ {0, 0, 0} }; TMPLPRO_LOCAL PSTRING parse_expr(PSTRING expression, struct tmplpro_state* state) { PSTRING expr_retval; struct expr_parser exprobj; expr_retval.begin=expression.begin; expr_retval.endnext=expression.begin; exprobj.expr_curpos=expression.begin; exprobj.exprarea=expression; exprobj.state = state; exprobj.is_expect_quote_like=1; // TODO!! exprobj.is_tt_like_logical=0; yyparse (state, &exprobj, &expr_retval); if (NULL!=expr_retval.begin && NULL==expr_retval.endnext) log_expr(&exprobj, TMPL_LOG_ERROR, "parse_expr internal warning: %s\n", "endnext is null pointer"); return expr_retval; } static void log_expr(struct expr_parser* exprobj, int loglevel, const char* fmt, ...) { va_list vl; va_start(vl, fmt); log_state(exprobj->state, loglevel, "in EXPR:at pos " MOD_TD " [" MOD_TD "]: ", TO_PTRDIFF_T((exprobj->expr_curpos)-(exprobj->state->top)), TO_PTRDIFF_T((exprobj->expr_curpos)-(exprobj->exprarea).begin)); tmpl_vlog(loglevel, fmt, vl); va_end(vl); } static PSTRING fill_symbuf (struct expr_parser* exprobj, int is_accepted(unsigned char)) { /* skip first char, already tested */ PSTRING retval = {exprobj->expr_curpos++}; while (exprobj->expr_curpos < (exprobj->exprarea).endnext && is_accepted(*exprobj->expr_curpos)) exprobj->expr_curpos++; retval.endnext= exprobj->expr_curpos; return retval; } static int is_alnum_lex (unsigned char c) { return (c == '_' || isalnum (c)); } static int is_not_identifier_ext_end (unsigned char c) { return (c != '}'); } #define TESTOP(c1,c2,z) if (c1 == c) { char d=*++(exprobj->expr_curpos); if (c2 != d) return c; else (exprobj->expr_curpos)++; return z; } #define TESTOP3(c1,c2,c3,num2,str3) if (c1 == c) { char d=*++(exprobj->expr_curpos); if (c2 == d) {(exprobj->expr_curpos)++; return num2;} else if (c3 == d) {(exprobj->expr_curpos)++; exprobj->is_expect_quote_like=1; return str3;} else return c; } static int yylex (YYSTYPE *lvalp, struct tmplpro_state* state, struct expr_parser* exprobj) { register unsigned char c = 0; int is_identifier_ext; /* TODO: newline? */ /* Ignore white space, get first nonwhite character. */ while ((exprobj->expr_curpos)<(exprobj->exprarea).endnext && ((c = *(exprobj->expr_curpos)) == ' ' || c == '\t')) (exprobj->expr_curpos)++; if ((exprobj->expr_curpos)>=(exprobj->exprarea).endnext) return 0; /* Char starts a quote => read a string */ if ('\''==c || '"'==c || (exprobj->is_expect_quote_like && '/'==c) ) { PSTRING strvalue; unsigned char terminal_quote=c; int escape_flag = 0; c =* ++(exprobj->expr_curpos); strvalue.begin = exprobj->expr_curpos; strvalue.endnext = exprobj->expr_curpos; while ((exprobj->expr_curpos)<(exprobj->exprarea).endnext && c != terminal_quote) { /* any escaped char with \ , incl. quote */ if ('\\' == c) { escape_flag = 1; exprobj->expr_curpos+=2; c =*(exprobj->expr_curpos); } else { c = * ++(exprobj->expr_curpos); } } strvalue.endnext = exprobj->expr_curpos; if ((exprobj->expr_curpos)<(exprobj->exprarea).endnext && ((c = *(exprobj->expr_curpos)) == terminal_quote)) (exprobj->expr_curpos)++; if (escape_flag) { (*lvalp).numval.type=EXPR_TYPE_UPSTR; } else { (*lvalp).numval.type=EXPR_TYPE_PSTR; } (*lvalp).numval.val.strval=strvalue; exprobj->is_expect_quote_like=0; return NUM; } exprobj->is_expect_quote_like=0; /* Char starts a number => parse the number. */ if (c == '.' || isdigit (c)) { (*lvalp).numval=exp_read_number (exprobj, &(exprobj->expr_curpos), (exprobj->exprarea).endnext); return NUM; } /* * Emiliano Bruni extension to Expr: * original HTML::Template allows almost arbitrary chars in parameter names, * but original HTML::Template::Expr (as to 0.04) allows only * var to be m![A-Za-z_][A-Za-z0-9_]*!. * with this extension, arbitrary chars can be used * if bracketed in ${}, as, for example, EXPR="${foo.bar} eq 'a'". * first it was bracketing in {}, but it is changed * * COMPATIBILITY WARNING. * Currently, this extension is not present in HTML::Template::Expr (as of 0.04). */ /* Let's try to see if this is an identifier between two { } - Emiliano */ is_identifier_ext = (int) (c == '{' || c == '$'); /* Char starts an identifier => read the name. */ /* variables with _leading_underscore are allowed too */ if (isalpha (c) || c=='_' || is_identifier_ext) { const symrec_const *s; PSTRING name; if (is_identifier_ext) { (exprobj->expr_curpos)++; /* jump over $ or { */ if ('$' == c && '{' == *(exprobj->expr_curpos)) { (exprobj->expr_curpos)++; /* jump over { */ #ifndef ALLOW_OLD_BRACKETING_IN_EXPR } else { log_expr(exprobj, TMPL_LOG_ERROR, "{} bracketing is deprecated. Use ${} bracketing.\n"); #endif } name=fill_symbuf(exprobj, is_not_identifier_ext_end); if ((exprobj->expr_curpos)<(exprobj->exprarea).endnext) (exprobj->expr_curpos)++; /* Jump the last } - Emiliano */ } else { name=fill_symbuf(exprobj, is_alnum_lex); } s = getsym (builtin_ops_symrec, name); if (s != 0) { (*lvalp).tptr = s; return s->type; } { const char* next_char= exprobj->expr_curpos; /* optimization: funcs is always followed by ( */ while ((next_char<(exprobj->exprarea).endnext) && isspace(*next_char)) next_char++; if ((*next_char)=='(') { /* user-defined functions have precedence over buit-in */ if (((*lvalp).extfunc.func=(state->param->IsExprUserfncFuncPtr)(state->param->expr_func_map, name))) { return EXTFUNC; } s = getsym (builtin_funcs_symrec, name); if (s != 0) { (*lvalp).tptr = s; return s->type; } } (*lvalp).uservar=name; /*log_expr(exprobj,TMPL_LOG_DEBUG2, "yylex: returned variable name %.*s\n",(int)(name.endnext-name.begin),name.begin);*/ return VAR; } } TESTOP3('=','=','~',numEQ,reLIKE) TESTOP3('!','=','~',numNE,reNOTLIKE) TESTOP('>','=',numGE) TESTOP('<','=',numLE) TESTOP('&','&',AND) TESTOP('|','|',OR) /* Any other character is a token by itself. */ (exprobj->expr_curpos)++; return c; } static struct exprval call_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call USERFUNC) { struct exprval emptyval = {EXPR_TYPE_PSTR}; emptyval.val.strval.begin=NULL; emptyval.val.strval.endnext=NULL; exprobj->userfunc_call = emptyval; param->CallExprUserfncFuncPtr(param->ext_calluserfunc_state, USERFUNC.arglist, USERFUNC.func, &(exprobj->userfunc_call)); if (param->debug>6) _tmplpro_expnum_debug (exprobj->userfunc_call, "EXPR: function call: returned "); param->FreeExprArglistFuncPtr(USERFUNC.arglist); USERFUNC.arglist = NULL; /* never happen; tmplpro_set_expr_as_* never set EXPR_TYPE_NULL * * if (exprobj->userfunc_call.type == EXPR_TYPE_NULL) exprobj->userfunc_call.type = EXPR_TYPE_PSTR; */ return exprobj->userfunc_call; } static void pusharg_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call USERFUNC, struct exprval arg) { if (arg.type == EXPR_TYPE_UPSTR) { arg.val.strval=expr_unescape_pstring_val(&(exprobj->state->expr_left_pbuffer),arg.val.strval); arg.type=EXPR_TYPE_PSTR; } exprobj->userfunc_call = arg; param->PushExprArglistFuncPtr(USERFUNC.arglist,&(exprobj->userfunc_call)); if (param->debug>6) _tmplpro_expnum_debug (arg, "EXPR: arglist: pushed "); } #include "exprtool.inc" #include "exprpstr.inc" HTML-Template-Pro-0.9510/loadfile.inc0000644000076400007640000001143311435301403015623 0ustar igorigor/* -*- c -*- * File: loadfile.h * Author: Igor Vlasenko * Created: Thu Sep 8 17:16:48 2005 * * $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef USE_MMAP #ifdef WIN32 /* * the win32 code of Viacheslav Sheveliov * viy: should work for win64 too. */ #include #include static PSTRING mmap_load_file(const char *filepath) { PSTRING memarea = { NULL, NULL }; HANDLE hFile, hMapObject = NULL; hFile = CreateFile( TEXT(filepath), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if (hFile != INVALID_HANDLE_VALUE) { hMapObject = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hMapObject) { // Get a pointer to the file-mapped shared memory. LPCTSTR lpvMem = (LPTSTR) MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, 0); if (lpvMem) { // Everything OK! memarea.begin = (char *) lpvMem; memarea.endnext = memarea.begin + GetFileSize(hFile, NULL); // After MapViewOfFile we don't need file handles no more. // Undocumented, but it works! (In read-only mode?) CloseHandle(hMapObject); CloseHandle(hFile); return memarea; } } } // Something goes wrong { // Save last error code, before any system call DWORD dwLastError = GetLastError(); // Report error, if file size != 0 // Mapping of zero-length file cause CreateFileMapping to fail. // So skip error messages in this case. if (hFile == INVALID_HANDLE_VALUE && GetFileSize(hFile, NULL) != 0) fprintf(stderr, "Could not open file '%s'. (system error#%ld)\n", filepath, dwLastError); } // Close all opened handles if (hMapObject) CloseHandle(hMapObject); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); return memarea; } /* we use function, not define, because someday we may need its address */ static int mmap_unload_file(PSTRING memarea) { return UnmapViewOfFile((void*) memarea.begin) ? 0 : -1; }; /* define mmap_unload_file(map) (UnmapViewOfFile((LPCVOID) map.begin) ? 0 : -1) */ #else /* unix, sweet unix :) */ #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_SYS_STAT_H) /* # define NULL 0 */ #include #include #include /* open */ #include /* close */ static PSTRING mmap_load_file (const char* filepath) { int fd; struct stat st; size_t size_in_bytes; PSTRING memarea={NULL,NULL}; fd = open(filepath, O_RDONLY); if (fd == -1) return memarea; /* {NULL,NULL} */ fstat(fd, &st); size_in_bytes = st.st_size; /* mmap size_in_bytes+1 to avoid crash with empty file */ memarea.begin = (char *) mmap(0, size_in_bytes+1, PROT_READ, MAP_SHARED, fd, 0); close(fd); memarea.endnext=memarea.begin+size_in_bytes; return memarea; } static int mmap_unload_file (PSTRING memarea) { /* destroying */ return munmap((void *)memarea.begin, memarea.endnext-memarea.begin); } #endif /* UNIX */ #endif /* WIN32 */ #else /* * system seems to have no mmap ; * we use standard C buffered read */ #include static PSTRING mmap_load_file (const char* filepath) { FILE *stream; size_t size_in_bytes=0; size_t realsize; size_t chunksize=4096; size_t memsize=chunksize; PSTRING memarea={NULL,NULL}; char* writepoint; /* text mode for HTML::Template compatibility */ stream = fopen(filepath, "r"); if (stream == NULL) return memarea; /* {NULL,NULL} */ /* mmap size_in_bytes+1 to avoid crash with empty file */ memarea.begin=(const char*) malloc(memsize+1); writepoint=(char*)memarea.begin; while (1) { realsize=fread(writepoint, 1, chunksize, stream); size_in_bytes+=realsize; if (realsize==chunksize) { writepoint+=chunksize; if (size_in_bytes+chunksize>memsize) { memsize*=2; memarea.begin=(char*) realloc((char*)memarea.begin, memsize+1); writepoint=((char*)memarea.begin)+size_in_bytes; } } else { fclose(stream); memarea.endnext=memarea.begin+size_in_bytes; return memarea; } } } static int mmap_unload_file (PSTRING memarea) { /* destroying */ free((char*)memarea.begin); return 0; } #endif /* USE_MMAP */ HTML-Template-Pro-0.9510/loopvar.inc0000644000076400007640000000640211253464547015547 0ustar igorigorstatic const char* const innerloopname[]={ "", "first__", "last__", "inner__", "odd__", "counter__" }; static const char* const INNERLOOPNAME[]={ "", "FIRST__", "LAST__", "INNER__", "ODD__", "COUNTER__" }; #define HTML_TEMPLATE_INNER_LOOP_VAR_FIRST 1 #define HTML_TEMPLATE_INNER_LOOP_VAR_LAST 2 #define HTML_TEMPLATE_INNER_LOOP_VAR_INNER 3 #define HTML_TEMPLATE_INNER_LOOP_VAR_ODD 4 #define HTML_TEMPLATE_INNER_LOOP_VAR_COUNTER 5 #define HTML_TEMPLATE_FIRST_INNER_LOOP 1 #define HTML_TEMPLATE_LAST_INNER_LOOP 5 static int try_inner_loop_variable (PSTRING name) { int i; const char* cur_pos; const char* pattern; const char* PATTERN; for (i=HTML_TEMPLATE_FIRST_INNER_LOOP; i<=HTML_TEMPLATE_LAST_INNER_LOOP; i++) { cur_pos=name.begin; pattern=innerloopname[i]; PATTERN=INNERLOOPNAME[i]; while (*pattern && cur_posvar_scope_stack); if (isScopeLoop(currentScope) && name.endnext-name.begin>4 && '_'==*(name.begin) && '_'==*(name.begin+1) ) { /* we can meet loop variables here -- try it first */ /* length of its name >4 */ /* __first__ __last__ __inner__ __odd__ __counter__ */ PSTRING shiftedname; /* (PSTRING) {name.begin+2,name.endnext} */ shiftedname.begin=name.begin+2; shiftedname.endnext=name.endnext; switch (try_inner_loop_variable(shiftedname)) { case 0: break; case HTML_TEMPLATE_INNER_LOOP_VAR_FIRST: if (currentScope->loop==0) { /* first__ */ retval.begin=TrueString; retval.endnext=TrueString+1; } else { retval.begin=FalseString; retval.endnext=FalseString+1; }; break; case HTML_TEMPLATE_INNER_LOOP_VAR_LAST: if (currentScope->loop==(currentScope->loop_count-1)) { retval.begin=TrueString; retval.endnext=TrueString+1; } else { retval.begin=FalseString; retval.endnext=FalseString+1; }; break; case HTML_TEMPLATE_INNER_LOOP_VAR_ODD: if ((currentScope->loop%2)==0) { retval.begin=TrueString; retval.endnext=TrueString+1; } else { retval.begin=FalseString; retval.endnext=FalseString+1; }; break; case HTML_TEMPLATE_INNER_LOOP_VAR_INNER: if (currentScope->loop>0 && (currentScope->loop_count<0 /* loop_count < 0 if number of loops is unknown/undefined */ || currentScope->loop < (currentScope->loop_count-1))) { retval.begin=TrueString; retval.endnext=TrueString+1; } else { retval.begin=FalseString; retval.endnext=FalseString+1; }; break; case HTML_TEMPLATE_INNER_LOOP_VAR_COUNTER: { char* const buffer = param->loopvarbuf; loop=currentScope->loop+1; snprintf(buffer,sizeof(param->loopvarbuf),"%d",loop); retval.begin=buffer; retval.endnext=buffer+strlen(buffer); } break; } } return retval; } /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/templates/0000755000076400007640000000000012144122665015356 5ustar igorigorHTML-Template-Pro-0.9510/templates/globals.tmpl0000644000076400007640000000036710617575362017716 0ustar igorigor Some global var: Some Loop. Some local data Something global, but hidden Hidden! HTML-Template-Pro-0.9510/templates/js.tmpl0000644000076400007640000000003510617575362016677 0ustar igorigorHTML-Template-Pro-0.9510/templates/multiline_tags.tmpl0000644000076400007640000000011210617575362021277 0ustar igorigor HTML-Template-Pro-0.9510/templates/escape.tmpl0000644000076400007640000000024410617575362017525 0ustar igorigorThis should be a bunch of HTML-escaped stuff: HTML-Template-Pro-0.9510/templates/newline_test1.tmpl0000644000076400007640000000005210617575362021043 0ustar igorigorSTARTEND HTML-Template-Pro-0.9510/templates/include_path/0000755000076400007640000000000012144122665020015 5ustar igorigorHTML-Template-Pro-0.9510/templates/include_path/a.tmpl0000644000076400007640000000003410617575362021141 0ustar igorigorFoo HTML-Template-Pro-0.9510/templates/include_path/one.tmpl0000644000076400007640000000005210617575362021502 0ustar igorigorONE HTML-Template-Pro-0.9510/templates/include_path/inner.tmpl0000644000076400007640000000001510617575362022033 0ustar igorigorI AM INNER 1 HTML-Template-Pro-0.9510/templates/include_path/b.tmpl0000644000076400007640000000000410617575362021137 0ustar igorigorBar HTML-Template-Pro-0.9510/templates/ifelse.tmpl0000644000076400007640000000013310617575362017531 0ustar igorigorThis is a line outside the if. INSIDE IF INSIDE ELSE HTML-Template-Pro-0.9510/templates/loop-if.tmpl0000644000076400007640000000023710617575362017634 0ustar igorigor Loop not filled in! HTML-Template-Pro-0.9510/templates/vanguard2.tmpl0000644000076400007640000000002410617575362020152 0ustar igorigor%baz% sdfsdgsdhsgf HTML-Template-Pro-0.9510/templates/recursive.tmpl0000644000076400007640000000006410617575362020274 0ustar igorigorI am infinity. HTML-Template-Pro-0.9510/templates/default.tmpl0000644000076400007640000000036110617575362017711 0ustar igorigorcause it's hard to , and are ing to HTML-Template-Pro-0.9510/templates/medium.tmpl0000644000076400007640000001540610617575362017553 0ustar igorigor Global Navigator Administration : Office Editor
Office Editor
Office Data
> >
Company Name >
Office Name
Address
City
State
Country
Postal Code
Phone Number
Secondary Phone Number
Email
Website
Intranet URL
Logo Upload New Logo:
Photo Upload New Photo:
Subcategories
Description
> >
Case Study
Client Brands Account Manager
> Add a Case Study
Contacts
> This office has Contacts.
HTML-Template-Pro-0.9510/templates/newline_test2.tmpl0000644000076400007640000000000710617575362021044 0ustar igorigorincludeHTML-Template-Pro-0.9510/templates/included2.tmpl0000644000076400007640000000000610617575362020132 0ustar igorigor5 5 5 HTML-Template-Pro-0.9510/templates/simple-loop-nonames.tmpl0000644000076400007640000000026210617575362022163 0ustar igorigor Simple Template I am a simple loop template. HTML-Template-Pro-0.9510/templates/global-loops.tmpl0000644000076400007640000000037710617575362020666 0ustar igorigorglobal: outer loop foo: inner loop bar: inner loop foo: inner loop global: HTML-Template-Pro-0.9510/templates/if.tmpl0000644000076400007640000000016010617575362016660 0ustar igorigorThis is a line outside the if. INSIDE the if unless HTML-Template-Pro-0.9510/templates/outer.tmpl0000644000076400007640000000006010617575362017417 0ustar igorigorI AM OUTER I AM OUTER HTML-Template-Pro-0.9510/templates/double_loop.tmpl0000644000076400007640000000020410617575362020564 0ustar igorigor One of David's numbers is . VAR TIME: HTML-Template-Pro-0.9510/templates/loop-context.tmpl0000644000076400007640000000026710617575362020725 0ustar igorigor:FIRST:INNER:LAST:ODD HTML-Template-Pro-0.9510/templates/long_loops.tmpl0000644000076400007640000003003210617575362020436 0ustar igorigor WPP Hotel Directory Vistor Comments: <TMPL_VAR PROPNAME>
Inside WPPNew searchReturn to hotel list WPP Hotel Directory
WPP Hotel DirectoryWPP Hotel Directory
General InfoRates and ChargesFacilities and AmenitiesPoliciesAlso in the areaComments
>
Back to the topVistor Comments

 
> Posted by: > Rating:
COLSPAN=2> Comment



 
> Posted by: > Rating:
COLSPAN=2> Comment



 
Thank you for you comment !
The moderators have been notified of your new comment - they will review it as soon as possible.


 


HTML-Template-Pro-0.9510/templates/other-loop.tmpl0000644000076400007640000000012710617575362020355 0ustar igorigorOUTSIDE INSIDE HTML-Template-Pro-0.9510/templates/query-test.tmpl0000644000076400007640000000064610617575362020415 0ustar igorigor HTML-Template-Pro-0.9510/templates/query-test2.tmpl0000644000076400007640000000043310617575362020471 0ustar igorigor HTML-Template-Pro-0.9510/templates/simple.tmpl0000644000076400007640000000020610617575362017554 0ustar igorigor Simple Template IIII am a simple template. HTML-Template-Pro-0.9510/templates/case_loop.tmpl0000644000076400007640000000010310617575362020223 0ustar igorigor HTML-Template-Pro-0.9510/templates/searchpath/0000755000076400007640000000000012144122665017500 5ustar igorigorHTML-Template-Pro-0.9510/templates/searchpath/two.tmpl0000644000076400007640000000003610617575362021217 0ustar igorigorTWO HTML-Template-Pro-0.9510/templates/searchpath/three.tmpl0000644000076400007640000000000610617575362021512 0ustar igorigorTHREE HTML-Template-Pro-0.9510/templates/searchpath/included.tmpl0000644000076400007640000000005310617575362022174 0ustar igorigor9 9 9 HTML-Template-Pro-0.9510/templates/include_path2/0000755000076400007640000000000012144122665020077 5ustar igorigorHTML-Template-Pro-0.9510/templates/include_path2/inner.tmpl0000644000076400007640000000001510617575362022115 0ustar igorigorI AM INNER 2 HTML-Template-Pro-0.9510/templates/include.tmpl0000644000076400007640000000007510617575362017712 0ustar igorigor1 1 1 2 2 2 3 3 3 6 6 6 HTML-Template-Pro-0.9510/templates/context.tmpl0000644000076400007640000000031710617575362017752 0ustar igorigorand , . pingpong HTML-Template-Pro-0.9510/templates/included.tmpl0000644000076400007640000000005310617575362020052 0ustar igorigor4 4 4 HTML-Template-Pro-0.9510/templates/simple-loop.tmpl0000644000076400007640000000025310617575362020525 0ustar igorigor Simple Template I am a simple loop template. HTML-Template-Pro-0.9510/templates/counter.tmpl0000644000076400007640000000026110617575362017743 0ustar igorigor HTML-Template-Pro-0.9510/templates/unless.tmpl0000644000076400007640000000011610617575362017574 0ustar igorigor INSIDE UNLESS INSIDE ELSE HTML-Template-Pro-0.9510/templates/urlescape.tmpl0000644000076400007640000000006610617575362020252 0ustar igorigorSome URL escaped stuff: HTML-Template-Pro-0.9510/templates/vanguard1.tmpl0000644000076400007640000000004410617575362020153 0ustar igorigor%foo% HTML-Template-Pro-0.9510/templates/default_escape.tmpl0000644000076400007640000000014210617575362021226 0ustar igorigor be HTML-Template-Pro-0.9510/README.win320000644000076400007640000000704611302273271015203 0ustar igorigorCompiling and using either perl module HTML::Template::Pro or C library backend htmltmplpro.dll under win32/win64. ---------------------------------------------------------- Note that issues related to other languages' bindings are discussed in corresponding bindings. Release 0.82 and later have full native support for win32 and win64. The source of HTML-Template-Pro should be ANSI C portable, except unix/win specific sections of file loadfile.inc. Those sections can be enabled with MMAP=1 or disabled with MMAP=0. If MMAP=0 (--without-mmap) slow ANSI C buffered read will be used instead. There is ifdef-ed section of win32/win64-specific code, with code fixes and improved section of WIN32 code of Viacheslav Sheveliov. Also, it is known to build successfully on WIN64, thanks to Robert Henniger. Windows memory mapping code use MapViewOfFile/UnmapViewOfFile WIN32 system calls. It was disabled by default, because it might not be compatible with original HTML-Template when dealing with CRLF-ed templates (It opens them in binary mode instead of text one). [UPD: I think there should be no difference, at least for C library. Windows users, please, test and enlighten me!] Nevertheless, compiling with MMAP=1 (--with-mmap, -DUSE_MMAP) should improve perfomance and/or memory consumption. Latest releases of htmltmplpro, built with mingw32 for win32 are avaliable on sourceforge and in sisyphus.ru: see http://www.sisyphus.ru/en/srpm/Sisyphus/mingw32-htmltmplpro http://www.sisyphus.ru/en/srpm/Sisyphus/mingw32-pcre If you want to compile htmltmplpro from sources and you do want to use regexps in EXPR="..." you need an optional PCRE library. Optional PCRE library for win32 can be obtained either from Sisyphus, http://www.sisyphus.ru/en/srpm/Sisyphus/mingw32-pcre or from http://gnuwin32.sourceforge.net/packages/pcre.htm (seems to be too old) Unpack it into pcre subdirectory. Perl module should be built using Makefile.PL. It is known to compile and work properly under Strawberry Perl. The C library can be built for Windows using CMake http://www.cmake.org/cmake/resources/software.html which has a GUI interface and can generate projects for # Visual Studio 6 # Visual Studio 7 # Visual Studio 7 .NET 2003 # Visual Studio 8 2005 # Visual Studio 8 2005 Win64 # Visual Studio 9 2008 # Visual Studio 9 2008 Win64 # Watcom WMake # CodeBlocks - MinGW Makefiles # Eclipse CDT4 - MinGW Makefiles # Eclipse CDT4 - NMake Makefiles # Eclipse CDT4 - Unix Makefiles # Borland Makefiles # MSYS Makefiles # MinGW Makefiles # NMake Makefiles Also autotools-based minGW cross-compilation from linux to win32 is also known to work. Maybe autotools-based cygwin and minGW 64 compilation will work too, please, report your success. Example CMake usage. Unpack source tree. Run CMakeSetup.exe, set up path to the source tree, set up path to the build tree to the same value. press configure button, choose, for example, Visual Studio 9 2008. verify red-labelled configuration options. Change, for example, CMAKE_INSTALL_PREFIX. press configure button again, press generate button. Then open generated config in Visual Studio 9 2008 and compile it. If you want to use another build system, be sure to define properly int64_type, used in EXPR internally. for list of possible defines consult CMakeLists.txt and configure.ac/config.h.in in the library source distribution. If you will try to complie this code on a win system, and will get a trouble, be so kind to send me a bugreport including logs of failed build. Note that I often have no place to test win32/win64 code, so patches are always welcome. HTML-Template-Pro-0.9510/exprtool.inc0000644000076400007640000002060011265055755015735 0ustar igorigor/* -*- c -*- * File: exprtool.c * Author: Igor Vlasenko * Created: Mon Jul 25 15:29:17 2005 * * $Id$ */ /* #include "exprtool.h" #include // for yylex alnum #include // for printf */ #define EXPR_CHECK_NUMBER(exprobj, ptr) switch (ptr->type) { \ case EXPR_TYPE_INT: case EXPR_TYPE_DBL: break; \ case EXPR_TYPE_UPSTR: case EXPR_TYPE_PSTR: expr_to_num(exprobj, ptr); break; \ default: _tmplpro_expnum_debug(*ptr, "FATAL:internal expr type error. please report\n"); \ ptr->type = EXPR_TYPE_INT; \ } #define EXPR_CHECK_LOGICAL(exprobj, ptr) switch (ptr->type) { \ case EXPR_TYPE_INT: case EXPR_TYPE_DBL: break; \ case EXPR_TYPE_UPSTR: case EXPR_TYPE_PSTR: expr_to_bool(exprobj, ptr); break; \ default: _tmplpro_expnum_debug(*ptr, "FATAL:internal expr type error. please report\n"); \ ptr->type = EXPR_TYPE_INT; \ } static EXPR_char expr_to_int_or_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) { EXPR_CHECK_NUMBER(exprobj, val1); EXPR_CHECK_NUMBER(exprobj, val2); if ((val1->type == EXPR_TYPE_INT) && (val2->type == EXPR_TYPE_INT)) return EXPR_TYPE_INT; if ((val1->type == EXPR_TYPE_DBL) && (val2->type == EXPR_TYPE_DBL)) return EXPR_TYPE_DBL; if (val1->type == EXPR_TYPE_INT) { val1->type=EXPR_TYPE_DBL; val1->val.dblval=(double) val1->val.intval; } if (val2->type == EXPR_TYPE_INT) { val1->type=EXPR_TYPE_DBL; val2->val.dblval=(double) val2->val.intval; } return EXPR_TYPE_DBL; } static EXPR_char expr_to_int_or_dbl_logop (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) { EXPR_CHECK_LOGICAL(exprobj, val1); EXPR_CHECK_LOGICAL(exprobj, val2); if (val1->type == EXPR_TYPE_INT && val2->type == EXPR_TYPE_INT) return EXPR_TYPE_INT; if (val1->type == EXPR_TYPE_DBL && val2->type == EXPR_TYPE_DBL) return EXPR_TYPE_DBL; if (val1->type == EXPR_TYPE_INT) { val1->type=EXPR_TYPE_DBL; val1->val.dblval=(double) val1->val.intval; } if (val2->type == EXPR_TYPE_INT) { val1->type=EXPR_TYPE_DBL; val2->val.dblval=(double) val2->val.intval; } return EXPR_TYPE_DBL; } static EXPR_char expr_to_int_or_dbl_logop1 (struct expr_parser* exprobj, struct exprval* val1) { EXPR_CHECK_LOGICAL(exprobj, val1); return val1->type; } static EXPR_char expr_to_int_or_dbl1 (struct expr_parser* exprobj, struct exprval* val1) { EXPR_CHECK_NUMBER(exprobj, val1); return val1->type; } static void expr_to_dbl1 (struct expr_parser* exprobj, struct exprval* val1) { EXPR_CHECK_NUMBER(exprobj, val1); if (val1->type == EXPR_TYPE_INT) { val1->type=EXPR_TYPE_DBL; val1->val.dblval=(double) val1->val.intval; } } static void expr_to_int1 (struct expr_parser* exprobj, struct exprval* val1) { EXPR_CHECK_NUMBER(exprobj, val1); if (val1->type == EXPR_TYPE_DBL) { val1->type=EXPR_TYPE_INT; val1->val.intval=(EXPR_int64) val1->val.dblval; /* _tmplpro_expnum_debug(*val1, "WARN:converting to `int' from `double'"); */ } } static void expr_to_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) { expr_to_dbl1(exprobj, val1); expr_to_dbl1(exprobj, val2); } static void expr_to_int (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) { expr_to_int1(exprobj, val1); expr_to_int1(exprobj, val2); } #define EXPR_CHECK_STRING(pbuff, ptr) switch (ptr->type) { \ case EXPR_TYPE_PSTR: break; \ case EXPR_TYPE_UPSTR: ptr->val.strval=expr_unescape_pstring_val(pbuff,ptr->val.strval); break; \ case EXPR_TYPE_INT: ptr->val.strval=int_to_pstring(ptr->val.intval,pbuffer_string(pbuff),pbuffer_size(pbuff)); break; \ case EXPR_TYPE_DBL: ptr->val.strval=double_to_pstring(ptr->val.dblval,pbuffer_string(pbuff),pbuffer_size(pbuff)); break; \ default: _tmplpro_expnum_debug(*ptr, "FATAL:internal expr string error. please report\n"); \ } \ ptr->type = EXPR_TYPE_PSTR; static void expr_to_str (struct tmplpro_state* state, struct exprval* val1, struct exprval* val2) { EXPR_CHECK_STRING(&(state->expr_left_pbuffer), val1); EXPR_CHECK_STRING(&(state->expr_right_pbuffer), val2); } static void expr_to_str1 (struct tmplpro_state* state, struct exprval* val1) { EXPR_CHECK_STRING(&(state->expr_left_pbuffer), val1); } static int is_float_lex (char c) { return (c == '.' || isdigit (c)); } static struct exprval exp_read_number (struct expr_parser* exprobj, const char* *curposptr, const char* endchars) { char c = **curposptr; struct exprval retval; EXPR_int64 iretval=0; double dretval=0; EXPR_int64 offset=0; int sign=1; retval.type=EXPR_TYPE_INT; retval.val.intval=0; if ((*curposptr)val.strval.begin; EXPR_char type = val1->type; if (type == EXPR_TYPE_PSTR || type == EXPR_TYPE_UPSTR) { if (NULL==curpos) { val1->type = EXPR_TYPE_INT; val1->val.intval = 0; } else { /* escaped string can't be read properly anyway */ *val1=exp_read_number (exprobj, &curpos, val1->val.strval.endnext); } } } static void expr_to_bool (struct expr_parser* exprobj, struct exprval* val1) { if (val1->type == EXPR_TYPE_PSTR || val1->type == EXPR_TYPE_UPSTR) { const char* begin=val1->val.strval.begin; const char* end=val1->val.strval.endnext; const char* curpos=begin; if (begin==end) { val1->type = EXPR_TYPE_INT; val1->val.intval = 0; } else { *val1=exp_read_number (exprobj, &curpos, end); if (val1->type == EXPR_TYPE_INT) { if (val1->val.intval || (curpos == end)) return; else val1->val.intval=1; /* strings are true in perl */ } else if (val1->type == EXPR_TYPE_DBL) { if (val1->val.dblval || (curpos == end)) return; else val1->val.dblval=1.0; /* strings are true in perl */ } } } } static void _tmplpro_expnum_debug (struct exprval val, char* msg) { tmpl_log(TMPL_LOG_DEBUG,"--> debug %s:type %c ",msg,val.type); if (val.type == EXPR_TYPE_INT) tmpl_log(TMPL_LOG_DEBUG,"ival=%" EXPR_PRId64 "\n",val.val.intval); else if (val.type == EXPR_TYPE_DBL) tmpl_log(TMPL_LOG_DEBUG,"dval=%f\n",val.val.dblval); else if (val.type == EXPR_TYPE_PSTR) { tmpl_log(TMPL_LOG_DEBUG,"pstr(%c):",(int) val.type); if (NULL==val.val.strval.begin) tmpl_log(TMPL_LOG_DEBUG,"{begin=NULL}"); if (NULL==val.val.strval.endnext) tmpl_log(TMPL_LOG_DEBUG,"{endnext=NULL}"); tmpl_log(TMPL_LOG_DEBUG,"sval=%.*s\n",(int)(val.val.strval.endnext-val.val.strval.begin),val.val.strval.begin); } else if (val.type == EXPR_TYPE_NULL) { tmpl_log(TMPL_LOG_DEBUG,"NULL\n"); if (NULL!=val.val.strval.begin) tmpl_log(TMPL_LOG_DEBUG,"{begin!=NULL}"); if (NULL!=val.val.strval.endnext) tmpl_log(TMPL_LOG_DEBUG,"{endnext!=NULL}"); } else { tmpl_log(TMPL_LOG_DEBUG,"unknown(%c) as ival=%" EXPR_PRId64 "\n",(int) val.type,val.val.intval); } } /* * checks if it is stringval and unescape it (copies to the buffer). * it implies that only one string at a time can use buffer. */ static PSTRING expr_unescape_pstring_val(pbuffer* pbuff, PSTRING val) { PSTRING retval; const char* curpos = val.begin; const char* endnext= val.endnext; char* buf=pbuffer_resize(pbuff, endnext-curpos+1); char* bufpos = buf; while (curpos < endnext) { if (*curpos == '\\') { *bufpos=*(++curpos); } else { *bufpos=*curpos; } curpos++; bufpos++; } retval.begin = buf; retval.endnext = bufpos; return retval; } HTML-Template-Pro-0.9510/pbuffer.c0000644000076400007640000000352711253453604015164 0ustar igorigor#include "pbuffer.h" /* reentrant pbuffer functions */ TMPLPRO_LOCAL size_t pbuffer_size(const pbuffer* pBuffer) { return pBuffer->bufsize; } TMPLPRO_LOCAL void pbuffer_preinit(pbuffer* pBuffer) { pBuffer->bufsize=0; pBuffer->buffer=NULL; } TMPLPRO_LOCAL char* pbuffer_init(pbuffer* pBuffer) { pBuffer->bufsize=256; pBuffer->buffer=(char*) malloc (pBuffer->bufsize * sizeof(char)); return pBuffer->buffer; } TMPLPRO_LOCAL char* pbuffer_init_as(pbuffer* pBuffer,size_t size) { pBuffer->bufsize=PBUFFER_MULTIPLICATOR*size; pBuffer->buffer=(char*) malloc (pBuffer->bufsize * sizeof(char)); return pBuffer->buffer; } TMPLPRO_LOCAL char* pbuffer_string(const pbuffer* pBuffer) { return pBuffer->buffer; } TMPLPRO_LOCAL char* pbuffer_resize(pbuffer* pBuffer, size_t size) { if (pBuffer->bufsize==0) { pbuffer_init_as(pBuffer, size); } else if (pBuffer->bufsize< size) { pBuffer->bufsize=PBUFFER_MULTIPLICATOR*size; /* aggresive memory allocation to prevent frequent requests*/ pBuffer->buffer=(char*) realloc (pBuffer->buffer,pBuffer->bufsize * sizeof(char)); } return pBuffer->buffer; } TMPLPRO_LOCAL void pbuffer_free(pbuffer* pBuffer) { if (pBuffer->bufsize!=0) { pBuffer->bufsize=0; free(pBuffer->buffer); pBuffer->buffer=NULL; } } TMPLPRO_LOCAL void pbuffer_fill_from_pstring(pbuffer* pBuffer, PSTRING pstr) { size_t size = pstr.endnext - pstr.begin; const char* from = pstr.begin; char* dest; if (pBuffer->bufsize==0) { pbuffer_init_as(pBuffer, size+1); } else if (pBuffer->bufsizebuffer; while (from test_esc1 \<>"; %FAhidden: end HTML-Template-Pro-0.9510/pparam.h0000644000076400007640000000737312144122512015012 0ustar igorigor/* -*- c -*- * File: pparam.h * Author: Igor Vlasenko * Created: Thu Jul 9 20:05:37 2009 */ #ifndef _PPARAM_H #define _PPARAM_H 1 #include "proscope.h" #include "pbuffer.h" #include "exprval.h" /* TODO: remove together with buffer */ /* for wrappers; flag better always be int32 - useful for Mono */ #if HAVE_INTTYPES_H # include typedef int32_t flag; #else # if HAVE_STDINT_H # include typedef int32_t flag; # else typedef int flag; # endif #endif struct tmplpro_param { int global_vars; int max_includes; /*default:16 */ int debug; int tmpl_var_case; flag no_includes; flag loop_context_vars; flag strict; /* filters --- indicates whether to use * external file loader hook specified as LoadFileFuncPtr. * Set it to 1 if you want to preprocess file with filters * before they'll be processed by exec_tmpl */ flag filters; int default_escape; /* one of HTML_TEMPLATE_OPT_ESCAPE_* */ const char* filename; /* template file */ PSTRING scalarref; /* memory area */ flag path_like_variable_scope; flag search_path_on_include; char** path; char* template_root; /* flag vanguard_compatibility_mode; */ /* hooks to perl or other container */ /* HTML::Template callback hooks */ writer_functype WriterFuncPtr; get_ABSTRACT_VALUE_functype GetAbstractValFuncPtr; ABSTRACT_VALUE2PSTRING_functype AbstractVal2pstringFuncPtr; ABSTRACT_VALUE2ABSTRACT_ARRAY_functype AbstractVal2abstractArrayFuncPtr; get_ABSTRACT_ARRAY_length_functype GetAbstractArrayLengthFuncPtr; get_ABSTRACT_MAP_functype GetAbstractMapFuncPtr; /* user-supplied --- optional; we use it for full emulation of perl quirks */ is_ABSTRACT_VALUE_true_functype IsAbstractValTrueFuncPtr; find_file_functype FindFileFuncPtr; load_file_functype LoadFileFuncPtr; unload_file_functype UnloadFileFuncPtr; exit_loop_scope_functype ExitLoopScopeFuncPtr; /* external state references to be supplied to callbacks */ ABSTRACT_WRITER* ext_writer_state; ABSTRACT_FILTER* ext_filter_state; ABSTRACT_FINDFILE* ext_findfile_state; ABSTRACT_DATASTATE* ext_data_state; ABSTRACT_CALLER* ext_calluserfunc_state; /* HTML::Template::Expr hooks */ init_expr_arglist_functype InitExprArglistFuncPtr; free_expr_arglist_functype FreeExprArglistFuncPtr; /** important note: PushExprArglistFuncPtr should always copy the supplied pstring arg as it could point to a temporary location. */ push_expr_arglist_functype PushExprArglistFuncPtr; call_expr_userfnc_functype CallExprUserfncFuncPtr; is_expr_userfnc_functype IsExprUserfncFuncPtr; ABSTRACT_FUNCMAP* expr_func_map; /* private */ /* flags to be declared */ /* TODO use in walk_through_nested_loops */ flag warn_unused; /* private */ int found_syntax_error; int htp_errno; int cur_includes; /* internal counter of include depth */ const char* masterpath; /* file that has included this file, or NULL */ /* variable scope (nested loops) passed to include */ struct scope_stack var_scope_stack; int param_map_count; /* internal counter of pushed scope roots */ /* private buffer of builtin tmpl2string */ pbuffer builtin_tmpl2string_buffer; /* private buffer of builtin_findfile */ pbuffer builtin_findfile_buffer; /* private buffer of write_chars_to_pbuffer */ pbuffer builtin_writer_buffer; /* private buffers of walk_through_nested_loops */ PSTRING lowercase_varname; pbuffer lowercase_varname_buffer; PSTRING uppercase_varname; pbuffer uppercase_varname_buffer; /* private buffer for escape_pstring */ pbuffer escape_pstring_buffer; /* private buffer for get_loop_context_vars_value */ char loopvarbuf[20]; /* for snprintf %d */ }; #endif /* _PPARAM_H */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/exprtool.h0000644000076400007640000000750211406441172015406 0ustar igorigor/* -*- c -*- * File: exprtool.h * Author: Igor Vlasenko * Created: Mon Jul 25 15:29:04 2005 * * $Id$ */ #ifndef _EXPRTOOL_H #define _EXPRTOOL_H 1 #include "pstring.h" #include "exprval.h" struct expr_parser { struct tmplpro_state* state; PSTRING exprarea; const char* expr_curpos; /* for callbacks */ struct exprval userfunc_call; /* * is_expect_quote_like allows recognization of quotelike. * if not is_expect_quote_like we look only for 'str' and, possibly, "str" * if is_expect_quote_like we also look for /str/. */ int is_expect_quote_like; /* * is_tt_like_logical: if set, && and || behave like in TemplateToolkit */ int is_tt_like_logical; }; #define DO_MATHOP(exprobj, z,op,x,y) switch (z.type=expr_to_int_or_dbl(exprobj, &x,&y)) { \ case EXPR_TYPE_INT: z.val.intval=x.val.intval op y.val.intval;break; \ case EXPR_TYPE_DBL: z.val.dblval=x.val.dblval op y.val.dblval;break; \ } #define DO_LOGOP(exprobj, z,op,x,y) z.type=EXPR_TYPE_INT; switch (expr_to_int_or_dbl_logop(exprobj, &x,&y)) { \ case EXPR_TYPE_INT: z.val.intval=x.val.intval op y.val.intval;break; \ case EXPR_TYPE_DBL: z.val.intval=x.val.dblval op y.val.dblval;break; \ } #define DO_LOGOP1(exprobj,z,op,x) z.type=EXPR_TYPE_INT; switch (expr_to_int_or_dbl_logop1(exprobj, &x)) { \ case EXPR_TYPE_INT: z.val.intval= op x.val.intval;break; \ case EXPR_TYPE_DBL: z.val.intval= op x.val.dblval;break; \ } #define DO_CMPOP(exprobj, z,op,x,y) switch (expr_to_int_or_dbl(exprobj, &x,&y)) { \ case EXPR_TYPE_INT: z.val.intval=x.val.intval op y.val.intval;break; \ case EXPR_TYPE_DBL: z.val.intval=x.val.dblval op y.val.dblval;break; \ }; z.type=EXPR_TYPE_INT; #define DO_TXTOP(z,op,x,y,buf) expr_to_str(buf, &x,&y); z.type=EXPR_TYPE_INT; z.val.intval = op (x.val.strval,y.val.strval); #define DO_TXTOPLOG(z,op,x,y,exprobj) expr_to_str(exprobj->state, &x,&y); z.type=EXPR_TYPE_INT; z.val.intval = op (exprobj,x.val.strval,y.val.strval); static EXPR_char expr_to_int_or_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2); static EXPR_char expr_to_int_or_dbl1 (struct expr_parser* exprobj, struct exprval* val1); static EXPR_char expr_to_int_or_dbl_logop (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2); static EXPR_char expr_to_int_or_dbl_logop1 (struct expr_parser* exprobj, struct exprval* val1); static void expr_to_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2); static void expr_to_int (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2); static void expr_to_dbl1 (struct expr_parser* exprobj, struct exprval* val); static void expr_to_int1 (struct expr_parser* exprobj, struct exprval* val1); static void expr_to_str (struct tmplpro_state* state, struct exprval* val1, struct exprval* val2); static void expr_to_str1 (struct tmplpro_state* state, struct exprval* val1); static void expr_to_num (struct expr_parser* exprobj, struct exprval* val1); static void expr_to_bool (struct expr_parser* exprobj, struct exprval* val1); static struct exprval exp_read_number (struct expr_parser* exprobj, const char* *curposptr, const char* endchars); /* this stuff is defined or used in expr.y */ static void log_expr(struct expr_parser* exprobj, int loglevel, const char* fmt, ...) FORMAT_PRINTF(3,4); static PSTRING expr_unescape_pstring_val(pbuffer* pbuff, PSTRING val); static void _tmplpro_expnum_debug (struct exprval val, char* msg); struct user_func_call { ABSTRACT_USERFUNC* func; /* for user-defined function name */ ABSTRACT_ARGLIST* arglist; }; static struct exprval call_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call extfunc); static void pusharg_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call extfunc, struct exprval arg); #endif /* exprtool.h */ HTML-Template-Pro-0.9510/tagstack.inc0000644000076400007640000000323111721660661015656 0ustar igorigor#include #include #define INIT_ENV_DEPTH 256 static void tagstack_init(struct tagstack* tagstack) { tagstack->depth=INIT_ENV_DEPTH; tagstack->pos=-1; tagstack->entry=(struct tagstack_entry*) malloc (tagstack->depth * sizeof(struct tagstack_entry)); } static void tagstack_free(struct tagstack* tagstack) { tagstack->depth=-1; tagstack->pos=-1; free(tagstack->entry); } INLINE static int tagstack_notempty(const struct tagstack* tagstack) { return tagstack->pos >= 0; } /* static void tagstack_entry_debug(struct tagstack_entry item) { tmpl_log(TMPL_LOG_DEBUG,"vcontext = %d value=%d\n",item.vcontext,item.value); } */ INLINE static struct tagstack_entry* tagstack_top(const struct tagstack* tagstack) { return tagstack->entry+tagstack->pos; } static struct tagstack_entry tagstack_pop(struct tagstack* tagstack, int* is_underflow) { if (is_underflow != NULL) *is_underflow=0; if (tagstack->pos<0) { tagstack->pos=0; if (is_underflow != NULL) *is_underflow=1; if (tagstack->depth<0) { tmpl_log(TMPL_LOG_ERROR,"FATAL:stack error:tags stack is uninitialized\n"); tagstack_init(tagstack); } } return *(tagstack->entry+ tagstack->pos--); } static void tagstack_push(struct tagstack* tagstack, struct tagstack_entry item) { /* overflow check */ if (++(tagstack->pos)>=tagstack->depth) { if (tagstack->depthdepth=INIT_ENV_DEPTH; tagstack->depth*=2; tagstack->entry=(struct tagstack_entry*) realloc (tagstack->entry, tagstack->depth * sizeof(struct tagstack_entry)); } *(tagstack->entry+tagstack->pos)=item; } /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/benchmark.pl.t0000644000076400007640000000727010724553105016116 0ustar igorigor### HTML::Template is required for benchmark. # Before `make install' is performed this script should be runnable with # prove -l -b benchmark.pl. # After `make install' it should work as `perl benchmark.pl' ######################### use Test; BEGIN { plan tests => 1}; use Benchmark; use HTML::Template; use HTML::Template::Pro; ok(1); # If we made it this far, we're ok. ######################### my $tmpl; my $output; my @varset1=(VAR1=>VAR1,VAR2=>VAR2,VAR3=>VAR3,VAR10=>VAR10); my @varset2=(STUFF1 => '<>"; %FA'); my @refset1=( HASHREF0=>[], HASHREF2=>[{},{}], HASHREF1=>[ {LOOPVAR1=>'LOOP1-VAR1',LOOPVAR2=>'LOOP1-VAR2',LOOPVAR3=>'LOOP1-VAR3',LOOPVAR10=>'LOOP1-VAR10'}, {LOOPVAR1=>'LOOP2-VAR1',LOOPVAR2=>'LOOP2-VAR2',LOOPVAR3=>'LOOP2-VAR3',LOOPVAR10=>'LOOP2-VAR10'}, {LOOPVAR1=>'LOOP3-VAR1',LOOPVAR2=>'LOOP3-VAR2',LOOPVAR3=>'LOOP3-VAR3',LOOPVAR10=>'LOOP3-VAR10'}, {LOOPVAR1=>'LOOP4-VAR1',LOOPVAR2=>'LOOP4-VAR2',LOOPVAR3=>'LOOP4-VAR3',LOOPVAR10=>'LOOP4-VAR10'}, ]); #test_tmpl('test_loop1', @varset1, @refset1); #test_tmpl('test_loop2', @varset1, @refset1); #test_tmpl('test_loop3', @varset1, @refset1); test_tmpl('test_var1', @varset1); test_tmpl('test_var2', @varset1); test_tmpl('test_var3', @varset1, @varset2); test_tmpl('test_if1', @varset1); test_tmpl('test_if2', @varset1); test_tmpl('test_if3', @refset1); #test_tmpl('test_include1', @varset1); #test_tmpl('test_include2', @varset1); test_tmpl('test_loop1', @varset1, @refset1); test_tmpl('test_loop2', @varset1, @refset1); test_tmpl('test_loop3', @varset1, @refset1); test_tmpl('test_loop4', @varset1, @refset1); test_tmpl('test_loop5', @varset1, @refset1); # ------------------------- sub test_tmpl { my $testname=shift; my @param=@_; &test_tmpl_complete($testname,@param); &test_tmpl_output($testname,@param); } sub test_tmpl_output { my $testname=shift; my $tmpl; my $output; chdir 'templates-Pro'; my $file=$testname; open (OUTFILE, ">/dev/null"); $tmplo=HTML::Template->new(filename=>$file.'.tmpl', die_on_bad_params=>0, strict=>0, case_sensitive=>0, loop_context_vars=>1); $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl', loop_context_vars=>1, case_sensitive=>0); $tmplo->param(@_); $tmpl->param(@_); my $count=1000; $t = timeit($count, sub {$tmpl->output(print_to => *OUTFILE);}); print "N:$testname:output only: $count loops of new code took:\n",timestr($t),"\n"; $t = timeit($count, sub {$tmplo->output(print_to => *OUTFILE);}); print "O:$testname:output only: $count loops of old Template.pm took:\n",timestr($t),"\n"; $tmpl->output(print_to => *OUTFILE); close (OUTFILE); chdir '..'; } sub test_tmpl_complete { my $testname=shift; my @param=@_; my $tmpl; my $output; chdir 'templates-Pro'; my $file=$testname; open (OUTFILE, ">/dev/null"); $tmplo=HTML::Template->new(filename=>$file.'.tmpl', die_on_bad_params=>0, strict=>0, case_sensitive=>0, loop_context_vars=>1); $tmplo->param(@_); my $count=1000; $t = timeit($count, sub { $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl', loop_context_vars=>1, case_sensitive=>0, die_on_bad_params=>0); $tmpl->param(@param); $tmpl->output(print_to => *OUTFILE); }); print "N:$testname:complete: $count loops of new code took:\n",timestr($t),"\n"; $t = timeit($count, sub { $tmpl=HTML::Template->new(filename=>$file.'.tmpl', loop_context_vars=>1, case_sensitive=>0, die_on_bad_params=>0); $tmpl->param(@param); $tmpl->output(print_to => *OUTFILE); }); print "O:$testname:complete: $count loops of old Template.pm took:\n",timestr($t),"\n"; $tmpl->output(print_to => *OUTFILE); close (OUTFILE); chdir '..'; } ### Local Variables: ### mode: perl ### End: HTML-Template-Pro-0.9510/procore.c0000644000076400007640000005360511436246221015204 0ustar igorigor#include #include #include #include #include "tmplpro.h" #include "pconst.h" #include "procore.h" #include "prostate.h" #include "provalue.h" #include "tagstack.h" #include "pbuffer.h" #include "parse_expr.h" #include "pparam.h" #include "optint.h" #include "proscope.h" #include "proscope.inc" #include "pstrutils.inc" #include "pmiscdef.h" /*for snprintf */ /* for mmap_load_file & mmap_unload_file */ #include "loadfile.inc" #include "loopvar.inc" #define HTML_TEMPLATE_NO_TAG -1 #define HTML_TEMPLATE_BAD_TAG 0 #define HTML_TEMPLATE_FIRST_TAG_USED 1 #define HTML_TEMPLATE_TAG_VAR 1 #define HTML_TEMPLATE_TAG_INCLUDE 2 #define HTML_TEMPLATE_TAG_LOOP 3 #define HTML_TEMPLATE_TAG_IF 4 #define HTML_TEMPLATE_TAG_ELSE 5 #define HTML_TEMPLATE_TAG_UNLESS 6 #define HTML_TEMPLATE_TAG_ELSIF 7 #define HTML_TEMPLATE_LAST_TAG_USED 7 static const char* const tagname[]={ "Bad or unsupported tag", /* 0 */ "var", "include", "loop", "if", "else", "unless", "elsif" }; static const char* const TAGNAME[]={ "Bad or unsupported tag", /* 0 */ "VAR", "INCLUDE", "LOOP", "IF", "ELSE", "UNLESS", "ELSIF" }; static int debuglevel=0; #define TAG_OPT_NAME 0 #define TAG_OPT_EXPR 1 #define TAG_OPT_ESCAPE 2 #define TAG_OPT_DEFAULT 3 #define MIN_TAG_OPT 0 #define MAX_TAG_OPT 3 static const char* const tagopt[]={"name", "expr", "escape", "default" }; static const char* const TAGOPT[]={"NAME", "EXPR", "ESCAPE", "DEFAULT" }; #include "prostate.inc" #include "tags.inc" static const char const tag_can_be_closed[]={ 1 /*Bad or unsupported tag*/, 0 /*VAR*/, 0 /*INCLUDE*/, 1 /*LOOP*/, 1 /*IF*/, 0 /*ELSE*/, 1 /*UNLESS*/, 1 /*ELSIF*/, 0 /**/, }; static const char const tag_has_opt[][6]={ /* "name", "expr", "escape", "default", todo, todo */ { 0, 0, 0, 0, 0, 0 }, /*Bad or unsupported tag*/ { 1, 1, 1, 1, 0, 0 }, /*VAR*/ { 1, 1, 0, 1, 0, 0 }, /*INCLUDE*/ { 1, 0, 0, 0, 0, 0 }, /*LOOP*/ { 1, 1, 0, 0, 0, 0 }, /*IF*/ { 0, 0, 0, 0, 0, 0 }, /*ELSE*/ { 1, 1, 0, 0, 0, 0 }, /*UNLESS*/ { 1, 1, 0, 0, 0, 0 }, /*ELSIF*/ { 0, 0, 0, 0, 0, 0 }, /**/ }; typedef void (*tag_handler_func)(struct tmplpro_state *state, const PSTRING* const TagOptVal); static const tag_handler_func const output_closetag_handler[]={ tag_handler_unknown, /*Bad or unsupported tag*/ tag_handler_unknown, /*VAR*/ tag_handler_unknown, /*INCLUDE*/ tag_handler_closeloop, /*LOOP*/ tag_handler_closeif, /*IF*/ tag_handler_unknown, /*ELSE*/ tag_handler_closeunless, /*UNLESS*/ tag_handler_unknown, /*ELSIF*/ tag_handler_unknown, /**/ }; static const tag_handler_func const output_opentag_handler[]={ tag_handler_unknown, /*Bad or unsupported tag*/ tag_handler_var, /*VAR*/ tag_handler_include, /*INCLUDE*/ tag_handler_loop, /*LOOP*/ tag_handler_if, /*IF*/ tag_handler_else, /*ELSE*/ tag_handler_unless, /*UNLESS*/ tag_handler_elsif, /*ELSIF*/ tag_handler_unknown, /**/ }; static int is_string(struct tmplpro_state *state, const char* pattern,const char* PATTERN) { const char* cur_pos=state->cur_pos; register const char* const next_to_end = state->next_to_end; while (*pattern && cur_pos=next_to_end) return 0; state->cur_pos=cur_pos; return 1; } static INLINE void jump_over_space(struct tmplpro_state *state) { register const char* const next_to_end = state->next_to_end; while (isspace(*(state->cur_pos)) && state->cur_poscur_pos++;}; } static INLINE void jump_to_char(struct tmplpro_state *state, char c) { register const char* const next_to_end = state->next_to_end; while (c!=*(state->cur_pos) && state->cur_poscur_pos++;}; } static PSTRING read_tag_parameter_value (struct tmplpro_state *state) { PSTRING modifier_value; char cur_char; char quote_char=0; register const char* cur_pos; const char* const next_to_end=state->next_to_end; jump_over_space(state); cur_pos=state->cur_pos; cur_char=*cur_pos; if (('"'==cur_char) || ('\''==cur_char)) { quote_char=*cur_pos; cur_pos++; } modifier_value.begin=cur_pos; cur_char=*cur_pos; if (quote_char) { while (quote_char!=cur_char #ifdef COMPAT_ON_BROKEN_QUOTE /* compatibility mode; HTML::Template doesn't allow '>' inside quotes */ && ('>' != quote_char) #endif && cur_pos'!=cur_char && ! isspace(cur_char) && cur_pos=next_to_end) { log_state(state,TMPL_LOG_ERROR,"quote char %c at pos " MOD_TD " is not terminated\n", quote_char,TO_PTRDIFF_T(state->cur_pos - state->top)); modifier_value.endnext=modifier_value.begin; jump_over_space(state); return modifier_value; } modifier_value.endnext=cur_pos; if (quote_char) { if (quote_char==*cur_pos) { cur_pos++; } else { log_state(state,TMPL_LOG_ERROR,"found %c instead of end quote %c at pos " MOD_TD "\n", *cur_pos,quote_char,TO_PTRDIFF_T(cur_pos - state->top)); } } state->cur_pos=cur_pos; /* if (debuglevel) log_state(state,TMPL_LOG_DEBUG2," at pos " MOD_TD "",TO_PTRDIFF_T(state->cur_pos-state->top)); */ jump_over_space(state); return modifier_value; } static int try_tag_parameter (struct tmplpro_state *state,const char *modifier,const char *MODIFIER) { const char* const initial_pos=state->cur_pos; jump_over_space(state); if (is_string(state, modifier, MODIFIER)) { jump_over_space(state); if ('='==*(state->cur_pos)) { state->cur_pos++; jump_over_space(state); return 1; } } state->cur_pos=initial_pos; return 0; } static void try_tmpl_var_options (struct tmplpro_state *state, int tag_type, PSTRING* TagOptVal) { int i; int opt_found = 1; /* reading parameter */ while (opt_found) { int found_in_loop=0; for (i=MIN_TAG_OPT; i<=MAX_TAG_OPT; i++) { if ( /* we will complain about syntax errors later; tag_has_opt[tag_type][i] && */ try_tag_parameter(state, tagopt[i], TAGOPT[i])) { TagOptVal[i] = read_tag_parameter_value(state); found_in_loop=1; if (debuglevel) log_state(state,TMPL_LOG_DEBUG,"in tag %s: found option %s=%.*s\n", TAGNAME[tag_type], TAGOPT[i],(int)(TagOptVal[i].endnext-TagOptVal[i].begin),TagOptVal[i].begin); } } if (!found_in_loop) opt_found = 0; } } static void process_tmpl_tag(struct tmplpro_state *state) { const int is_tag_closed=state->is_tag_closed; int tag_type=HTML_TEMPLATE_BAD_TAG; PSTRING TagOptVal[MAX_TAG_OPT+1]; int i; for (i=MIN_TAG_OPT; i<=MAX_TAG_OPT; i++) { TagOptVal[i].begin = NULL; TagOptVal[i].endnext = NULL; } for (i=HTML_TEMPLATE_FIRST_TAG_USED; i<=HTML_TEMPLATE_LAST_TAG_USED; i++) { if (is_string(state, tagname[i], TAGNAME[i])) { tag_type=i; state->tag=tag_type; if (debuglevel) { if (is_tag_closed) { tmpl_log(TMPL_LOG_DEBUG, "found at pos " MOD_TD "\n",TAGNAME[i], TO_PTRDIFF_T(state->cur_pos-state->top)); } else { tmpl_log(TMPL_LOG_DEBUG, "found at pos " MOD_TD "\n",TAGNAME[i], TO_PTRDIFF_T(state->cur_pos-state->top)); } } break; } } if (HTML_TEMPLATE_BAD_TAG==tag_type) { state->param->found_syntax_error=1; log_state(state,TMPL_LOG_ERROR, "found bad/unsupported tag at pos " MOD_TD "\n", TO_PTRDIFF_T(state->cur_pos-state->top)); /* TODO: flush its data --- */ state->cur_pos++; return; } if (is_tag_closed && !tag_can_be_closed[tag_type]) { state->param->found_syntax_error=1; log_state(state,TMPL_LOG_ERROR, "incorrect closed tag at pos " MOD_TD "\n", TAGNAME[tag_type], TO_PTRDIFF_T(state->cur_pos-state->top)); } if (is_tag_closed || ! tag_has_opt[tag_type][TAG_OPT_NAME]) { /* tag has no parameter */ #ifdef COMPAT_ALLOW_NAME_IN_CLOSING_TAG /* requested compatibility mode to try reading NAME inside (useful for comments?) */ try_tag_parameter(state, tagopt[TAG_OPT_NAME], TAGOPT[TAG_OPT_NAME]); read_tag_parameter_value(state); #endif } else { try_tmpl_var_options(state, tag_type, TagOptVal); /* suport for short syntax */ if (TagOptVal[TAG_OPT_NAME].begin == NULL && tag_has_opt[tag_type][TAG_OPT_NAME] && (!tag_has_opt[tag_type][TAG_OPT_EXPR] || TagOptVal[TAG_OPT_EXPR].begin == NULL )) { TagOptVal[TAG_OPT_NAME]=read_tag_parameter_value(state); try_tmpl_var_options(state, tag_type, TagOptVal); } if (TagOptVal[TAG_OPT_NAME].begin == NULL && tag_has_opt[tag_type][TAG_OPT_NAME] && (!tag_has_opt[tag_type][TAG_OPT_EXPR] || TagOptVal[TAG_OPT_EXPR].begin == NULL )) { state->param->found_syntax_error=1; log_state(state,TMPL_LOG_ERROR,"NAME or EXPR is required for TMPL_%s\n", TAGNAME[tag_type]); } for (i=MIN_TAG_OPT; i<=MAX_TAG_OPT; i++) { if (TagOptVal[i].begin!=NULL && ! tag_has_opt[tag_type][i]) { state->param->found_syntax_error=1; log_state(state,TMPL_LOG_ERROR,"TMPL_%s does not support %s= option\n", TAGNAME[tag_type], TAGOPT[i]); } } } if (state->is_tag_commented) { /* try read comment end */ /* jump_over_space(state); it should be already done :( */ jump_over_space(state); if (state->cur_posnext_to_end-2 && '-'==*(state->cur_pos) && '-'==*(state->cur_pos+1)) { state->cur_pos+=2; } } /* template tags could also be decorated as xml */ if (!is_tag_closed && '/'==*(state->cur_pos)) state->cur_pos++; if ('>'==*(state->cur_pos)) { state->cur_pos++; } else { state->param->found_syntax_error=1; log_state(state,TMPL_LOG_ERROR,"end tag:found %c instead of > at pos " MOD_TD "\n", *state->cur_pos, TO_PTRDIFF_T(state->cur_pos-state->top)); } /* flush run chars (if in SHOW mode) */ if (state->is_visible) { (state->param->WriterFuncPtr)(state->param->ext_writer_state,state->last_processed_pos,state->tag_start); state->last_processed_pos=state->cur_pos; } if (is_tag_closed) { output_closetag_handler[tag_type](state,TagOptVal); } else { output_opentag_handler[tag_type](state,TagOptVal); } } /* max offset to ensure we are not out of file when try 0); if (buffer[tmplen-1]=='.') { tmplen--; len=tmplen; } retval.begin=buffer; retval.endnext=buffer+len; return retval; } static PSTRING int_to_pstring (EXPR_int64 number, char buffer[], size_t bufsize) { size_t len=0; PSTRING retval; snprintf(buffer, bufsize,"%" EXPR_PRId64 , number); len=strlen(buffer); retval.begin=buffer; retval.endnext=buffer+len; return retval; } static int pstring_ge(PSTRING a, PSTRING b) { const char* in_a=a.begin; const char* in_b=b.begin; if (in_b==NULL) return 1; if (in_a==NULL) return 0; while (in_a= *(--in_b) ) return 1; else return 0; } static int pstring_le(PSTRING a, PSTRING b) { const char* in_a=a.begin; const char* in_b=b.begin; if (in_a==NULL) return 1; if (in_b==NULL) return 0; while (in_a *(--in_b)) ) return 1; else return 0; } static int pstring_lt(PSTRING a, PSTRING b) { const char* in_a=a.begin; const char* in_b=b.begin; if (in_b==NULL) return 0; if (in_a==NULL) return 1; while (in_a static int re_like(struct expr_parser* exprobj, PSTRING a, PSTRING b) { pcre* re; int ovector[30]; int rc, erroffset; const char* error; const char* subject=a.begin; int subject_length=(int)(a.endnext-a.begin); char* pattern; if (subject==NULL) { log_expr(exprobj,TMPL_LOG_INFO, "regular expression: applied to undefined value.\n"); return 0; } if (b.begin==NULL || (b.endnext-b.begin)==0) { log_expr(exprobj,TMPL_LOG_INFO, "regular expression: the pattern is empty or undefined.\n"); return 1; } pattern=(char*)malloc(b.endnext-b.begin); if (pattern==NULL) { log_expr(exprobj,TMPL_LOG_ERROR, "regular expression: memory allocation failed.\n"); return 0; } strncpy(pattern, b.begin, (b.endnext-b.begin)); *(pattern+(b.endnext-b.begin))=0; re = pcre_compile(pattern, 0, &error, &erroffset, NULL); /* default character set */ free(pattern); if (re==NULL) { log_expr(exprobj,TMPL_LOG_ERROR, "regular expression: PCRE compilation failed at offset %d: %s\n", erroffset, error); return 0; } rc=pcre_exec(re, NULL, subject, subject_length, 0, 0, ovector, 30); return (rc<0)?0:1; } #endif HTML-Template-Pro-0.9510/Makefile.PL0000644000076400007640000002374311723342563015346 0ustar igorigoruse 5.005; use ExtUtils::MakeMaker; use Config; use File::Spec; #use strict; use warnings; $Verbose = 1; my ($INC, $DEFINE, $LIBS, $O_FILES, $STATIC_BUILD); our $VERSION=''; eval `grep 'VERSION *=' lib/HTML/Template/Pro.pm`; if (grep {/^DYNAMIC=1/} @ARGV) { $STATIC_BUILD=0; $INC='-I/usr/include/htmltmplpro'; $DEFINE='-DUSE_SYSTEM_HTP_HEADER'; $LIBS='-lhtmltmplpro'; $O_FILES=''; } else { $STATIC_BUILD=1; $INC='-I.'; $DEFINE='-DHTMLTMPLPRO_STATIC'; $LIBS='-lm'; $O_FILES='$(O_FILES)'; } my %DEF=( MAINTAINER => $^O eq 'linux' && -d '.git' ? 1 : 0, PCRE => 1, DEBUG => 0, MMAP => 1, IMITATE=>0, ); $DEF{PACKAGE_VERSION}=$VERSION if $VERSION; &configure() if $STATIC_BUILD; ### -------------------------------------- ### testing whether sources are consistent ### -------------------------------------- unless ((stat('test_crlf.out'))[7] == 47) { my @tests_to_skip=('HTML-Template-Pro.t', 'HTML-Template.t', 'realloc.t'); print < 'HTML::Template::Pro', VERSION_FROM => 'lib/HTML/Template/Pro.pm', # finds $VERSION PREREQ_PM => {'JSON', => 2.0, # safe to skip 'File::Path' => 2.0, 'File::Spec' => 0, 'Test::More' => 0, }, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/HTML/Template/Pro.pm', # retrieve abstract from module AUTHOR => 'I. Yu. Vlasenko ') : ()), LIBS => [$LIBS], DEFINE => $DEFINE, # e.g., '-DHAVE_SOMETHING' INC => $INC, OBJECT => $O_FILES, # link all the C files too # license is: as perl itself or Artistic or GPL2+ or LGPL2+. # 'perl' is a valid string for META1.4 spec # https://rt.cpan.org/Public/Bug/Display.html?id=44210 LICENSE => 'perl', # PERL_MALLOC_OK => 1 # read first, static only depend => { 'expr.o' => 'calc.inc exprtool.inc exprpstr.inc', 'procore.o' => 'proscope.inc pstrutils.inc loadfile.inc loopvar.inc', }, ); sub MY::postamble { return '' unless $DEF{MAINTAINER}; return <<'MAKE_FRAG'; expr.c: calc.inc exprtool.inc exprpstr.inc procore\$(OBJ_EXT): loadfile.inc tagstack.inc optint.c: optint.re2c.m4 #proparam.c proparam.h: pparam.h # ./pparam2proparam rpm: dist rpmbuild -ta --clean HTML-Template-Pro-$(VERSION).tar.gz .re2c.c: re2c $< > $@ %.re2c: %.re2c.m4 m4 -P $< > $@ MANIFEST.git:: git-ls-files > MANIFEST.git index.html: README Makefile echo '

SourceForge.net Logo
SourceForge Summary page of the project
Home page of the author
Download

' > $@
	cat $< >> $@
	echo '
' >> $@ TARBALL=HTML-Template-Pro-$(VERSION).tar.gz SF_HOME='viy2@html-tmpl-pro.sf.net:/home/groups/h/ht/html-tmpl-pro/htdocs/' sourceforge: tardist index.html ssh-add ~/.ssh/id_dsa.sf ( echo cd uploads; \ echo put $(TARBALL); \ echo quit ) | /usr/bin/sftp viy2@frs.sourceforge.net scp index.html $(SF_HOME) json:: rm -rf templates-Pro/json export HTP_DUMP=1; $(MAKE) test .SUFFIXES: .re2c MAKE_FRAG } # those tests are based on ones from Time-HiRes-01.20 sub try_compile_and_link { my ($c, $cccmd, $ccflags, $verbose) = @_; $verbose = 1 unless defined $verbose; my ($ok) = 0; my ($tmp) = File::Spec->catfile( File::Spec->tmpdir(), "tmp$$" ); local(*TMPC); my $obj_ext = $Config{obj_ext} || ".o"; unlink("$tmp.c", "$tmp$obj_ext"); if (open(TMPC, ">$tmp.c")) { print TMPC $c; close(TMPC); my $COREincdir = File::Spec->canonpath(File::Spec->catfile($Config{'archlibexp'}, 'CORE')); $ccflags .= ' '. $Config{'ccflags'} . ' ' . "-I$COREincdir"; my $cc=$Config{'cc'}; $cc||='cc'; if ($^O eq 'VMS') { my $perl_core = $Config{'installarchlib'}; $perl_core =~ s/\]$/.CORE]/; $cccmd = "$cc /include=(perl_root:[000000],$perl_core) $tmp.c"; } $cccmd = "$cc -o $tmp $ccflags $tmp.c @$LIBS" unless (defined $cccmd); print "trying $cccmd\n" if $verbose; system($cccmd); if ($^O eq 'VMS') { $ok = -s "$tmp$obj_ext" && -x _; unlink("$tmp.c", "$tmp$obj_ext"); } else { my $exe = $tmp . ($Config{_exe} || ''); $ok = -s $exe && -x _; unlink("$tmp.c", $exe); } } $ok; } sub has_header { my $header=shift; print "looking for $header...\n"; if (try_compile_and_link(' #include <'.$header.'> static int foo() { return 0; } int main (int argc, char** argv) { foo(); } ',undef, '')){ print "$header found.\n"; return 1; } print "$header not found.\n"; return 0; } sub has_pcre { print "looking for pcre...\n"; if (try_compile_and_link(' #include static int foo() { return 0; } int main (int argc, char** argv) { foo(); } ',undef, '-I/usr/include/pcre -lpcre')){ print "pcre found.\n"; return 1; } print "pcre not found.\n"; return 0; } sub has_mmap { print "looking for mmap...\n"; if (try_compile_and_link(' #include #include #include #include static char* mmap_load_file (const char* filepath) { int fd; struct stat st; size_t size_in_bytes; char* memarea=NULL; fd = open(filepath, O_RDONLY); if (fd == -1) return memarea; /* {NULL,NULL} */ fstat(fd, &st); size_in_bytes = st.st_size; /* mmap size_in_bytes+1 to avoid crash with empty file */ memarea = (char *) mmap(0, size_in_bytes+1, PROT_READ, MAP_SHARED, fd, 0); close(fd); return memarea; } int main (int argc, char** argv) { mmap_load_file("file"); } ',undef, '')){ print "mmap found.\n"; return 1; } print "mmap not found.\n"; return 0; } sub has_func { my ($func_call)=@_; print "looking for $func_call\n"; if (try_compile_and_link(' #include int main (int argc, char** argv) { '.$func_call.'; } ',undef, '')){ print "$func_call found.\n"; return 1; } print "$func_call not found.\n"; return 0; } sub find_int64 { foreach my $type ('__int64','long long','int64_t','long','int') { return $type if try_as_int64($type); } return; } sub try_as_int64 { my $type=shift; print "looking for int64: trying $type..."; if (try_compile_and_link(' int main (int argc, char** argv) { if (sizeof('.$type.')==8) return 0; return sizeof('.$type.'); } ',undef, '',0)){ print "Ok.\n"; return 1; } print "no.\n"; return 0; } sub configure { $DEF{PCRE}=has_pcre(); if ($^O eq 'os2' or $^O eq 'dos') { $DEF{MMAP}=0; } elsif ($^O eq 'MSWin32') { # win 32 mmap is disabled by default # $DEF{MMAP}=1; $DEF{MMAP}=0; # no, compiler is yet unknown here; # and some creepy M**soft tools may not understand long long :( # $DEF{INT64_NAME} = "long long";? } else { $DEF{HAS_MMAP}=has_mmap(); } $DEF{INT64_NAME} ||= find_int64(); $DEF{INT64_NAME} ||= $Config{i64type}; my $i; for ($i=0; $i<@ARGV; $i++) { if ($ARGV[$i]=~/^(PCRE|PEDANTIC|DEBUG|MMAP|IMITATE)=(.+)/) { $DEF{$1}=$2; } else { next; } splice @ARGV, $i, 1; $i--; } #$DEF{MMAP}=0 if $^O =~ /MSWin32/ and $DEF{'IMITATE'}; $DEFINE.=' -DDEBUG' if $DEF{DEBUG}; $DEFINE.=' -DUSE_MMAP ' if $DEF{MMAP}; $DEFINE.=' -DHAVE_STDINT_H ' if has_header('stdint.h'); $DEFINE.=' -DHAVE_INTTYPES_H ' if has_header('inttypes.h'); $DEFINE.=' -DHAVE_STRDUP' if has_func('strdup("str")'); $DEFINE.=' -DHAVE__STRDUP' if has_func('_strdup("str")'); $DEFINE.=' -DHAVE_SYS_MMAN_H -DHAVE_SYS_STAT_H' if ($DEF{HAS_MMAP}); $DEFINE.=' -DCOMPAT_ON_BROKEN_QUOTE -DCOMPAT_ALLOW_NAME_IN_CLOSING_TAG' if ($DEF{'IMITATE'}); $DEFINE.=' -pedantic -DPEDANTIC' if ($DEF{'PEDANTIC'}); $DEFINE.=' -DINT64_NAME="' . $DEF{'INT64_NAME'}.'"' if ($DEF{'INT64_NAME'}); if ($DEF{'INT64_NAME'}) { if ($DEF{'INT64_NAME'} eq "long long") { $DEFINE.=' -DSIZEOF_LONG_LONG=8'; } elsif ($DEF{'INT64_NAME'} eq "long") { $DEFINE.=' -DSIZEOF_LONG=8'; } } if ($DEF{PCRE}) { $INC.=' -I/usr/include/pcre'; $DEFINE.=' -DHAVE_PCRE'; $LIBS.=' -lpcre'; print " ===================================================================== build with libpcre (Stanislav Yadykin's regexp extension) is enabled. ===================================================================== if you have not installed libpcre, you still can build the module without libpcre (with this extension disabled) using perl Makefile.PL PCRE=0 "; } else { print " ================================================= build with libpcre is disabled. ================================================= Stanislav Yadykin's regexp extension is disabled. "; } if ($DEF{IMITATE}) { print " ===================================================================== Compatibility mode for syntactically incorrect templates is enabled. Note, that this mode could be a bit slower than default but it will be useful if you rely on HTML::Template behaviour in undefined cases. ===================================================================== "; } else { print " ===================================================================== Compatibility mode for syntactically incorrect templates is disabled. It is the fast default. ===================================================================== "; } } HTML-Template-Pro-0.9510/callback_stubs.inc0000644000076400007640000000412511436451714017034 0ustar igorigor/* * File: callback_stubs.c * Author: Igor Vlasenko * Created: Tue Jul 14 22:47:11 2009 */ #include "pstring.h" #include "pbuffer.h" struct builtin_writer_state { size_t size; pbuffer* bufptr; }; /* writer_functype stub */ /* endnext points on next character to end of interval as in c++ */ static void BACKCALL stub_write_chars_to_stdout (ABSTRACT_WRITER* none,const char* begin, const char* endnext) { if (endnext==begin) return; if (0==fwrite(begin, sizeof(char), endnext-begin, stdout)) { tmpl_log(TMPL_LOG_ERROR,"find_file_func stub: can't fwrite to stdout\n"); } } /* writer_functype stub */ /* endnext points at the character next to the end of the interval */ static void BACKCALL stub_write_chars_to_pbuffer (ABSTRACT_WRITER* state,const char* begin, const char* endnext) { size_t addlen = endnext-begin; size_t oldlen; pbuffer* pbuf; if (addlen==0) return; oldlen = ((struct builtin_writer_state*) state)->size; pbuf = ((struct builtin_writer_state*) state)->bufptr; pbuffer_resize(pbuf, oldlen + addlen + 1); memcpy(pbuffer_string(pbuf) + oldlen, begin, addlen); ((struct builtin_writer_state*) state)->size += addlen; } static ABSTRACT_USERFUNC* BACKCALL stub_is_expr_userfnc_func (ABSTRACT_FUNCMAP* af, PSTRING name) { tmpl_log(TMPL_LOG_DEBUG,"is_expr_userfnc_func stub: EXPR is not initialized properly. user func dispatcher was not supplied.\n"); return NULL; } static PSTRING BACKCALL stub_load_file_func (ABSTRACT_FILTER* none, const char* filename) { tmpl_log(TMPL_LOG_ERROR,"load_file_func stub: callback function for filters was not specified."); return mmap_load_file(filename); } static int BACKCALL stub_unload_file_func (ABSTRACT_FILTER* none, PSTRING memarea) { tmpl_log(TMPL_LOG_ERROR,"unload_file_func stub: callback function for filters was not specified."); return mmap_unload_file(memarea); } static int BACKCALL stub_get_ABSTRACT_ARRAY_length_func (ABSTRACT_DATASTATE* none1, ABSTRACT_ARRAY* none) { return -1; /* treat all arrays as arrays of undefined length */ } /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/expr_iface.c0000644000076400007640000000352411247772713015645 0ustar igorigor/* * File: expr_iface.c * Author: Igor Vlasenko * Created: Sat Apr 15 21:15:24 2006 */ #include #include "tmplpro.h" #include "exprval.h" #include "pparam.h" API_IMPL void APICALL tmplpro_set_expr_as_int64 (struct exprval* p,EXPR_int64 ival) { p->type=EXPR_TYPE_INT; p->val.intval=ival; } API_IMPL void APICALL tmplpro_set_expr_as_double (struct exprval* p,double dval) { p->type=EXPR_TYPE_DBL; p->val.dblval=dval; } API_IMPL void APICALL tmplpro_set_expr_as_string (struct exprval* p, const char* sval) { p->type=EXPR_TYPE_PSTR; p->val.strval.begin=sval; p->val.strval.endnext=sval; if (NULL!=sval) p->val.strval.endnext+=strlen(sval); } API_IMPL void APICALL tmplpro_set_expr_as_pstring (struct exprval* p,PSTRING pval) { p->type=EXPR_TYPE_PSTR; p->val.strval=pval; } API_IMPL void APICALL tmplpro_set_expr_as_null (struct exprval* p) { p->type=EXPR_TYPE_PSTR; p->val.strval.begin=NULL; p->val.strval.endnext=NULL; } API_IMPL int APICALL tmplpro_get_expr_type (struct exprval* p) { if (p->type == EXPR_TYPE_PSTR) { if (NULL==p->val.strval.begin) { p->val.strval.endnext=NULL; p->type = EXPR_TYPE_NULL; } else if (NULL==p->val.strval.endnext) { /* should never happen */ p->val.strval.endnext=p->val.strval.begin+strlen(p->val.strval.begin); } /* never happen; but let it be for future compatibility */ } else if (p->type == EXPR_TYPE_NULL) { p->val.strval.begin=NULL; p->val.strval.endnext=NULL; } return (int) p->type; } API_IMPL EXPR_int64 APICALL tmplpro_get_expr_as_int64 (struct exprval* p) { return p->val.intval; } API_IMPL double APICALL tmplpro_get_expr_as_double (struct exprval* p) { return p->val.dblval; } API_IMPL PSTRING APICALL tmplpro_get_expr_as_pstring (struct exprval* p) { return p->val.strval; } HTML-Template-Pro-0.9510/LGPL0000644000076400007640000006350211231403301014030 0ustar igorigor GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! HTML-Template-Pro-0.9510/procore.h0000644000076400007640000000102011436447452015202 0ustar igorigor#include "pstring.h" #include "tmpllog.h" #include "pabstract.h" struct tmplpro_param; static int tmplpro_exec_tmpl_filename (struct tmplpro_param* ProParams,const char* filename); static int tmplpro_exec_tmpl_scalarref (struct tmplpro_param* ProParams, PSTRING memarea); static const char* const errlist[] = { "ok", "invalid argument", "file not found", "can't open file", "syntax error in template", "not enough memory (allocation error)", "", "", "" }; /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/pbuffer.h0000644000076400007640000000143611253453632015167 0ustar igorigor#ifndef _PBUFFER_H #define _PBUFFER_H 1 #include #include #include "pstring.h" typedef struct pbuffer { size_t bufsize; char* buffer; } pbuffer; #define PBUFFER_MULTIPLICATOR 2 TMPLPRO_LOCAL size_t pbuffer_size(const pbuffer*); TMPLPRO_LOCAL void pbuffer_preinit(pbuffer* pBuffer); TMPLPRO_LOCAL char* pbuffer_init(pbuffer*); TMPLPRO_LOCAL char* pbuffer_init_as(pbuffer* pBuffer,size_t size); TMPLPRO_LOCAL char* pbuffer_string(const pbuffer*); TMPLPRO_LOCAL char* pbuffer_resize(pbuffer*, size_t size); TMPLPRO_LOCAL void pbuffer_free(pbuffer*); TMPLPRO_LOCAL void pbuffer_fill_from_pstring(pbuffer* pBuffer, PSTRING pstr); TMPLPRO_LOCAL void pbuffer_swap(pbuffer* buf1, pbuffer* buf2); #endif /* pbuffer.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/exprval.h0000644000076400007640000000072711250137055015214 0ustar igorigor/* -*- c -*- * File: exprval.h * Author: Igor Vlasenko * Created: Mon Jul 20 21:10:57 2009 */ #ifndef _EXPRVAL_H #define _EXPRVAL_H 1 #include "exprtype.h" typedef char EXPR_char; struct exprval { EXPR_char type; union uval { EXPR_int64 intval; /* integer */ double dblval; /* double */ PSTRING strval; } val; }; #define NEW_EXPRVAL(X) { X } #endif /* exprval.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/tags.inc0000644000076400007640000004145011721663705015022 0ustar igorigorstatic int get_escape_option(struct tmplpro_state *state, PSTRING OptEscape) { /* int escape = HTML_TEMPLATE_OPT_ESCAPE_NO; */ int escape = state->param->default_escape; if (OptEscape.beginparam->found_syntax_error=1; log_state(state,TMPL_LOG_ERROR, " unsupported value of ESCAPE=%.*s\n",(int)(OptEscape.endnext-OptEscape.begin),OptEscape.begin); } } return escape; } static void init_tmpl_var_case_buffers (struct tmplpro_param *param) { param->lowercase_varname.begin = NULL; param->lowercase_varname.endnext = NULL; param->uppercase_varname.begin = NULL; param->uppercase_varname.endnext = NULL; } static ABSTRACT_VALUE* get_abstract_value (struct tmplpro_param *param, int scope_level, PSTRING name) { ABSTRACT_VALUE* retval = NULL; ABSTRACT_MAP* param_HV = getScope(¶m->var_scope_stack, scope_level)->param_HV; ABSTRACT_DATASTATE* data_state = param->ext_data_state; get_ABSTRACT_VALUE_functype getval_func = param->GetAbstractValFuncPtr; int tmpl_var_case = param->tmpl_var_case; if ((tmpl_var_case & ASK_NAME_MASK) == ASK_NAME_DEFAULT || tmpl_var_case & ASK_NAME_AS_IS) { retval = getval_func(data_state, param_HV, name); if (retval != NULL) return retval; } if (tmpl_var_case & ASK_NAME_LOWERCASE) { if (param->lowercase_varname.begin == NULL) { param->lowercase_varname=lowercase_pstring(¶m->lowercase_varname_buffer, name); } retval = getval_func(data_state, param_HV, param->lowercase_varname); if (retval != NULL) return retval; } if (tmpl_var_case & ASK_NAME_UPPERCASE) { if (param->uppercase_varname.begin == NULL) { param->uppercase_varname=uppercase_pstring(¶m->uppercase_varname_buffer, name); } retval = getval_func(data_state, param_HV, param->uppercase_varname); if (retval != NULL) return retval; } return retval; } static ABSTRACT_VALUE* walk_through_nested_loops (struct tmplpro_param *param, PSTRING name) { int CurLevel; ABSTRACT_VALUE* valptr; init_tmpl_var_case_buffers (param); /* Shigeki Morimoto path_like_variable_scope extension */ if (param->path_like_variable_scope) { if(*(name.begin) == '/' || strncmp(name.begin, "../", 3) == 0){ PSTRING tmp_name; int GoalHash; if(*(name.begin) == '/'){ tmp_name.begin = name.begin+1; // skip '/' tmp_name.endnext = name.endnext; GoalHash = 0; }else{ tmp_name.begin = name.begin; tmp_name.endnext = name.endnext; GoalHash = curScopeLevel(¶m->var_scope_stack); while(strncmp(tmp_name.begin, "../", 3) == 0){ tmp_name.begin = tmp_name.begin + 3; // skip '../' GoalHash --; } } return get_abstract_value(param, GoalHash, tmp_name); } } /* end Shigeki Morimoto path_like_variable_scope extension */ CurLevel = curScopeLevel(¶m->var_scope_stack); valptr = get_abstract_value(param, CurLevel, name); if (valptr) return valptr; /* optional strict scoping; does it have much sence? if ((STRICT_SCOPING==param->global_vars)) return NULL; */ /* loop-bounded scoping; */ if (0==param->global_vars) { while (isScopeMap(getScope(¶m->var_scope_stack,CurLevel)) && --CurLevel>=0) { valptr = get_abstract_value(param, CurLevel, name); if (valptr!=NULL) return valptr; } return NULL; } while (--CurLevel>=0) { valptr = get_abstract_value(param, CurLevel, name); if (valptr!=NULL) return valptr; } return NULL; } TMPLPRO_LOCAL PSTRING _get_variable_value (struct tmplpro_param *param, PSTRING name) { PSTRING varvalue ={NULL, NULL}; ABSTRACT_VALUE* abstrval; if (param->loop_context_vars) { varvalue=get_loop_context_vars_value(param, name); } if (varvalue.begin==NULL) { abstrval=walk_through_nested_loops(param, name); if (abstrval!=NULL) varvalue=(param->AbstractVal2pstringFuncPtr)(param->ext_data_state, abstrval); } if (debuglevel>=TMPL_LOG_DEBUG2) { if (name.begin!=NULL) { tmpl_log(TMPL_LOG_DEBUG2,"_get_variable_value: name = %.*s ",(int)(name.endnext-name.begin),name.begin); } else { tmpl_log(TMPL_LOG_DEBUG2,"_get_variable_value: name = NULL "); } if (varvalue.begin!=NULL) { tmpl_log(TMPL_LOG_DEBUG2,"value = %.*s\n",(int)(varvalue.endnext-varvalue.begin),varvalue.begin); } else { tmpl_log(TMPL_LOG_DEBUG2,"value = UNDEF\n"); } } return varvalue; } static PSTRING get_variable_option (struct tmplpro_state *state, const PSTRING* const TagOptVal) { PSTRING varvalue ={NULL, NULL}; PSTRING defvalue = TagOptVal[TAG_OPT_DEFAULT]; if (TagOptVal[TAG_OPT_EXPR].begin!=NULL) { varvalue=parse_expr(TagOptVal[TAG_OPT_EXPR], state); } else { varvalue=_get_variable_value(state->param, TagOptVal[TAG_OPT_NAME]); } if (varvalue.begin==NULL) { if (defvalue.begin!=defvalue.endnext) { varvalue=defvalue; } } return varvalue; } static void tag_handler_var (struct tmplpro_state *state, const PSTRING* const TagOptVal) { PSTRING varvalue; int escapeopt; /* if (debuglevel>=TMPL_LOG_DEBUG2) { log_state(state,TMPL_LOG_DEBUG2,"Entered tag_handler_var\n"); }*/ if (! state->is_visible) return; varvalue = get_variable_option(state, TagOptVal); escapeopt = get_escape_option(state,TagOptVal[TAG_OPT_ESCAPE]); if (varvalue.begin==NULL) return; if (escapeopt!=HTML_TEMPLATE_OPT_ESCAPE_NO) { varvalue=escape_pstring(&state->param->escape_pstring_buffer, varvalue, escapeopt); } (state->param->WriterFuncPtr)(state->param->ext_writer_state,varvalue.begin,varvalue.endnext); } static void tag_handler_include (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tmplpro_param* param; char* filename; int x; PSTRING varvalue; PSTRING defvalue; if (! state->is_visible) return; param=state->param; if (param->no_includes) { log_state(state,TMPL_LOG_ERROR, "HTML::Template::Pro : Illegal attempt to use TMPL_INCLUDE in template file : (no_includes => 1)\n"); return; } if (param->max_includes && param->max_includes < param->cur_includes) { log_state(state,TMPL_LOG_INFO, "HTML::Template::Pro : TMPL_INCLUDE: max_includes exceeded.\n"); return; } param->cur_includes++; varvalue=TagOptVal[TAG_OPT_NAME]; defvalue = TagOptVal[TAG_OPT_DEFAULT]; if (TagOptVal[TAG_OPT_EXPR].begin!=NULL) { varvalue=parse_expr(TagOptVal[TAG_OPT_EXPR], state); }; if (varvalue.begin==varvalue.endnext && defvalue.begin!=defvalue.endnext) varvalue=defvalue; /* pstrdup */ { const long len = varvalue.endnext-varvalue.begin; filename =(char*) malloc(len+1); for (x=0;xcur_includes--; return; } static int is_var_true(struct tmplpro_state *state, const PSTRING* const TagOptVal) { register int ifval=-1; /*not yet defined*/ if (TagOptVal[TAG_OPT_EXPR].begin!=NULL) { /* if (debuglevel>=TMPL_LOG_DEBUG2) { tmpl_log(TMPL_LOG_DEBUG2,"is_var_true: expr = %.*s\n",(int)(TagOptVal[TAG_OPT_EXPR].endnext-TagOptVal[TAG_OPT_EXPR].begin),TagOptVal[TAG_OPT_EXPR].begin); }*/ ifval=is_pstring_true(parse_expr(TagOptVal[TAG_OPT_EXPR], state)); } else if (state->param->loop_context_vars) { PSTRING loop_var=get_loop_context_vars_value(state->param, TagOptVal[TAG_OPT_NAME]); if (loop_var.begin!=NULL) { ifval=is_pstring_true(loop_var); } } if (ifval==-1) { is_ABSTRACT_VALUE_true_functype userSuppliedIsTrueFunc; ABSTRACT_VALUE* abstrval=walk_through_nested_loops(state->param, TagOptVal[TAG_OPT_NAME]); if (abstrval==NULL) return 0; userSuppliedIsTrueFunc = state->param->IsAbstractValTrueFuncPtr; if (userSuppliedIsTrueFunc!=NULL) { ifval=(userSuppliedIsTrueFunc)(state->param->ext_data_state, abstrval); } else { ifval=is_pstring_true((state->param->AbstractVal2pstringFuncPtr)(state->param->ext_data_state, abstrval)); } } return ifval; } static void tag_handler_if (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry iftag; iftag.tag=HTML_TEMPLATE_TAG_IF; iftag.vcontext=state->is_visible; iftag.position=state->cur_pos; /* unused */ /* state->is_visible && means that we do not evaluate variable in shadow */ if (state->is_visible && is_var_true(state,TagOptVal)) { iftag.value=1; /* state->is_visible is not touched */ } else { iftag.value=0; state->is_visible=0; } tagstack_push(&(state->tag_stack), iftag); if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"tag_handler_if:visible context =%d value=%d ",iftag.vcontext,iftag.value); } static void tag_handler_unless (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry iftag; iftag.tag=HTML_TEMPLATE_TAG_UNLESS; iftag.vcontext=state->is_visible; iftag.position=state->cur_pos; /* unused */ /* state->is_visible && means that we do not evaluate variable in shadow */ if (state->is_visible && !is_var_true(state,TagOptVal)) { iftag.value=1; /* state->is_visible is not touched */ } else { iftag.value=0; state->is_visible=0; } tagstack_push(&(state->tag_stack), iftag); if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"tag_handler_unless:visible context =%d value=%d ",iftag.vcontext,iftag.value); } static INLINE int test_stack (int tag) { // return (tagstack_notempty(&(state->tag_stack)) && (tagstack_top(&(state->tag_stack))->tag==tag)); return 1; } static void tag_stack_debug (struct tmplpro_state *state, int stack_tag_type) { if (stack_tag_type) { if (tagstack_notempty(&(state->tag_stack))) { struct tagstack_entry* iftag=tagstack_top(&(state->tag_stack)); if (iftag->tag!=stack_tag_type) { log_state(state,TMPL_LOG_ERROR, "ERROR: tag mismatch with %s\n",TAGNAME[iftag->tag]); } } else { log_state(state,TMPL_LOG_ERROR, "ERROR: opening tag %s not found\n",TAGNAME[stack_tag_type]); } } } static struct tagstack_entry tagstack_smart_pop(struct tmplpro_state *state) { int is_underflow=0; struct tagstack_entry curtag=tagstack_pop(&(state->tag_stack), &is_underflow); if (is_underflow) { log_state(state,TMPL_LOG_ERROR,"stack underflow:tag stack is empty. Cased by closing tag w/o matching opening tag.\n"); } return curtag; } static void tag_handler_closeif (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry iftag; if (! test_stack(HTML_TEMPLATE_TAG_IF)) { tag_stack_debug(state,HTML_TEMPLATE_TAG_IF); return; } iftag=tagstack_smart_pop(state); if (0==state->is_visible) state->last_processed_pos=state->cur_pos; state->is_visible=iftag.vcontext; } static void tag_handler_closeunless (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry iftag; if (! test_stack(HTML_TEMPLATE_TAG_UNLESS)) { tag_stack_debug(state,HTML_TEMPLATE_TAG_UNLESS); return; } iftag=tagstack_smart_pop(state); if (0==state->is_visible) state->last_processed_pos=state->cur_pos; state->is_visible=iftag.vcontext; } static void tag_handler_else (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry* iftag; if (! test_stack(HTML_TEMPLATE_TAG_IF) && ! test_stack(HTML_TEMPLATE_TAG_UNLESS)) { tag_stack_debug(state,HTML_TEMPLATE_TAG_ELSE); return; } iftag=tagstack_top(&(state->tag_stack)); if (0==state->is_visible) state->last_processed_pos=state->cur_pos; if (iftag->value) { state->is_visible=0; } else if (1==iftag->vcontext) { state->is_visible=1; } if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"else:(pos " MOD_TD ") visible:context =%d, set to %d ", TO_PTRDIFF_T(iftag->position - state->top),iftag->vcontext,state->is_visible); } static void tag_handler_elsif (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry *iftag; if (! test_stack(HTML_TEMPLATE_TAG_IF) && ! test_stack(HTML_TEMPLATE_TAG_UNLESS)) { tag_stack_debug(state,HTML_TEMPLATE_TAG_ELSIF); return; } iftag=tagstack_top(&(state->tag_stack)); if (0==state->is_visible) state->last_processed_pos=state->cur_pos; if (iftag->value) { state->is_visible=0; } else if (1==iftag->vcontext) { /* test only if vcontext==true; if the whole tag if..endif itself is invisible, skip the is_var_true test */ /*TODO: it is reasonable to skip is_var_true test in if/unless too */ if (is_var_true(state,TagOptVal)) { iftag->value=1; state->is_visible=1; } else { iftag->value=0; state->is_visible=0; } } if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"elsif:(pos " MOD_TD ") visible:context =%d, set to %d ", TO_PTRDIFF_T(iftag->position - state->top), iftag->vcontext, state->is_visible); } static int next_loop (struct tmplpro_state* state) { #ifdef DEBUG log_state(state,TMPL_LOG_DEBUG2,"next_loop:before NextLoopFuncPtr\n"); #endif struct ProScopeEntry* currentScope = getCurrentScope(&state->param->var_scope_stack); if (!isScopeLoop(currentScope)) { log_state(state,TMPL_LOG_ERROR, "next_loop:at scope level %d: internal error - loop is null\n", curScopeLevel(&state->param->var_scope_stack)); return 0; } if (++currentScope->loop < currentScope->loop_count || currentScope->loop_count< 0) { ABSTRACT_MAP* arrayvalptr=(state->param->GetAbstractMapFuncPtr)(state->param->ext_data_state, currentScope->loops_AV,currentScope->loop); if ((arrayvalptr!=NULL)) { currentScope->param_HV=arrayvalptr; return 1; } else { /* either undefined loop ended normally or defined loop ended ubnormally */ if (currentScope->loop_count>0) log_state(state,TMPL_LOG_ERROR, "PARAM:LOOP:next_loop(%d): callback returned null scope\n", currentScope->loop); } } if (state->param->ExitLoopScopeFuncPtr) state->param->ExitLoopScopeFuncPtr(state->param->ext_data_state, currentScope->loops_AV); popScope(&state->param->var_scope_stack); return 0; } static int init_loop (struct tmplpro_state *state, const PSTRING* const TagOptVal) { int loop_count; ABSTRACT_ARRAY* loopptr=(ABSTRACT_ARRAY*) walk_through_nested_loops(state->param,TagOptVal[TAG_OPT_NAME]); if (loopptr==NULL) { return 0; } else { /* set loop array */ loopptr = (*state->param->AbstractVal2abstractArrayFuncPtr)(state->param->ext_data_state, loopptr); if (loopptr == NULL) { log_state(state,TMPL_LOG_ERROR, "PARAM:LOOP:loop argument:loop was expected but not found.\n"); return 0; } loop_count = (*state->param->GetAbstractArrayLengthFuncPtr)(state->param->ext_data_state, loopptr); /* 0 is an empty array; <0 is an undefined array (iterated until next_loop==NULL */ if (0==loop_count) return 0; pushScopeLoop(&state->param->var_scope_stack, loop_count, loopptr); return 1; } } static void tag_handler_loop (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry iftag; iftag.tag=HTML_TEMPLATE_TAG_LOOP; iftag.vcontext=state->is_visible; iftag.value=0; iftag.position=state->cur_pos; /* loop start - to restore in */ #ifdef DEBUG log_state(state,TMPL_LOG_DEBUG2,"tag_handler_loop:before InitLoopFuncPtr\n"); #endif if (state->is_visible && init_loop(state,TagOptVal) && next_loop(state)) { iftag.value=1; /* the loop is non - empty */ } else { /* empty loop is equal to ... */ state->is_visible=0; } #ifdef DEBUG log_state(state,TMPL_LOG_DEBUG2,"tag_handler_loop:after InitLoopFuncPtr\n"); #endif tagstack_push(&(state->tag_stack), iftag); } static void tag_handler_closeloop (struct tmplpro_state *state, const PSTRING* const TagOptVal) { struct tagstack_entry* iftag_ptr; if (! test_stack(HTML_TEMPLATE_TAG_LOOP)) { tag_stack_debug(state,HTML_TEMPLATE_TAG_LOOP); return; } iftag_ptr=tagstack_top(&(state->tag_stack)); if (iftag_ptr->value==1 && next_loop(state)) { /* continue loop */ state->cur_pos=iftag_ptr->position; state->last_processed_pos=iftag_ptr->position; return; } else { /* finish loop */ struct tagstack_entry iftag; iftag=tagstack_smart_pop(state); state->is_visible=iftag.vcontext; state->last_processed_pos=state->cur_pos; } } static void tag_handler_unknown (struct tmplpro_state *state, const PSTRING* const TagOptVal) { log_state(state,TMPL_LOG_ERROR,"tag_handler_unknown: unknown tag\n"); } /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/ppport.h0000644000076400007640000007220411243310123015045 0ustar igorigor /* ppport.h -- Perl/Pollution/Portability Version 2.011 * * Automatically Created by Devel::PPPort on Thu Feb 24 17:20:58 2005 * * Do NOT edit this file directly! -- Edit PPPort.pm instead. * * Version 2.x, Copyright (C) 2001, Paul Marquess. * Version 1.x, Copyright (C) 1999, Kenneth Albanowski. * This code may be used and distributed under the same license as any * version of Perl. * * This version of ppport.h is designed to support operation with Perl * installations back to 5.004, and has been tested up to 5.8.1. * * If this version of ppport.h is failing during the compilation of this * module, please check if a newer version of Devel::PPPort is available * on CPAN before sending a bug report. * * If you are using the latest version of Devel::PPPort and it is failing * during compilation of this module, please send a report to perlbug@perl.com * * Include all following information: * * 1. The complete output from running "perl -V" * * 2. This file. * * 3. The name & version of the module you were trying to build. * * 4. A full log of the build that failed. * * 5. Any other information that you think could be relevant. * * * For the latest version of this code, please retreive the Devel::PPPort * module from CPAN. * */ /* * In order for a Perl extension module to be as portable as possible * across differing versions of Perl itself, certain steps need to be taken. * Including this header is the first major one, then using dTHR is all the * appropriate places and using a PL_ prefix to refer to global Perl * variables is the second. * */ /* If you use one of a few functions that were not present in earlier * versions of Perl, please add a define before the inclusion of ppport.h * for a static include, or use the GLOBAL request in a single module to * produce a global definition that can be referenced from the other * modules. * * Function: Static define: Extern define: * newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL * */ /* To verify whether ppport.h is needed for your module, and whether any * special defines should be used, ppport.h can be run through Perl to check * your source code. Simply say: * * perl -x ppport.h *.c *.h *.xs foo/bar*.c [etc] * * The result will be a list of patches suggesting changes that should at * least be acceptable, if not necessarily the most efficient solution, or a * fix for all possible problems. It won't catch where dTHR is needed, and * doesn't attempt to account for global macro or function definitions, * nested includes, typemaps, etc. * * In order to test for the need of dTHR, please try your module under a * recent version of Perl that has threading compiled-in. * */ /* #!/usr/bin/perl @ARGV = ("*.xs") if !@ARGV; %badmacros = %funcs = %macros = (); $replace = 0; foreach () { $funcs{$1} = 1 if /Provide:\s+(\S+)/; $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/; $replace = $1 if /Replace:\s+(\d+)/; $badmacros{$2}=$1 if $replace and /^#\s*define\s+([a-zA-Z0-9_]+).*?\s+([a-zA-Z0-9_]+)/; $badmacros{$1}=$2 if /Replace (\S+) with (\S+)/; } foreach $filename (map(glob($_),@ARGV)) { unless (open(IN, "<$filename")) { warn "Unable to read from $file: $!\n"; next; } print "Scanning $filename...\n"; $c = ""; while () { $c .= $_; } close(IN); $need_include = 0; %add_func = (); $changes = 0; $has_include = ($c =~ /#.*include.*ppport/m); foreach $func (keys %funcs) { if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) { if ($c !~ /\b$func\b/m) { print "If $func isn't needed, you don't need to request it.\n" if $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m); } else { print "Uses $func\n"; $need_include = 1; } } else { if ($c =~ /\b$func\b/m) { $add_func{$func} =1 ; print "Uses $func\n"; $need_include = 1; } } } if (not $need_include) { foreach $macro (keys %macros) { if ($c =~ /\b$macro\b/m) { print "Uses $macro\n"; $need_include = 1; } } } foreach $badmacro (keys %badmacros) { if ($c =~ /\b$badmacro\b/m) { $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm); print "Uses $badmacros{$badmacro} (instead of $badmacro)\n"; $need_include = 1; } } if (scalar(keys %add_func) or $need_include != $has_include) { if (!$has_include) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)). "#include \"ppport.h\"\n"; $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m; } elsif (keys %add_func) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)); $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m; } if (!$need_include) { print "Doesn't seem to need ppport.h.\n"; $c =~ s/^.*#.*include.*ppport.*\n//m; } $changes++; } if ($changes) { open(OUT,">/tmp/ppport.h.$$"); print OUT $c; close(OUT); open(DIFF, "diff -u $filename /tmp/ppport.h.$$|"); while () { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; } close(DIFF); unlink("/tmp/ppport.h.$$"); } else { print "Looks OK\n"; } } __DATA__ */ #ifndef _P_P_PORTABILITY_H_ #define _P_P_PORTABILITY_H_ #ifndef PERL_REVISION # ifndef __PATCHLEVEL_H_INCLUDED__ # define PERL_PATCHLEVEL_H_IMPLICIT # include # endif # if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) # include # endif # ifndef PERL_REVISION # define PERL_REVISION (5) /* Replace: 1 */ # define PERL_VERSION PATCHLEVEL # define PERL_SUBVERSION SUBVERSION /* Replace PERL_PATCHLEVEL with PERL_VERSION */ /* Replace: 0 */ # endif #endif #define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION) /* It is very unlikely that anyone will try to use this with Perl 6 (or greater), but who knows. */ #if PERL_REVISION != 5 # error ppport.h only works with Perl version 5 #endif /* PERL_REVISION != 5 */ #ifndef ERRSV # define ERRSV perl_get_sv("@",FALSE) #endif #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)) /* Replace: 1 */ # define PL_Sv Sv # define PL_compiling compiling # define PL_copline copline # define PL_curcop curcop # define PL_curstash curstash # define PL_defgv defgv # define PL_dirty dirty # define PL_dowarn dowarn # define PL_hints hints # define PL_na na # define PL_perldb perldb # define PL_rsfp_filters rsfp_filters # define PL_rsfpv rsfp # define PL_stdingv stdingv # define PL_sv_no sv_no # define PL_sv_undef sv_undef # define PL_sv_yes sv_yes /* Replace: 0 */ #endif #ifndef PERL_UNUSED_DECL # ifdef HASATTRIBUTE # if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) # define PERL_UNUSED_DECL # else # define PERL_UNUSED_DECL __attribute__((unused)) # endif # else # define PERL_UNUSED_DECL # endif #endif #ifndef dNOOP # define NOOP (void)0 # define dNOOP extern int Perl___notused PERL_UNUSED_DECL #endif #ifndef dTHR # define dTHR dNOOP #endif #ifndef dTHX # define dTHX dNOOP # define dTHXa(x) dNOOP # define dTHXoa(x) dNOOP #endif #ifndef pTHX # define pTHX void # define pTHX_ # define aTHX # define aTHX_ #endif #ifndef dAX # define dAX I32 ax = MARK - PL_stack_base + 1 #endif #ifndef dITEMS # define dITEMS I32 items = SP - MARK #endif /* IV could also be a quad (say, a long long), but Perls * capable of those should have IVSIZE already. */ #if !defined(IVSIZE) && defined(LONGSIZE) # define IVSIZE LONGSIZE #endif #ifndef IVSIZE # define IVSIZE 4 /* A bold guess, but the best we can make. */ #endif #ifndef UVSIZE # define UVSIZE IVSIZE #endif #ifndef NVTYPE # if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) # define NVTYPE long double # else # define NVTYPE double # endif typedef NVTYPE NV; #endif #ifndef INT2PTR #if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) # define PTRV UV # define INT2PTR(any,d) (any)(d) #else # if PTRSIZE == LONGSIZE # define PTRV unsigned long # else # define PTRV unsigned # endif # define INT2PTR(any,d) (any)(PTRV)(d) #endif #define NUM2PTR(any,d) (any)(PTRV)(d) #define PTR2IV(p) INT2PTR(IV,p) #define PTR2UV(p) INT2PTR(UV,p) #define PTR2NV(p) NUM2PTR(NV,p) #if PTRSIZE == LONGSIZE # define PTR2ul(p) (unsigned long)(p) #else # define PTR2ul(p) INT2PTR(unsigned long,p) #endif #endif /* !INT2PTR */ #ifndef boolSV # define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) #endif #ifndef gv_stashpvn # define gv_stashpvn(str,len,flags) gv_stashpv(str,flags) #endif #ifndef newSVpvn # define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0)) #endif #ifndef newRV_inc /* Replace: 1 */ # define newRV_inc(sv) newRV(sv) /* Replace: 0 */ #endif /* DEFSV appears first in 5.004_56 */ #ifndef DEFSV # define DEFSV GvSV(PL_defgv) #endif #ifndef SAVE_DEFSV # define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) #endif #ifndef newRV_noinc # ifdef __GNUC__ # define newRV_noinc(sv) \ ({ \ SV *nsv = (SV*)newRV(sv); \ SvREFCNT_dec(sv); \ nsv; \ }) # else # if defined(USE_THREADS) static SV * newRV_noinc (SV * sv) { SV *nsv = (SV*)newRV(sv); SvREFCNT_dec(sv); return nsv; } # else # define newRV_noinc(sv) \ (PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv) # endif # endif #endif /* Provide: newCONSTSUB */ /* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63)) #if defined(NEED_newCONSTSUB) static #else extern void newCONSTSUB(HV * stash, char * name, SV *sv); #endif #if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) void newCONSTSUB(stash,name,sv) HV *stash; char *name; SV *sv; { U32 oldhints = PL_hints; HV *old_cop_stash = PL_curcop->cop_stash; HV *old_curstash = PL_curstash; line_t oldline = PL_curcop->cop_line; PL_curcop->cop_line = PL_copline; PL_hints &= ~HINT_BLOCK_SCOPE; if (stash) PL_curstash = PL_curcop->cop_stash = stash; newSUB( #if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22)) /* before 5.003_22 */ start_subparse(), #else # if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22) /* 5.003_22 */ start_subparse(0), # else /* 5.003_23 onwards */ start_subparse(FALSE, 0), # endif #endif newSVOP(OP_CONST, 0, newSVpv(name,0)), newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) ); PL_hints = oldhints; PL_curcop->cop_stash = old_cop_stash; PL_curstash = old_curstash; PL_curcop->cop_line = oldline; } #endif #endif /* newCONSTSUB */ #ifndef START_MY_CXT /* * Boilerplate macros for initializing and accessing interpreter-local * data from C. All statics in extensions should be reworked to use * this, if you want to make the extension thread-safe. See ext/re/re.xs * for an example of the use of these macros. * * Code that uses these macros is responsible for the following: * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" * 2. Declare a typedef named my_cxt_t that is a structure that contains * all the data that needs to be interpreter-local. * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. * 4. Use the MY_CXT_INIT macro such that it is called exactly once * (typically put in the BOOT: section). * 5. Use the members of the my_cxt_t structure everywhere as * MY_CXT.member. * 6. Use the dMY_CXT macro (a declaration) in all the functions that * access MY_CXT. */ #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) /* This must appear in all extensions that define a my_cxt_t structure, * right after the definition (i.e. at file scope). The non-threads * case below uses it to declare the data as static. */ #define START_MY_CXT #if (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION < 68 )) /* Fetches the SV that keeps the per-interpreter data. */ #define dMY_CXT_SV \ SV *my_cxt_sv = perl_get_sv(MY_CXT_KEY, FALSE) #else /* >= perl5.004_68 */ #define dMY_CXT_SV \ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ sizeof(MY_CXT_KEY)-1, TRUE) #endif /* < perl5.004_68 */ /* This declaration should be used within all functions that use the * interpreter-local data. */ #define dMY_CXT \ dMY_CXT_SV; \ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) /* Creates and zeroes the per-interpreter data. * (We allocate my_cxtp in a Perl SV so that it will be released when * the interpreter goes away.) */ #define MY_CXT_INIT \ dMY_CXT_SV; \ /* newSV() allocates one more than needed */ \ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ Zero(my_cxtp, 1, my_cxt_t); \ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) /* This macro must be used to access members of the my_cxt_t structure. * e.g. MYCXT.some_data */ #define MY_CXT (*my_cxtp) /* Judicious use of these macros can reduce the number of times dMY_CXT * is used. Use is similar to pTHX, aTHX etc. */ #define pMY_CXT my_cxt_t *my_cxtp #define pMY_CXT_ pMY_CXT, #define _pMY_CXT ,pMY_CXT #define aMY_CXT my_cxtp #define aMY_CXT_ aMY_CXT, #define _aMY_CXT ,aMY_CXT #else /* single interpreter */ #define START_MY_CXT static my_cxt_t my_cxt; #define dMY_CXT_SV dNOOP #define dMY_CXT dNOOP #define MY_CXT_INIT NOOP #define MY_CXT my_cxt #define pMY_CXT void #define pMY_CXT_ #define _pMY_CXT #define aMY_CXT #define aMY_CXT_ #define _aMY_CXT #endif #endif /* START_MY_CXT */ #ifndef IVdf # if IVSIZE == LONGSIZE # define IVdf "ld" # define UVuf "lu" # define UVof "lo" # define UVxf "lx" # define UVXf "lX" # else # if IVSIZE == INTSIZE # define IVdf "d" # define UVuf "u" # define UVof "o" # define UVxf "x" # define UVXf "X" # endif # endif #endif #ifndef NVef # if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ defined(PERL_PRIfldbl) /* Not very likely, but let's try anyway. */ # define NVef PERL_PRIeldbl # define NVff PERL_PRIfldbl # define NVgf PERL_PRIgldbl # else # define NVef "e" # define NVff "f" # define NVgf "g" # endif #endif #ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */ # define AvFILLp AvFILL #endif #ifdef SvPVbyte # if PERL_REVISION == 5 && PERL_VERSION < 7 /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */ # undef SvPVbyte # define SvPVbyte(sv, lp) \ ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp)) static char * my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp) { sv_utf8_downgrade(sv,0); return SvPV(sv,*lp); } # endif #else # define SvPVbyte SvPV #endif #ifndef SvPV_nolen # define SvPV_nolen(sv) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? SvPVX(sv) : sv_2pv_nolen(sv)) static char * sv_2pv_nolen(pTHX_ register SV *sv) { STRLEN n_a; return sv_2pv(sv, &n_a); } #endif #ifndef get_cv # define get_cv(name,create) perl_get_cv(name,create) #endif #ifndef get_sv # define get_sv(name,create) perl_get_sv(name,create) #endif #ifndef get_av # define get_av(name,create) perl_get_av(name,create) #endif #ifndef get_hv # define get_hv(name,create) perl_get_hv(name,create) #endif #ifndef call_argv # define call_argv perl_call_argv #endif #ifndef call_method # define call_method perl_call_method #endif #ifndef call_pv # define call_pv perl_call_pv #endif #ifndef call_sv # define call_sv perl_call_sv #endif #ifndef eval_pv # define eval_pv perl_eval_pv #endif #ifndef eval_sv # define eval_sv perl_eval_sv #endif #ifndef PERL_SCAN_GREATER_THAN_UV_MAX # define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 #endif #ifndef PERL_SCAN_SILENT_ILLDIGIT # define PERL_SCAN_SILENT_ILLDIGIT 0x04 #endif #ifndef PERL_SCAN_ALLOW_UNDERSCORES # define PERL_SCAN_ALLOW_UNDERSCORES 0x01 #endif #ifndef PERL_SCAN_DISALLOW_PREFIX # define PERL_SCAN_DISALLOW_PREFIX 0x02 #endif #if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1)) #define I32_CAST #else #define I32_CAST (I32*) #endif #ifndef grok_hex static UV _grok_hex (char *string, STRLEN *len, I32 *flags, NV *result) { NV r = scan_hex(string, *len, I32_CAST len); if (r > UV_MAX) { *flags |= PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = r; return UV_MAX; } return (UV)r; } # define grok_hex(string, len, flags, result) \ _grok_hex((string), (len), (flags), (result)) #endif #ifndef grok_oct static UV _grok_oct (char *string, STRLEN *len, I32 *flags, NV *result) { NV r = scan_oct(string, *len, I32_CAST len); if (r > UV_MAX) { *flags |= PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = r; return UV_MAX; } return (UV)r; } # define grok_oct(string, len, flags, result) \ _grok_oct((string), (len), (flags), (result)) #endif #if !defined(grok_bin) && defined(scan_bin) static UV _grok_bin (char *string, STRLEN *len, I32 *flags, NV *result) { NV r = scan_bin(string, *len, I32_CAST len); if (r > UV_MAX) { *flags |= PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = r; return UV_MAX; } return (UV)r; } # define grok_bin(string, len, flags, result) \ _grok_bin((string), (len), (flags), (result)) #endif #ifndef IN_LOCALE # define IN_LOCALE \ (PL_curcop == &PL_compiling ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) #endif #ifndef IN_LOCALE_RUNTIME # define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) #endif #ifndef IN_LOCALE_COMPILETIME # define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) #endif #ifndef IS_NUMBER_IN_UV # define IS_NUMBER_IN_UV 0x01 # define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 # define IS_NUMBER_NOT_INT 0x04 # define IS_NUMBER_NEG 0x08 # define IS_NUMBER_INFINITY 0x10 # define IS_NUMBER_NAN 0x20 #endif #ifndef grok_numeric_radix # define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(aTHX_ sp, send) #define grok_numeric_radix Perl_grok_numeric_radix bool Perl_grok_numeric_radix(pTHX_ const char **sp, const char *send) { #ifdef USE_LOCALE_NUMERIC #if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1)) if (PL_numeric_radix_sv && IN_LOCALE) { STRLEN len; char* radix = SvPV(PL_numeric_radix_sv, len); if (*sp + len <= send && memEQ(*sp, radix, len)) { *sp += len; return TRUE; } } #else /* pre5.6.0 perls don't have PL_numeric_radix_sv so the radix * must manually be requested from locale.h */ #include struct lconv *lc = localeconv(); char *radix = lc->decimal_point; if (radix && IN_LOCALE) { STRLEN len = strlen(radix); if (*sp + len <= send && memEQ(*sp, radix, len)) { *sp += len; return TRUE; } } #endif /* PERL_VERSION */ #endif /* USE_LOCALE_NUMERIC */ /* always try "." if numeric radix didn't match because * we may have data from different locales mixed */ if (*sp < send && **sp == '.') { ++*sp; return TRUE; } return FALSE; } #endif /* grok_numeric_radix */ #ifndef grok_number #define grok_number Perl_grok_number int Perl_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep) { const char *s = pv; const char *send = pv + len; const UV max_div_10 = UV_MAX / 10; const char max_mod_10 = UV_MAX % 10; int numtype = 0; int sawinf = 0; int sawnan = 0; while (s < send && isSPACE(*s)) s++; if (s == send) { return 0; } else if (*s == '-') { s++; numtype = IS_NUMBER_NEG; } else if (*s == '+') s++; if (s == send) return 0; /* next must be digit or the radix separator or beginning of infinity */ if (isDIGIT(*s)) { /* UVs are at least 32 bits, so the first 9 decimal digits cannot overflow. */ UV value = *s - '0'; /* This construction seems to be more optimiser friendly. (without it gcc does the isDIGIT test and the *s - '0' separately) With it gcc on arm is managing 6 instructions (6 cycles) per digit. In theory the optimiser could deduce how far to unroll the loop before checking for overflow. */ if (++s < send) { int digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { /* Now got 9 digits, so need to check each time for overflow. */ digit = *s - '0'; while (digit >= 0 && digit <= 9 && (value < max_div_10 || (value == max_div_10 && digit <= max_mod_10))) { value = value * 10 + digit; if (++s < send) digit = *s - '0'; else break; } if (digit >= 0 && digit <= 9 && (s < send)) { /* value overflowed. skip the remaining digits, don't worry about setting *valuep. */ do { s++; } while (s < send && isDIGIT(*s)); numtype |= IS_NUMBER_GREATER_THAN_UV_MAX; goto skip_value; } } } } } } } } } } } } } } } } } } numtype |= IS_NUMBER_IN_UV; if (valuep) *valuep = value; skip_value: if (GROK_NUMERIC_RADIX(&s, send)) { numtype |= IS_NUMBER_NOT_INT; while (s < send && isDIGIT(*s)) /* optional digits after the radix */ s++; } } else if (GROK_NUMERIC_RADIX(&s, send)) { numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */ /* no digits before the radix means we need digits after it */ if (s < send && isDIGIT(*s)) { do { s++; } while (s < send && isDIGIT(*s)); if (valuep) { /* integer approximation is valid - it's 0. */ *valuep = 0; } } else return 0; } else if (*s == 'I' || *s == 'i') { s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; if (s == send || (*s != 'F' && *s != 'f')) return 0; s++; if (s < send && (*s == 'I' || *s == 'i')) { s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; if (s == send || (*s != 'I' && *s != 'i')) return 0; s++; if (s == send || (*s != 'T' && *s != 't')) return 0; s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0; s++; } sawinf = 1; } else if (*s == 'N' || *s == 'n') { /* XXX TODO: There are signaling NaNs and quiet NaNs. */ s++; if (s == send || (*s != 'A' && *s != 'a')) return 0; s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; sawnan = 1; } else return 0; if (sawinf) { numtype &= IS_NUMBER_NEG; /* Keep track of sign */ numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT; } else if (sawnan) { numtype &= IS_NUMBER_NEG; /* Keep track of sign */ numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT; } else if (s < send) { /* we can have an optional exponent part */ if (*s == 'e' || *s == 'E') { /* The only flag we keep is sign. Blow away any "it's UV" */ numtype &= IS_NUMBER_NEG; numtype |= IS_NUMBER_NOT_INT; s++; if (s < send && (*s == '-' || *s == '+')) s++; if (s < send && isDIGIT(*s)) { do { s++; } while (s < send && isDIGIT(*s)); } else return 0; } } while (s < send && isSPACE(*s)) s++; if (s >= send) return numtype; if (len == 10 && memEQ(pv, "0 but true", 10)) { if (valuep) *valuep = 0; return IS_NUMBER_IN_UV; } return 0; } #endif /* grok_number */ #ifndef PERL_MAGIC_sv # define PERL_MAGIC_sv '\0' #endif #ifndef PERL_MAGIC_overload # define PERL_MAGIC_overload 'A' #endif #ifndef PERL_MAGIC_overload_elem # define PERL_MAGIC_overload_elem 'a' #endif #ifndef PERL_MAGIC_overload_table # define PERL_MAGIC_overload_table 'c' #endif #ifndef PERL_MAGIC_bm # define PERL_MAGIC_bm 'B' #endif #ifndef PERL_MAGIC_regdata # define PERL_MAGIC_regdata 'D' #endif #ifndef PERL_MAGIC_regdatum # define PERL_MAGIC_regdatum 'd' #endif #ifndef PERL_MAGIC_env # define PERL_MAGIC_env 'E' #endif #ifndef PERL_MAGIC_envelem # define PERL_MAGIC_envelem 'e' #endif #ifndef PERL_MAGIC_fm # define PERL_MAGIC_fm 'f' #endif #ifndef PERL_MAGIC_regex_global # define PERL_MAGIC_regex_global 'g' #endif #ifndef PERL_MAGIC_isa # define PERL_MAGIC_isa 'I' #endif #ifndef PERL_MAGIC_isaelem # define PERL_MAGIC_isaelem 'i' #endif #ifndef PERL_MAGIC_nkeys # define PERL_MAGIC_nkeys 'k' #endif #ifndef PERL_MAGIC_dbfile # define PERL_MAGIC_dbfile 'L' #endif #ifndef PERL_MAGIC_dbline # define PERL_MAGIC_dbline 'l' #endif #ifndef PERL_MAGIC_mutex # define PERL_MAGIC_mutex 'm' #endif #ifndef PERL_MAGIC_shared # define PERL_MAGIC_shared 'N' #endif #ifndef PERL_MAGIC_shared_scalar # define PERL_MAGIC_shared_scalar 'n' #endif #ifndef PERL_MAGIC_collxfrm # define PERL_MAGIC_collxfrm 'o' #endif #ifndef PERL_MAGIC_tied # define PERL_MAGIC_tied 'P' #endif #ifndef PERL_MAGIC_tiedelem # define PERL_MAGIC_tiedelem 'p' #endif #ifndef PERL_MAGIC_tiedscalar # define PERL_MAGIC_tiedscalar 'q' #endif #ifndef PERL_MAGIC_qr # define PERL_MAGIC_qr 'r' #endif #ifndef PERL_MAGIC_sig # define PERL_MAGIC_sig 'S' #endif #ifndef PERL_MAGIC_sigelem # define PERL_MAGIC_sigelem 's' #endif #ifndef PERL_MAGIC_taint # define PERL_MAGIC_taint 't' #endif #ifndef PERL_MAGIC_uvar # define PERL_MAGIC_uvar 'U' #endif #ifndef PERL_MAGIC_uvar_elem # define PERL_MAGIC_uvar_elem 'u' #endif #ifndef PERL_MAGIC_vstring # define PERL_MAGIC_vstring 'V' #endif #ifndef PERL_MAGIC_vec # define PERL_MAGIC_vec 'v' #endif #ifndef PERL_MAGIC_utf8 # define PERL_MAGIC_utf8 'w' #endif #ifndef PERL_MAGIC_substr # define PERL_MAGIC_substr 'x' #endif #ifndef PERL_MAGIC_defelem # define PERL_MAGIC_defelem 'y' #endif #ifndef PERL_MAGIC_glob # define PERL_MAGIC_glob '*' #endif #ifndef PERL_MAGIC_arylen # define PERL_MAGIC_arylen '#' #endif #ifndef PERL_MAGIC_pos # define PERL_MAGIC_pos '.' #endif #ifndef PERL_MAGIC_backref # define PERL_MAGIC_backref '<' #endif #ifndef PERL_MAGIC_ext # define PERL_MAGIC_ext '~' #endif #endif /* _P_P_PORTABILITY_H_ */ /* End of File ppport.h */ HTML-Template-Pro-0.9510/exprpstr.h0000644000076400007640000000137311406440664015426 0ustar igorigor/* -*- c -*- * File: pstring.h * Author: Igor Vlasenko * Created: Fri Jul 1 20:11:51 2005 * * $Id$ */ #ifndef _EXPR_TYPE_PSTR_H #define _EXPR_TYPE_PSTR_H 1 #include "exprval.h" static PSTRING double_to_pstring (double, char* buf, size_t bufsize); static PSTRING int_to_pstring (EXPR_int64, char* buf, size_t bufsize); static int pstring_ge(PSTRING, PSTRING); static int pstring_le(PSTRING, PSTRING); static int pstring_ne(PSTRING, PSTRING); static int pstring_eq(PSTRING, PSTRING); static int pstring_gt(PSTRING, PSTRING); static int pstring_lt(PSTRING, PSTRING); static int re_like(struct expr_parser* exprobj, PSTRING, PSTRING); static int re_notlike(struct expr_parser* exprobj, PSTRING, PSTRING); #endif /* exprpstr.h */ HTML-Template-Pro-0.9510/proparam.c0000644000076400007640000002555711337040211015350 0ustar igorigor/* generated; do not edit */ #include "pabidecl.h" #include "pabstract.h" #include "pparam.h" #include "proparam.h" API_IMPL int APICALL tmplpro_get_option_global_vars(struct tmplpro_param* param) { return param->global_vars; } API_IMPL void APICALL tmplpro_set_option_global_vars(struct tmplpro_param* param, int val) { param->global_vars=val; } API_IMPL int APICALL tmplpro_get_option_max_includes(struct tmplpro_param* param) { return param->max_includes; } API_IMPL void APICALL tmplpro_set_option_max_includes(struct tmplpro_param* param, int val) { param->max_includes=val; } API_IMPL int APICALL tmplpro_get_option_debug(struct tmplpro_param* param) { return param->debug; } API_IMPL void APICALL tmplpro_set_option_debug(struct tmplpro_param* param, int val) { param->debug=val; } API_IMPL int APICALL tmplpro_get_option_tmpl_var_case(struct tmplpro_param* param) { return param->tmpl_var_case; } API_IMPL void APICALL tmplpro_set_option_tmpl_var_case(struct tmplpro_param* param, int val) { param->tmpl_var_case=val; } API_IMPL int APICALL tmplpro_get_option_no_includes(struct tmplpro_param* param) { return (int) param->no_includes; } API_IMPL void APICALL tmplpro_set_option_no_includes(struct tmplpro_param* param, int val) { param->no_includes=(flag)val; } API_IMPL int APICALL tmplpro_get_option_loop_context_vars(struct tmplpro_param* param) { return (int) param->loop_context_vars; } API_IMPL void APICALL tmplpro_set_option_loop_context_vars(struct tmplpro_param* param, int val) { param->loop_context_vars=(flag)val; } API_IMPL int APICALL tmplpro_get_option_strict(struct tmplpro_param* param) { return (int) param->strict; } API_IMPL void APICALL tmplpro_set_option_strict(struct tmplpro_param* param, int val) { param->strict=(flag)val; } API_IMPL int APICALL tmplpro_get_option_filters(struct tmplpro_param* param) { return (int) param->filters; } API_IMPL void APICALL tmplpro_set_option_filters(struct tmplpro_param* param, int val) { param->filters=(flag)val; } API_IMPL int APICALL tmplpro_get_option_default_escape(struct tmplpro_param* param) { return param->default_escape; } API_IMPL void APICALL tmplpro_set_option_default_escape(struct tmplpro_param* param, int val) { param->default_escape=val; } API_IMPL const char* APICALL tmplpro_get_option_filename(struct tmplpro_param* param) { return param->filename; } API_IMPL void APICALL tmplpro_set_option_filename(struct tmplpro_param* param, const char* val) { param->filename=val; if (NULL!=val) { param->scalarref.begin=NULL; param->scalarref.endnext=NULL; } } API_IMPL PSTRING APICALL tmplpro_get_option_scalarref(struct tmplpro_param* param) { return param->scalarref; } API_IMPL void APICALL tmplpro_set_option_scalarref(struct tmplpro_param* param, PSTRING val) { param->scalarref=val; if (NULL!=val.begin) param->filename=NULL; } API_IMPL int APICALL tmplpro_get_option_path_like_variable_scope(struct tmplpro_param* param) { return (int) param->path_like_variable_scope; } API_IMPL void APICALL tmplpro_set_option_path_like_variable_scope(struct tmplpro_param* param, int val) { param->path_like_variable_scope=(flag)val; } API_IMPL int APICALL tmplpro_get_option_search_path_on_include(struct tmplpro_param* param) { return (int) param->search_path_on_include; } API_IMPL void APICALL tmplpro_set_option_search_path_on_include(struct tmplpro_param* param, int val) { param->search_path_on_include=(flag)val; } API_IMPL char** APICALL tmplpro_get_option_path(struct tmplpro_param* param) { return param->path; } API_IMPL void APICALL tmplpro_set_option_path(struct tmplpro_param* param, char** val) { param->path=val; } API_IMPL char* APICALL tmplpro_get_option_template_root(struct tmplpro_param* param) { return param->template_root; } API_IMPL void APICALL tmplpro_set_option_template_root(struct tmplpro_param* param, char* val) { param->template_root=val; } API_IMPL writer_functype APICALL tmplpro_get_option_WriterFuncPtr(struct tmplpro_param* param) { return param->WriterFuncPtr; } API_IMPL void APICALL tmplpro_set_option_WriterFuncPtr(struct tmplpro_param* param, writer_functype val) { param->WriterFuncPtr=val; } API_IMPL get_ABSTRACT_VALUE_functype APICALL tmplpro_get_option_GetAbstractValFuncPtr(struct tmplpro_param* param) { return param->GetAbstractValFuncPtr; } API_IMPL void APICALL tmplpro_set_option_GetAbstractValFuncPtr(struct tmplpro_param* param, get_ABSTRACT_VALUE_functype val) { param->GetAbstractValFuncPtr=val; } API_IMPL ABSTRACT_VALUE2PSTRING_functype APICALL tmplpro_get_option_AbstractVal2pstringFuncPtr(struct tmplpro_param* param) { return param->AbstractVal2pstringFuncPtr; } API_IMPL void APICALL tmplpro_set_option_AbstractVal2pstringFuncPtr(struct tmplpro_param* param, ABSTRACT_VALUE2PSTRING_functype val) { param->AbstractVal2pstringFuncPtr=val; } API_IMPL ABSTRACT_VALUE2ABSTRACT_ARRAY_functype APICALL tmplpro_get_option_AbstractVal2abstractArrayFuncPtr(struct tmplpro_param* param) { return param->AbstractVal2abstractArrayFuncPtr; } API_IMPL void APICALL tmplpro_set_option_AbstractVal2abstractArrayFuncPtr(struct tmplpro_param* param, ABSTRACT_VALUE2ABSTRACT_ARRAY_functype val) { param->AbstractVal2abstractArrayFuncPtr=val; } API_IMPL get_ABSTRACT_ARRAY_length_functype APICALL tmplpro_get_option_GetAbstractArrayLengthFuncPtr(struct tmplpro_param* param) { return param->GetAbstractArrayLengthFuncPtr; } API_IMPL void APICALL tmplpro_set_option_GetAbstractArrayLengthFuncPtr(struct tmplpro_param* param, get_ABSTRACT_ARRAY_length_functype val) { param->GetAbstractArrayLengthFuncPtr=val; } API_IMPL get_ABSTRACT_MAP_functype APICALL tmplpro_get_option_GetAbstractMapFuncPtr(struct tmplpro_param* param) { return param->GetAbstractMapFuncPtr; } API_IMPL void APICALL tmplpro_set_option_GetAbstractMapFuncPtr(struct tmplpro_param* param, get_ABSTRACT_MAP_functype val) { param->GetAbstractMapFuncPtr=val; } API_IMPL is_ABSTRACT_VALUE_true_functype APICALL tmplpro_get_option_IsAbstractValTrueFuncPtr(struct tmplpro_param* param) { return param->IsAbstractValTrueFuncPtr; } API_IMPL void APICALL tmplpro_set_option_IsAbstractValTrueFuncPtr(struct tmplpro_param* param, is_ABSTRACT_VALUE_true_functype val) { param->IsAbstractValTrueFuncPtr=val; } API_IMPL find_file_functype APICALL tmplpro_get_option_FindFileFuncPtr(struct tmplpro_param* param) { return param->FindFileFuncPtr; } API_IMPL void APICALL tmplpro_set_option_FindFileFuncPtr(struct tmplpro_param* param, find_file_functype val) { param->FindFileFuncPtr=val; } API_IMPL load_file_functype APICALL tmplpro_get_option_LoadFileFuncPtr(struct tmplpro_param* param) { return param->LoadFileFuncPtr; } API_IMPL void APICALL tmplpro_set_option_LoadFileFuncPtr(struct tmplpro_param* param, load_file_functype val) { param->LoadFileFuncPtr=val; } API_IMPL unload_file_functype APICALL tmplpro_get_option_UnloadFileFuncPtr(struct tmplpro_param* param) { return param->UnloadFileFuncPtr; } API_IMPL void APICALL tmplpro_set_option_UnloadFileFuncPtr(struct tmplpro_param* param, unload_file_functype val) { param->UnloadFileFuncPtr=val; } API_IMPL exit_loop_scope_functype APICALL tmplpro_get_option_ExitLoopScopeFuncPtr(struct tmplpro_param* param) { return param->ExitLoopScopeFuncPtr; } API_IMPL void APICALL tmplpro_set_option_ExitLoopScopeFuncPtr(struct tmplpro_param* param, exit_loop_scope_functype val) { param->ExitLoopScopeFuncPtr=val; } API_IMPL ABSTRACT_WRITER* APICALL tmplpro_get_option_ext_writer_state(struct tmplpro_param* param) { return param->ext_writer_state; } API_IMPL void APICALL tmplpro_set_option_ext_writer_state(struct tmplpro_param* param, ABSTRACT_WRITER* val) { param->ext_writer_state=val; } API_IMPL ABSTRACT_FILTER* APICALL tmplpro_get_option_ext_filter_state(struct tmplpro_param* param) { return param->ext_filter_state; } API_IMPL void APICALL tmplpro_set_option_ext_filter_state(struct tmplpro_param* param, ABSTRACT_FILTER* val) { param->ext_filter_state=val; } API_IMPL ABSTRACT_FINDFILE* APICALL tmplpro_get_option_ext_findfile_state(struct tmplpro_param* param) { return param->ext_findfile_state; } API_IMPL void APICALL tmplpro_set_option_ext_findfile_state(struct tmplpro_param* param, ABSTRACT_FINDFILE* val) { param->ext_findfile_state=val; } API_IMPL ABSTRACT_DATASTATE* APICALL tmplpro_get_option_ext_data_state(struct tmplpro_param* param) { return param->ext_data_state; } API_IMPL void APICALL tmplpro_set_option_ext_data_state(struct tmplpro_param* param, ABSTRACT_DATASTATE* val) { param->ext_data_state=val; } API_IMPL ABSTRACT_CALLER* APICALL tmplpro_get_option_ext_calluserfunc_state(struct tmplpro_param* param) { return param->ext_calluserfunc_state; } API_IMPL void APICALL tmplpro_set_option_ext_calluserfunc_state(struct tmplpro_param* param, ABSTRACT_CALLER* val) { param->ext_calluserfunc_state=val; } API_IMPL init_expr_arglist_functype APICALL tmplpro_get_option_InitExprArglistFuncPtr(struct tmplpro_param* param) { return param->InitExprArglistFuncPtr; } API_IMPL void APICALL tmplpro_set_option_InitExprArglistFuncPtr(struct tmplpro_param* param, init_expr_arglist_functype val) { param->InitExprArglistFuncPtr=val; } API_IMPL free_expr_arglist_functype APICALL tmplpro_get_option_FreeExprArglistFuncPtr(struct tmplpro_param* param) { return param->FreeExprArglistFuncPtr; } API_IMPL void APICALL tmplpro_set_option_FreeExprArglistFuncPtr(struct tmplpro_param* param, free_expr_arglist_functype val) { param->FreeExprArglistFuncPtr=val; } API_IMPL push_expr_arglist_functype APICALL tmplpro_get_option_PushExprArglistFuncPtr(struct tmplpro_param* param) { return param->PushExprArglistFuncPtr; } API_IMPL void APICALL tmplpro_set_option_PushExprArglistFuncPtr(struct tmplpro_param* param, push_expr_arglist_functype val) { param->PushExprArglistFuncPtr=val; } API_IMPL call_expr_userfnc_functype APICALL tmplpro_get_option_CallExprUserfncFuncPtr(struct tmplpro_param* param) { return param->CallExprUserfncFuncPtr; } API_IMPL void APICALL tmplpro_set_option_CallExprUserfncFuncPtr(struct tmplpro_param* param, call_expr_userfnc_functype val) { param->CallExprUserfncFuncPtr=val; } API_IMPL is_expr_userfnc_functype APICALL tmplpro_get_option_IsExprUserfncFuncPtr(struct tmplpro_param* param) { return param->IsExprUserfncFuncPtr; } API_IMPL void APICALL tmplpro_set_option_IsExprUserfncFuncPtr(struct tmplpro_param* param, is_expr_userfnc_functype val) { param->IsExprUserfncFuncPtr=val; } API_IMPL ABSTRACT_FUNCMAP* APICALL tmplpro_get_option_expr_func_map(struct tmplpro_param* param) { return param->expr_func_map; } API_IMPL void APICALL tmplpro_set_option_expr_func_map(struct tmplpro_param* param, ABSTRACT_FUNCMAP* val) { param->expr_func_map=val; } HTML-Template-Pro-0.9510/README.ru0000644000076400007640000000151710617575362014702 0ustar igorigorÏîëíîå îïèñàíèå â README.  êà÷åñòâå âñòóïëåíèÿ -- ñëåäóþùåå ïèñüìî: > Èíòåðåñíî. >  ÷¸ì ïðèíöèïèàëüíûå îòëè÷èÿ? "mod_perl abcence" îçíà÷àåò ÷òî êýøèðîâàòü > ðåçóëüòàòû ðàçáîðà îí íå óìååò? åìó ýòî íå íóæíî :) îí íå ñîçäàåò äåðåâà ðàçáîðà, òàê ÷òî åìó êåøèðîâàòü íå÷åãî :) åñëè ñðàâíèâàòü ñ HTML::Template, òî ó ïîñëåäíåãî âûâîä ÷åðåç $obj->output() óæå ñîçäàííîãî â new() äåðåâà ïðîèñõîäèò â 1-3 ðàçà ìåäëåííåå, ÷åì âåñü öèêë ó HTML::Template::Pro. ïëþñ 'use HTML::Template::Pro' î÷åíü ëåãêèé, òàê êàê âåñü êîä íà C. Âìåñòî äåðåâà èñïîëüçóåòñÿ ñàì ôàéë, êîä ðàáîòàåò êàê êîíå÷íûé àâòîìàò. ìîæíî ñðàâíèòü, òàì åñòü benchmark.pl.t. ðàçëè÷èÿ îïèñàíû â HTML::Template::Perlinterface.pod. îñíîâíîå --- die_on_bad_params âñåãäà ðàâåí 0, òàê êàê îøèáêè ñèíòàêñèñà tmpl ôàéëîâ íàõîäÿòñÿ â ïðîöåññå âûâîäà (ïå÷àòàåòñÿ Warning). Ñ óâàæåíèåì, È. Â. HTML-Template-Pro-0.9510/t/0000755000076400007640000000000012144122665013623 5ustar igorigorHTML-Template-Pro-0.9510/t/03complex.t0000644000076400007640000001104610617575362015635 0ustar igorigoruse Test::More tests => 18-2; use HTML::Template::Pro; my $template = HTML::Template::Expr->new(path => ['t/templates'], filename => 'complex.tmpl', ); #is($template->query(name => 'unused'), 'VAR', "query(name => unused)"); #my %params = map { $_ => 1 } $template->param(); #ok(exists $params{unused}, "param(unused)"); $template->param(foo => 11, bar => 0, fname => 'president', lname => 'clinton', unused => 0); my $output = $template->output(); like($output, qr/Foo is greater than 10/i, "greater than"); ok($output !~ qr/Bar and Foo/i, "and"); like($output, qr/Bar or Foo/i, "or"); like($output, qr/Bar - Foo = -11/i, "subtraction"); like($output, qr/Math Works, Alright/i, "math"); like($output, qr/My name is President Clinton/, "string op 1"); like($output, qr/Resident Alien is phat/, "string op 2"); like($output, qr/Resident has 8 letters, which is less than 10 and greater than 5/, "string length"); $template = HTML::Template::Expr->new(path => ['t/templates'], filename => 'loop.tmpl', global_vars => 1, ); $template->param(simple => [ { foo => 10 }, { foo => 100 }, { foo => 1000 } ]); $template->param(color => 'blue'); $template->param(complex => [ { fname => 'Yasunari', lname => 'Kawabata', inner => [ { stat_name => 'style', stat_value => 100 , }, { stat_name => 'shock', stat_value => 1, }, { stat_name => 'poetry', stat_value => 100 }, { stat_name => 'machismo', stat_value => 50 }, ], }, { fname => 'Yukio', lname => 'Mishima', inner => [ { stat_name => 'style', stat_value => 50, }, { stat_name => 'shock', stat_value => 100, }, { stat_name => 'poetry', stat_value => 1 }, { stat_name => 'machismo', stat_value => 100 }, ], }, ]); $output = $template->output(); like($output, qr/Foo is less than 10.\s+Foo is greater than 10.\s+Foo is greater than 10./, "math in loops"); # test user-defined functions my $repeat = sub { $_[0] x $_[1] }; $template = HTML::Template::Expr->new(path => ['t/templates'], filename => 'func.tmpl', functions => { repeat => $repeat, }, ); $template->param(repeat_me => 'foo '); $output = $template->output(); like($output, qr/foo foo foo foo/, "user defined function"); like($output, qr/FOO FOO FOO FOO/, "user defined function with uc()"); # test numeric functions $template = HTML::Template::Expr->new(path => ['t/templates'], filename => 'numerics.tmpl', ); $template->param(float => 5.1, four => 4); $output = $template->output; like($output, qr/INT: 5/, "int()"); like($output, qr/SQRT: 2/, "sqrt()"); like($output, qr/SQRT2: 4/, "sqrt() 2"); like($output, qr/SUM: 14/, "int(4 + 10.1)"); like($output, qr/SPRINTF: 14.1000/, "sprintf('%0.4f', (10.1 + 4))"); HTML-Template-Pro-0.9510/t/pod.t0000644000076400007640000000030110617575362014575 0ustar igorigoruse strict; use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; my @poddirs = qw( lib ); all_pod_files_ok( all_pod_files( @poddirs ) ); HTML-Template-Pro-0.9510/t/htp_version.t0000644000076400007640000000041711450364016016347 0ustar igorigor#!/usr/bin/perl -w use Test::More no_plan; use HTML::Template::Pro; my $src1 =<<"END;"; END; my $template1 = HTML::Template::Pro->new(scalarref => \$src1, debug=> 0); my $out=$template1->output(); print $out; ok(length($out)>0); __END__ HTML-Template-Pro-0.9510/t/error_output.t0000644000076400007640000000055311721662255016570 0ustar igorigor#!/usr/bin/perl -w use Test::More no_plan; use HTML::Template::Pro; my $src1 =<<"END;"; name foo END; my $template1 = HTML::Template::Pro->new(scalarref => \$src1, debug=> -1); $template1->param(foo => 1); my $out=$template1->output(); #print $out; ok(1); # not crashed __END__ HTML-Template-Pro-0.9510/t/HTML/0000755000076400007640000000000012144122665014367 5ustar igorigorHTML-Template-Pro-0.9510/t/HTML/Template/0000755000076400007640000000000012144122665016142 5ustar igorigorHTML-Template-Pro-0.9510/t/HTML/Template/Pro/0000755000076400007640000000000012144122665016702 5ustar igorigorHTML-Template-Pro-0.9510/t/HTML/Template/Pro/CommonTest.pm0000644000076400007640000001052211436275457021343 0ustar igorigorpackage HTML::Template::Pro::CommonTest; use strict; use warnings; use Carp; use Test; use File::Spec; use File::Path; use HTML::Template::Pro qw/:const/; #use Data::Dumper; use JSON; require Exporter; use vars qw/@ISA @EXPORT/; @ISA=qw/Exporter/; @EXPORT =qw/test_tmpl test_tmpl_std test_tmpl_expr dryrun/; use vars qw/$DumpDir $DumpDir_no_cs/; $DumpDir='json-cs'; $DumpDir_no_cs='json'; #$Data::Dumper::Terse=1; #$Data::Dumper::Indent=1; #$Data::Dumper::Useqq=1; #$Data::Dumper::Pair = ' : '; ######################### my $DEBUG=$ENV{HTP_DEBUG}; $DEBUG||=0; sub test_tmpl { my $file=shift; my $optref=shift; my @param=@_; my $tmpl; print "\n--------------- Test: $file ---------------------\n"; chdir 'templates-Pro'; $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl',debug=>$DEBUG, @$optref); $tmpl->param(@param); &dryrun($tmpl,$file); $ENV{HTP_DUMP} && &dump_test ($file,{@$optref},{@param}); chdir '..'; } sub test_tmpl_expr { my $file=shift; my $tmpl; print "\n--------------- Test: $file ---------------------\n"; chdir 'templates-Pro'; $tmpl=HTML::Template::Pro->new(filename=>$file.'.tmpl', loop_context_vars=>1, case_sensitive=>1,tmpl_var_case=>ASK_NAME_UPPERCASE|ASK_NAME_AS_IS,debug=>$DEBUG, functions=>{'hello' => sub { return "hi, $_[0]!" }}); $tmpl->param(@_); # per-object extension $tmpl->register_function('per_object_call' => sub { return shift()."-arg"}); $tmpl->register_function('perobjectcall2' => sub { return shift()."-arg"}); &dryrun($tmpl,$file); chdir '..'; } my $case_ext = [ loop_context_vars=>1, case_sensitive=>0, ]; my $case_int = [ loop_context_vars=>1, case_sensitive=>1, tmpl_var_case=>ASK_NAME_UPPERCASE, ]; sub test_tmpl_std { my ($file,@args)=@_; &test_tmpl($file, $case_ext, @args); &test_tmpl($file, $case_int, @args); } sub dryrun { my $tmpl=shift; my $file=shift; open (OUTFILE, ">$file.raw") || die "can't open $file.raw: $!"; binmode (OUTFILE); $tmpl->output(print_to => *OUTFILE); close (OUTFILE) || die "can't close $file.raw: $!"; my $fileout = &catfile("$file.out"); my $files_equal=&catfile("$file.raw") eq $fileout; if ($files_equal) { ok($files_equal) && unlink "$file.raw"; } else { if (-x '/usr/bin/diff') { print STDERR `diff -u $file.out $file.raw`; } else { print STDERR "# >>> ---$file.raw---\nTODO: diff here\n>>> ---end $file.raw---\n"; } } my $output=$tmpl->output(); ok (defined $output and $output eq $fileout); } sub catfile { my $file=shift; open (INFILE, $file) || die "can't open $file: $!"; binmode (INFILE); local $/; my $catfile=; close (INFILE) || die "can't close $file: $!"; return $catfile; } my %filename_counter; $0=~/([\w_-]+)(?:\.t)$/; my $dump_prefix = $1 ? "$1-" : ''; sub _dump_file_name { my ($DumpDir,$file) = @_; my $plain=$file; $plain=~s![\\/:]!_!g; return File::Spec->catfile($DumpDir, $dump_prefix.$plain.'-'.sprintf("%.2d",++$filename_counter{$file}).'.json'); } sub dump_test { my ($file,$optref,$paramref) = @_; mkpath ([$DumpDir,$DumpDir_no_cs]); my $tojson = { 'file' => $file, 'options' => $optref, 'params' => $paramref, }; &__dump_json(&_dump_file_name($DumpDir,$file), $tojson); my $case_sensitive=$optref->{'case_sensitive'}; if (defined $case_sensitive) { delete $optref->{'case_sensitive'}; $optref->{'tmpl_var_case'}=ASK_NAME_UPPERCASE unless $case_sensitive; } &__dump_json(&_dump_file_name($DumpDir_no_cs,$file), $tojson); } sub __dump_json { my ($dump_file, $tojson) = @_; open FH, '>', $dump_file or die "can't open ($!) ".$dump_file; print FH to_json($tojson, {utf8 => 1, pretty => 1}); close (FH) or die "can't close ($!) ".$dump_file; } ### Local Variables: ### mode: perl ### End: 1; __END__ #head1 NAME HTML::Template::Pro::CommonTest - internal common test library #head1 DESCRIPTION internal common test library #head1 AUTHOR I. Vlasenko, Eviy@altlinux.orgE #head1 COPYRIGHT AND LICENSE Copyright (C) 2009 by I. Yu. Vlasenko. This library is free software; you can redistribute it and/or modify it under either the LGPL2+ or under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available. #cut HTML-Template-Pro-0.9510/t/05path_like_variable_scope.t0000644000076400007640000000303311250015204021135 0ustar igorigoruse strict; use warnings; use Test::More qw(no_plan); use lib qw(../blib); use HTML::Template::Pro; my $template_text=<<'END;'; END; my $template = HTML::Template->new( path_like_variable_scope => 1, scalarref => \$template_text, ); $template->param(top_level_value => "3", class => [ { teacher_name => "Adam", person => [ { name => "Jon", age => "20", }, { name => "Bob", age => "21", }, ], }, { } ]); is($template->output, <<'END;'); Adam Jon 20 3 15 Adam Bob 21 3 15 END; HTML-Template-Pro-0.9510/t/HTML-Template.t0000644000076400007640000010312111676075515016335 0ustar igorigor#!/usr/bin/perl -w use strict; use Test::More qw(no_plan); use_ok('HTML::Template::Pro'); my ($output, $template, $result); # test a simple template $template = HTML::Template->new( path => 'templates', filename => 'simple.tmpl', debug => 0 ); $template->param('ADJECTIVE', 'very'); $output = $template->output; ok($output !~ /ADJECTIVE/ and $template->param('ADJECTIVE') eq 'very'); # try something a bit larger $template = HTML::Template->new( path => 'templates', filename => 'medium.tmpl', # debug => 1, ); $template->param('ALERT', 'I am alert.'); $template->param('COMPANY_NAME', "MY NAME IS"); $template->param('COMPANY_ID', "10001"); $template->param('OFFICE_ID', "10103214"); $template->param('NAME', 'SAM I AM'); $template->param('ADDRESS', '101011 North Something Something'); $template->param('CITY', 'NEW York'); $template->param('STATE', 'NEw York'); $template->param('ZIP','10014'); $template->param('PHONE','212-929-4315'); $template->param('PHONE2',''); $template->param('SUBCATEGORIES','kfldjaldsf'); $template->param('DESCRIPTION',"dsa;kljkldasfjkldsajflkjdsfklfjdsgkfld\nalskdjklajsdlkajfdlkjsfd\n\talksjdklajsfdkljdsf\ndsa;klfjdskfj"); $template->param('WEBSITE','http://www.assforyou.com/'); $template->param('INTRANET_URL','http://www.something.com'); $template->param('REMOVE_BUTTON', ""); $template->param('COMPANY_ADMIN_AREA', "Manage Office Administrators"); $template->param('CASESTUDIES_LIST', "adsfkljdskldszfgfdfdsgdsfgfdshghdmfldkgjfhdskjfhdskjhfkhdsakgagsfjhbvdsaj hsgbf jhfg sajfjdsag ffasfj hfkjhsdkjhdsakjfhkj kjhdsfkjhdskfjhdskjfkjsda kjjsafdkjhds kjds fkj skjh fdskjhfkj kj kjhf kjh sfkjhadsfkj hadskjfhkjhs ajhdsfkj akj fkj kj kj kkjdsfhk skjhadskfj haskjh fkjsahfkjhsfk ksjfhdkjh sfkjhdskjfhakj shiou weryheuwnjcinuc 3289u4234k 5 i 43iundsinfinafiunai saiufhiudsaf afiuhahfwefna uwhf u auiu uh weiuhfiuh iau huwehiucnaiuncianweciuninc iuaciun iucniunciunweiucniuwnciwe"); $template->param('NUMBER_OF_CONTACTS', "aksfjdkldsajfkljds"); $template->param('COUNTRY_SELECTOR', "klajslkjdsafkljds"); $template->param('LOGO_LINK', "dsfpkjdsfkgljdsfkglj"); $template->param('PHOTO_LINK', "lsadfjlkfjdsgkljhfgklhasgh"); $output = $template->output; ok($output !~ /new( path => 'templates', filename => 'simple-loop.tmpl', # debug => 1, ); $template->param('ADJECTIVE_LOOP', [ { ADJECTIVE => 'really' }, { ADJECTIVE => 'very' } ] ); $output = $template->output; ok($output !~ /ADJECTIVE_LOOP/ and $output =~ /really.*very/s); # test a simple loop template $template = HTML::Template->new( path => 'templates', filename => 'simple-loop-nonames.tmpl', # debug => 1, ); $template->param('ADJECTIVE_LOOP', [ { ADJECTIVE => 'really' }, { ADJECTIVE => 'very' } ] ); $output = $template->output; ok($output !~ /ADJECTIVE_LOOP/ and $output =~ /really.*very/s); # test a long loop template - mostly here to use timing on. $template = HTML::Template->new( path => 'templates', filename => 'long_loops.tmpl', # debug => 1, ); $output = $template->output; ok(1); # test a template with TMPL_INCLUDE $template = HTML::Template->new( path => 'templates', filename => 'include.tmpl', # debug => 1, ); $output = $template->output; ok(not (!($output =~ /5/) || !($output =~ /6/))); # test a template with TMPL_INCLUDE and cacheing. $template = HTML::Template->new( path => 'templates', filename => 'include.tmpl', cache => 1, # cache_debug => 1, # debug => 1, ); $output = $template->output; ok(not (!($output =~ /5/) || !($output =~ /6/))); # stimulates a cache miss # system('touch templates/included2.tmpl'); my $template2 = HTML::Template->new( path => 'templates', filename => 'include.tmpl', cache => 1, # cache_debug => 1, # debug => 1, ); $output = $template->output; ok(not (!($output =~ /5/) || !($output =~ /6/))); # test associate my $template_one = HTML::Template->new( path => 'templates', filename => 'simple.tmpl', # debug => 1, ); $template_one->param('ADJECTIVE', 'very'); my $template_two = HTML::Template->new ( path => 'templates', filename => 'simple.tmpl', associate => $template_one, # debug => 1, ); $output = $template_two->output; ok($output !~ /ADJECTIVE/ and $output =~ /very/); # test a simple loop template my $template_l = HTML::Template->new( path => 'templates', filename => 'other-loop.tmpl', # debug => 1, ); # $template_l->param('ADJECTIVE_LOOP', [ { ADJECTIVE => 'really' }, { ADJECTIVE => 'very' } ] ); $output = $template_l->output; ok($output !~ /INSIDE/); # test a simple if template my $template_i = HTML::Template->new( path => 'templates', filename => 'if.tmpl', # debug => 1, ); # $template_l->param('ADJECTIVE_LOOP', [ { ADJECTIVE => 'really' }, { ADJECTIVE => 'very' } ] ); $output = $template_i->output; ok($output !~ /INSIDE/); # test a simple if template my $template_i2 = HTML::Template->new( path => 'templates', filename => 'if.tmpl', # stack_debug => 1, # debug => 1, ); $template_i2->param(BOOL => 1); $output = $template_i2->output; ok($output =~ /INSIDE/); # test a simple if/else template my $template_ie = HTML::Template->new( path => 'templates', filename => 'ifelse.tmpl', # debug => 1, ); $output = $template_ie->output; ok ($output =~ /INSIDE ELSE/); # test a simple if/else template my $template_ie2 = HTML::Template->new( path => 'templates', filename => 'ifelse.tmpl', # debug => 1, ); $template_ie2->param(BOOL => 1); $output = $template_ie2->output; ok($output =~ /INSIDE IF/ and $output !~ /INSIDE ELSE/); # test a bug involving two loops with the same name $template = HTML::Template->new( path => 'templates', filename => 'double_loop.tmpl', # debug => 1, ); $template->param('myloop', [ { var => 'first'}, { var => 'second' }, { var => 'third' } ] ); $output = $template->output; ok($output =~ /David/); # test escapeing $template = HTML::Template->new( path => 'templates', filename => 'escape.tmpl', # debug => 1, ); $template->param(STUFF => '<>"\''); #" $output = $template->output; ok($output !~ /[<>"']/); #" # test a simple template, using new param() call format $template = HTML::Template->new( path => 'templates', filename => 'simple.tmpl', # debug => 1, ); $template->param( { 'ADJECTIVE' => 'very' } ); $output = $template->output; ok($output !~ /ADJECTIVE/ and $output =~ /very/); SKIP: { skip "Skipping die test. Not supported in Pro\n", 1 if (!exists($ENV{TEST_DIE}) or !$ENV{TEST_DIE}); # test a recursively including template eval { $template = HTML::Template->new( path => 'templates', filename => 'recursive.tmpl', ); $output = $template->output; }; ok(defined($@) and ($@ =~ /recursive/)); } # test a template using unless $template = HTML::Template->new( path => 'templates', filename => 'unless.tmpl', # debug => 1 ); $template->param(BOOL => 1); $output = $template->output; ok($output !~ /INSIDE UNLESS/ and $output =~ /INSIDE ELSE/); # test a template using unless $template = HTML::Template->new( path => 'templates', filename => 'unless.tmpl', #debug => 1, #debug_stack => 1 ); $template->param(BOOL => 0); $output = $template->output; ok($output =~ /INSIDE UNLESS/ and $output !~ /INSIDE ELSE/); # test a template using loop_context_vars $template = HTML::Template->new( path => 'templates', filename => 'context.tmpl', loop_context_vars => 1, #debug => 1, #debug_stack => 1 ); $template->param(FRUIT => [ {KIND => 'Apples'}, {KIND => 'Oranges'}, {KIND => 'Brains'}, {KIND => 'Toes'}, {KIND => 'Kiwi'} ]); $template->param(PINGPONG => [ {}, {}, {}, {}, {}, {} ]); $output = $template->output; ok($output =~ /Apples, Oranges, Brains, Toes, and Kiwi./ and $output =~ /pingpongpingpongpingpong/); $template = HTML::Template->new( path => 'templates', filename => 'loop-if.tmpl', #debug => 1, #debug_stack => 1 ); $output = $template->output; ok($output =~ /Loop not filled in/); $template = HTML::Template->new( path => 'templates', filename => 'loop-if.tmpl', #debug => 1, #debug_stack => 1 ); $template->param(LOOP_ONE => [{VAR => "foo"}]); $output = $template->output; ok($output !~ /Loop not filled in/); # test shared memory - enable by setting the environment variable # TEST_SHARED_MEMORY to 1. SKIP: { skip "Skipping shared memory cache test. See README to enable\n", 2 if (!exists($ENV{TEST_SHARED_MEMORY}) or !$ENV{TEST_SHARED_MEMORY}); require 'IPC/SharedCache.pm'; my $template_prime = HTML::Template->new( filename => 'simple-loop.tmpl', path => ['templates/'], shared_cache => 1, ipc_key => 'TEST', #cache_debug => 1, ); my $template = HTML::Template->new( filename => 'simple-loop.tmpl', path => ['templates/'], shared_cache => 1, ipc_key => 'TEST', #cache_debug => 1, ); $template->param('ADJECTIVE_LOOP', [ { ADJECTIVE => 'really' }, { ADJECTIVE => 'very' } ] ); $output = $template->output; ok($output !~ /ADJECTIVE_LOOP/ and $output =~ /really.*very/s); my $template_prime2 = HTML::Template->new( filename => 'simple-loop.tmpl', path => ['templates/'], double_cache => 1, ipc_key => 'TEST', #cache_debug => 1, ); my $template2 = HTML::Template->new( filename => 'simple-loop.tmpl', path => ['templates/'], double_cache => 1, ipc_key => 'TEST', #cache_debug => 1, ); $template->param('ADJECTIVE_LOOP', [ { ADJECTIVE => 'really' }, { ADJECTIVE => 'very' } ] ); $output = $template->output; ok($output !~ /ADJECTIVE_LOOP/ and $output =~ /really.*very/s); IPC::SharedCache::remove('TEST'); } # test CGI associate bug eval { require 'CGI.pm'; }; SKIP: { skip "Skipping associate tests, need CGI.pm to test associate\n", 1 if ($@); my $query = CGI->new(''); $query->param('AdJecTivE' => 'very'); $template = HTML::Template->new( path => 'templates', filename => 'simple.tmpl', debug => 0, associate => $query, ); $output = $template->output; ok($output =~ /very/); } # test subroutine as VAR $template = HTML::Template->new( path => 'templates', filename => 'simple.tmpl', debug => 0, ); $template->param(ADJECTIVE => sub { return 'v' . '1e' . '2r' . '3y'; }); $output = $template->output; ok($output =~ /v1e2r3y/); # test cache - non automated, requires turning on debug watching STDERR! $template = HTML::Template->new( path => ['templates/'], filename => 'simple.tmpl', cache => 1, # cache_debug => 1, debug => 0, ); $template->param(ADJECTIVE => sub { return 'v' . '1e' . '2r' . '3y'; }); $output = $template->output; $template = HTML::Template->new( path => ['templates/'], filename => 'simple.tmpl', cache => 1, # cache_debug => 1, debug => 0, ); ok($output =~ /v1e2r3y/); # test URL escapeing $template = HTML::Template->new( path => 'templates', filename => 'urlescape.tmpl', # debug => 1, # stack_debug => 1, ); $template->param(STUFF => '<>"; %FA'); #" $output = $template->output; ok($output !~ /[<>"]/); #" SKIP: { skip "Skipping query test. Not supported in Pro\n", 2 if (!exists($ENV{TEST_QUERY}) or !$ENV{TEST_QUERY}); # test query() $template = HTML::Template->new( path => 'templates', filename => 'query-test.tmpl', ); my %params = map {$_ => 1} $template->query(loop => 'EXAMPLE_LOOP'); my @result; eval { @result = $template->query(loop => ['EXAMPLE_LOOP', 'BEE']); }; ok($@ =~ /error/ and $template->query(name => 'var') eq 'VAR' and $template->query(name => 'EXAMPLE_LOOP') eq 'LOOP' and exists $params{bee} and exists $params{bop} and exists $params{example_inner_loop} and $template->query(name => ['EXAMPLE_LOOP', 'EXAMPLE_INNER_LOOP']) eq 'LOOP' ); # test query() $template = HTML::Template->new( path => 'templates', filename => 'query-test2.tmpl', ); my %p = map {$_ => 1} $template->query(loop => ['LOOP_FOO', 'LOOP_BAR']); ok(exists $p{foo} and exists $p{bar} and exists $p{bash}); } # test global_vars $template = HTML::Template->new( path => 'templates', filename => 'globals.tmpl', global_vars => 1, ); $template->param(outer_loop => [{loop => [{'LOCAL' => 'foo'}]}]); $template->param(global => 'bar'); $template->param(hidden_global => 'foo'); $result = $template->output(); ok($result =~ /foobar/); SKIP: { skip "Skipping vanguard test. Not supported in Pro\n", 1 if (!exists($ENV{TEST_VANGUARD}) or !$ENV{TEST_VANGUARD}); $template = HTML::Template->new( path => 'templates', filename => 'vanguard1.tmpl', vanguard_compatibility_mode => 1, ); $template->param(FOO => 'bar'); $template->param(BAZ => 'bop'); $result = $template->output(); ok($result =~ /bar/ and $result =~ /bop/); } $template = HTML::Template->new( path => 'templates', filename => 'loop-context.tmpl', loop_context_vars => 1, ); $template->param(TEST_LOOP => [ { NUM => 1 } ]); $result = $template->output(); ok($result =~ /1:FIRST::LAST:ODD/); # test a TMPL_INCLUDE from a later path directory back up to an earlier one # when using the search_path_on_include option $template = HTML::Template->new( path => ['templates/searchpath/','templates/'], search_path_on_include => 1, filename => 'include.tmpl', ); $output = $template->output; ok($output =~ /9/ and $output =~ /6/); SKIP: { skip "Skipping die test. Not supported in Pro\n", 1 if (!exists($ENV{TEST_DIE}) or !$ENV{TEST_DIE}); # test no_includes eval { $template = HTML::Template->new( path => ['templates/'], filename => 'include.tmpl', no_includes => 1, ); }; ok(defined $@ and $@ =~ /no_includes/); } # test file cache - non automated, requires turning on debug watching STDERR! $template = HTML::Template->new( path => ['templates/'], filename => 'simple.tmpl', file_cache_dir => './blib/temp_cache_dir', file_cache => 1, #cache_debug => 1, #debug => 0, ); $template->param(ADJECTIVE => sub { "3y"; }); $output = $template->output; $template = HTML::Template->new( path => ['templates/'], filename => 'simple.tmpl', file_cache_dir => './blib/temp_cache_dir', file_cache => 1, #cache_debug => 1, #debug => 0, ); ok($output =~ /3y/); my $x; $template = HTML::Template->new(filename => 'templates/simple-loop.tmpl', filter => { sub => sub { $x = 1; for (@{$_[0]}) { $_ = "$x : $_"; $x++; } }, format => 'array', }, file_cache_dir => './blib/temp_cache_dir', file_cache => 1, global_vars => 1, ); $template->param('ADJECTIVE_LOOP', [ { ADJECTIVE => 'really' }, { ADJECTIVE => 'very' } ] ); $output = $template->output; ok($output =~ /very/); $template = HTML::Template->new(filename => './templates/include_path/a.tmpl'); $output = $template->output; ok($output =~ /Bar/); open(OUT, ">blib/test.out") or die $!; $template = HTML::Template->new(filename => './templates/include_path/a.tmpl'); $template->output(print_to => *OUT); close(OUT); open(OUT, "blib/test.out") or die $!; $output = join('',); close(OUT); ok($output =~ /Bar/); my $test = 39; # test with case sensitive params on my $template_source = < simple template. END_OF_TMPL $template = HTML::Template->new( scalarref => \$template_source, case_sensitive => 1, debug => 0 ); $template->param('adverb', 'very'); $template->param('ADVERB', 'painfully'); $output = $template->output; ok($output !~ /ADVERB/i and $template->param('ADVERB') eq 'painfully' and $template->param('adverb') eq 'very' and $output =~ /very painfully/); # test with case sensitive params off $template_source = < simple template. END_OF_TMPL $template = HTML::Template->new( scalarref => \$template_source, case_sensitive => 0, debug => 0 ); $template->param('adverb', 'very'); $template->param('ADVERB', 'painfully'); $output = $template->output; ok($output !~ /ADVERB/i and $template->param('ADVERB') eq 'painfully' and $template->param('adverb') eq 'painfully' and $output =~ /painfully painfully/); $template = HTML::Template->new(filename => './templates/include_path/a.tmpl', filter => sub { ${$_[0]} =~ s/Bar/Zanzabar/g; } ); $output = $template->output; ok($output =~ /Zanzabar/); $template = HTML::Template->new(filename => './templates/include_path/a.tmpl', filter => [ { sub => sub { ${$_[0]} =~ s/Bar/Zanzabar/g; }, format => 'scalar' }, { sub => sub { ${$_[0]} =~ s/bar/bar!!!/g; }, format => 'scalar' } ] ); $output = $template->output; ok($output =~ /Zanzabar!!!/); $template = HTML::Template->new(filename => './templates/include_path/a.tmpl', filter => { sub => sub { $x = 1; for (@{$_[0]}) { $_ = "$x : $_"; $x++; } }, format => 'array', } ); $output = $template->output; ok($output =~ /1 : Foo/); $template = HTML::Template->new( scalarref => \ "\n", ); $template->param(ADJECTIVE => "3y"); $output = $template->output(); ok($output =~ /3y/); $template = HTML::Template->new(path => ['templates'], filename => 'newline_test1.tmpl', filter => sub {}, ); $output = $template->output(); ok($output =~ /STARTincludeEND/); # test multiline tags $template = HTML::Template->new(path => ['templates'], filename => 'multiline_tags.tmpl', global_vars => 1, ); $template->param(FOO => 'foo!', bar => [{}, {}]); $output = $template->output(); ok($output =~ /foo!\n/ && $output =~ /foo!foo!\nfoo!foo!/); # test new() from filehandle open(TEMPLATE, "templates/simple.tmpl"); $template = HTML::Template->new(filehandle => *TEMPLATE); $template->param('ADJECTIVE', 'very'); $output = $template->output; ok($output !~ /ADJECTIVE/ and $template->param('ADJECTIVE') eq 'very'); close(TEMPLATE); # test new_() from filehandle open(TEMPLATE, "templates/simple.tmpl"); $template = HTML::Template->new_filehandle(*TEMPLATE); $template->param('ADJECTIVE', 'very'); $output = $template->output; ok($output !~ /ADJECTIVE/ and $template->param('ADJECTIVE') eq 'very'); close(TEMPLATE); # test case sensitive loop variables $template = HTML::Template->new(path => ['templates'], filename => 'case_loop.tmpl', case_sensitive => 1, ); $template->param(loop => [ { foo => 'bar', FOO => 'BAR' } ]); $output = $template->output(); ok($output =~ /bar BAR/); # test ifs with code refd $template = HTML::Template->new(path => ['templates'], filename => 'if.tmpl'); $template->param(bool => sub { 0 }); $output = $template->output(); ok($output !~ /INSIDE/ and $output =~ /unless/); # test global_vars for loops within loops $template = HTML::Template->new(path => ['templates'], filename => 'global-loops.tmpl', global_vars => 1); $template->param(global => "global val"); $template->param(outer_loop => [ { foo => 'foo val 1', inner_loop => [ { bar => 'bar val 1' }, { bar => 'bar val 2' }, ], }, { foo => 'foo val 2', inner_loop => [ { bar => 'bar val 3' }, { bar => 'bar val 4' }, ], } ]); $output = $template->output; ok($output =~ /inner loop foo: foo val 1/ and $output =~ /inner loop foo: foo val 2/); # test nested include path handling $template = HTML::Template->new(path => ['templates'], filename => 'include_path/one.tmpl'); $output = $template->output; ok($output =~ /ONE/ and $output =~ /TWO/ and $output =~ /THREE/); # test using HTML_TEMPLATE_ROOT with path { local $ENV{HTML_TEMPLATE_ROOT} = "templates"; $template = HTML::Template->new( path => ['searchpath'], filename => 'three.tmpl', ); $output = $template->output; ok($output =~ /THREE/); } # test __counter__ $template = HTML::Template->new(path => ['templates'], filename => 'counter.tmpl', loop_context_vars => 1); $template->param(foo => [ {a => 'a'}, {a => 'b'}, {a => 'c'} ]); $template->param(outer => [ {inner => [ {a => 'a'}, {a => 'b'}, {a => 'c'} ] }, {inner => [ {a => 'x'}, {a => 'y'}, {a => 'z'} ] }, ]); $output = $template->output; ok($output =~ /^1a2b3c$/m); ok($output =~ /^11a2b3c21x2y3z$/m); # test default $template = HTML::Template->new(path => ['templates'], filename => 'default.tmpl'); $template->param(cl => 'clothes'); $template->param(start => 'start'); $output = $template->output; ok($output =~ /cause it's getting hard to think, and my clothes are starting to shrink/); SKIP: { skip "Skipping die test. Not supported in Pro\n", 1 if (!exists($ENV{TEST_DIE}) or !$ENV{TEST_DIE}); # test invalid eval { my $template = HTML::Template->new(scalarref => \''); }; ok($@ =~ /No NAME given/); } # test a case where a different path should stimulate a cache miss # even though the main template is the same $template = HTML::Template->new(path => ['templates', 'templates/include_path'], filename => 'outer.tmpl', search_path_on_include => 1, cache => 1, # cache_debug => 1, ); $output = $template->output; ok($output =~ /I AM OUTER/); ok($output =~ /I AM INNER 1/); $template = HTML::Template->new(path => ['templates', 'templates/include_path2'], filename => 'outer.tmpl', search_path_on_include => 1, cache => 1, # cache_debug => 1, ); $output = $template->output; ok($output =~ /I AM OUTER/); ok($output =~ /I AM INNER 2/); # try the same thing with the file cache $template = HTML::Template->new(path => ['templates', 'templates/include_path'], filename => 'outer.tmpl', search_path_on_include => 1, file_cache_dir => './blib/temp_cache_dir', file_cache => 1, # cache_debug => 1, ); $output = $template->output; ok($output =~ /I AM OUTER/); ok($output =~ /I AM INNER 1/); $template = HTML::Template->new(path => ['templates', 'templates/include_path2'], filename => 'outer.tmpl', search_path_on_include => 1, file_cache_dir => './blib/temp_cache_dir', file_cache => 1, # cache_debug => 1, ); $output = $template->output; ok($output =~ /I AM OUTER/); ok($output =~ /I AM INNER 2/); # test javascript escaping $template = HTML::Template->new(path => ['templates'], filename => 'js.tmpl'); $template->param(msg => qq{"He said 'Hello'.\n\r"}); $output = $template->output(); is($output, q{\u0022He said \u0027Hello\u0027.\u000a\u000d\u0022}); SKIP: { skip "Skipping die test. Not supported in Pro\n", 1 if (!exists($ENV{TEST_DIE}) or !$ENV{TEST_DIE}); # test empty filename eval { $template = $template = HTML::Template->new(path => ['templates'], filename => ''); }; like($@, qr/empty filename/); # end commented for Pro } # test default escaping #ok(exists $template->{options}->{default_escape} && !defined $template->{options}->{default_escape}, "default default_escape"); $template = HTML::Template->new(path => ['templates'], filename => 'default_escape.tmpl', default_escape => 'UrL'); #is($template->{options}->{default_escape}, 'URL'); $template->param(STUFF => q{Joined with space}); $output = $template->output(); like($output, qr{^Joined%20with%20space}); $template = HTML::Template->new(path => ['templates'], filename => 'default_escape.tmpl', default_escape => 'html'); $template->param(STUFF => q{Joined&with"cruft}); $template->param(LOOP => [ { MORE_STUFF => '<&>' }, { MORE_STUFF => '>&<' } ]); $template->param(a => ''); $output = $template->output(); like($output, qr{^Joined&with"cruft}); like($output, qr{<&>>&<}); like($output, qr{because it's <b>}); eval { $template = HTML::Template->new(path => ['templates'], filename => 'default_escape.tmpl', default_escape => 'wml'); }; #like($@, qr/Invalid setting for default_escape/); HTML-Template-Pro-0.9510/t/HTML-Template-Expr.t0000644000076400007640000000435411450351040017235 0ustar igorigor # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl HTML-Template-Pro.t' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test; BEGIN { plan tests => 1+4*8+2*7 }; use HTML::Template::Pro; use lib "t"; use HTML::Template::Pro::CommonTest; ok(1); # If we made it this far, we're ok. ######################### my $DEBUG=$ENV{HTMLTEMPLATEPRODEBUG}; $DEBUG||=0; HTML::Template::Pro->register_function('registered_func'=>sub { return shift(); }); HTML::Template::Pro->register_function('hello_string'=>sub { return 'hello!'; }); HTML::Template::Pro->register_function('arglist'=>sub { return '['.join('][',@_).']'; }); HTML::Template::Pro->register_function( f1 => sub { return "F1: @_"; }); HTML::Template::Pro->register_function( f2 => sub { return "F2: @_"; }); HTML::Template::Pro->register_function( fUNDEF => sub { return undef; }); my @exprset1=(ONE=>1,TWO=>2,THREE=>3,ZERO=>0,MINUSTEN=>-10, FILE=>'test_if1.tmpl', TWENTY=>20,FOURTY=>50, EMPTYSTR=>''); my @brunoext=('FOO.BAR'=>''); my @refset1=( HASHREF0=>[], HASHREF2=>[{},{}], HASHREF1=>[ {LOOPVAR1=>'LOOP1-VAR1',LOOPVAR2=>'LOOP1-VAR2',LOOPVAR3=>'LOOP1-VAR3',LOOPVAR10=>'LOOP1-VAR10'}, {LOOPVAR1=>'LOOP2-VAR1',LOOPVAR2=>'LOOP2-VAR2',LOOPVAR3=>'LOOP2-VAR3',LOOPVAR10=>'LOOP2-VAR10'}, {LOOPVAR1=>'LOOP3-VAR1',LOOPVAR2=>'LOOP3-VAR2',LOOPVAR3=>'LOOP3-VAR3',LOOPVAR10=>'LOOP3-VAR10'}, {LOOPVAR1=>'LOOP4-VAR1',LOOPVAR2=>'LOOP4-VAR2',LOOPVAR3=>'LOOP4-VAR3',LOOPVAR10=>'LOOP4-VAR10'}, ]); test_tmpl_std('test_expr1', @exprset1); test_tmpl_std('test_expr2', @exprset1); test_tmpl_std('test_expr3', @exprset1); test_tmpl_std('test_expr4', @brunoext); test_tmpl_std('test_expr5', @exprset1); test_tmpl_std('test_expr6', @exprset1); test_tmpl_std('test_expr7', @refset1); test_tmpl_std('test_expr8', @exprset1); test_tmpl('test_expr9',[], n=>2); test_tmpl_expr('test_userfunc1', @exprset1); test_tmpl_expr('test_userfunc2', @exprset1); test_tmpl_expr('test_userfunc3', @exprset1); test_tmpl_expr('test_userfunc4', @exprset1); test_tmpl_expr('test_userfunc5', @exprset1); test_tmpl_expr('test_userfunc6', @exprset1); # ------------------------- __END__ ### Local Variables: ### mode: perl ### End: HTML-Template-Pro-0.9510/t/templates/0000755000076400007640000000000012144122665015621 5ustar igorigorHTML-Template-Pro-0.9510/t/templates/register.tmpl0000644000076400007640000000012310617575362020350 0ustar igorigorOK HTML-Template-Pro-0.9510/t/templates/loop.tmpl0000644000076400007640000000121210617575362017475 0ustar igorigorFoo is greater thanless than 10. Name: Stats: [high][low][medium] Color: HTML-Template-Pro-0.9510/t/templates/foo.tmpl0000644000076400007640000000021110617575362017305 0ustar igorigorFoo: Foo is greater than 11. Foo is less than or equal to 11. HTML-Template-Pro-0.9510/t/templates/negative.tmpl0000644000076400007640000000004710617575362020333 0ustar igorigorYes HTML-Template-Pro-0.9510/t/templates/numerics.tmpl0000644000076400007640000000032410617575362020354 0ustar igorigorINT: SQRT: SQRT2: SUM: SPRINTF: HTML-Template-Pro-0.9510/t/templates/complex.tmpl0000644000076400007640000000146410617575362020204 0ustar igorigor... Foo is greater than 10. Bar and Foo. Bar or Foo. Bar - Foo = Math Works, Alright My name is . Yo, Alien is phat. has letters, which is less than 10greater than 10 and greater than 5less than 5 HTML-Template-Pro-0.9510/t/templates/func.tmpl0000644000076400007640000000012210617575362017456 0ustar igorigor HTML-Template-Pro-0.9510/t/06loop_var.t0000644000076400007640000000270611375556737016024 0ustar igorigoruse Test::More no_plan; use HTML::Template::Pro; my $src_name =<<"END;"; name foo END; my $src_expr_1 =<<"END;"; [] name foo END; my $src_expr_2 =<<"END;"; name foo END; my $template_name = HTML::Template::Expr->new(scalarref => \$src_name); my $template_expr_1 = HTML::Template::Expr->new(scalarref => \$src_expr_1); my $template_expr_2 = HTML::Template::Expr->new(scalarref => \$src_expr_2); my $l = [ { x => 1} ]; $template_expr_1->param(foo => 1); like($template_expr_1->output(), qr/name foo/i, "expr foo with scalar"); $template_expr_1->param(foo => $l); like($template_expr_1->output(), qr/name foo/i, "expr foo with arrayref"); $template_name->param(foo => 1); like($template_name->output(), qr/name foo/i, "name foo with scalar"); $template_name->param(foo => [ { x => 1} ]); like($template_name->output(), qr/name foo/i, "name foo with arrayref"); $template_expr_1->param(foo => 1); like($template_expr_1->output(), qr/name foo/i, "expr foo with scalar"); $template_expr_1->param(foo => [ { x => 1} ]); like($template_expr_1->output(), qr/name foo/i, "expr foo with arrayref"); $template_expr_2->param(foo => 1); like($template_expr_2->output(), qr/name foo/i, "expr foo_or_bar with scalar"); $template_expr_2->param(foo => [ { x => 1} ]); like($template_expr_2->output(), qr/name foo/i, "expr foo_or_bar with arrayref"); __END__ HTML-Template-Pro-0.9510/t/02basic.t0000644000076400007640000000120410617575362015241 0ustar igorigoruse Test::More tests => 3; use HTML::Template::Pro; my $template = HTML::Template::Expr->new(path => ['t/templates'], filename => 'foo.tmpl'); $template->param(foo => 100); my $output = $template->output(); like($output, qr/greater than/i, "greater than"); $template->param(foo => 10); $output = $template->output(); like($output, qr/less than/i, "less than"); $template = HTML::Template::Expr->new(path => ['t/templates'], filename => 'negative.tmpl'); $template->param(foo => 100); $output = $template->output(); like($output, qr/Yes/, "negative numbers work"); HTML-Template-Pro-0.9510/t/02random.t0000644000076400007640000000103110617575362015436 0ustar igorigoruse Test::More tests => 200; use HTML::Template::Pro; use strict; my $text = q{YESNO}; my $template = HTML::Template->new( scalarref => \$text, ); $template->param(foo => sub { int(rand(2)) }); # make sure HTML::Template never goes both ways down an if, which it # used to do because it would re-evaluate the conditional at the else. # Need to test it many times to be sure since it can guess right. my $good = 1; for (1..200) { my $r = $template->output; ok($r eq 'YES' or $r eq 'NO'); }; HTML-Template-Pro-0.9510/t/realloc.t0000644000076400007640000000056611247206666015447 0ustar igorigor#!/usr/bin/perl -w use Test; BEGIN { $tests=30; plan tests => $tests; } use HTML::Template::Pro; use vars qw/$test/; my $mult=10; my $t = HTML::Template::Pro->new( filename => 'templates-Pro/test_malloc.tmpl' , debug=>0); for($x=25;$x<25+$tests*$mult;$x+=$mult) { my $txt='xxxxxxxxxx'x$x; $t->param('text' => $txt ); ok($t->output eq ($txt . "\n")) ; } HTML-Template-Pro-0.9510/t/01coderefs.t0000644000076400007640000000053310617575362015755 0ustar igorigoruse strict; use Test::More qw(no_plan); use HTML::Template::Pro; my ($output, $template, $result); # test escapes with code-refs $template = HTML::Template->new(path => 'templates', filename => 'escape.tmpl'); $template->param(STUFF => sub { '<>"\'' } ); $output = $template->output; ok($output !~ /[<>"']/); #" HTML-Template-Pro-0.9510/t/04register.t0000644000076400007640000000133610617575362016014 0ustar igorigoruse Test::More tests => 3; use HTML::Template::Pro; HTML::Template::Expr->register_function(directory_exists => sub { my $dir = shift; return -d $dir; }); HTML::Template::Expr->register_function(commify => sub { local $_ = shift; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; return $_; }); my $template = HTML::Template::Expr->new(path => ['t/templates'], filename => 'register.tmpl', ); my $output = $template->output; like $output, qr/^OK/, 'directory_exists()'; like $output, qr/2,000/, 'comify'; eval { HTML::Template::Expr->register_function('foo', 'bar'); }; like $@, qr/must be subroutine ref/, 'type check'; HTML-Template-Pro-0.9510/t/magic.t0000644000076400007640000000275311247225214015074 0ustar igorigor#!/usr/bin/perl -w use Test::More; use HTML::Template::Pro; eval "require Tie::Hash"; if ($@) { plan skip_all => "Tie::Hash is required for testing POD"; exit; } eval "require Tie::Array"; if ($@) { plan skip_all => "Tie::Array is required for testing POD"; exit; } else { $tests=2; plan tests => $tests; } my %plainhash; tie %plainhash, 'TestHash1'; my @plainarray; tie @plainarray, 'TestArray'; my $t = HTML::Template::Pro->new( filename => 'templates-Pro/test_loop2.tmpl' , debug=>0, case_sensitive => 1, ); $t->param('HASHREF1' => [ \%plainhash] ); ok($t->output =~/MAGIC1/); $t->param('HASHREF1' => \@plainarray ); my $out=$t->output(); ok($out =~/MAGIC1/ && $out =~/MAGIC2/); #$t->output(); package TestHash1; use vars qw/@ISA/; @ISA = 'Tie::StdHash'; require Tie::Hash; sub TIEHASH { my $none; my $storage = bless \$none, shift; $storage } sub FETCH { return 'MAGIC1'; } package TestHash2; use vars qw/@ISA/; @ISA = 'Tie::StdHash'; require Tie::Hash; sub TIEHASH { my $storage = bless {}, shift; $storage } sub FETCH { return 'MAGIC2'; } package TestArray; use vars qw/@ISA $count/; @ISA = ('Tie::StdArray'); require Tie::Array; BEGIN { $count = 0; } sub TIEARRAY { my $none; my $storage = bless \$none, shift; $storage } sub FETCHSIZE { return 2; } sub FETCH { my %myhash; if ($count++==0) { tie %myhash, 'TestHash1'; } else { tie %myhash, 'TestHash2'; } return \%myhash; } HTML-Template-Pro-0.9510/t/HTML-Template-Pro.t0000644000076400007640000000616611676075515017106 0ustar igorigor# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl HTML-Template-Pro.t' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use strict; use Test; BEGIN { my $test_tmpl_std = 4; my $test_tmpl = 2; plan tests => 1+$test_tmpl_std*21+$test_tmpl*5; } use File::Spec; use HTML::Template::Pro; use lib "t"; use HTML::Template::Pro::CommonTest; ok(1); # If we made it this far, we're ok. ######################### my @varset1=(VAR1=>'VAR1',VAR2=>'VAR2',VAR3=>'VAR3',VAR10=>'VAR10'); my @varset2=(STUFF1 => '&foo"bar\'=-;+ \<>"; %FA'."hidden:\r\012end", STUFF2=>'Some"'."' Txt'"); my @refset1=( HASHREF0=>[], HASHREF2=>[{},{}], HASHREF1=>[ {LOOPVAR1=>'LOOP1-VAR1',LOOPVAR2=>'LOOP1-VAR2',LOOPVAR3=>'LOOP1-VAR3',LOOPVAR10=>'LOOP1-VAR10'}, {LOOPVAR1=>'LOOP2-VAR1',LOOPVAR2=>'LOOP2-VAR2',LOOPVAR3=>'LOOP2-VAR3',LOOPVAR10=>'LOOP2-VAR10'}, {LOOPVAR1=>'LOOP3-VAR1',LOOPVAR2=>'LOOP3-VAR2',LOOPVAR3=>'LOOP3-VAR3',LOOPVAR10=>'LOOP3-VAR10'}, {LOOPVAR1=>'LOOP4-VAR1',LOOPVAR2=>'LOOP4-VAR2',LOOPVAR3=>'LOOP4-VAR3',LOOPVAR10=>'LOOP4-VAR10'}, ]); my @outer=({TEST=>'1'},{TEST=>'2'},{TEST=>'3'}); my @inner=({TST=>'A'},{TST=>'B'}); my @refset2=(INNER=>\@inner, OUTER=>\@outer); if ($ENV{HTP_TEST_BROKEN}) { # manual test test_tmpl_std('test_broken', @varset1, @refset1); } test_tmpl_std('test_esc1', @varset1, @varset2); test_tmpl_std('test_esc2', @varset1, @varset2); test_tmpl_std('test_esc3', @varset1, @varset2); test_tmpl_std('test_esc4', @varset1, @varset2); test_tmpl_std('test_var1', @varset1); test_tmpl_std('test_var2', @varset1); test_tmpl_std('test_var3', @varset1, @varset2); test_tmpl_std('test_if1', @varset1); test_tmpl_std('test_if2', @varset1); test_tmpl_std('test_if3', @refset1); test_tmpl_std('test_if4', @varset1); test_tmpl_std('test_if5', @varset1); test_tmpl_std('test_if7', @varset1); test_tmpl_std('test_include1', @varset1); test_tmpl('test_include2', [max_includes=>10], @varset1); test_tmpl_std('test_include3', @varset1); test_tmpl('test_include4', [path=>['include/1', 'include/2']]); test_tmpl('test_include5', [path=>['include/1', 'include/2'], search_path_on_include=>1]); test_tmpl_std('test_loop1', @varset1, @refset1); test_tmpl_std('test_loop2', @varset1, @refset1); test_tmpl_std('test_loop3', @varset1, @refset1); test_tmpl_std('test_loop4', @varset1, @refset1); test_tmpl_std('test_loop5', @varset1, @refset1); test_tmpl('test_loop6',[loop_context_vars=>1,global_vars=>1], @refset2); test_tmpl_std('include/2', 'LIST', [{TEST => 1}, {TEST=>2}]); # todo: use config.h and grep defines from here # if IMITATE==1 (-DCOMPAT_ALLOW_NAME_IN_CLOSING_TAG) #test_tmpl_std('test_if6', @varset1); my $devnull=File::Spec->devnull(); if (defined $devnull) { close (STDERR); #open(STDERR, '>>', $devnull); # is better, but seems not for perl 5.005 open (STDERR, '>/dev/null') || print STDERR "devnull: $!\n"; } test_tmpl('test_broken1',[debug=>-1], @varset1, @refset1); # not a test -- to see warnings on broken tmpl # test_tmpl_std('test_broken', @varset1, @refset1); ### Local Variables: ### mode: perl ### End: HTML-Template-Pro-0.9510/README0000644000076400007640000000750711723223675014256 0ustar igorigorHTML-Template-Pro version 0.9509 ============================== DESCRIPTION Original HTML::Template is written by Sam Tregar, sam@tregar.com with contributions of many people mentioned there. Their efforts caused HTML::Template to be mature html tempate engine which separate perl code and html design. Yet powerful, HTML::Template is slow, especially if mod_perl isn't available or in case of disk usage and memory limitations. HTML::Template::Pro is a fast lightweight C/Perl+XS reimplementation of HTML::Template (as of 2.9) and HTML::Template::Expr (as of 0.0.7). It is not intended to be a complete replacement, but to be a fast implementation of HTML::Template if you don't need quering, the extended facility of HTML::Template. Designed for heavy upload, resource limitations, abcence of mod_perl. HTML::Template::Pro has complete support of filters and HTML::Template::Expr's tag EXPR="", including user-defined functions. HTML::Template work cycle uses 2 steps. First, it loads and parse template. Then it accepts param() calls until you call output(). output() is its second phase where it produces a page from the parsed tree of template, obtained in the 1st step. HTML::Template::Pro loads, parse and outputs template on fly, when you call $tmpl->output(), in one pass. The corresponding code is written in C and glued to Perl using Perl+XS. As a result, when compared to HTML::Template in ordinary calls, it runs 10-25 times faster. Comparing to HTML::Template with all caching enabled under mod_perl, it still 1-3 times faster. At that HTML::Template caching requires considerable amount of memory (per process, shareable, or on disk) to be permanently filled with parsed trees, whereas HTML::Template::Pro doesn't consume memory for caches and use mmap() for reading templates on disk. INSTALLATION This module is tested on Linux and FreeBSD. There are success reports on MacOS X, Solaris, Windows. Windows users should look at README.win32. For Unixes it currently use POSIX mmap() system call, which may be unavaliable on some systems. In such case add argument MMAP=0 to perl Makefile.PL. To install this module type the following: perl Makefile.PL make make test make install If you have libpcre installed try perl Makefile.PL PCRE=1 other optional parameters include DEBUG (build with extra debug level) and IMITATE (imitate behavior of HTML::Template in all circumstances, even on broken templates, for a little cost of perfomance). So a fully fledged build is perl Makefile.PL PCRE=1 DEBUG=1 IMITATE=1 DEPENDENCIES This module requires these other modules and libraries: modules: File::Spec libraries: libpcre (optional) TODO Add support for die_on_bad_params => 1. Add support for quering. Improve debug message subsystem. WEBSITE You can find information about HTML::Template::Pro at: http://html-tmpl-pro.sourceforge.net and http://sourceforge.net/projects/html-tmpl-pro Original HTML::Template and other related modules are located at: http://html-template.sourceforge.net COPYRIGHT AND LICENCE Copyright (C) 2005-2009 by I. Yu. Vlasenko. Pieces of code in Pro.pm and documentation of HTML::Template are copyright (C) 2000-2009 Sam Tregar (sam@tregar.com) Other contributors to the code base are listed in Changes. The template syntax, interface conventions and a large piece of documentation of HTML::Template::Pro are based on CPAN module HTML::Template by Sam Tregar, sam@tregar.com. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available, or, at your option, under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. HTML-Template-Pro-0.9510/calc.inc0000644000076400007640000000645411353163364014770 0ustar igorigor/* -*- c -*- * File: calc.c * $Id$ */ #include #include #include #include "pmiscdef.h" #include "tmplpro.h" /* for tmplpro_version */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef HAVE_DRAND48 #define drand48() (((float) rand())/((float) RAND_MAX)) #define srand48(x) (srand((x))) #endif static const symrec_const * getsym (const symrec_const symrec_array[], PSTRING sym_name) { long int len = sym_name.endnext-sym_name.begin; const symrec_const* ptr; for (ptr=symrec_array; ptr->name!=NULL; ptr++) if (len == ptr->len && strncmp (ptr->name,sym_name.begin,len) == 0) return ptr; return 0; } #define ABS(X) (((X)<0)? (-X) : (X)) static struct exprval builtin_int (struct expr_parser* exprobj, struct exprval e) { expr_to_int1(exprobj, &e); return e; } static struct exprval builtin_abs (struct expr_parser* exprobj, struct exprval e) { expr_to_int_or_dbl1(exprobj, &e); if (e.type==EXPR_TYPE_DBL) e.val.dblval = ABS(e.val.dblval); else if (e.type==EXPR_TYPE_INT) e.val.intval = ABS(e.val.intval); return e; } static struct exprval builtin_defined (struct expr_parser* exprobj, struct exprval e) { struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT); if (e.type==EXPR_TYPE_NULL || (e.type==EXPR_TYPE_PSTR && e.val.strval.begin == NULL)) retval.val.intval = 0; else retval.val.intval = 1; return retval; } static struct exprval builtin_length (struct expr_parser* exprobj, struct exprval e) { struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT); expr_to_str1(exprobj->state, &e); retval.val.intval = (EXPR_int64) (e.val.strval.endnext - e.val.strval.begin); return retval; } static struct exprval builtin_hex (struct expr_parser* exprobj, struct exprval e) { struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT); unsigned int scan = 0; expr_to_str1(exprobj->state, &e); if (e.val.strval.begin!=NULL) sscanf(e.val.strval.begin, "%x", &scan); retval.val.intval = scan; return retval; } static struct exprval builtin_oct (struct expr_parser* exprobj, struct exprval e) { struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT); unsigned int scan = 0; expr_to_str1(exprobj->state, &e); if (e.val.strval.begin!=NULL) sscanf(e.val.strval.begin, "%o", &scan); retval.val.intval = scan; return retval; } static int _srand_called = 0; static struct exprval builtin_srand (struct expr_parser* exprobj, struct exprval e) { struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_DBL); expr_to_int1(exprobj, &e); if (e.val.intval == 0) { e.val.intval=clock(); } srand48(e.val.intval); _srand_called = 1; retval.val.dblval = 0; return retval; } static struct exprval builtin_rand (struct expr_parser* exprobj, struct exprval e) { struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_DBL); if (EXPR_TYPE_PSTR == e.type && NULL == e.val.strval.begin) { e.type = EXPR_TYPE_DBL; e.val.dblval = 1.0; } expr_to_dbl1(exprobj, &e); if (!_srand_called) srand48(clock()); retval.val.dblval = drand48() * e.val.dblval; return retval; } static struct exprval builtin_version (struct expr_parser* exprobj, struct exprval e) { struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_PSTR); retval.val.strval.begin = tmplpro_version(); retval.val.strval.endnext = retval.val.strval.begin + strlen(retval.val.strval.begin); return retval; } HTML-Template-Pro-0.9510/loadfile.h0000644000076400007640000000034110617575362015317 0ustar igorigor/* -*- c -*- * File: loadfile.h * Author: Igor Vlasenko * Created: Thu Sep 8 17:16:48 2005 * * $Id$ */ PSTRING mmap_load_file (const char* filepath); int mmap_unload_file (PSTRING memarea); HTML-Template-Pro-0.9510/optint.c0000644000076400007640000007611611300025066015042 0ustar igorigor/* Generated by re2c 0.13.5 on Sun Nov 15 18:20:06 2009 */ #line 1 "optint.re2c" #include "pabidecl.h" #include "pabstract.h" #include "pparam.h" #include "pconst.h" API_IMPL int APICALL tmplpro_get_int_option(struct tmplpro_param* param, const char *p, int* failure_ptr) { register const char* YYMARKER; param->htp_errno = 0; if (failure_ptr) *failure_ptr=0; #line 18 "" { unsigned char yych; yych = (unsigned char)*p; switch (yych) { case 'd': goto yy5; case 'f': goto yy10; case 'g': goto yy2; case 'l': goto yy8; case 'm': goto yy4; case 'n': goto yy7; case 'p': goto yy11; case 's': goto yy9; case 't': goto yy6; default: goto yy12; } yy2: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'l': goto yy144; default: goto yy3; } yy3: #line 32 "optint.re2c" {if (failure_ptr) *failure_ptr=ERR_PRO_INVALID_ARGUMENT; param->htp_errno=ERR_PRO_INVALID_ARGUMENT; return 0;} #line 44 "" yy4: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'a': goto yy132; default: goto yy3; } yy5: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'e': goto yy114; default: goto yy3; } yy6: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'm': goto yy101; default: goto yy3; } yy7: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'o': goto yy90; default: goto yy3; } yy8: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'o': goto yy73; default: goto yy3; } yy9: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'e': goto yy45; case 't': goto yy46; default: goto yy3; } yy10: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'i': goto yy38; default: goto yy3; } yy11: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'a': goto yy13; default: goto yy3; } yy12: yych = (unsigned char)*++p; goto yy3; yy13: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy15; default: goto yy14; } yy14: p = YYMARKER; goto yy3; yy15: yych = (unsigned char)*++p; switch (yych) { case 'h': goto yy16; default: goto yy14; } yy16: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy17; default: goto yy14; } yy17: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy18; default: goto yy14; } yy18: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy19; default: goto yy14; } yy19: yych = (unsigned char)*++p; switch (yych) { case 'k': goto yy20; default: goto yy14; } yy20: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy21; default: goto yy14; } yy21: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy22; default: goto yy14; } yy22: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy23; default: goto yy14; } yy23: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy24; default: goto yy14; } yy24: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy25; default: goto yy14; } yy25: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy26; default: goto yy14; } yy26: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy27; default: goto yy14; } yy27: yych = (unsigned char)*++p; switch (yych) { case 'b': goto yy28; default: goto yy14; } yy28: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy29; default: goto yy14; } yy29: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy30; default: goto yy14; } yy30: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy31; default: goto yy14; } yy31: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy32; default: goto yy14; } yy32: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy33; default: goto yy14; } yy33: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy34; default: goto yy14; } yy34: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy35; default: goto yy14; } yy35: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy36; default: goto yy14; } yy36: ++p; #line 29 "optint.re2c" {return (int) param->path_like_variable_scope;} #line 236 "" yy38: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy39; default: goto yy14; } yy39: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy40; default: goto yy14; } yy40: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy41; default: goto yy14; } yy41: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy42; default: goto yy14; } yy42: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy43; default: goto yy14; } yy43: ++p; #line 27 "optint.re2c" {return (int) param->filters;} #line 271 "" yy45: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy52; default: goto yy14; } yy46: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy47; default: goto yy14; } yy47: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy48; default: goto yy14; } yy48: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy49; default: goto yy14; } yy49: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy50; default: goto yy14; } yy50: ++p; #line 26 "optint.re2c" {return (int) param->strict;} #line 306 "" yy52: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy53; default: goto yy14; } yy53: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy54; default: goto yy14; } yy54: yych = (unsigned char)*++p; switch (yych) { case 'h': goto yy55; default: goto yy14; } yy55: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy56; default: goto yy14; } yy56: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy57; default: goto yy14; } yy57: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy58; default: goto yy14; } yy58: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy59; default: goto yy14; } yy59: yych = (unsigned char)*++p; switch (yych) { case 'h': goto yy60; default: goto yy14; } yy60: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy61; default: goto yy14; } yy61: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy62; default: goto yy14; } yy62: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy63; default: goto yy14; } yy63: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy64; default: goto yy14; } yy64: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy65; default: goto yy14; } yy65: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy66; default: goto yy14; } yy66: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy67; default: goto yy14; } yy67: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy68; default: goto yy14; } yy68: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy69; default: goto yy14; } yy69: yych = (unsigned char)*++p; switch (yych) { case 'd': goto yy70; default: goto yy14; } yy70: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy71; default: goto yy14; } yy71: ++p; #line 30 "optint.re2c" {return (int) param->search_path_on_include;} #line 425 "" yy73: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy74; default: goto yy14; } yy74: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy75; default: goto yy14; } yy75: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy76; default: goto yy14; } yy76: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy77; default: goto yy14; } yy77: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy78; default: goto yy14; } yy78: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy79; default: goto yy14; } yy79: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy80; default: goto yy14; } yy80: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy81; default: goto yy14; } yy81: yych = (unsigned char)*++p; switch (yych) { case 'x': goto yy82; default: goto yy14; } yy82: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy83; default: goto yy14; } yy83: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy84; default: goto yy14; } yy84: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy85; default: goto yy14; } yy85: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy86; default: goto yy14; } yy86: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy87; default: goto yy14; } yy87: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy88; default: goto yy14; } yy88: ++p; #line 25 "optint.re2c" {return (int) param->loop_context_vars;} #line 520 "" yy90: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy91; default: goto yy14; } yy91: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy92; default: goto yy14; } yy92: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy93; default: goto yy14; } yy93: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy94; default: goto yy14; } yy94: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy95; default: goto yy14; } yy95: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy96; default: goto yy14; } yy96: yych = (unsigned char)*++p; switch (yych) { case 'd': goto yy97; default: goto yy14; } yy97: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy98; default: goto yy14; } yy98: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy99; default: goto yy14; } yy99: ++p; #line 24 "optint.re2c" {return (int) param->no_includes;} #line 579 "" yy101: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy102; default: goto yy14; } yy102: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy103; default: goto yy14; } yy103: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy104; default: goto yy14; } yy104: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy105; default: goto yy14; } yy105: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy106; default: goto yy14; } yy106: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy107; default: goto yy14; } yy107: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy108; default: goto yy14; } yy108: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy109; default: goto yy14; } yy109: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy110; default: goto yy14; } yy110: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy111; default: goto yy14; } yy111: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy112; default: goto yy14; } yy112: ++p; #line 23 "optint.re2c" {return param->tmpl_var_case;} #line 650 "" yy114: yych = (unsigned char)*++p; switch (yych) { case 'b': goto yy115; case 'f': goto yy116; default: goto yy14; } yy115: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy129; default: goto yy14; } yy116: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy117; default: goto yy14; } yy117: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy118; default: goto yy14; } yy118: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy119; default: goto yy14; } yy119: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy120; default: goto yy14; } yy120: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy121; default: goto yy14; } yy121: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy122; default: goto yy14; } yy122: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy123; default: goto yy14; } yy123: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy124; default: goto yy14; } yy124: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy125; default: goto yy14; } yy125: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy126; default: goto yy14; } yy126: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy127; default: goto yy14; } yy127: ++p; #line 28 "optint.re2c" {return param->default_escape;} #line 734 "" yy129: yych = (unsigned char)*++p; switch (yych) { case 'g': goto yy130; default: goto yy14; } yy130: ++p; #line 22 "optint.re2c" {return param->debug;} #line 745 "" yy132: yych = (unsigned char)*++p; switch (yych) { case 'x': goto yy133; default: goto yy14; } yy133: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy134; default: goto yy14; } yy134: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy135; default: goto yy14; } yy135: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy136; default: goto yy14; } yy136: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy137; default: goto yy14; } yy137: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy138; default: goto yy14; } yy138: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy139; default: goto yy14; } yy139: yych = (unsigned char)*++p; switch (yych) { case 'd': goto yy140; default: goto yy14; } yy140: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy141; default: goto yy14; } yy141: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy142; default: goto yy14; } yy142: ++p; #line 21 "optint.re2c" {return param->max_includes;} #line 810 "" yy144: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy145; default: goto yy14; } yy145: yych = (unsigned char)*++p; switch (yych) { case 'b': goto yy146; default: goto yy14; } yy146: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy147; default: goto yy14; } yy147: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy148; default: goto yy14; } yy148: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy149; default: goto yy14; } yy149: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy150; default: goto yy14; } yy150: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy151; default: goto yy14; } yy151: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy152; default: goto yy14; } yy152: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy153; default: goto yy14; } yy153: ++p; #line 20 "optint.re2c" {return param->global_vars;} #line 869 "" } #line 33 "optint.re2c" } API_IMPL int APICALL tmplpro_set_int_option(struct tmplpro_param* param, const char *p, int val) { register const char* YYMARKER; param->htp_errno = 0; #line 883 "" { unsigned char yych; yych = (unsigned char)*p; switch (yych) { case 'd': goto yy160; case 'f': goto yy165; case 'g': goto yy157; case 'l': goto yy163; case 'm': goto yy159; case 'n': goto yy162; case 'p': goto yy166; case 's': goto yy164; case 't': goto yy161; default: goto yy167; } yy157: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'l': goto yy299; default: goto yy158; } yy158: #line 56 "optint.re2c" {param->htp_errno=ERR_PRO_INVALID_ARGUMENT; return ERR_PRO_INVALID_ARGUMENT;} #line 908 "" yy159: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'a': goto yy287; default: goto yy158; } yy160: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'e': goto yy269; default: goto yy158; } yy161: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'm': goto yy256; default: goto yy158; } yy162: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'o': goto yy245; default: goto yy158; } yy163: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'o': goto yy228; default: goto yy158; } yy164: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'e': goto yy200; case 't': goto yy201; default: goto yy158; } yy165: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'i': goto yy193; default: goto yy158; } yy166: yych = (unsigned char)*(YYMARKER = ++p); switch (yych) { case 'a': goto yy168; default: goto yy158; } yy167: yych = (unsigned char)*++p; goto yy158; yy168: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy170; default: goto yy169; } yy169: p = YYMARKER; goto yy158; yy170: yych = (unsigned char)*++p; switch (yych) { case 'h': goto yy171; default: goto yy169; } yy171: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy172; default: goto yy169; } yy172: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy173; default: goto yy169; } yy173: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy174; default: goto yy169; } yy174: yych = (unsigned char)*++p; switch (yych) { case 'k': goto yy175; default: goto yy169; } yy175: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy176; default: goto yy169; } yy176: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy177; default: goto yy169; } yy177: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy178; default: goto yy169; } yy178: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy179; default: goto yy169; } yy179: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy180; default: goto yy169; } yy180: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy181; default: goto yy169; } yy181: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy182; default: goto yy169; } yy182: yych = (unsigned char)*++p; switch (yych) { case 'b': goto yy183; default: goto yy169; } yy183: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy184; default: goto yy169; } yy184: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy185; default: goto yy169; } yy185: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy186; default: goto yy169; } yy186: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy187; default: goto yy169; } yy187: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy188; default: goto yy169; } yy188: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy189; default: goto yy169; } yy189: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy190; default: goto yy169; } yy190: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy191; default: goto yy169; } yy191: ++p; #line 53 "optint.re2c" {param->path_like_variable_scope=(flag)val; return 0;} #line 1100 "" yy193: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy194; default: goto yy169; } yy194: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy195; default: goto yy169; } yy195: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy196; default: goto yy169; } yy196: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy197; default: goto yy169; } yy197: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy198; default: goto yy169; } yy198: ++p; #line 51 "optint.re2c" {param->filters=(flag)val; return 0;} #line 1135 "" yy200: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy207; default: goto yy169; } yy201: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy202; default: goto yy169; } yy202: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy203; default: goto yy169; } yy203: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy204; default: goto yy169; } yy204: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy205; default: goto yy169; } yy205: ++p; #line 50 "optint.re2c" {param->strict=(flag)val; return 0;} #line 1170 "" yy207: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy208; default: goto yy169; } yy208: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy209; default: goto yy169; } yy209: yych = (unsigned char)*++p; switch (yych) { case 'h': goto yy210; default: goto yy169; } yy210: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy211; default: goto yy169; } yy211: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy212; default: goto yy169; } yy212: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy213; default: goto yy169; } yy213: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy214; default: goto yy169; } yy214: yych = (unsigned char)*++p; switch (yych) { case 'h': goto yy215; default: goto yy169; } yy215: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy216; default: goto yy169; } yy216: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy217; default: goto yy169; } yy217: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy218; default: goto yy169; } yy218: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy219; default: goto yy169; } yy219: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy220; default: goto yy169; } yy220: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy221; default: goto yy169; } yy221: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy222; default: goto yy169; } yy222: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy223; default: goto yy169; } yy223: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy224; default: goto yy169; } yy224: yych = (unsigned char)*++p; switch (yych) { case 'd': goto yy225; default: goto yy169; } yy225: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy226; default: goto yy169; } yy226: ++p; #line 54 "optint.re2c" {param->search_path_on_include=(flag)val; return 0;} #line 1289 "" yy228: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy229; default: goto yy169; } yy229: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy230; default: goto yy169; } yy230: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy231; default: goto yy169; } yy231: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy232; default: goto yy169; } yy232: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy233; default: goto yy169; } yy233: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy234; default: goto yy169; } yy234: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy235; default: goto yy169; } yy235: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy236; default: goto yy169; } yy236: yych = (unsigned char)*++p; switch (yych) { case 'x': goto yy237; default: goto yy169; } yy237: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy238; default: goto yy169; } yy238: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy239; default: goto yy169; } yy239: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy240; default: goto yy169; } yy240: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy241; default: goto yy169; } yy241: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy242; default: goto yy169; } yy242: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy243; default: goto yy169; } yy243: ++p; #line 49 "optint.re2c" {param->loop_context_vars=(flag)val; return 0;} #line 1384 "" yy245: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy246; default: goto yy169; } yy246: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy247; default: goto yy169; } yy247: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy248; default: goto yy169; } yy248: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy249; default: goto yy169; } yy249: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy250; default: goto yy169; } yy250: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy251; default: goto yy169; } yy251: yych = (unsigned char)*++p; switch (yych) { case 'd': goto yy252; default: goto yy169; } yy252: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy253; default: goto yy169; } yy253: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy254; default: goto yy169; } yy254: ++p; #line 48 "optint.re2c" {param->no_includes=(flag)val; return 0;} #line 1443 "" yy256: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy257; default: goto yy169; } yy257: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy258; default: goto yy169; } yy258: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy259; default: goto yy169; } yy259: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy260; default: goto yy169; } yy260: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy261; default: goto yy169; } yy261: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy262; default: goto yy169; } yy262: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy263; default: goto yy169; } yy263: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy264; default: goto yy169; } yy264: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy265; default: goto yy169; } yy265: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy266; default: goto yy169; } yy266: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy267; default: goto yy169; } yy267: ++p; #line 47 "optint.re2c" {param->tmpl_var_case=val; return 0;} #line 1514 "" yy269: yych = (unsigned char)*++p; switch (yych) { case 'b': goto yy270; case 'f': goto yy271; default: goto yy169; } yy270: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy284; default: goto yy169; } yy271: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy272; default: goto yy169; } yy272: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy273; default: goto yy169; } yy273: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy274; default: goto yy169; } yy274: yych = (unsigned char)*++p; switch (yych) { case 't': goto yy275; default: goto yy169; } yy275: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy276; default: goto yy169; } yy276: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy277; default: goto yy169; } yy277: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy278; default: goto yy169; } yy278: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy279; default: goto yy169; } yy279: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy280; default: goto yy169; } yy280: yych = (unsigned char)*++p; switch (yych) { case 'p': goto yy281; default: goto yy169; } yy281: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy282; default: goto yy169; } yy282: ++p; #line 52 "optint.re2c" {param->default_escape=val; return 0;} #line 1598 "" yy284: yych = (unsigned char)*++p; switch (yych) { case 'g': goto yy285; default: goto yy169; } yy285: ++p; #line 46 "optint.re2c" {param->debug=val; return 0;} #line 1609 "" yy287: yych = (unsigned char)*++p; switch (yych) { case 'x': goto yy288; default: goto yy169; } yy288: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy289; default: goto yy169; } yy289: yych = (unsigned char)*++p; switch (yych) { case 'i': goto yy290; default: goto yy169; } yy290: yych = (unsigned char)*++p; switch (yych) { case 'n': goto yy291; default: goto yy169; } yy291: yych = (unsigned char)*++p; switch (yych) { case 'c': goto yy292; default: goto yy169; } yy292: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy293; default: goto yy169; } yy293: yych = (unsigned char)*++p; switch (yych) { case 'u': goto yy294; default: goto yy169; } yy294: yych = (unsigned char)*++p; switch (yych) { case 'd': goto yy295; default: goto yy169; } yy295: yych = (unsigned char)*++p; switch (yych) { case 'e': goto yy296; default: goto yy169; } yy296: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy297; default: goto yy169; } yy297: ++p; #line 45 "optint.re2c" {param->max_includes=val; return 0;} #line 1674 "" yy299: yych = (unsigned char)*++p; switch (yych) { case 'o': goto yy300; default: goto yy169; } yy300: yych = (unsigned char)*++p; switch (yych) { case 'b': goto yy301; default: goto yy169; } yy301: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy302; default: goto yy169; } yy302: yych = (unsigned char)*++p; switch (yych) { case 'l': goto yy303; default: goto yy169; } yy303: yych = (unsigned char)*++p; switch (yych) { case '_': goto yy304; default: goto yy169; } yy304: yych = (unsigned char)*++p; switch (yych) { case 'v': goto yy305; default: goto yy169; } yy305: yych = (unsigned char)*++p; switch (yych) { case 'a': goto yy306; default: goto yy169; } yy306: yych = (unsigned char)*++p; switch (yych) { case 'r': goto yy307; default: goto yy169; } yy307: yych = (unsigned char)*++p; switch (yych) { case 's': goto yy308; default: goto yy169; } yy308: ++p; #line 44 "optint.re2c" {param->global_vars=val; return 0;} #line 1733 "" } #line 57 "optint.re2c" } static void _reset_int_options_set_zero_defaults(struct tmplpro_param* param) { param->global_vars=0; param->debug=0; param->tmpl_var_case=0; param->no_includes=(flag)0; param->loop_context_vars=(flag)0; param->strict=(flag)0; param->filters=(flag)0; param->default_escape=0; param->path_like_variable_scope=(flag)0; param->search_path_on_include=(flag)0; } TMPLPRO_LOCAL void _reset_int_options_set_nonzero_defaults(struct tmplpro_param* param) { param->max_includes=16; } API_IMPL void APICALL tmplpro_reset_int_options(struct tmplpro_param* param) { _reset_int_options_set_zero_defaults(param); _reset_int_options_set_nonzero_defaults(param); } /* * Local variables: * mode: c * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ HTML-Template-Pro-0.9510/.gitignore0000644000076400007640000000064711436266657015374 0ustar igorigor# git-ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ *.o *~ Makefile Pro.bs Pro.c blib pm_to_blib Makefile.old semantic.cache templates-Pro/json templates-Pro/json-cs getoptint.re2c.inc resetopt0.inc resetoptnot0.inc setoptint.re2c.inc HTML-Template-Pro-0.9510/pmiscdef.h0000644000076400007640000000316711256720631015332 0ustar igorigor#ifndef _PMISCDEF_H #define _PMISCDEF_H 1 #include /* snprintf MS VC++ support; * thanks to Viacheslav Sheveliov */ #ifdef _MSC_VER # define snprintf _snprintf #endif /* printf ptrdiff_t format modifier */ #if __STDC_VERSION__ >= 199901L # define TO_PTRDIFF_T(X) (X) # define MOD_TD "%td" #elif defined _MSC_VER # define TO_PTRDIFF_T(X) (X) # define MOD_TD "%Id" #else # define TO_PTRDIFF_T(X) ((long) (X)) # define MOD_TD "%ld" #endif #if ! defined HAVE_STRDUP && ! defined strdup # if defined HAVE__STRDUP # define strdup _strdup # else # define strdup(str) strcpy(malloc(strlen(str) + 1), str) # endif #endif #define COMPILE_TIME_ASSERT(x) \ void __cta_proto__(int __cta_foo__[(x) ? 1 : -1]) #ifdef __GNUC__ #define FORMAT_PRINTF(X,Y) __attribute__ ((__format__ (__printf__, X, Y))) #else #define FORMAT_PRINTF(X,Y) #endif #if defined(__GNUC__) && !(defined(PEDANTIC)) #define INLINE inline #else /* !__GNUC__ */ #define INLINE #endif /* __GNUC__ */ /* C89 compatible flexible array struct header { size_t len; unsigned char data[FLEXIBLE_SIZE]; }; struct header *my_header = malloc(SIZEOF_FLEXIBLE(struct header, data, n)); expands to = malloc(offsetof(struct header, data) + n * sizeof my_header->data); Setting FLEXIBLE_SIZE to SIZE_MAX almost ensures this will fail : struct header *my_header = malloc(sizeof *my_header); */ #define FLEXIBLE_SIZE SIZE_MAX /* or whatever maximum length for an array */ #define SIZEOF_FLEXIBLE(type, member, length) \ ( offsetof(type, member) + (length) * sizeof ((type *)0)->member[0] ) #endif /* pmiscdef.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/proparam.h0000644000076400007640000006362111337040211015347 0ustar igorigor /*! \file proparam.h \brief Getters and setters for libhtmltmplpro options. Public interface to get and set libhtmltmplpro options. \author Igor Vlasenko \warning This header file should never be included directly. Include instead. */ /* generated; do not edit */ #ifndef _PROPARAM_H #define _PROPARAM_H 1 struct tmplpro_param; /*! \fn int tmplpro_get_option_global_vars(struct tmplpro_param*); \brief get value of global_vars option. see HTML::Template::Pro perl module documentation for global_vars option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_global_vars(struct tmplpro_param*); /*! \fn void tmplpro_set_option_global_vars(struct tmplpro_param*,int); \brief set value of global_vars option. see HTML::Template::Pro perl module documentation for global_vars option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_global_vars(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_max_includes(struct tmplpro_param*); \brief get value of max_includes option. see HTML::Template::Pro perl module documentation for max_includes option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_max_includes(struct tmplpro_param*); /*! \fn void tmplpro_set_option_max_includes(struct tmplpro_param*,int); \brief set value of max_includes option. see HTML::Template::Pro perl module documentation for max_includes option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_max_includes(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_debug(struct tmplpro_param*); \brief get value of debug option. see HTML::Template::Pro perl module documentation for debug option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_debug(struct tmplpro_param*); /*! \fn void tmplpro_set_option_debug(struct tmplpro_param*,int); \brief set value of debug option. see HTML::Template::Pro perl module documentation for debug option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_debug(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_tmpl_var_case(struct tmplpro_param*); \brief get value of tmpl_var_case option. see HTML::Template::Pro perl module documentation for tmpl_var_case option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_tmpl_var_case(struct tmplpro_param*); /*! \fn void tmplpro_set_option_tmpl_var_case(struct tmplpro_param*,int); \brief set value of tmpl_var_case option. see HTML::Template::Pro perl module documentation for tmpl_var_case option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_tmpl_var_case(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_no_includes(struct tmplpro_param*); \brief get value of no_includes option. see HTML::Template::Pro perl module documentation for no_includes option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_no_includes(struct tmplpro_param*); /*! \fn void tmplpro_set_option_no_includes(struct tmplpro_param*,int); \brief set value of no_includes option. see HTML::Template::Pro perl module documentation for no_includes option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_no_includes(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_loop_context_vars(struct tmplpro_param*); \brief get value of loop_context_vars option. see HTML::Template::Pro perl module documentation for loop_context_vars option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_loop_context_vars(struct tmplpro_param*); /*! \fn void tmplpro_set_option_loop_context_vars(struct tmplpro_param*,int); \brief set value of loop_context_vars option. see HTML::Template::Pro perl module documentation for loop_context_vars option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_loop_context_vars(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_strict(struct tmplpro_param*); \brief get value of strict option. see HTML::Template::Pro perl module documentation for strict option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_strict(struct tmplpro_param*); /*! \fn void tmplpro_set_option_strict(struct tmplpro_param*,int); \brief set value of strict option. see HTML::Template::Pro perl module documentation for strict option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_strict(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_filters(struct tmplpro_param*); \brief get value of filters option. see HTML::Template::Pro perl module documentation for filters option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_filters(struct tmplpro_param*); /*! \fn void tmplpro_set_option_filters(struct tmplpro_param*,int); \brief set value of filters option. see HTML::Template::Pro perl module documentation for filters option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_filters(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_default_escape(struct tmplpro_param*); \brief get value of default_escape option. see HTML::Template::Pro perl module documentation for default_escape option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_default_escape(struct tmplpro_param*); /*! \fn void tmplpro_set_option_default_escape(struct tmplpro_param*,int); \brief set value of default_escape option. see HTML::Template::Pro perl module documentation for default_escape option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_default_escape(struct tmplpro_param*,int); /*! \fn const char* tmplpro_get_option_filename(struct tmplpro_param*); \brief get value of filename option. see HTML::Template::Pro perl module documentation for filename option. \param param -- pointer to an internal state. */ TMPLPRO_API const char* APICALL tmplpro_get_option_filename(struct tmplpro_param*); /*! \fn void tmplpro_set_option_filename(struct tmplpro_param*,const char*); \brief set value of filename option. see HTML::Template::Pro perl module documentation for filename option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_filename(struct tmplpro_param*,const char*); /*! \fn PSTRING tmplpro_get_option_scalarref(struct tmplpro_param*); \brief get value of scalarref option. see HTML::Template::Pro perl module documentation for scalarref option. \param param -- pointer to an internal state. */ TMPLPRO_API PSTRING APICALL tmplpro_get_option_scalarref(struct tmplpro_param*); /*! \fn void tmplpro_set_option_scalarref(struct tmplpro_param*,PSTRING); \brief set value of scalarref option. see HTML::Template::Pro perl module documentation for scalarref option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_scalarref(struct tmplpro_param*,PSTRING); /*! \fn int tmplpro_get_option_path_like_variable_scope(struct tmplpro_param*); \brief get value of path_like_variable_scope option. see HTML::Template::Pro perl module documentation for path_like_variable_scope option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_path_like_variable_scope(struct tmplpro_param*); /*! \fn void tmplpro_set_option_path_like_variable_scope(struct tmplpro_param*,int); \brief set value of path_like_variable_scope option. see HTML::Template::Pro perl module documentation for path_like_variable_scope option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_path_like_variable_scope(struct tmplpro_param*,int); /*! \fn int tmplpro_get_option_search_path_on_include(struct tmplpro_param*); \brief get value of search_path_on_include option. see HTML::Template::Pro perl module documentation for search_path_on_include option. \param param -- pointer to an internal state. */ TMPLPRO_API int APICALL tmplpro_get_option_search_path_on_include(struct tmplpro_param*); /*! \fn void tmplpro_set_option_search_path_on_include(struct tmplpro_param*,int); \brief set value of search_path_on_include option. see HTML::Template::Pro perl module documentation for search_path_on_include option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_search_path_on_include(struct tmplpro_param*,int); /*! \fn char** tmplpro_get_option_path(struct tmplpro_param*); \brief get value of path option. see HTML::Template::Pro perl module documentation for path option. \param param -- pointer to an internal state. */ TMPLPRO_API char** APICALL tmplpro_get_option_path(struct tmplpro_param*); /*! \fn void tmplpro_set_option_path(struct tmplpro_param*,char**); \brief set value of path option. see HTML::Template::Pro perl module documentation for path option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_path(struct tmplpro_param*,char**); /*! \fn char* tmplpro_get_option_template_root(struct tmplpro_param*); \brief get value of template_root option. see HTML::Template::Pro perl module documentation for template_root option. \param param -- pointer to an internal state. */ TMPLPRO_API char* APICALL tmplpro_get_option_template_root(struct tmplpro_param*); /*! \fn void tmplpro_set_option_template_root(struct tmplpro_param*,char*); \brief set value of template_root option. see HTML::Template::Pro perl module documentation for template_root option. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_template_root(struct tmplpro_param*,char*); /*! \fn writer_functype tmplpro_get_option_WriterFuncPtr(struct tmplpro_param*); \brief get address of callback of ::writer_functype \param param -- pointer to an internal state. */ TMPLPRO_API writer_functype APICALL tmplpro_get_option_WriterFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_WriterFuncPtr(struct tmplpro_param*,writer_functype); \brief set callback of ::writer_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_WriterFuncPtr(struct tmplpro_param*,writer_functype); /*! \fn get_ABSTRACT_VALUE_functype tmplpro_get_option_GetAbstractValFuncPtr(struct tmplpro_param*); \brief get address of callback of ::get_ABSTRACT_VALUE_functype \param param -- pointer to an internal state. */ TMPLPRO_API get_ABSTRACT_VALUE_functype APICALL tmplpro_get_option_GetAbstractValFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_GetAbstractValFuncPtr(struct tmplpro_param*,get_ABSTRACT_VALUE_functype); \brief set callback of ::get_ABSTRACT_VALUE_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_GetAbstractValFuncPtr(struct tmplpro_param*,get_ABSTRACT_VALUE_functype); /*! \fn ABSTRACT_VALUE2PSTRING_functype tmplpro_get_option_AbstractVal2pstringFuncPtr(struct tmplpro_param*); \brief get address of callback of ::ABSTRACT_VALUE2PSTRING_functype \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_VALUE2PSTRING_functype APICALL tmplpro_get_option_AbstractVal2pstringFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_AbstractVal2pstringFuncPtr(struct tmplpro_param*,ABSTRACT_VALUE2PSTRING_functype); \brief set callback of ::ABSTRACT_VALUE2PSTRING_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_AbstractVal2pstringFuncPtr(struct tmplpro_param*,ABSTRACT_VALUE2PSTRING_functype); /*! \fn ABSTRACT_VALUE2ABSTRACT_ARRAY_functype tmplpro_get_option_AbstractVal2abstractArrayFuncPtr(struct tmplpro_param*); \brief get address of callback of ::ABSTRACT_VALUE2ABSTRACT_ARRAY_functype \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_VALUE2ABSTRACT_ARRAY_functype APICALL tmplpro_get_option_AbstractVal2abstractArrayFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_AbstractVal2abstractArrayFuncPtr(struct tmplpro_param*,ABSTRACT_VALUE2ABSTRACT_ARRAY_functype); \brief set callback of ::ABSTRACT_VALUE2ABSTRACT_ARRAY_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_AbstractVal2abstractArrayFuncPtr(struct tmplpro_param*,ABSTRACT_VALUE2ABSTRACT_ARRAY_functype); /*! \fn get_ABSTRACT_ARRAY_length_functype tmplpro_get_option_GetAbstractArrayLengthFuncPtr(struct tmplpro_param*); \brief get address of callback of ::get_ABSTRACT_ARRAY_length_functype \param param -- pointer to an internal state. */ TMPLPRO_API get_ABSTRACT_ARRAY_length_functype APICALL tmplpro_get_option_GetAbstractArrayLengthFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_GetAbstractArrayLengthFuncPtr(struct tmplpro_param*,get_ABSTRACT_ARRAY_length_functype); \brief set callback of ::get_ABSTRACT_ARRAY_length_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_GetAbstractArrayLengthFuncPtr(struct tmplpro_param*,get_ABSTRACT_ARRAY_length_functype); /*! \fn get_ABSTRACT_MAP_functype tmplpro_get_option_GetAbstractMapFuncPtr(struct tmplpro_param*); \brief get address of callback of ::get_ABSTRACT_MAP_functype \param param -- pointer to an internal state. */ TMPLPRO_API get_ABSTRACT_MAP_functype APICALL tmplpro_get_option_GetAbstractMapFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_GetAbstractMapFuncPtr(struct tmplpro_param*,get_ABSTRACT_MAP_functype); \brief set callback of ::get_ABSTRACT_MAP_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_GetAbstractMapFuncPtr(struct tmplpro_param*,get_ABSTRACT_MAP_functype); /*! \fn is_ABSTRACT_VALUE_true_functype tmplpro_get_option_IsAbstractValTrueFuncPtr(struct tmplpro_param*); \brief get address of callback of ::is_ABSTRACT_VALUE_true_functype \param param -- pointer to an internal state. */ TMPLPRO_API is_ABSTRACT_VALUE_true_functype APICALL tmplpro_get_option_IsAbstractValTrueFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_IsAbstractValTrueFuncPtr(struct tmplpro_param*,is_ABSTRACT_VALUE_true_functype); \brief set callback of ::is_ABSTRACT_VALUE_true_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_IsAbstractValTrueFuncPtr(struct tmplpro_param*,is_ABSTRACT_VALUE_true_functype); /*! \fn find_file_functype tmplpro_get_option_FindFileFuncPtr(struct tmplpro_param*); \brief get address of callback of ::find_file_functype \param param -- pointer to an internal state. */ TMPLPRO_API find_file_functype APICALL tmplpro_get_option_FindFileFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_FindFileFuncPtr(struct tmplpro_param*,find_file_functype); \brief set callback of ::find_file_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_FindFileFuncPtr(struct tmplpro_param*,find_file_functype); /*! \fn load_file_functype tmplpro_get_option_LoadFileFuncPtr(struct tmplpro_param*); \brief get address of callback of ::load_file_functype \param param -- pointer to an internal state. */ TMPLPRO_API load_file_functype APICALL tmplpro_get_option_LoadFileFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_LoadFileFuncPtr(struct tmplpro_param*,load_file_functype); \brief set callback of ::load_file_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_LoadFileFuncPtr(struct tmplpro_param*,load_file_functype); /*! \fn unload_file_functype tmplpro_get_option_UnloadFileFuncPtr(struct tmplpro_param*); \brief get address of callback of ::unload_file_functype \param param -- pointer to an internal state. */ TMPLPRO_API unload_file_functype APICALL tmplpro_get_option_UnloadFileFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_UnloadFileFuncPtr(struct tmplpro_param*,unload_file_functype); \brief set callback of ::unload_file_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_UnloadFileFuncPtr(struct tmplpro_param*,unload_file_functype); /*! \fn exit_loop_scope_functype tmplpro_get_option_ExitLoopScopeFuncPtr(struct tmplpro_param*); \brief get address of callback of ::exit_loop_scope_functype \param param -- pointer to an internal state. */ TMPLPRO_API exit_loop_scope_functype APICALL tmplpro_get_option_ExitLoopScopeFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_ExitLoopScopeFuncPtr(struct tmplpro_param*,exit_loop_scope_functype); \brief set callback of ::exit_loop_scope_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_ExitLoopScopeFuncPtr(struct tmplpro_param*,exit_loop_scope_functype); /*! \fn ABSTRACT_WRITER* tmplpro_get_option_ext_writer_state(struct tmplpro_param*); \brief get value of an external pointer that will be passed to a callback. see ::ABSTRACT_WRITER. \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_WRITER* APICALL tmplpro_get_option_ext_writer_state(struct tmplpro_param*); /*! \fn void tmplpro_set_option_ext_writer_state(struct tmplpro_param*,ABSTRACT_WRITER*); \brief set external pointer that will be passed to a callback. see ::ABSTRACT_WRITER. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_ext_writer_state(struct tmplpro_param*,ABSTRACT_WRITER*); /*! \fn ABSTRACT_FILTER* tmplpro_get_option_ext_filter_state(struct tmplpro_param*); \brief get value of an external pointer that will be passed to a callback. see ::ABSTRACT_FILTER. \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_FILTER* APICALL tmplpro_get_option_ext_filter_state(struct tmplpro_param*); /*! \fn void tmplpro_set_option_ext_filter_state(struct tmplpro_param*,ABSTRACT_FILTER*); \brief set external pointer that will be passed to a callback. see ::ABSTRACT_FILTER. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_ext_filter_state(struct tmplpro_param*,ABSTRACT_FILTER*); /*! \fn ABSTRACT_FINDFILE* tmplpro_get_option_ext_findfile_state(struct tmplpro_param*); \brief get value of an external pointer that will be passed to a callback. see ::ABSTRACT_FINDFILE. \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_FINDFILE* APICALL tmplpro_get_option_ext_findfile_state(struct tmplpro_param*); /*! \fn void tmplpro_set_option_ext_findfile_state(struct tmplpro_param*,ABSTRACT_FINDFILE*); \brief set external pointer that will be passed to a callback. see ::ABSTRACT_FINDFILE. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_ext_findfile_state(struct tmplpro_param*,ABSTRACT_FINDFILE*); /*! \fn ABSTRACT_DATASTATE* tmplpro_get_option_ext_data_state(struct tmplpro_param*); \brief get value of an external pointer that will be passed to a callback. see ::ABSTRACT_DATASTATE. \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_DATASTATE* APICALL tmplpro_get_option_ext_data_state(struct tmplpro_param*); /*! \fn void tmplpro_set_option_ext_data_state(struct tmplpro_param*,ABSTRACT_DATASTATE*); \brief set external pointer that will be passed to a callback. see ::ABSTRACT_DATASTATE. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_ext_data_state(struct tmplpro_param*,ABSTRACT_DATASTATE*); /*! \fn ABSTRACT_CALLER* tmplpro_get_option_ext_calluserfunc_state(struct tmplpro_param*); \brief get value of an external pointer that will be passed to a callback. see ::ABSTRACT_CALLER. \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_CALLER* APICALL tmplpro_get_option_ext_calluserfunc_state(struct tmplpro_param*); /*! \fn void tmplpro_set_option_ext_calluserfunc_state(struct tmplpro_param*,ABSTRACT_CALLER*); \brief set external pointer that will be passed to a callback. see ::ABSTRACT_CALLER. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_ext_calluserfunc_state(struct tmplpro_param*,ABSTRACT_CALLER*); /*! \fn init_expr_arglist_functype tmplpro_get_option_InitExprArglistFuncPtr(struct tmplpro_param*); \brief get address of callback of ::init_expr_arglist_functype \param param -- pointer to an internal state. */ TMPLPRO_API init_expr_arglist_functype APICALL tmplpro_get_option_InitExprArglistFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_InitExprArglistFuncPtr(struct tmplpro_param*,init_expr_arglist_functype); \brief set callback of ::init_expr_arglist_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_InitExprArglistFuncPtr(struct tmplpro_param*,init_expr_arglist_functype); /*! \fn free_expr_arglist_functype tmplpro_get_option_FreeExprArglistFuncPtr(struct tmplpro_param*); \brief get address of callback of ::free_expr_arglist_functype \param param -- pointer to an internal state. */ TMPLPRO_API free_expr_arglist_functype APICALL tmplpro_get_option_FreeExprArglistFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_FreeExprArglistFuncPtr(struct tmplpro_param*,free_expr_arglist_functype); \brief set callback of ::free_expr_arglist_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_FreeExprArglistFuncPtr(struct tmplpro_param*,free_expr_arglist_functype); /*! \fn push_expr_arglist_functype tmplpro_get_option_PushExprArglistFuncPtr(struct tmplpro_param*); \brief get address of callback of ::push_expr_arglist_functype \param param -- pointer to an internal state. */ TMPLPRO_API push_expr_arglist_functype APICALL tmplpro_get_option_PushExprArglistFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_PushExprArglistFuncPtr(struct tmplpro_param*,push_expr_arglist_functype); \brief set callback of ::push_expr_arglist_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_PushExprArglistFuncPtr(struct tmplpro_param*,push_expr_arglist_functype); /*! \fn call_expr_userfnc_functype tmplpro_get_option_CallExprUserfncFuncPtr(struct tmplpro_param*); \brief get address of callback of ::call_expr_userfnc_functype \param param -- pointer to an internal state. */ TMPLPRO_API call_expr_userfnc_functype APICALL tmplpro_get_option_CallExprUserfncFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_CallExprUserfncFuncPtr(struct tmplpro_param*,call_expr_userfnc_functype); \brief set callback of ::call_expr_userfnc_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_CallExprUserfncFuncPtr(struct tmplpro_param*,call_expr_userfnc_functype); /*! \fn is_expr_userfnc_functype tmplpro_get_option_IsExprUserfncFuncPtr(struct tmplpro_param*); \brief get address of callback of ::is_expr_userfnc_functype \param param -- pointer to an internal state. */ TMPLPRO_API is_expr_userfnc_functype APICALL tmplpro_get_option_IsExprUserfncFuncPtr(struct tmplpro_param*); /*! \fn void tmplpro_set_option_IsExprUserfncFuncPtr(struct tmplpro_param*,is_expr_userfnc_functype); \brief set callback of ::is_expr_userfnc_functype \param param -- pointer to an internal state. \param val -- callback address to set. */ TMPLPRO_API void APICALL tmplpro_set_option_IsExprUserfncFuncPtr(struct tmplpro_param*,is_expr_userfnc_functype); /*! \fn ABSTRACT_FUNCMAP* tmplpro_get_option_expr_func_map(struct tmplpro_param*); \brief get value of an external pointer that will be passed to a callback. see ::ABSTRACT_FUNCMAP. \param param -- pointer to an internal state. */ TMPLPRO_API ABSTRACT_FUNCMAP* APICALL tmplpro_get_option_expr_func_map(struct tmplpro_param*); /*! \fn void tmplpro_set_option_expr_func_map(struct tmplpro_param*,ABSTRACT_FUNCMAP*); \brief set external pointer that will be passed to a callback. see ::ABSTRACT_FUNCMAP. \param param -- pointer to an internal state. \param val -- value to set. */ TMPLPRO_API void APICALL tmplpro_set_option_expr_func_map(struct tmplpro_param*,ABSTRACT_FUNCMAP*); #endif /* proparam.h */ HTML-Template-Pro-0.9510/tagstack.h0000644000076400007640000000143211721657401015333 0ustar igorigor#ifndef _TAGSTACK_H #define _TAGSTACK_H 1 struct tagstack_entry { int tag; /* code of tag */ int value; /* if (true/false) - used in else */ int vcontext; /* visibility context of the tag (visible/unvisible) */ const char* position; /* start of tag; useful for loops */ }; static void tagstack_init(struct tagstack* tagstack); static void tagstack_free(struct tagstack* tagstack); static void tagstack_push(struct tagstack* tagstack, struct tagstack_entry); static struct tagstack_entry tagstack_pop(struct tagstack* tagstack, int* is_underflow); INLINE static struct tagstack_entry* tagstack_top(const struct tagstack* tagstack); INLINE static int tagstack_notempty(const struct tagstack* tagstack); #endif /* tagstack.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/pparam2proparam0000755000076400007640000001746411302256747016432 0ustar igorigor#!/usr/bin/perl -w use strict; use warnings; my %proparam_c_set_hook = ( filename => " if (NULL!=val) { param->scalarref.begin=NULL; param->scalarref.endnext=NULL; }\n", scalarref => " if (NULL!=val.begin) param->filename=NULL;\n", ); open (PP,'pparam.h'); open (PARAMH,'>','proparam.h'); open (PARAMC,'>','proparam.c'); #open (PGETINT,'>','getoptint.re2c'); #open (PSETINT,'>','setoptint.re2c'); open (PGETINT2,'>','getoptint.re2c.inc'); open (PSETINT2,'>','setoptint.re2c.inc'); open (PPRESET0,'>','resetopt0.inc'); open (PPRESET1,'>','resetoptnot0.inc'); open (PARAMM1,'>','mono-wrapper/src/htp-c-opts.cs.inc'); open (PARAMM2,'>','mono-wrapper/src/htp-intset.cs.inc'); open (PARAMM3,'>','mono-wrapper/src/htp-intget.cs.inc'); open (PARAMM4,'>','mono-wrapper/src/htp-intprop.cs.inc'); open (PARAMDLLSYM,'>','htmltmplpro/src/libhtmltmplpro.sym'); open (PARAMDLLDEF,'>','htmltmplpro/src/libhtmltmplpro.def'); print PARAMDLLDEF "LIBRARY htmltmplpro\r\nEXPORTS\r\n"; { open my $fh, "<", 'htmltmplpro/src/libhtmltmplpro.sym.header' or die $!; # local $/; # enable localized slurp mode # my $content = <$fh>; # print PARAMDLLDEF $content; # close $fh; while (my $sym = <$fh>) { chomp $sym; print PARAMDLLDEF " $sym\r\n"; print PARAMDLLSYM "$sym\n"; } } print PARAMH ' /*! \file proparam.h \brief Getters and setters for libhtmltmplpro options. Public interface to get and set libhtmltmplpro options. \author Igor Vlasenko \warning This header file should never be included directly. Include instead. */ /* generated; do not edit */ #ifndef _PROPARAM_H #define _PROPARAM_H 1 struct tmplpro_param; '; print PARAMC '/* generated; do not edit */ #include "pabidecl.h" #include "pabstract.h" #include "pparam.h" #include "proparam.h" '; print PARAMM1 ' /* generated; do not edit */ internal class C_OPTS { '; print PARAMM2 '/* generated; do not edit */ '; print PARAMM3 '/* generated; do not edit */ '; #print PGETINT catfile('getoptint.re2c.header'); #print PSETINT catfile('setoptint.re2c.header'); #----------- BEGIN LOOP------------------- while () { last if m!/\*\s*private\s*\*/!; next if /^\s*\};\s*$/; next if /typedef/; next unless m!^\s*(.+);\s*(/\*.+\*/)?\s*$!; my $field=$1; my $default_value=0; $default_value=$1 if m!/\*\s*default:(\d+).+\*/!; #print STDERR "defval: $default_value\n" if $default_value; $field=~/(.*?)\s+(\S+)$/; my $type=$1; my $name=$2; my $flagtype=$type; $flagtype=~s/flag/int/; my $monotype=$flagtype; $monotype=~s/ABSTRACT_.*\*/IntPtr/; $monotype=~s/char\*\*/IntPtr/; $monotype=~s/const char\*/IntPtr/; $monotype=~s/char\*/IntPtr/; #$monotype=~s/struct exprval/exprval/; $monotype='C_API.'.$monotype if $monotype=~/(functype|PSTRING)/; my $is_int_option = $monotype eq 'int'; my $is_bool_option = $is_int_option && $type eq 'flag'; if ($flagtype=~/functype$/) { print PARAMH "/*! \\fn $flagtype tmplpro_get_option_$name(struct tmplpro_param*); \\brief get address of callback of ::$flagtype \\param param -- pointer to an internal state. */ "; } elsif ($flagtype=~/^ABSTRACT_/) { my $typeref=$flagtype; $typeref=~s/\*//; print PARAMH "/*! \\fn $flagtype tmplpro_get_option_$name(struct tmplpro_param*); \\brief get value of an external pointer that will be passed to a callback. see ::$typeref. \\param param -- pointer to an internal state. */ "; } else { print PARAMH "/*! \\fn $flagtype tmplpro_get_option_$name(struct tmplpro_param*); \\brief get value of $name option. see HTML::Template::Pro perl module documentation for $name option. \\param param -- pointer to an internal state. */ "; } print PARAMH "TMPLPRO_API $flagtype APICALL tmplpro_get_option_$name(struct tmplpro_param*); "; if ($flagtype=~/functype$/) { print PARAMH "/*! \\fn void tmplpro_set_option_$name(struct tmplpro_param*,$flagtype); \\brief set callback of ::$flagtype \\param param -- pointer to an internal state. \\param val -- callback address to set. */ "; } elsif ($flagtype=~/^ABSTRACT_/) { my $typeref=$flagtype; $typeref=~s/\*//; print PARAMH "/*! \\fn void tmplpro_set_option_$name(struct tmplpro_param*,$flagtype); \\brief set external pointer that will be passed to a callback. see ::$typeref. \\param param -- pointer to an internal state. \\param val -- value to set. */ "; } else { print PARAMH "/*! \\fn void tmplpro_set_option_$name(struct tmplpro_param*,$flagtype); \\brief set value of $name option. see HTML::Template::Pro perl module documentation for $name option. \\param param -- pointer to an internal state. \\param val -- value to set. */ "; } print PARAMH "TMPLPRO_API void APICALL tmplpro_set_option_$name(struct tmplpro_param*,$flagtype); "; my $c_get_line = ($type eq 'flag' ? '(int) ':'').'param->'.$name; my $c_set_line = "param->$name=".($type eq 'flag' ? '(flag)':'').'val'; print PARAMC " API_IMPL $flagtype APICALL tmplpro_get_option_$name(struct tmplpro_param* param) { return $c_get_line; } API_IMPL void APICALL tmplpro_set_option_$name(struct tmplpro_param* param, $flagtype val) { $c_set_line; ".($proparam_c_set_hook{$name} ? $proparam_c_set_hook{$name} : ''). "} "; #print PGETINT ' "'.$name.'" {return '.$c_get_line.";}\n" if $is_int_option; #print PSETINT ' "'.$name.'" {'.$c_set_line."; return 0;}\n" if $is_int_option; print PGETINT2 ' "'.$name.'" {return '.$c_get_line.";}\n" if $is_int_option; print PSETINT2 ' "'.$name.'" {'.$c_set_line."; return 0;}\n" if $is_int_option; if ($is_int_option) { if ($default_value) { print PPRESET1 " param->$name=".($type eq 'flag' ? '(flag)':'').$default_value.";\n"; } else { print PPRESET0 " param->$name=".($type eq 'flag' ? '(flag)':'').$default_value.";\n"; } } print PARAMM1 " [DllImport(DLL.HTP_DLL, CallingConvention=DLL.HTP_CallingConvention, CharSet=DLL.HTPCharSet)] internal static extern $monotype tmplpro_get_option_$name(IntPtr c_param); [DllImport(DLL.HTP_DLL, CallingConvention=DLL.HTP_CallingConvention, CharSet=DLL.HTPCharSet)] internal static extern void tmplpro_set_option_$name(IntPtr c_param, $monotype val); "; print PARAMM2 ' case "'.$name.'": '."\t".'C_OPTS.tmplpro_set_option_'.$name.'(_c_param, val); break; ' if $is_int_option; print PARAMM3 ' case "'.$name.'": '."\t".'return C_OPTS.tmplpro_get_option_'.$name.'(_c_param); ' if $is_int_option; print PARAMM4 ' /// /// HTML::Template::Pro template processing option. /// see HTML::Template::Pro perl module documentation for '.$name.' option. /// public int '.$name.' { get { return C_OPTS.tmplpro_get_option_'.$name.'(_c_param); } set { C_OPTS.tmplpro_set_option_'.$name.'(_c_param, value); } } ' if $is_int_option; print PARAMDLLDEF " tmplpro_get_option_$name\r\n"; print PARAMDLLDEF " tmplpro_set_option_$name\r\n"; print PARAMDLLSYM "tmplpro_get_option_$name\n"; print PARAMDLLSYM "tmplpro_set_option_$name\n"; } #----------- END LOOP------------------- print PARAMH ' #endif /* proparam.h */ '; print PARAMM1 ' } '; #print PGETINT catfile('getoptint.re2c.footer'); #print PSETINT catfile('setoptint.re2c.footer'); close (PARAMH); close (PARAMC); close (PARAMM1); close (PARAMM2); close (PARAMM3); close (PARAMM4); close (PARAMDLLDEF); #close (PGETINT); #close (PSETINT); close (PGETINT2); close (PSETINT2); close (PPRESET0); close (PPRESET1); sub catfile { my $file=shift; open (INFILE, $file) || die "can't open $file: $!"; binmode (INFILE); local $/; my $catfile=; close (INFILE) || die "can't close $file: $!"; return $catfile; } HTML-Template-Pro-0.9510/prostate.h0000644000076400007640000000156611255446414015405 0ustar igorigor#ifndef _PROSTATE_H #define _PROSTATE_H 1 #include "pbuffer.h" struct tagstack { struct tagstack_entry* entry; int pos; int depth; }; struct tmplpro_param; typedef int boolval; struct tmplpro_state { boolval is_visible; const char* top; const char* next_to_end; const char* last_processed_pos; const char* cur_pos; struct tmplpro_param* param; /* current tag */ int tag; boolval is_tag_closed; boolval is_tag_commented; const char* tag_start; /* internal buffers */ /* tag stack */ struct tagstack tag_stack; /* expr string buffers; used to unescape pstring args and for num -> string */ pbuffer expr_left_pbuffer; pbuffer expr_right_pbuffer; }; extern TMPLPRO_LOCAL void log_state(struct tmplpro_state*, int level, const char *fmt, ...) FORMAT_PRINTF(3,4); #endif /* prostate.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/proscope.inc0000644000076400007640000000545511253454141015713 0ustar igorigor/* -*- c -*- * File: proscope.c * Author: Igor Vlasenko * Created: Thu May 26 15:25:57 2005 * * $Id$ */ #include #include "proscope.h" #include "tmpllog.h" #define START_NUMBER_OF_NESTED_LOOPS 64 static void Scope_init(struct scope_stack* scopestack) { scopestack->max=START_NUMBER_OF_NESTED_LOOPS; scopestack->root=(struct ProScopeEntry*) malloc ((scopestack->max) * sizeof(struct ProScopeEntry)); if (NULL==scopestack->root) tmpl_log(TMPL_LOG_ERROR, "DIE:_Scope_init:internal error:not enough memory\n"); scopestack->level=-1; } static void Scope_free(struct scope_stack* scopestack) { free(scopestack->root); scopestack->max=-1; scopestack->level=-1; } INLINE static int curScopeLevel(const struct scope_stack* scopestack) { return scopestack->level; } INLINE static struct ProScopeEntry* getCurrentScope(const struct scope_stack* scopestack) { return scopestack->root+scopestack->level; } INLINE static struct ProScopeEntry* getScope(const struct scope_stack* scopestack, int depth) { return &(scopestack->root)[depth]; } static void popScope(struct scope_stack* scopestack) { if (scopestack->level>0) scopestack->level--; else tmpl_log(TMPL_LOG_ERROR, "WARN:PopScope:internal error:scope is exhausted\n"); } static void _pushScope(struct scope_stack* scopestack) { if (scopestack->max<0) { tmpl_log(TMPL_LOG_ERROR, "WARN:PushScope:internal warning:why scope is empty?\n"); Scope_init(scopestack); } ++scopestack->level; if (scopestack->level>scopestack->max) { if (scopestack->maxmax=START_NUMBER_OF_NESTED_LOOPS; scopestack->max*=2; scopestack->root=(struct ProScopeEntry*) realloc (scopestack->root, (scopestack->max) * sizeof(struct ProScopeEntry)); } } static void pushScopeLoop(struct scope_stack* scopestack, int loop_count, void *loops_AV) { struct ProScopeEntry* CurrentScope; _pushScope(scopestack); CurrentScope=scopestack->root+scopestack->level; CurrentScope->loop=-1; CurrentScope->loop_count = loop_count; CurrentScope->flags=0; CurrentScope->loops_AV=loops_AV; CurrentScope->param_HV=NULL; } static void pushScopeMap(struct scope_stack* scopestack, void *param_HV, int flags) { struct ProScopeEntry* CurrentScope; _pushScope(scopestack); CurrentScope=scopestack->root+scopestack->level; CurrentScope->flags=flags; CurrentScope->loops_AV=NULL; CurrentScope->param_HV=param_HV; } static void Scope_reset(struct scope_stack* scopestack, int keep_count) { int init_level=-1; // TODO; find out scope level if (scopestack->max<0) { tmpl_log(TMPL_LOG_ERROR, "ERROR:Scope_reset:internal error:scope is empty.\n"); Scope_init(scopestack); scopestack->level=init_level; } else { scopestack->level=keep_count+init_level; } } HTML-Template-Pro-0.9510/provalue.h0000644000076400007640000000034011236037175015365 0ustar igorigor#ifndef _PROVALUE_H #define _PROVALUE_H 1 #include TMPLPRO_LOCAL PSTRING _get_variable_value (struct tmplpro_param *param, PSTRING name); #endif /* provalue.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/exprtype.h0000644000076400007640000000252411247444721015417 0ustar igorigor/*! \file exprtype.h \brief description of EXPR variable type. EXPR variable type is passed to and from user-supplied functions. \author Igor Vlasenko \warning This header file should never be included directly. Include instead. */ #ifndef _EXPRTYPE_H #define _EXPRTYPE_H 1 #ifdef HAVE_CONFIG_H #include "config.h" #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #define EXPR_TYPE_INT 'i' #define EXPR_TYPE_DBL 'd' #define EXPR_TYPE_PSTR 'p' /* NULL is for interface only, internally NULL pstring is used. */ #define EXPR_TYPE_NULL '\0' /* UPSTR is for internal use only. it is never passed to user functions. */ #define EXPR_TYPE_UPSTR 'u' #if defined INT64_MAX || defined int64_t typedef int64_t EXPR_int64; #elif defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8 typedef long long int EXPR_int64; #elif defined INT64_NAME typedef INT64_NAME EXPR_int64; #else typedef long int EXPR_int64; #endif #if defined PRId64 # define EXPR_PRId64 PRId64 #elif defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8 # define EXPR_PRId64 "lld" #elif defined _MSC_VER # define EXPR_PRId64 "I64d" #else # define EXPR_PRId64 "ld" #endif struct exprval; #endif /* exprtype.h */ /* * Local Variables: * mode: c * End: */ HTML-Template-Pro-0.9510/META.yml0000644000076400007640000000117312144122665014633 0ustar igorigor--- #YAML:1.0 name: HTML-Template-Pro version: 0.9510 abstract: Perl/XS module to use HTML Templates from CGI scripts author: - I. Yu. Vlasenko license: perl distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: File::Path: 2 File::Spec: 0 JSON: 2 Test::More: 0 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.56 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4