예제 #1
0
/**
 * @short Parses a block variable and writes the code necesary.
 * 
 * It can go deep inside a dict or list, and apply filters.
 */
void variable_write(parser_status *st, onion_block *b){
	
	function_add_code(st,
"  {\n"
"    const char *tmp;\n");
	variable_solve(st, onion_block_data(b), "tmp", STRING);
	function_add_code(st,
"    if (tmp)\n"
"      onion_response_write_html_safe(res, tmp);\n"
"  }\n");
}
예제 #2
0
/// Ends a for
void tag_endfor(parser_status *st, list *l){
	// First the preorder function
	function_data *d=function_pop(st);
	function_add_code(st, "  %s(dr->dict, dr->res);\n", d->id);
	
	// Now the normal code
	d=function_pop(st);
	function_add_code(st, "%s, &dr);\n"
"    }\n"
"    onion_dict_free(tmpcontext);\n"
"  }\n", d->id);
}
예제 #3
0
파일: parser.c 프로젝트: 511860050/onion
/**
 * @short One block read from in, prepare the output.
 * 
 * Depending on the mode of the block it calls the appropiate handler: variable, tag or just write text.
 */
void write_block(parser_status *st, onion_block *b){
	int mode=st->last_wmode;
	//ONION_DEBUG("Write mode %d, code %s", mode, b->data);
	switch(mode){
		case TEXT:
		{
			int oldl;
			if ( (oldl=onion_block_size(b)) ){
				if (oldl>0){ // Not Just \0
					int use_orig_line_numbers_bak=use_orig_line_numbers;
					use_orig_line_numbers=0;
					char *safe=onion_c_quote_new(onion_block_data(b));
					function_add_code(st, "  onion_response_write(res, ");
					int pos=0;
					int size=strlen(safe);
					char *s=safe;
					//ONION_DEBUG("------- pos %d, size %d",pos,size);
					while (pos<size){
						//ONION_DEBUG("pos %d, size %d",pos,size);
						char *e=strstr(s, "\n");
						if (!e)
							break;
						*e='\0';
						if (pos==0)
							function_add_code(st, "%s\n", s);
						else
							function_add_code(st, "      %s\n", s);
						pos+=(e-s)+1;
						s=e+1;
					}
					if (pos==0)
						function_add_code(st, "%s, %d);\n", s, oldl);
					else
						function_add_code(st, "      %s, %d);\n", s, oldl);
					use_orig_line_numbers=use_orig_line_numbers_bak;
					free(safe);
				}
			}
		}
			break;
		case VARIABLE:
			variable_write(st, b);
			break;
		case TAG:
			tag_write(st, b);
			break;
		default:
			ONION_ERROR("Unknown final mode %d", mode);
	}
	onion_block_clear(st->rawblock);
}
예제 #4
0
파일: parser.c 프로젝트: IPInfusion/SDN-IP
/**
 * @short One block read from in, prepare the output.
 * 
 * Depending on the mode of the block it calls the appropiate handler: variable, tag or just write text.
 */
void write_block(parser_status *st, onion_block *b){
	int mode=st->last_wmode;
	//ONION_DEBUG("Write mode %d, code %s", mode, b->data);
	switch(mode){
		case TEXT:
		{
			int oldl;
			if ( (oldl=onion_block_size(b)) ){
				char *safe=onion_c_quote_new(onion_block_data(b));
				function_add_code(st, "  onion_response_write(res, %s, %d);\n", safe, oldl);
				free(safe);
			}
		}
			break;
		case VARIABLE:
			variable_write(st, b);
			break;
		case TAG:
			tag_write(st, b);
			break;
		default:
			ONION_ERROR("Unknown final mode %d", mode);
	}
	onion_block_clear(st->rawblock);
}
예제 #5
0
/// Do the first for part.
void tag_for(parser_status *st, list *l){
	function_add_code(st, 
"  {\n"
"    onion_dict *loopdict=onion_dict_get_dict(context, \"%s\");\n", tag_value_arg (l,3));
	function_add_code(st, 
"    onion_dict *tmpcontext=onion_dict_hard_dup(context);\n"
"    if (loopdict){\n"
"      dict_res dr={ .dict = tmpcontext, .res=res };\n"
"      onion_dict_preorder(loopdict, ");
	function_data *d=function_new(st, NULL);
	d->signature="dict_res *dr, const char *key, const void *value, int flags";

	function_add_code(st, 
"  onion_dict_add(dr->dict, \"%s\", value, OD_DUP_VALUE|OD_REPLACE|(flags&OD_TYPE_MASK));\n", tag_value_arg(l,1));
	
	function_new(st, NULL);
}
예제 #6
0
/// Include an external html. This is only the call, the programmer must compile such html too.
void tag_include(parser_status* st, list* l){
	function_data *d=function_new(st, "%s", tag_value_arg(l, 1));
	function_pop(st);
	onion_block_free(d->code); // This means no impl
	d->code=NULL; 
	
	function_add_code(st, "  %s(context, res);\n", d->id);
}
예제 #7
0
/// Starts an if
void tag_if(parser_status *st, list *l){
	int lc=list_count(l);
	if (lc==2){
		function_add_code(st, 
"  {\n"
"    const char *tmp;\n"
		);
		variable_solve(st, tag_value_arg(l, 1), "tmp", tag_type_arg(l,1));
		function_add_code(st, 
"    if (tmp && strcmp(tmp, \"false\")!=0)\n", tag_value_arg(l,1));
	}
	else if (lc==4){
		const char *op=tag_value_arg(l, 2);
		const char *opcmp=NULL;
		if (strcmp(op,"==")==0)
			opcmp="==0";
		else if (strcmp(op,"<=")==0)
			opcmp="<=0";
		else if (strcmp(op,"<")==0)
			opcmp="<0";
		else if (strcmp(op,">=")==0)
			opcmp=">=0";
		else if (strcmp(op,">")==0)
			opcmp=">0";
		else if (strcmp(op,"!=")==0)
			opcmp="!=0";
		if (opcmp){
			function_add_code(st,
"  {\n"
"    const char *op1, *op2;\n");
			variable_solve(st, tag_value_arg(l, 1), "op1", tag_type_arg(l,1));
			variable_solve(st, tag_value_arg(l, 3), "op2", tag_type_arg(l,3));
			function_add_code(st,
"    if (op1==op2 || (op1 && op2 && strcmp(op1, op2)%s))\n",opcmp);
		}
		else{
			ONION_ERROR("%s:%d Unkonwn operator for if: %s", st->infilename, st->line, op);
			st->status=1;
		}
	}
	else{
		ONION_ERROR("%s:%d If only allows 1 or 3 arguments. TODO. Has %d.", st->infilename, st->line, lc-1);
		st->status=1;
	}
	function_new(st, NULL);
}
예제 #8
0
void tag_extends(parser_status *st, list *l){
	function_data *d=function_new(st, "%s", tag_value_arg(l, 1));
	function_pop(st);
	onion_block_free(d->code);
	d->code=NULL;
	
	function_add_code(st, "  %s(context, res);", d->id);
	d=(function_data*)st->function_stack->tail->data;
	d->flags|=F_NO_MORE_WRITE;
}
예제 #9
0
void tag_block(parser_status *st, list *l){
	const char *block_name=tag_value_arg(l, 1);
	function_add_code(st, 
"  {\n"
"    void (*f)(onion_dict *context, onion_response *res);\n"
"    f=(void*)onion_dict_get(context, \"__block_%s__\");\n"
"    if (f)\n"
"      f(context, res);\n"
"  }\n", block_name);

	char tmp[256];
	strncpy(tmp, st->infilename, sizeof(tmp));
	function_data *d=function_new(st, "%s__block_%s", basename(tmp),  block_name);
	function_add_code_f(st->blocks_init, 
"  if (!onion_dict_get(context, \"__block_%s__\"))\n"
"    onion_dict_add(context, \"__block_%s__\", %s, 0);\n", block_name, block_name, d->id);
}
예제 #10
0
/// endif
void tag_endif(parser_status *st, list *l){
	function_data *d=function_pop(st);
	function_add_code(st, "      %s(context, res);\n  }\n", d->id);
}
예제 #11
0
/// Else part
void tag_else(parser_status *st, list *l){
	function_data *d=function_pop(st);
	function_add_code(st, "      %s(context, res);\n    else\n", d->id);
	
	function_new(st, NULL);
}
예제 #12
0
/**
 * @short Compiles the infilename to outfilename.
 */
int work(const char *infilename, const char *outfilename, onion_assets_file *assets){
	tag_init();
	parser_status status;
	memset(&status, 0, sizeof(status));
	status.mode=TEXT;
	status.functions=list_new((void*)function_free);
	status.function_stack=list_new(NULL);
	status.status=0;
	status.line=1;
	status.rawblock=onion_block_new();
	status.infilename=infilename;
	char tmp2[256];
	strncpy(tmp2, infilename, sizeof(tmp2)-1);
	const char *tname=basename(tmp2);
  ONION_DEBUG("Create init function on top, tname %s",tname);
	status.blocks_init=function_new(&status, "%s_blocks_init", tname);
	status.blocks_init->signature="onion_dict *context";
	
	if (strcmp(infilename, "-")==0)
		status.in=stdin;
	else
		status.in=fopen(infilename,"rt");
	
	if (!status.in){
		ONION_ERROR("Could not open in file %s", infilename);
		goto work_end;
	}

	ONION_DEBUG("Create main function on top, tname %s",tname);
	function_new(&status, tname);
	
	function_add_code(&status, 
"  int has_context=(context!=NULL);\n"
"  if (!has_context)\n"
"    context=onion_dict_new();\n"
"  \n"
"  %s(context);\n",  status.blocks_init->id);
	
	parse_template(&status);
	
	((function_data*)status.function_stack->tail->data)->flags=0;
	
	function_add_code(&status,
"  if (!has_context)\n"
"    onion_dict_free(context);\n"
	);
	
	if (status.status){
		ONION_ERROR("Parsing error");
		goto work_end;
	}

	if (strcmp(outfilename, "-")==0)
		status.out=stdout;
	else
		status.out=fopen(outfilename,"wt");
	if (!status.out){
		ONION_ERROR("Could not open out file %s", infilename);
		goto work_end;
	}
	
	fprintf(status.out,
"/** Autogenerated by otemplate v. 0.2.0 */\n"
"\n"
"#include <libintl.h>\n"
"#include <string.h>\n\n"
"#include <onion/onion.h>\n"
"#include <onion/dict.h>\n"
"\n"
"typedef struct dict_res_t{\n"
"	onion_dict *dict;\n"
"	onion_response *res;\n"
"}dict_res;\n"
"\n"
"\n");

	functions_write_declarations_assets(&status, assets);
	
	functions_write_declarations(&status);

	functions_write_main_code(&status);

	if (use_orig_line_numbers)
		fprintf(status.out, "#line 1 \"%s\"\n", infilename);

	functions_write_code(&status);

work_end:
	if (status.in)
		fclose(status.in);
	if (status.out)
		fclose(status.out);
	list_free(status.functions);
	list_free(status.function_stack);
	//list_free(status.blocks);
	onion_block_free(status.rawblock);
	
	tag_free();
	return status.status;
}
예제 #13
0
/**
 * @short Solves a variable into code.
 * 
 * It uses the type to check it its a literal string, a dcit string or a dict.
 */
void variable_solve(parser_status *st, const char *data, const char *tmpname, vartype_e type){
	if (type==LITERAL){
		char *s=onion_c_quote_new(data);
		function_add_code(st,
"    %s=%s;\n", tmpname, s);
		free(s);
		return;
	}
	if (! (type==STRING || type==DICT) ){
		ONION_ERROR("Invalid type for variable solve");
		exit(1);
	}
	
	
	list *parts=list_new(onion_block_free);
	onion_block *lastblock;
	list_add(parts, lastblock=onion_block_new());
	
	
	int i=0;
	int l=strlen(data);
	const char *d=data;
	for (i=0;i<l;i++){
		if (d[i]=='.')
			list_add(parts, lastblock=onion_block_new());
		else if (d[i]==' ')
			continue;
		else
			onion_block_add_char(lastblock, d[i]);
	}

	if (list_count(parts)==1){
		char *s=onion_c_quote_new(onion_block_data(lastblock));
		if (type==STRING)
			function_add_code(st, 
	"    %s=onion_dict_get(context, %s);\n", tmpname, s);
		else if (type==DICT)
			function_add_code(st, 
	"    %s=onion_dict_get_dict(context, %s);\n", tmpname, s);
		free(s);
	}
	else{
		if (type==STRING)
			function_add_code(st,"    %s=onion_dict_rget(context", tmpname);
		else if (type==DICT)
			function_add_code(st,"    %s=onion_dict_rget_dict(context", tmpname);
		else{
			ONION_ERROR("Invalid type for variable solve");
			exit(1);
		}
		list_item *it=parts->head;
		while (it){
			lastblock=it->data;
			char *s=onion_c_quote_new(onion_block_data(lastblock));
			function_add_code(st,", %s", s);
			free(s);
			it=it->next;
		}
		function_add_code(st,", NULL);\n");
	}
	list_free(parts);
}