/*==================================================================*\
| EXIP - Embeddable EXI Processor in C |
|--------------------------------------------------------------------|
| This work is licensed under BSD 3-Clause License |
| The full license terms and conditions are located in LICENSE.txt |
\===================================================================*/
/**
* @file textOutputUtils.c
* @brief Implement utility functions for storing EXIPSchema instances as human readable descriptions
* @date May 7, 2012
* @author Rumen Kyusakov
* @version 0.5
* @par[Revision] $Id: textOutputUtils.c 328 2013-10-30 16:00:10Z kjussakov $
*/
#include "schemaOutputUtils.h"
#include "sTables.h"
static void writeValueTypeString(FILE* out, EXIType exiType);
errorCode textGrammarOutput(QNameID qnameid, Index grIndex, EXIGrammar* gr, EXIPSchema* schema, FILE* out)
{
Index ruleIter, prodIter;
Production* tmpProd;
EXIType exiType = VALUE_TYPE_NONE;
fprintf(out, "Grammar %d [%d:%d] ", (int) grIndex, (int) qnameid.uriId, (int) qnameid.lnId);
fwrite(schema->uriTable.uri[qnameid.uriId].uriStr.str, sizeof(CharType), schema->uriTable.uri[qnameid.uriId].uriStr.length, out);
fprintf(out, ":");
fwrite(GET_LN_URI_QNAME(schema->uriTable, qnameid).lnStr.str, sizeof(CharType), GET_LN_URI_QNAME(schema->uriTable, qnameid).lnStr.length, out);
fprintf(out, "\n");
for(ruleIter = 0; ruleIter < gr->count; ruleIter++)
{
fprintf(out, "NT-%d: \n", (int) ruleIter);
for(prodIter = 0; prodIter < gr->rule[ruleIter].pCount; prodIter++)
{
tmpProd = &gr->rule[ruleIter].production[gr->rule[ruleIter].pCount - 1 - prodIter];
if(GET_PROD_EXI_EVENT(tmpProd->content) != EVENT_SE_QNAME && tmpProd->typeId != INDEX_MAX)
exiType = GET_EXI_TYPE(schema->simpleTypeTable.sType[tmpProd->typeId].content);
else
exiType = VALUE_TYPE_NONE;
switch(GET_PROD_EXI_EVENT(tmpProd->content))
{
case EVENT_SD:
fprintf(out, "\tSD ");
break;
case EVENT_ED:
fprintf(out, "\tED ");
break;
case EVENT_SE_QNAME:
fprintf(out, "\tSE ([%d:%d]", (int) tmpProd->qnameId.uriId, (int) tmpProd->qnameId.lnId);
fwrite(schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.str, sizeof(CharType), schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.length, out);
fprintf(out, ":");
fwrite(GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.str, sizeof(CharType), GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.length, out);
fprintf(out, ") ");
break;
case EVENT_SE_URI:
fprintf(out, "\tSE (uri) ");
break;
case EVENT_SE_ALL:
fprintf(out, "\tSE (*) ");
break;
case EVENT_EE:
fprintf(out, "\tEE ");
break;
case EVENT_AT_QNAME:
fprintf(out, "\tAT ([%d:%d]", (int) tmpProd->qnameId.uriId, (int) tmpProd->qnameId.lnId);
fwrite(schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.str, sizeof(CharType), schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.length, out);
fprintf(out, ":");
fwrite(GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.str, sizeof(CharType), GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.length, out);
fprintf(out, ") ");
writeValueTypeString(out, exiType);
break;
case EVENT_AT_URI:
fprintf(out, "\tAT (uri) ");
break;
case EVENT_AT_ALL:
fprintf(out, "\tAT (*) ");
writeValueTypeString(out, exiType);
break;
case EVENT_CH:
fprintf(out, "\tCH ");
writeValueTypeString(out, exiType);
break;
case EVENT_NS:
fprintf(out, "\tNS ");
break;
case EVENT_CM:
fprintf(out, "\tCM ");
break;
case EVENT_PI:
fprintf(out, "\tPI ");
break;
case EVENT_DT:
fprintf(out, "\tDT ");
break;
case EVENT_ER:
fprintf(out, "\tER ");
break;
case EVENT_SC:
fprintf(out, "\tSC ");
break;
case EVENT_VOID:
fprintf(out, " ");
break;
default:
return EXIP_UNEXPECTED_ERROR;
}
if(GET_PROD_NON_TERM(tmpProd->content) != GR_VOID_NON_TERMINAL)
{
fprintf(out, "\tNT-%u\t", (unsigned int) GET_PROD_NON_TERM(tmpProd->content));
}
fprintf(out, "%d\n", (int) prodIter);
}
fprintf(out, "\n");
}
return EXIP_OK;
}
static void writeValueTypeString(FILE* out, EXIType exiType)
{
switch(exiType)
{
case VALUE_TYPE_NONE:
fprintf(out, "[N/A] ");
break;
case VALUE_TYPE_STRING:
fprintf(out, "[str] ");
break;
case VALUE_TYPE_FLOAT:
fprintf(out, "[float] ");
break;
case VALUE_TYPE_DECIMAL:
fprintf(out, "[dec] ");
break;
case VALUE_TYPE_DATE_TIME:
case VALUE_TYPE_YEAR:
case VALUE_TYPE_DATE:
case VALUE_TYPE_MONTH:
case VALUE_TYPE_TIME:
fprintf(out, "[dateTime] ");
break;
case VALUE_TYPE_BOOLEAN:
fprintf(out, "[bool] ");
break;
case VALUE_TYPE_BINARY:
fprintf(out, "[bin] ");
break;
case VALUE_TYPE_LIST:
fprintf(out, "[list] ");
break;
case VALUE_TYPE_QNAME:
fprintf(out, "[qname] ");
break;
case VALUE_TYPE_UNTYPED:
fprintf(out, "[untyped] ");
break;
case VALUE_TYPE_INTEGER:
fprintf(out, "[int] ");
break;
case VALUE_TYPE_SMALL_INTEGER:
fprintf(out, "[short] ");
break;
case VALUE_TYPE_NON_NEGATIVE_INT:
fprintf(out, "[uint] ");
break;
}
}
errorCode recursiveTextGrammarOutput(QNameID qnameid, Index grIndex, EXIGrammar* gr, EXIPSchema* schema, FILE* out)
{
errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
Index r, p;
tmp_err_code = textGrammarOutput(qnameid, grIndex, gr, schema, out);
if(tmp_err_code != EXIP_OK)
return tmp_err_code;
for(r = 0; r < gr->count; r++)
{
for(p = 0; p < gr->rule[r].pCount; p++)
{
if(GET_PROD_EXI_EVENT(gr->rule[r].production[p].content) == EVENT_SE_QNAME &&
gr->rule[r].production[p].typeId != INDEX_MAX)
{
tmp_err_code = recursiveTextGrammarOutput(gr->rule[r].production[p].qnameId, gr->rule[r].production[p].typeId, &schema->grammarTable.grammar[gr->rule[r].production[p].typeId], schema, out);
if(tmp_err_code != EXIP_OK)
return tmp_err_code;
}
}
}
return EXIP_OK;
}