1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
TP-Link_Archer-XR500v/EN7526G_3.18Kernel_SDK/tools/romfile_merge/romfile_merge.c
2024-07-22 01:58:46 -03:00

444 lines
11 KiB
C
Executable File

#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <pthread.h>
#include "romfile_merge.h"
#include "mxml.h"
#define FAIL -1
/*______________________________________________________________________________
** isNode
**
** descriptions:
** Check the name is used for node.
**
** parameters:
** name: Specify the element of name.
**
** return:
** Success: 1
** Otherwise: 0
**____________________________________________________________________________
*/
int
isNode(const char *name){
return 1;
}/* end isNode */
/*______________________________________________________________________________
** whitespace_cb
**
** descriptions:
** Let the mxmlSaveFile() function know when to insert newlines and tabs...
** parameters:
** None
** return:
** Success: newlines
** Otherwise: Null
**____________________________________________________________________________
*/
/*
* 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert
* newlines and tabs...
*/
const char * /* O - Whitespace string or NULL */
whitespace_cb(mxml_node_t *node, /* I - Element node */
int where) /* I - Open or close tag? */
{
mxml_node_t *parent= NULL; /* Parent node */
int level; /* Indentation level */
const char *name= NULL; /* Name of element */
static const char *tabs = "\t\t\t\t\t\t\t\t";
/* Tabs for indentation */
/*
* We can conditionally break to a new line before or after any element.
* These are just common HTML elements...
*/
name = node->value.element.name;
if((where == MXML_WS_BEFORE_OPEN)
|| (isNode(name) && (where ==MXML_WS_BEFORE_CLOSE))){
for (level = -1, parent = node->parent;
parent;
level ++, parent = parent->parent);
if (level > 8){
level = 8;
}
else if (level < 0){
level = 0;
}
return (tabs + 8 - level);
}
else if ((where == MXML_WS_AFTER_CLOSE)
||(isNode(name) && where == MXML_WS_AFTER_OPEN)){
return ("\n");
}
else if (where == MXML_WS_AFTER_OPEN && !node->child){
return ("\n");
}
/*
* Return NULL for no added whitespace...
*/
return (NULL);
}/* end whitespace_cb */
/*______________________________________________________________________________
** load_def_romfile
**
** descriptions:
** To parser default romfile.cfg
**
** parameters:
** file: Specify the file path.
**
** return:
** Success: root of mxml_node_t address
** Otherwise: NULL
**____________________________________________________________________________
*/
mxml_node_t *
load_romfile(char *file){
FILE *fp=NULL;
mxml_node_t *tree=NULL;
char buf[128];
fp = fopen(file,"r");
if(fp == NULL){
fprintf(stderr, OPEN_FAIL_MSG, file, strerror(errno));
return NULL;
}
tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
if(tree == NULL){
fprintf(stderr, DEF_ROMFILE_ERR_MSG);
fclose(fp);
return NULL;
}
fclose(fp);
return tree;
}
int
getOptionFromConfigFile(char* opt,char* configFile)
{
FILE *fp =NULL;
char line[512] = {0};
int rev = 0;
char *ptr = NULL;
fp = fopen(configFile,"r");
if(opt[0] == '!')
{
rev = 1;
opt++;
}
//printf("configFile:%s\n",configFile);
#ifdef DEBUG
printf("rev:%d, macro:%s\n",rev,opt);
#endif
if(fp == NULL)
{
printf("error opening configure file!\n");
exit(1);
}
while(fgets (line, sizeof(line), fp) )
{
ptr = strstr(line,opt);
if(ptr && strstr(ptr+strlen(opt), "y"))
{
fclose(fp);
// printf("SUCESS\n");
if(rev == 0)
return 1;
else
return 0;
}
memset(line, 0, sizeof(line));
}
fclose(fp);
// printf("not found\n");
if(rev == 0)
return 0;
else
return 1;
}
int
parseOption(char *nodeName, char *fileOpt, char *fileConfig)
{
FILE *fpOpt = NULL;
char line[1024] = {0};
char option[8][64];
char compileOpt[256]= {0};
int n, found = 0;
int i;
char *ptmp = NULL;
char tmpopt[34] = {0};
int index = 0;
int mode = 0;
int ret = 0;
int lineNum = 0;
fpOpt = fopen(fileOpt, "r");
if(fpOpt == NULL)
{
printf("error opening file:%s for reading\n", fileOpt);
exit(1);
}
while(fgets (line, sizeof(line) -1, fpOpt) )
{
memset(option, 0, sizeof(option) );
memset(compileOpt, 0, sizeof(compileOpt));
n = sscanf(line, "%s : %s %s %s %s %s %s %s %s", compileOpt,
option[0],option[1],option[2],option[3],option[4],option[5],option[6],option[7]);
#ifdef DEBUG
printf("\ncompileOpt = %s\n", compileOpt);
printf("option[0] = %s\n",option[0]);
printf("option[1] = %s\n",option[1]);
printf("option[2] = %s\n",option[2]);
printf("option[3] = %s\n",option[3]);
printf("option[4] = %s\n",option[4]);
printf("option[5] = %s\n",option[5]);
printf("option[6] = %s\n",option[6]);
printf("option[7] = %s\n",option[7]);
#endif
/* the definition without node name, skip this invalid line */
if(n < 2)
{
printf("Invalid line:%d in config file:%s, n = %d !\n", lineNum, fileOpt, n);
continue;
}
#ifdef DEBUG
printf("n = %d\n", n);
#endif
/*find the node name in the line */
for(i = 0; i < n - 1; i++)
{
if(!strcmp(nodeName, option[i]) )
{
found = 1;
break;
}
#ifdef DEBUG
printf("option[%d] = %s\n", i, option[i]);
#endif
}
/* in case of node is found, parse the compileoption*/
if(found ==1)
{
/* when || is found in the compile option string, parse each of them*/
#ifdef DEBUG
printf("compileOpt = %s\n", &compileOpt[index]);
#endif
while( (ptmp = strstr(&compileOpt[index], "||")) != NULL)
{
#ifdef DEBUG
printf("ptmp = %s\n", ptmp);
#endif
mode = 1;
//ret = 0;
memset(tmpopt, 0, sizeof(tmpopt));
strncpy(tmpopt, &compileOpt[index], ptmp - compileOpt - index);
index = ptmp - compileOpt + 2;
#ifdef DEBUG
printf("ptmp = %s, tmpopt = %s\n", ptmp, tmpopt);
#endif
//ret = ret || (!!getOptionFromConfigFile( tmpopt, fileConfig)) ;
ret = !!getOptionFromConfigFile( tmpopt, fileConfig);
if(ret)
goto out;
}
/* when && is found in the compile option string, parse each of them*/
if(mode == 0)
{
while( (ptmp = strstr(&compileOpt[index], "&&")) != NULL)
{
#ifdef DEBUG
printf("ptmp = %s\n", ptmp);
#endif
mode = 2;
//ret = 1;
memset(tmpopt, 0, sizeof(tmpopt));
strncpy(tmpopt, &compileOpt[index], ptmp - compileOpt - index);
index = ptmp - compileOpt + 2;
#ifdef DEBUG
printf("ptmp = %s, tmpopt = %s\n", ptmp, tmpopt);
#endif
//ret = ret && (!!getOptionFromConfigFile( tmpopt, fileConfig)) ;
ret = !!getOptionFromConfigFile( tmpopt, fileConfig) ;
if(!ret)
goto out;
}
}
/*parse the last compile option, according to defferent mode*/
switch (mode)
{
case 0:
ret = getOptionFromConfigFile(compileOpt, fileConfig);
break;
case 1:
//ret = ret || (!!getOptionFromConfigFile(&compileOpt[index], fileConfig) );
ret = !!getOptionFromConfigFile(&compileOpt[index], fileConfig) ;
#ifdef DEBUG
printf("case 1: &compileOpt[index] = %s\n", &compileOpt[index]);
#endif
break;
case 2:
#ifdef DEBUG
printf("case 2: &compileOpt[index] = %s\n", &compileOpt[index]);
#endif
//ret = ret && (!!getOptionFromConfigFile(&compileOpt[index], fileConfig) );
ret = !!getOptionFromConfigFile(&compileOpt[index], fileConfig) ;
}
fclose(fpOpt);
#ifdef DEBUG
printf("111nodeName = %s, ret = %d, mode = %d!\n", nodeName, ret, mode);
#endif
return ret;
}
memset(line, 0, sizeof(line));
lineNum++;
}
out:
fclose(fpOpt);
#ifdef DEBUG
printf("222nodeName = %s, ret = 1!\n", nodeName);
#endif
return 1;
}
mxml_node_t *
merge_romfile_tree (mxml_node_t *tree_main, mxml_node_t *tree_custom,char *fileOpt, char *fileConfig)
{
mxml_node_t *custom_node = NULL, *main_node = NULL;
mxml_node_t *tmp_node = NULL;
FILE *fp = NULL;
if(tree_main == NULL && tree_custom == NULL)
return NULL;
else if(tree_main == NULL && tree_custom != NULL)
return tree_custom;
else if(tree_main != NULL && tree_custom == NULL)
return tree_main;
custom_node = mxmlWalkNext(tree_custom, tree_custom, MXML_DESCEND);
#ifdef DEBUG
if(custom_node->type == MXML_ELEMENT)
printf("customer_node->value.element.name:%d\n", custom_node->value);
#endif
while(custom_node)
{
if(custom_node->type == MXML_ELEMENT)
{
#ifdef DEBUG
printf("customer_node->value.element.name:%s\n", custom_node->value.element.name);
#endif
}
else
goto this;
#ifdef DEBUG
printf("name:%s\n", custom_node->value.element.name);
#endif
main_node = mxmlFindElement(tree_main, tree_main, custom_node->value.element.name, NULL, NULL, MXML_DESCEND);
if(main_node)
{
#ifdef DEBUG
printf("main name is:%s\n", main_node->value.element.name);
#endif
mxmlDelete(main_node);
}
tmp_node = custom_node;
custom_node = mxmlWalkNext(tmp_node, tree_custom/*parantNode*/, MXML_NO_DESCEND);
mxmlRemove(tmp_node);
mxmlAdd(tree_main, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, tmp_node);
continue;
this:
custom_node = mxmlWalkNext(custom_node, tree_custom/*parantNode*/, MXML_NO_DESCEND);
}
main_node = mxmlWalkNext(tree_main, tree_main, MXML_DESCEND);
#ifdef DEBUG
if(main_node->type == MXML_ELEMENT)
printf("main_node->value.element.name:%d\n", main_node->value);
#endif
while(main_node)
{
int optFound = 0;
if(main_node->type == MXML_ELEMENT)
{
#ifdef DEBUG
printf("main_node->value.element.name:%s\n", main_node->value.element.name);
#endif
}
else
goto that;
optFound = parseOption(main_node->value.element.name, fileOpt, fileConfig);
#ifdef DEBUG
if(optFound)
printf("name:%s found!\n", main_node->value.element.name);
else
printf("name:%s not found!\n", main_node->value.element.name);
#endif
if(optFound == 0)
{
tmp_node = main_node;
main_node = mxmlWalkNext(tmp_node, tree_main/*parantNode*/, MXML_NO_DESCEND);
mxmlDelete(tmp_node);
continue;
}
that:
main_node = mxmlWalkNext(main_node, tree_main/*parantNode*/, MXML_NO_DESCEND);
}
return tree_main;
}
int
main(int argc, char* argv[])
{
mxml_node_t *tree_main = NULL, *tree_custom = NULL;
mxml_node_t *tree_save = NULL;
FILE *fp= NULL;
int retval = 0;
tree_main = load_romfile(argv[1]);
tree_custom = load_romfile(argv[2]);
tree_save = merge_romfile_tree( tree_main, tree_custom, argv[4], argv[5] );
fp = fopen(argv[3], "w");
if(fp == NULL || tree_save == NULL){
if(fp)
fclose(fp);
return FAIL;
}
else{
retval = mxmlSaveFile(tree_save, fp, whitespace_cb);
fclose(fp);
}
return retval;
}