Exemplo n.º 1
0
/**
 * Initializes the ngtemplate library.  This must be called before dictionaries
 * can be created or templates processed
 */
void ngt_init() {
    if (s_initialized)  {
        return;
    }
    
    s_initialized = 1;
    s_global_dictionary = ngt_dictionary_new();
    _init_global_dictionary(s_global_dictionary);
}
Exemplo n.º 2
0
/**
 * Reads in key/value pairs of the form Key = Value <newline>
 * Note that there is little error handling here, so make sure everything is formatted correctly
 *
 * For nested sections, note that if you have another section at the same level, it must be signified by
 * "}{", do NOT put a newline between the closing brace of the last section and the opening brace of the
 * next one.  This is due to the fragility of the parser, but since it's a test function, it's really not
 * worth fixing it.
 */
char* read_in_dictionary(ngt_dictionary* d, char* in_ptr, int *line, int in_dictionary) {
    // TODO:  This is one big hack of a function.  We should clean this up some time
    
    char marker[MAXMARKERLENGTH];
    char value[MAXVALUELENGTH];
    char *ptr;
    int ch, after_equals, escaped, in_comment, found_dictionary;
    
    memset(marker, 0, MAXMARKERLENGTH);
    memset(value, 0, MAXVALUELENGTH);
    
    escaped = 0;
    after_equals = 0;
    in_comment = 0;
    ptr = marker;
    if (!in_ptr)    {
        return 0;
    }
    
    found_dictionary = in_dictionary;
    while (!found_dictionary && *in_ptr)    {
        if (*in_ptr     == '{' &&
            *(in_ptr+1) == '{' &&
            *(in_ptr+2) == '!' &&
            *(in_ptr+3) == '#')
        {
            found_dictionary = 1;
            in_ptr+=4;  // Skip over those starting characters
            break;          
        }
        
        in_ptr++;
    }
    
    if (!found_dictionary)  {
        return 0;
    }
    
    while (*in_ptr) {
        if (*in_ptr     == '#' &&
            *(in_ptr+1) == '!' &&
            *(in_ptr+2) == '}' &&
            *(in_ptr+3) == '}') {
                
            // Found the end
            return 0;
        }
        
        ch = (int)*in_ptr++;
        
        
        if (!in_comment && ch == '#')   {
            // Start comment until newline
            in_comment = 1;
            continue;
        } else if (in_comment) {
            if (ch == '\r' || ch == '\n')   {
                // Done with comment
                in_comment = 0;
            } else {
                continue;
            }
        } 
        
        if (ch == '\\') {
            // We have an escape character coming
            ch = (int)*in_ptr++;
            if (ch == EOF)  {
                fprintf(stderr, "Unexpected End of File after escape character on line %d\n", *line);
                exit(-1);
            }
            
            if (ch != '{' && ch != '}' && ch != '!' && ch != '=' && ch != '#')  {
                fprintf(stderr, "Unrecognized escape character ('\\%c') on line %d\n", ch, *line);
                exit(-1);
            }
            
            escaped = 1;
        } else {
            escaped = 0;
        }
            
        if (!escaped && ch == '{')  {
            if (!after_equals)  {
                fprintf(stderr, "Unexpected '{' before '=' on line %d\n", *line);
                exit(-1);
            }
            
            ngt_dictionary* child = ngt_dictionary_new();
            ngt_add_dictionary(d, marker, child, NGT_SECTION_VISIBLE);
            in_ptr = read_in_dictionary(child, in_ptr, line, 1);
            continue;
        }
        
        if (!escaped && ch == '}')  {
            if (ptr != marker && !after_equals) {
                fprintf(stderr, "Unexpected '}' before '=' on line %d\n", *line);
                exit(-1);
            }
            
            if (!(d->parent))   {
                fprintf(stderr, "Unexpected '}' before '{' on line %d\n", *line);
                exit(-1);
            }
            
            // If we got here, it means that we were a recursive read_in_dictionary call and it's
            // time for us to exit
            return in_ptr;
        }
        
        if (ch == '\r' || ch == '\n')   {
            if (ptr != marker && ptr != value)  {
                // We have a valid pair (we hope)
                ngt_set_string(d, marker, value);
            }
            
            memset(marker, 0, MAXMARKERLENGTH);
            memset(value, 0, MAXVALUELENGTH);
            
            ptr = marker;
            after_equals = 0;
            (*line)++;
            continue;
        }
        
        if (!after_equals && (ch == ' ' || ch == '\t')) {
            // Skip whitespace
            continue;
        }
        
        if (!escaped && ch == '=')  {
            if (ptr == marker)  {
                fprintf(stderr, "Null marker on line %d\n", *line);
                exit(-1);
            }
            
            ptr = value;
            after_equals = 1;
            continue;
        }
        
        *(ptr++) = ch;
        
    }
    
    return in_ptr;
    
}
Exemplo n.º 3
0
/**
 * ngt_embed - Turn one or more template files into C code for embedding into programs
 */
int ngt_embed(const char* code_template, FILE* out, int argc, char** argv)  {
    int i;
    ngt_template* tpl;
    ngt_dictionary* dict;
    char* output;
    char file[PATH_MAX];
    char name[PATH_MAX];
    
    if (argc == 1)  {
        fprintf(stderr, "USAGE: ngtembed file1[=name1] file2[=name2] ... fileN[=nameN] [>out_file]\n");
        return -1;
    }

    tpl = ngt_new();
    dict = ngt_dictionary_new();
    
    ngt_add_modifier(tpl, "breakup_lines", _breakup_lines_modifier_cb);
    ngt_set_delimiters(tpl, "@", "@");
    ngt_set_dictionary(tpl, dict);
    tpl->tmpl = (char*)code_template;
    
    for (i = 1; i < argc; i++)  {
        char* p;
        int m, has_name;

        p = argv[i];
        m = 0;
        has_name = 0;
        while (*p)  {
            if (m < PATH_MAX && *p == '=')  {
                // Setting an explicit name.  Throw out what we've done so far
                has_name = 1;
                m = 0;
                p++;
                continue;
            }
            
            if (*p == '.' || *p == '\\' || *p == '/')   {
                name[m] = '_';
            } else {
                name[m] = *p;
            }
            
            if (!has_name)  {
                file[m] = *p;
                file[m+1] = '\0';
            }
            
            p++;
            m++;
        }
        name[m] = '\0';
        
        if (m)  {
            stringbuilder* sb;
            FILE* fd;
            int ch;
            
            fd = fopen(file, "r");
            if (!fd)    {
                fprintf(stderr, "Could not open '%s' for reading\n", file);
                return -1;
            }
            
            ngt_dictionary* section = ngt_dictionary_new();
                        
            ngt_set_string(section, "TemplateName", name);
                        
            sb = sb_new();
            while ((ch = fgetc(fd)) != EOF) {
                sb_append_ch(sb, (char)ch);
            }
            
            ngt_set_string(section, "TemplateBody", sb_cstring(sb));
            sb_destroy(sb, 1);
                        
            ngt_add_dictionary(dict, "Template", section, NGT_SECTION_VISIBLE);
            fclose(fd);
        }
    }
    
    ngt_expand(tpl, &output);
    fprintf(out, "%s\n", output);
    
    ngt_destroy(tpl);
    ngt_dictionary_destroy(dict);
    free(output);
}