#include "lexer.h" struct TMPL_token* TMPL_alloc_token(void); void TMPL_free_token(struct TMPL_token* token); enum TMPL_tagtype starts_with_token(const char* str, size_t strlen); size_t tagtype_len(enum TMPL_tagtype t); struct TMPL_token* scan_text( const char* start, size_t strlen, size_t* consumed ); struct TMPL_token* scan_tag( const char* start, size_t strlen, size_t* consumed ); void print_tokens(struct TMPL_token* head); /*Allocates a token*/ struct TMPL_token* TMPL_alloc_token(){ struct TMPL_token* ret = (struct TMPL_token*)malloc(sizeof(struct TMPL_token)); ret->next = NULL; return ret; } /*Frees an allocated token*/ void TMPL_free_token(struct TMPL_token* token){ struct TMPL_token* cursor = token; while(cursor != NULL){ struct TMPL_token* this = cursor; cursor = cursor->next; free(this); } } /*Check if it starts with the names of any of our tokens*/ enum TMPL_tagtype starts_with_token(const char* str, size_t strlen){ /*Make sure we get TMPL_ first*/ if(strlen < 5){ return tag_null; } if(*str != 'T' || *(str + 1) != 'M' || *(str + 2) != 'P' || *(str + 3) != 'L' || *(str + 4) != '_'){ return tag_null; } if(strlen > TAG_VAR_LENGTH && *(str + 5) == 'V' && *(str + 6) == 'A' && *(str + 7) == 'R' && *(str + 8) == ' '){ return tag_var; }else if(strlen > TAG_IF_LENGTH && *(str + 5) == 'I' && *(str + 6) == 'F' && *(str + 7) == ' '){ return tag_if; }else if(strlen > TAG_END_LENGTH && *(str + 5) == 'E' && *(str + 6) == 'N' && *(str + 7) == 'D'){ return tag_end; }else if(strlen > TAG_ELSE_LENGTH && *(str + 5) == 'E'/*Check for both else and elseif*/ && *(str + 6) == 'L' && *(str + 7) == 'S' && *(str + 8) == 'E'){ if(*(str + 9) != 'I'){ return tag_else; }else if(strlen > TAG_ELSEIF_LENGTH && *(str + 9) == 'I' && *(str + 10) == 'F' && *(str + 11) == ' '){ return tag_elseif; }else{ return tag_null; } }else if(strlen > TAG_LOOP_LENGTH && *(str + 5) == 'L' && *(str + 6) == 'O' && *(str + 7) == 'O' && *(str + 8) == 'P' && *(str + 9) == ' '){ return tag_loop; }else if(strlen > TAG_BREAK_LENGTH && *(str + 5) == 'B' && *(str + 6) == 'R' && *(str + 7) == 'E' && *(str + 8) == 'A' && *(str + 9) == 'K'){ return tag_break; }else if(strlen > TAG_CONTINUE_LENGTH && *(str + 5) == 'C' && *(str + 6) == 'O' && *(str + 7) == 'N' && *(str + 8) == 'T' && *(str + 9) == 'I' && *(str + 10) == 'N' && *(str + 11) == 'U' && *(str + 12) == 'E'){ return tag_continue; }else{ return tag_null; } } /*Find the lenth of a tag*/ size_t tagtype_len(enum TMPL_tagtype t){ switch(t){ case tag_null: return TAG_NULL_LENGTH; case tag_text: return TAG_TEXT_LENGTH; case tag_var: return TAG_VAR_LENGTH; case tag_if: return TAG_IF_LENGTH; case tag_end: return TAG_END_LENGTH; case tag_elseif: return TAG_ELSEIF_LENGTH; case tag_else: return TAG_ELSE_LENGTH; case tag_loop: return TAG_LOOP_LENGTH; case tag_break: return TAG_BREAK_LENGTH; case tag_continue: return TAG_CONTINUE_LENGTH; } return 0; } /*Quickly find the token*/ struct TMPL_token* scan_text(const char* start, size_t strlen, size_t* consumed){ struct TMPL_token* t = TMPL_alloc_token(); t->start = start; enum TMPL_tagtype type = tag_null; const char* cursor = start; while(type == tag_null){ int left = strlen - (cursor - start); cursor = (const char*)memchr(cursor,'<',left); if(cursor == NULL){ cursor = start + (strlen > 0 ? strlen : 1); break; } type = starts_with_token(cursor+1,strlen); if(type == tag_null){ cursor++; } } t->end = cursor; t->length = t->end - t->start; *consumed = t->length; return t; } struct TMPL_token* scan_tag(const char* start, size_t strlen, size_t* consumed){ struct TMPL_token* t = TMPL_alloc_token(); t->start = start; char* cursor = (char*)memchr(start,'>',strlen); t->end = cursor+1;/*Include the '>'*/ t->length = t->end - t->start; *consumed = t->length; return t; } void print_tokens(struct TMPL_token* head){ struct TMPL_token* cursor = head; while(cursor != NULL){ printf("char start is %p char end is %p cursor is %p type is %d\n",cursor->start, cursor->end,(void*)cursor,(int)cursor->type); const char* i; for(i = cursor->start; i != cursor->end; i++){ printf("%c",*i); } printf("\n----\n"); cursor = cursor->next; } printf("Finished printing tokens\n"); }