main.c
来自「gaca源码」· C语言 代码 · 共 1,280 行 · 第 1/3 页
C
1,280 行
}
fprintf(vrml_code, "\treturn (GF_Node *)p;\n}\n\n");
}
fprintf(vrml_code, "\n\n\n");
//creator function
fprintf(vrml_code, "GF_Node *gf_sg_x3d_node_new(u32 NodeTag)\n{\n\tswitch (NodeTag) {\n");
for (i=0; i<gf_list_count(BNodes); i++) {
n = gf_list_get(BNodes, i);
if (!n->skip_impl) fprintf(vrml_code, "\tcase TAG_X3D_%s:\n\t\treturn %s_Create();\n", n->name, n->name);
}
fprintf(vrml_code, "\tdefault:\n\t\treturn NULL;\n\t}\n}\n\n");
fprintf(vrml_code, "#ifndef GF_NODE_USE_POINTERS\n");
fprintf(vrml_code, "const char *gf_sg_x3d_node_get_class_name(u32 NodeTag)\n{\n\tswitch (NodeTag) {\n");
for (i=0; i<gf_list_count(BNodes); i++) {
n = gf_list_get(BNodes, i);
if (!n->skip_impl) fprintf(vrml_code, "\tcase TAG_X3D_%s:\n\t\treturn \"%s\";\n", n->name, n->name);
}
fprintf(vrml_code, "\tdefault:\n\t\treturn \"Unknown Node\";\n\t}\n}\n\n");
fprintf(vrml_code, "void gf_sg_x3d_node_del(GF_Node *node)\n{\n\tswitch (node->sgprivate->tag) {\n");
for (i=0; i<gf_list_count(BNodes); i++) {
n = gf_list_get(BNodes, i);
if (!n->skip_impl) fprintf(vrml_code, "\tcase TAG_X3D_%s:\n\t\t%s_Del(node); return;\n", n->name, n->name);
}
fprintf(vrml_code, "\tdefault:\n\t\treturn;\n\t}\n}\n\n");
fprintf(vrml_code, "u32 gf_sg_x3d_node_get_field_count(GF_Node *node)\n{\n\tswitch (node->sgprivate->tag) {\n");
for (i=0; i<gf_list_count(BNodes); i++) {
n = gf_list_get(BNodes, i);
if (!n->skip_impl) fprintf(vrml_code, "\tcase TAG_X3D_%s:return %s_get_field_count(node, 0);\n", n->name, n->name);
}
fprintf(vrml_code, "\tdefault:\n\t\treturn 0;\n\t}\n}\n\n");
fprintf(vrml_code, "GF_Err gf_sg_x3d_node_get_field(GF_Node *node, GF_FieldInfo *field)\n{\n\tswitch (node->sgprivate->tag) {\n");
for (i=0; i<gf_list_count(BNodes); i++) {
n = gf_list_get(BNodes, i);
if (!n->skip_impl) fprintf(vrml_code, "\tcase TAG_X3D_%s: return %s_get_field(node, field);\n", n->name, n->name);
}
fprintf(vrml_code, "\tdefault:\n\t\treturn GF_BAD_PARAM;\n\t}\n}\n\n");
fprintf(vrml_code, "\n#endif\n\n");
fprintf(vrml_code, "\nu32 gf_node_x3d_type_by_class_name(const char *node_name)\n{\n\tif(!node_name) return 0;\n");
for (i=0; i<gf_list_count(BNodes); i++) {
n = gf_list_get(BNodes, i);
if (!n->skip_impl) fprintf(vrml_code, "\tif (!strcmp(node_name, \"%s\")) return TAG_X3D_%s;\n", n->name, n->name);
}
fprintf(vrml_code, "\treturn 0;\n}\n\n");
}
static u32 IsNodeInTable(X3DNode *node, char *NDTName)
{
u32 i;
char *ndt;
for (i=0; i<gf_list_count(node->NDT); i++) {
ndt = gf_list_get(node->NDT, i);
if (!strcmp(ndt, NDTName)) return 1;
}
return 0;
}
static u32 GetNDTCount(char *NDTName, GF_List *XNodes)
{
u32 i, nodeCount;
X3DNode *n;
nodeCount = 0;
for (i=0; i<gf_list_count(XNodes); i++) {
n = gf_list_get(XNodes, i);
if (!IsNodeInTable(n, NDTName)) continue;
nodeCount++;
}
return nodeCount;
}
/*write NDTs*/
void WriteNDT(FILE *f, GF_List *XNodes, GF_List *NDTs)
{
u32 i, j, count;
Bool first;
X3DNode *n;
char *NDTName;
fprintf(f, "\n\n/* NDT X3D */\n\n");
//for all NDTs
for (i=0; i<gf_list_count(NDTs); i++) {
NDTName = gf_list_get(NDTs, i);
count = GetNDTCount(NDTName, XNodes);
if (!count) continue;
fprintf(f, "#define %s_X3D_Count\t%d\n", NDTName, count);
fprintf(f, "static const u32 %s_X3D_TypeToTag[%d] = {\n", NDTName, count);
first = 1;
//browse each node.
for (j=0; j<gf_list_count(XNodes); j++) {
n = gf_list_get(XNodes, j);
if (!IsNodeInTable(n, NDTName)) continue;
if (first) {
fprintf(f, " TAG_X3D_%s", n->name);
first = 0;
} else {
fprintf(f, ", TAG_X3D_%s", n->name);
}
}
fprintf(f, "\n};\n\n");
}
//NodeTag complete translation
fprintf(f, "\n\n\nBool X3D_IsNodeInTable(u32 NDT_Tag, u32 NodeTag)\n{\n\tconst u32 *types;\n\tu32 count, i;\n\tif (!NodeTag) return 0;\n\ttypes = NULL; count = 0;\n");
fprintf(f, "\tswitch (NDT_Tag) {\n");
for (i=0; i<gf_list_count(NDTs); i++) {
NDTName = gf_list_get(NDTs, i);
count = GetNDTCount(NDTName, XNodes);
if (!count) continue;
fprintf(f, "\tcase NDT_%s:\n\t\ttypes = %s_X3D_TypeToTag; count = %s_X3D_Count; break;\n", NDTName, NDTName, NDTName);
}
fprintf(f, "\tdefault:\n\t\treturn 0;\n\t}\n");
fprintf(f, "\tfor(i=0; i<count; i++) { if (types[i]==NodeTag) return 1;}\n");
fprintf(f, "\treturn 0;\n}\n");
}
void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs)
{
char sLine[2000];
char token[100];
char *p;
X3DNode *n;
X3DField *f;
u32 j, i, k;
//get lines one by one
n = NULL;
while (!feof(nodes)) {
fgets(sLine, 2000, nodes);
//skip comment and empty lines
if (sLine[0] == '#') continue;
if (sLine[0] == '\n') continue;
CurrentLine = sLine;
//parse the line till end of line
while (GetNextToken(token, " \t")) {
//this is a new node
if (!strcmp(token, "PROTO") ) {
n = BlankNode();
gf_list_add(BNodes, n);
//get its name
GetNextToken(n->name, " \t[");
//extract the NDTs
GetNextToken(token, "\t[ %#=");
if (strcmp(token, "NDT")) {
printf("Corrupted template file\n");
return;
}
while (1) {
GetNextToken(token, "=, \t");
//done with NDTs
if (!token[0]) break;
//update the NDT list
CheckInTable(token, NDTs);
p = malloc(strlen(token)+1);
strcpy(p, token);
gf_list_add(n->NDT, p);
}
}
//this is NOT a field
else if (token[0] == ']' || token[0] == '{' || token[0] == '}' ) {
break;
}
//parse a field
else {
if (!n) {
printf("Corrupted template file\n");
return;
}
f = BlankField();
gf_list_add(n->Fields, f);
//get the field type
strcpy(f->type, token);
GetNextToken(f->familly, " \t");
GetNextToken(f->name, " \t");
//fix for our own code :(
if (!strcmp(f->name, "tag")) strcpy(f->name, "_tag");
//has default
skip_sep(" \t");
if (GetNextToken(token, "#\t")) {
j=0;
while (token[j] == ' ') j+=1;
if (token[j] == '[') j+=1;
if (token[j] == '"') j+=1;
if (token[j] != '"' && token[j] != ']') {
strcpy(f->def, token+j);
j=1;
while (j) {
switch (f->def[strlen(f->def)-1]) {
case ' ':
case '"':
case ']':
f->def[strlen(f->def)-1] = 0;
break;
default:
j=0;
break;
}
}
} else {
strcpy(f->def, "");
}
if (!strcmp(f->familly, "SFFloat")) {
if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) {
strcpy(f->def, "GF_MAX_FLOAT");
} else if (!strcmp(f->def, "-I")) {
strcpy(f->def, "GF_MIN_FLOAT");
}
} else if (!strcmp(f->familly, "SFTime")) {
if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) {
strcpy(f->def, "GF_MAX_FLOAT");
} else if (!strcmp(f->def, "-I")) {
strcpy(f->def, "GF_MIN_FLOAT");
}
} else if (!strcmp(f->familly, "SFInt32")) {
if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) {
strcpy(f->def, "2 << 31");
} else if (!strcmp(f->def, "-I")) {
strcpy(f->def, "- (2 << 31)");
}
}
}
//has other
while (GetNextToken(token, " \t#%=")) {
switch (token[0]) {
//bounds
case 'b':
case 'q':
case 'a':
printf("Corrupted X3D template file (quantization/animation not allowed)\n");
gf_list_del_item(n->Fields, f);
free(f);
return;
default:
break;
}
}
/*we ignore these*/
if (!stricmp(f->name, "bboxCenter") || !stricmp(f->name, "bboxSize")) {
gf_list_del_item(n->Fields, f);
free(f);
}
}
}
}
for (k=0; k<gf_list_count(BNodes); k++) {
n = gf_list_get(BNodes, k);
for (i=0; i<gf_list_count(n->Fields); i++) {
f = gf_list_get(n->Fields, i);
//nothing on events
if (!strcmp(f->type, "eventIn")) continue;
if (!strcmp(f->type, "eventOut")) continue;
if (!strcmp(f->def, "")) continue;
if (strstr(f->familly, "Node")) continue;
n->hasDefault = 1;
}
}
}
void WriteNodeDump(FILE *f, X3DNode *n)
{
X3DField *bf;
u32 i;
fprintf(f, "static const char *%s_FieldName[] = {\n", n->name);
for (i=0; i<gf_list_count(n->Fields); i++) {
bf = gf_list_get(n->Fields, i);
if (!i) {
fprintf(f, " \"%s\"", bf->name);
} else {
fprintf(f, ", \"%s\"", bf->name);
}
}
fprintf(f, "\n};\n\n");
}
void parse_profile(GF_List *nodes, FILE *prof)
{
char sLine[2000];
X3DNode *n;
Bool found;
u32 i;
while (!feof(prof)) {
fgets(sLine, 2000, prof);
//skip comment and empty lines
if (sLine[0] == '#') continue;
if (sLine[0] == '\n') continue;
if (strstr(sLine, "Proximity"))
found = 0;
found = 1;
while (found) {
switch (sLine[strlen(sLine)-1]) {
case '\n':
case '\r':
case ' ':
sLine[strlen(sLine)-1] = 0;
break;
default:
found = 0;
break;
}
}
if (0) {
printf("Warning: cannot disable node %s (required in all BIFS profiles)\n", sLine);
} else {
found = 0;
for (i=0; i<gf_list_count(nodes); i++) {
n = gf_list_get(nodes, i);
if (!stricmp(n->name, sLine)) {
n->skip_impl = 1;
found = 1;
break;
}
}
if (!found) printf("cannot disable %s: node not found\n", sLine);
}
}
}
int main (int argc, char **argv)
{
FILE *nodes, *pf;
GF_List *XNodes, *NDTs;
X3DNode *n;
X3DField *bf;
u32 nb_nodes, nb_imp;
nodes = fopen("templates_X3D.txt", "rt");
if (!nodes) {
fprintf(stdout, "cannot open \"templates_X3D.txt\" - aborting\n");
return 0;
}
XNodes = gf_list_new();
NDTs = gf_list_new();
//all nodes are in the same list but we keep version info
ParseTemplateFile(nodes, XNodes, NDTs);
fclose(nodes);
if (argc>1) {
pf = fopen(argv[1], "rt");
if (!pf) fprintf(stdout, "Cannot open profile file %s\n", argv[1]);
else {
parse_profile(XNodes, pf);
fclose(pf);
}
}
//write the nodes def
WriteNodesFile(XNodes, NDTs);
nodes = BeginFile(1);
//write all nodes init stuff
WriteNodeCode(XNodes, nodes);
WriteNDT(nodes, XNodes, NDTs);
EndFile(nodes, 1);
//free NDTs
while (gf_list_count(NDTs)) {
char *tmp = gf_list_get(NDTs, 0);
free(tmp);
gf_list_rem(NDTs, 0);
}
gf_list_del(NDTs);
nb_nodes = gf_list_count(XNodes);
nb_imp = 0;
//free nodes
while (gf_list_count(XNodes)) {
n = gf_list_get(XNodes, 0);
if (!n->skip_impl) nb_imp++;
gf_list_rem(XNodes, 0);
while (gf_list_count(n->NDT)) {
char *tmp = gf_list_get(n->NDT, 0);
free(tmp);
gf_list_rem(n->NDT, 0);
}
gf_list_del(n->NDT);
while (gf_list_count(n->Fields)) {
bf = gf_list_get(n->Fields, 0);
free(bf);
gf_list_rem(n->Fields, 0);
}
gf_list_del(n->Fields);
free(n);
}
gf_list_del(XNodes);
fprintf(stdout, "Generation done: %d nodes implemented (%d nodes total)\n", nb_imp, nb_nodes);
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?