From 1d1cb9e3d003f23bddce0a744ffc60a7e82bf23c Mon Sep 17 00:00:00 2001 From: Alexander Pickering Date: Thu, 28 Dec 2017 22:03:59 -0500 Subject: Changed render function Render function now returns the length of the string it returns --- README.html | 420 ----------------------------------------------------------- README.md | 26 ++-- ctemplates.c | 8 +- ctemplates.h | 6 +- 4 files changed, 23 insertions(+), 437 deletions(-) delete mode 100644 README.html diff --git a/README.html b/README.html deleted file mode 100644 index f519ec9..0000000 --- a/README.html +++ /dev/null @@ -1,420 +0,0 @@ -

C TemplateS

- -

If you found this page using a search engine, you may be looking for the -original libctemplate by Stephen C. Losen

- -

libctemplates is a template expander written for use with HTML. It's goals are -to be simple, versitile, and fast. This library started off as a -fork of libctemplate, but eventually became a total rewrite. libctemplate, -the original, was built primarily for cgi applications. libctemplate was -tightly coupled with file streams, while libctemplateS renders templates to -strings for use in any application, FastCGI or Kore, for example. -If you think libctemplates is missing a feature, feel free to suggest it to -alexandermpickering@gmail.com, -or, even better, write it yourself and send the patch! You can find -instructions on createing and sending git patches here.

- -

Contents

- -
    -
  1. Installation
  2. -
  3. Usage
  4. -
  5. Quick refrence
  6. -
  7. Examples
  8. -
- -

- -

Installation

- -

Run the make file. libctemplates should compile on any system with a c99 -complient c compiler. If you are on linux, run

- -
make; make install
-
- -

- -

Usage

- -

Just include the ctemplates.h header and make sure you're linking against -libctemplates.a, for example:

- -
gcc main.c -lctemplates
-
- -

- -

Quick refrence

- -

Structs

- - - -

Functions

- -
struct TMPL_templates* TMPL_alloc_template(char* template_string)
-
- -

Creates a template from the given string. This can be pretty expensive -so try to only do it once for each template you need, and call render() -as many times as you need on that template.

- -
void TMPL_free_template(struct TMPL_templates* template)
-
- -

Frees a previously allocated template.

- -
struct TMPL_varlist* TMPL_alloc_varlist()
-
- -

Allocates a variable list that you can add variables and loops to.

- -
void TMPL_free_varlist(struct TMPL_varlist* varlist)
-
- -

Frees a previously allocated varlist, and any loops that have been added.

- -
struct TMPL_loop* TMPL_alloc_loop()
-
- -

Allocates a loop that you can add varlists to.

- -
void TMPL_free_loop(struct TMPL_loop* loop)
-
- -

Frees a previously allocated loop, and any varlists that have been added.

- -
void TMPL_add_var_to_varlist(struct TMPL_varlist* vl, char* name, char* value)  
-
- -

Adds a variable to a variable list

- -
void TMPL_add_loop_to_varlist(struct TMPL_varlist* vl,char* name,struct TMPL_loop* loop)  
-
- -

Adds a loop to a varlist

- -
void TMPL_add_varlist_to_loop(struct TMPL_loop* l, struct TMPL_varlist* vl)  
-
- -

Adds a varlist that should be used one iteration through the loop

- -
char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* vl)  
-
- -

Turns a template and varlist into a string. the returned char* should NOT be freed. The returned char* is only valid until TMPL_render() is called again. If you need it even after TMPL_render() is called, copy it.

- -

- -

Examples

- -

Hello, World!

- -

At it's most simple, libctemplates just copies whatever template you give it. -For example:

- -

main.c

- -
#include <ctemplate.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-char* template = "Hello, world!";
-
-int main(){
-    struct TMPL_templates* t = TMPL_alloc_template(template);
-    if(t == NULL){
-        printf("Failed to compile\n");
-        exit(-1);
-    }
-    struct TMPL_varlist* vl = TMPL_alloc_varlist();
-    char* output = TMPL_render(t,vl);
-    printf("Output: %s\n",output);
-    TMPL_free_varlist(vl);
-    TMPL_free_template(t);
-    return 0;
-}
-
- -

output

- -
Output: Hello, world!
-
- -

Variable substitution

- -

template.html

- -
Value is:<TMPL_VAR name="varname" default="optional default">
-
- -

main.c

- -
#include <ctemplate.h>
-
-int main(){
-    /* 
-    It usually helps to seperate the template from the
-    C code. It does mean to need to read in a file though.
-    Try to only call TMPL_alloc_template once for each
-    template you have, and then use TMPL_render() whenever
-    you need to use them.
-    */
-    FILE* fp = fopen("template.html","r");
-    if(fp == NULL){
-        printf("Failed to open file!\n");
-        exit(-1);
-    }
-    fseek(fp,0,SEEK_END);
-    size_t file_len = ftell(fp);
-    char template[file_len];
-    fread(template,sizeof(char),file_len,fp);
-
-    struct TMPL_templates* t;
-    struct TMPL_varlist* vl;
-
-    /*
-    Render the template without a variable named "varname"
-    This will use the variable's default, if it has one.
-    If the variable has no default, and is not supplied a value,
-    it errors, and stores a message that can be retrived with
-    TMPL_get_error(...)
-    */
-    t = TMPL_alloc_template(template);
-    vl = TMPL_alloc_varlist();
-    char* without_variable = TMPL_render(t,vl);
-    printf("Without variable: %s\n",without_variable);
-    TMPL_free_template(t);
-    TMPL_free_varlist(vl);
-
-    /*
-    Now render a template with a variable, use the
-    TMPL_add_var_to_varlist(...) to supply the template with
-    variables.
-    */
-    t = TMPL_alloc_template(template);
-    vl = TMPL_alloc_varlist();
-    TMPL_add_var_to_varlist(vl,"varname","Hello, world!");
-    char* with_variable = TMPL_render(t,vl);
-    printf("With variable:%s\n",with_variable);
-    TMPL_free_template(t);
-    TMPL_free_varlist(vl);
-
-    return 0;
-}
-
- -

output

- -
Without variable:
-Value is:optional default
-
-
-With variable:
-Value is:Hello, world!
-
- -

If/Elseif/Else

- -

If and elseif statements check if strings are the same. They do a strcmp(), so be mindful not to use really long strings if you don't need them.

- -

template.html

- -
What happened:
-<TMPL_IF name="varname" value="1234">
-    "varname" was "1234"
-<TMPL_ELSEIF name="var2" value="pass">
-    "var2" was "pass"
-<TMPL_ELSE>
-    "varname" was not "1234", and "var2" was not "pass"
-<TMPL_END>
-
- -

main.c

- -
#include <stdlib.h>
-#include <stdio.h>
-#include <ctemplate.h>
-
-int main(){
-    /* 
-    Same as before, just read a file in
-    */
-    FILE* fp = fopen("template.html","r");
-    if(fp == NULL){
-        printf("Failed to open file!\n");
-        exit(-1);
-    }
-    fseek(fp,0,SEEK_END);
-    size_t file_len = ftell(fp);
-    rewind(fp);
-    char template[file_len];
-    fread(template,sizeof(char),file_len,fp);
-
-    /*
-    No need to rebuild the template each time,
-    just alloc it once.
-    */
-    struct TMPL_templates* t = TMPL_alloc_template(template);
-    struct TMPL_varlist* vl;
-
-    /*
-    If the variable the "if" or "elseif" is looking for dosn't exist,
-    the condition is considered false.
-    */
-    vl = TMPL_alloc_varlist();
-    char* without_variable = TMPL_render(t,vl);
-    printf("Without variable:\n%s\n",without_variable);
-
-    /*
-    Add a variable to make the second condition true, and reprint
-    After we call TMPL_render() again, whatever pointer it returned
-    last time may have been freed. Be sure to copy it into your own
-    buffer if you still need it.
-    */
-    TMPL_add_var_to_varlist(vl,"var2","pass");
-    char* with_one = TMPL_render(t,vl);
-    printf("With 1 variable:\n%s\n",TMPL_render(t,vl));
-
-    /*
-    Always be sure to free things!
-    */
-    TMPL_free_varlist(vl);
-    TMPL_free_template(t);
-
-    return 0;
-}
-
- -

output

- -
Without variable:
-
-What happened:
-
-    "varname" was not "1234", and "var2" was not "pass"
-
-
-
-With 1 variable:
-
-What happened:
-
-    "var2" was "pass"
-
- -

Notice that the tabs in the template are preserved in the output. This is not -a minifier! Just a template expander!

- -

Loops

- -

Loops are special in libctemplates, loops each have their own namespace, and -only variables that have been added to the namespace are acessable in the loop.

- -

template.html

- -
What happened:
-<TMPL_LOOP name="myloop">
-    This time through the loop, my variable is <TMPL_VAR name="loopvar">
-<TMPL_END>
-
- -

main.c

- -
#include <stdlib.h>
-#include <stdio.h>
-#include <ctemplate.h>
-
-int main(){
-    /* 
-    Same as before
-    */
-    FILE* fp = fopen("template.html","r");
-    if(fp == NULL){
-        printf("Failed to open file!\n");
-        exit(-1);
-    }
-    fseek(fp,0,SEEK_END);
-    size_t file_len = ftell(fp);
-    rewind(fp);
-    char template[file_len];
-    fread(template,sizeof(char),file_len,fp);
-
-    /*
-    Same as before
-    */
-    struct TMPL_templates* t = TMPL_alloc_template(template);
-    struct TMPL_varlist* vl = TMPL_alloc_varlist();
-
-    /*
-    Now create a loop variable and add some things to it.
-    This is usually not as verbose as it looks here, since you'll
-    usually do this in a C loop.
-    */
-    struct TMPL_loop* loop = TMPL_alloc_loop();
-
-    struct TMPL_varlist* first = TMPL_alloc_varlist();
-    TMPL_add_var_to_varlist(first,"loopvar","first");
-    TMPL_add_varlist_to_loop(loop,first);
-
-    struct TMPL_varlist* second = TMPL_alloc_varlist();
-    TMPL_add_var_to_varlist(second,"loopvar","second");
-    TMPL_add_varlist_to_loop(loop,second);
-
-    struct TMPL_varlist* third = TMPL_alloc_varlist();
-    TMPL_add_var_to_varlist(third,"loopvar","third");
-    TMPL_add_varlist_to_loop(loop,third);
-
-    /*
-    Remember to add the loop to the varlist you'll eventually
-    pass to TMPL_render() with the correct name.
-    */
-    TMPL_add_loop_to_varlist(vl,"myloop",loop);
-
-    char* output = TMPL_render(t,vl);
-    printf("Output:\n%s\n",output);
-
-    /*
-    When freeing a varlist, any loops it has are automatically
-    also freed. When freeing a loop, any varlists it contains
-    are also automatically freed. This means you only need to
-    free your top-level varlist!
-    */
-    TMPL_free_varlist(vl);
-    TMPL_free_template(t);
-}
-
- -

output

- -
Output:
-What happened:
-This time through the loop, my variable is first
-This time through the loop, my variable is second
-This time through the loop, my variable is theird
-Done!
-
- - - - diff --git a/README.md b/README.md index 93029a0..c0deebb 100644 --- a/README.md +++ b/README.md @@ -92,9 +92,9 @@ Adds a loop to a varlist Adds a varlist that should be used one iteration through the loop - char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* vl) + char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* vl, size_t* length) -Turns a template and varlist into a string. the returned char\* should NOT be freed. The returned char\* is only valid until TMPL\_render() is called again. If you need it even after TMPL\_render() is called, copy it. +Turns a template and varlist into a string. the returned char\* should NOT be freed. The returned char\* is only valid until TMPL\_render() is called again. If you need it even after TMPL\_render() is called, copy it. The length of the returned string is put into `length` to help in copying.
## Examples @@ -119,8 +119,10 @@ For example: exit(-1); } struct TMPL_varlist* vl = TMPL_alloc_varlist(); - char* output = TMPL_render(t,vl); + size_t dummy; + char* output = TMPL_render(t,vl,&dummy); printf("Output: %s\n",output); + printf("Length: %d\n",(int)dummy); TMPL_free_varlist(vl); TMPL_free_template(t); return 0; @@ -170,7 +172,8 @@ For example: */ t = TMPL_alloc_template(template); vl = TMPL_alloc_varlist(); - char* without_variable = TMPL_render(t,vl); + size_t dummy; + char* without_variable = TMPL_render(t,vl,&dummy); printf("Without variable: %s\n",without_variable); TMPL_free_template(t); TMPL_free_varlist(vl); @@ -183,7 +186,8 @@ For example: t = TMPL_alloc_template(template); vl = TMPL_alloc_varlist(); TMPL_add_var_to_varlist(vl,"varname","Hello, world!"); - char* with_variable = TMPL_render(t,vl); + size_t dummy; + char* with_variable = TMPL_render(t,vl,&dummy); printf("With variable:%s\n",with_variable); TMPL_free_template(t); TMPL_free_varlist(vl); @@ -248,7 +252,8 @@ If and elseif statements check if strings are the same. They do a strcmp(), so b the condition is considered false. */ vl = TMPL_alloc_varlist(); - char* without_variable = TMPL_render(t,vl); + size_t dummy; + char* without_variable = TMPL_render(t,vl,&dummy); printf("Without variable:\n%s\n",without_variable); /* @@ -258,8 +263,9 @@ If and elseif statements check if strings are the same. They do a strcmp(), so b buffer if you still need it. */ TMPL_add_var_to_varlist(vl,"var2","pass"); - char* with_one = TMPL_render(t,vl); - printf("With 1 variable:\n%s\n",TMPL_render(t,vl)); + size_t dummy; + char* with_one = TMPL_render(t,vl,&dummy); + printf("With 1 variable:\n%s\n",with_one); /* Always be sure to free things! @@ -354,8 +360,8 @@ only variables that have been added to the namespace are acessable in the loop. pass to TMPL_render() with the correct name. */ TMPL_add_loop_to_varlist(vl,"myloop",loop); - - char* output = TMPL_render(t,vl); + size_t size; + char* output = TMPL_render(t,vl,&size); printf("Output:\n%s\n",output); /* diff --git a/ctemplates.c b/ctemplates.c index 5befdd4..a470ebc 100644 --- a/ctemplates.c +++ b/ctemplates.c @@ -143,7 +143,8 @@ void TMPL_render_helper( ); char* TMPL_render( struct TMPL_templates* t, - struct TMPL_varlist* varlist + struct TMPL_varlist* varlist, + size_t* size_p ); struct TMPL_templates* TMPL_alloc_template(char* tmplstr); void TMPL_free_template(struct TMPL_templates* t); @@ -997,14 +998,13 @@ TMPL_render_helper(struct TMPL_templates* t, struct TMPL_varlist* varlist){ } char* -TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* varlist){ +TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* varlist, size_t* size_p){ if(t->out != NULL){ free_tmpl_buf(t->out); } t->out = alloc_tmpl_buf(); TMPL_render_helper(t,varlist); - size_t dummy; - char* ret = bstringify(t->out,&dummy); + char* ret = bstringify(t->out,size_p); return ret; } diff --git a/ctemplates.h b/ctemplates.h index a2d33a1..e0e4a63 100644 --- a/ctemplates.h +++ b/ctemplates.h @@ -214,16 +214,16 @@ void TMPL_free_fmtlist(struct TMPL_fmtlist* fmtlist); FILE *out, FILE *errout); */ -struct TMPL_varlist* TMPL_alloc_varlist(); +struct TMPL_varlist* TMPL_alloc_varlist(void); void TMPL_free_varlist(struct TMPL_varlist* t); -struct TMPL_varitem* TMPL_alloc_varitem(); +struct TMPL_varitem* TMPL_alloc_varitem(void); void TMPL_free_varitem(struct TMPL_varitem* vi); struct TMPL_templates* TMPL_alloc_template(char* t); void TMPL_free_template(struct TMPL_templates* t); -char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* varlist); +char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* varlist, size_t* size_p); struct TMPL_tagnode* TMPL_alloc_tagnode(enum TMPL_tagtype); void TMPL_free_tagnode(struct TMPL_tagnode* tn); -- cgit v1.2.3-70-g09d2