1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/dknlnl-oneLineTemplate

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
OneLineTemplate.c 6.9 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
dknlnl Отправлено 12.12.2014 18:27 a9f9458
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "OneLineTemplate.h"
#include "micro.h"
#define STATE1 1
#define STATE2 2
#define STATE3 3
#define STATE4 4
static size_t GetVarIndex(const char *varName, const SymTable *symTable, size_t symTableLen)
{
size_t varIndex = 0;
for (size_t i = 1; i < symTableLen; i++)
{
if(0 == strcmp(varName, symTable[i].varName))
{
varIndex = i;
break;
}
}
ld("varIndex = %u", varIndex);
Return varIndex;
}
OneLineTemplate* OneLineTemplateCreate(const char* text, const SymTable *symTable, size_t symTableLen)
{
OneLineTemplate *head = NULL;
OneLineTemplate *tail = NULL;
OneLineTemplate *newNode = NULL;
size_t textIndex = 0;
int state = STATE1;
char currentChr = 0;
char token[1024] = {0};
size_t tokenIndex = 0;
while((currentChr = text[textIndex++]) != '\0')
{
if (STATE1 == state)
{
if ('{' != currentChr)
{
//commone char, just put it into token
token[tokenIndex++] = currentChr;
}
else
{
//about to get a var, first need to save token if needed
if (0 != tokenIndex)
{
token[tokenIndex] = '\0';
newNode = (OneLineTemplate*)malloc(sizeof(OneLineTemplate));
if (NULL == newNode)
{
OneLineTemplateRelase(head);
Return NULL;
}
newNode->dataType = DATATYPE_CONSTTEXT;
snprintf(newNode->data.constText, sizeof(newNode->data.constText), "%s", token);
newNode->next = NULL;
//insert into list;
if (NULL != head)
{
tail->next = newNode;
tail = newNode;
}
else
{
head = newNode;
tail = head;
}
}
//reset tokenIndex for further use, and state change to STATE2
tokenIndex = 0;
state = STATE2;
}
}
else if (STATE2 == state)
{
if ((currentChr >= 'a' && currentChr <= 'z') ||
(currentChr >= 'A' && currentChr <= 'Z'))
{
//var char, put it into token
token[tokenIndex++] = currentChr;
state = STATE3;
}
else
{
//error, expecting [a-zA-Z]
le("expecting [a-zA-z], but got %c", currentChr);
state = STATE4;
}
}
else if(STATE3 == state)
{
if ((currentChr >= 'a' && currentChr <= 'z') ||
(currentChr >= 'A' && currentChr <= 'Z') ||
(currentChr >= '0' && currentChr <= '9'))
{
//var char, put it into token
token[tokenIndex++] = currentChr;
}
else if('}' == currentChr)
{
//got a var
token[tokenIndex] = '\0';
newNode = (OneLineTemplate*)malloc(sizeof(OneLineTemplate));
if (NULL == newNode)
{
OneLineTemplateRelase(head);
Return NULL;
}
newNode->dataType = DATATYPE_VARINDEX;
snprintf(newNode->data.var.varName, sizeof(newNode->data.var.varName), "%s", token);
newNode->data.var.varIndex = GetVarIndex(token, symTable, symTableLen);
newNode->next = NULL;
//insert into list;
if (NULL != head)
{
tail->next = newNode;
tail = newNode;
}
else
{
head = newNode;
tail = head;
}
//reset tokenIndex
tokenIndex = 0;
state = STATE1;
}
else
{
//error, expecting [a-zA-Z0-9}]
le("expecting [a-zA-z0-9}], but got %c at index %d", currentChr, textIndex - 1);
state = STATE4;
}
}
else if (STATE4 == state)
{
//error state
OneLineTemplateRelase(head);
head = NULL;
break;
}
}
if (STATE1 == state)
{
//about to get a var, first need to save token if needed
if (0 != tokenIndex)
{
token[tokenIndex] = '\0';
newNode = (OneLineTemplate*)malloc(sizeof(OneLineTemplate));
if (NULL == newNode)
{
OneLineTemplateRelase(head);
Return NULL;
}
newNode->dataType = DATATYPE_CONSTTEXT;
snprintf(newNode->data.constText, sizeof(newNode->data.constText), "%s", token);
newNode->next = NULL;
//insert into list;
if (NULL != head)
{
tail->next = newNode;
tail = newNode;
}
else
{
head = newNode;
tail = head;
}
}
}
else
{
OneLineTemplateRelase(head);
Return NULL;
}
Return head;
}
void OneLineTemplateRelase(OneLineTemplate *tpl)
{
OneLineTemplate *current = tpl;
OneLineTemplate *next = NULL;
while(current)
{
next = current->next;
free(current);
current = next;
}
}
//TODO: expandTextLen need to be check
int OneLineTemplateExpand(const OneLineTemplate *tpl, const SymTable *symTable, size_t symTableLen, char *expandText, size_t expandTextLen)
{
const OneLineTemplate *current = tpl;
const OneLineTemplate *next = NULL;
size_t expandTextIndex = 0;
while(current && (expandTextLen > expandTextIndex))
{
next = current->next;
if (DATATYPE_CONSTTEXT == current->dataType)
{
ld("current->data.constText = %s", current->data.constText);
expandTextIndex += snprintf(expandText + expandTextIndex, expandTextLen - expandTextIndex, "%s", current->data.constText);
}
else if(current->data.var.varIndex < symTableLen)
{
ld("current->data.var.varIndex = %u:%s", current->data.var.varIndex, symTable[current->data.var.varIndex].varValue);
expandTextIndex += snprintf(expandText + expandTextIndex, expandTextLen - expandTextIndex, "%s", symTable[current->data.var.varIndex].varValue);
}
else
{
//error, var.varIndex is to not in [0, symTableLen)
Return -1;
}
current = next;
}
Return 0;
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/dknlnl-oneLineTemplate.git
git@api.gitlife.ru:oschina-mirror/dknlnl-oneLineTemplate.git
oschina-mirror
dknlnl-oneLineTemplate
dknlnl-oneLineTemplate
master