/* * dTemplate.xs * parse method * * $Id: dTemplate.xs 52 2003-07-31 22:01:00Z dlux $ * * $URL: http://svn.dlux.hu:81/public/dTemplate/trunk/dTemplate.xs $ * */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* consts */ #define INITIAL_CHUNK_SIZE 32 #define TABLE_SEP_CHAR ' ' /* method field constants */ #define FILENAME 0 #define TEXT 1 #define COMPILED 2 #define PARSEHASH 3 #define MALLOC_MAGIC_COOKIE 494 /* string chunk declaration */ typedef struct _StringChunk { I32 allocated; I32 endpos; char *data; } StringChunk; static StringChunk* new_StringChunk (I32 size) { StringChunk *self; Newz(MALLOC_MAGIC_COOKIE, self, 1, StringChunk); New(MALLOC_MAGIC_COOKIE, self->data, size+1, char); self->allocated = size+1; * (self->data) = 0; return self; } static void append_StringChunk (StringChunk* self, char *data, I32 size) { if (self->allocated <= self->endpos + size) { int new_alloc = 2 * (self->endpos + size); Renew(self->data, new_alloc, char); self->allocated = new_alloc; } Copy(data, self->data + self->endpos, size, char); self->endpos += size; * (self->data + self->endpos) = 0; } static void free_StringChunk (StringChunk* self) { Safefree(self->data); Safefree(self); } #define DO_IF_GET_MAGIC(sv) if (SvGMAGICAL(sv)) mg_get(sv) MODULE = dTemplate PACKAGE = dTemplate::Template void parse(...) PPCODE: { SV* self = ST(0); SV** compiledSV; AV* array; void *variable_invert; char *compiled, *walk, *variable_table; STRLEN compiled_len; I32 i, number_of_variables, vars_left; SV **variable; HV *global_parse_hash = perl_get_hv("dTemplate::parse", TRUE); HV *encoder_hash = perl_get_hv("dTemplate::ENCODERS", TRUE); SV *notassigned_mode = perl_get_sv("dTemplate::NOTASSIGNED_MODE", FALSE); SV **local_parse_href; HV *local_parse_hash; StringChunk *result; if (!SvROK(self)) XSRETURN_UNDEF; array = (AV*) SvRV(self); compiledSV = av_fetch(array, COMPILED, FALSE); if (!compiledSV || *compiledSV == &PL_sv_undef) { dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(self); PUTBACK; perl_call_method("compile", G_VOID | G_DISCARD ); FREETMPS; LEAVE; } // Local parse hash local_parse_href = av_fetch(array, PARSEHASH, FALSE); if (local_parse_href && *local_parse_href != &PL_sv_undef) local_parse_hash = (HV*) SvRV(*local_parse_href); else local_parse_hash = NULL; compiledSV = av_fetch(array, COMPILED, 0); if (!compiledSV || *compiledSV == &PL_sv_undef) XSRETURN_UNDEF; /* silently returns with undef if the retrieve is failed */ /* get the compiled string */ walk = compiled = SvPV(*compiledSV, compiled_len); /* get the number of variables in this template */ vars_left = number_of_variables = * ( (I32 *) walk )++; /* initializing the parser parameters */ Newz(1, variable, number_of_variables, SV *); variable_table = walk; variable_invert = (void *) variable_table + strlen(variable_table) + 1; result = new_StringChunk(INITIAL_CHUNK_SIZE); walk = (char *) variable_invert + strlen(variable_table) - 1; /* parameter processing */ if (!vars_left) goto param_proc_end; for (i=1; i=0 && index data, result->endpos)); free_StringChunk(result); ST(0) = res; XSRETURN(1); } }