xml_maker.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  1. /*
  2. * xml_maker.c
  3. *
  4. * 配置目标文件转换程序
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stddef.h>
  10. #include <ctype.h>
  11. #include "elf.c"
  12. typedef struct
  13. {
  14. char e_name [64];
  15. char e_title[128];
  16. unsigned e_items;
  17. char e_refer[64];
  18. char e_attr [128];
  19. char comment[128];
  20. } enum_type_t;
  21. typedef struct
  22. {
  23. char m_name [64];
  24. char m_title[128];
  25. unsigned m_value;
  26. char m_refer[64];
  27. char m_attr [128];
  28. char comment[128];
  29. } enum_item_t;
  30. typedef struct
  31. {
  32. char s_name [64];
  33. char s_title[128];
  34. unsigned s_size;
  35. unsigned s_items;
  36. char s_refer[64];
  37. char s_attr [128];
  38. char comment[128];
  39. } struct_type_t;
  40. typedef struct
  41. {
  42. char m_type [64];
  43. char m_name [64];
  44. char m_title[128];
  45. unsigned m_offs;
  46. unsigned m_size;
  47. unsigned m_array;
  48. char m_refer[64];
  49. char m_range[64];
  50. char m_attr [128];
  51. char comment[128];
  52. } struct_item_t;
  53. typedef struct
  54. {
  55. unsigned cfg_id;
  56. char c_name [64];
  57. char c_title[128];
  58. unsigned c_size;
  59. unsigned c_items;
  60. char c_refer[64];
  61. char c_attr [128];
  62. char comment[128];
  63. } class_type_t;
  64. typedef struct
  65. {
  66. char m_type [64];
  67. char m_name [64];
  68. char m_title[128];
  69. unsigned m_offs;
  70. unsigned m_size;
  71. unsigned m_array;
  72. char m_refer[64];
  73. char m_range[64];
  74. char m_attr [128];
  75. char comment[128];
  76. } class_item_t;
  77. typedef struct
  78. {
  79. u8_t format[4];
  80. u8_t magic [4];
  81. u16_t user_version;
  82. u8_t minor_version;
  83. u8_t major_version;
  84. u16_t total_size;
  85. u16_t num_cfgs;
  86. } config_header_t;
  87. typedef struct
  88. {
  89. u8_t cfg_id;
  90. u8_t sub_pos;
  91. u8_t cfg_size;
  92. } config_info_t;
  93. typedef struct
  94. {
  95. u32_t cfg_id:8;
  96. u32_t sub_pos:12;
  97. u32_t cfg_size:12;
  98. } config_info_new_t;
  99. typedef struct
  100. {
  101. char* obj_file;
  102. char* xml_file;
  103. char* version;
  104. int start_cfg_id;
  105. } xml_maker_t;
  106. static xml_maker_t xml_maker;
  107. static int get_args(int argc, char* argv[])
  108. {
  109. xml_maker_t* p = &xml_maker;
  110. if (!(argc == 4 || argc == 5))
  111. goto err;
  112. p->obj_file = argv[1];
  113. p->xml_file = argv[2];
  114. p->version = argv[3];
  115. //set start cfg_id if passed
  116. p->start_cfg_id = 0;
  117. if (argc == 5)
  118. p->start_cfg_id = strtol(argv[4], NULL, 16);
  119. return 0;
  120. err:
  121. printf(" usage: xml_maker.exe obj_file xml_file version [id]\n");
  122. return -1;
  123. }
  124. static int get_symbol_type(elf_obj_t* obj, Elf_Sym* sym, char* type)
  125. {
  126. char* name;
  127. if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT ||
  128. ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
  129. return -1;
  130. if (sym->st_shndx == SHN_UNDEF)
  131. return -1;
  132. name = &obj->strtab[sym->st_name];
  133. if (strncmp(name, type, strlen(type)) == 0)
  134. return 1;
  135. return -1;
  136. }
  137. static void* get_object_data(elf_obj_t* obj, Elf_Sym* sym)
  138. {
  139. Elf_Shdr* shdr;
  140. void* cfg_data = malloc(sym->st_size);
  141. memset(cfg_data, 0, sym->st_size);
  142. shdr = &obj->shdrtab[sym->st_shndx];
  143. fseek(obj->file, shdr->sh_offset + sym->st_value, SEEK_SET);
  144. fread(cfg_data, 1, sym->st_size, obj->file);
  145. return cfg_data;
  146. }
  147. static int get_config_id(elf_obj_t* obj, Elf_Sym* sym)
  148. {
  149. int cfg_id = -1;
  150. char* name;
  151. name = &obj->strtab[sym->st_name];
  152. if (sscanf(&name[strlen("class_")], "%x", &cfg_id) != 1)
  153. return -1;
  154. return cfg_id;
  155. }
  156. static int get_config_num(elf_obj_t* obj)
  157. {
  158. int num = 0;
  159. int i;
  160. for (i = 0; i < obj->num_syms; i++)
  161. {
  162. Elf_Sym* sym = &obj->symtab[i];
  163. if (get_symbol_type(obj, sym, "class_") > 0)
  164. num += 1;
  165. }
  166. return num;
  167. }
  168. static void* get_config_data(elf_obj_t* obj, int cfg_id)
  169. {
  170. int i;
  171. for (i = 0; i < obj->num_syms; i++)
  172. {
  173. Elf_Sym* sym = &obj->symtab[i];
  174. if (get_symbol_type(obj, sym, "class_") > 0)
  175. {
  176. if (get_config_id(obj, sym) == cfg_id)
  177. {
  178. return get_object_data(obj, sym);
  179. }
  180. }
  181. }
  182. printf(" failed %s: 0x%02X\n", __FUNCTION__, cfg_id);
  183. exit(EXIT_FAILURE);
  184. return NULL;
  185. }
  186. static int is_mbc_utf8(u8_t* data)
  187. {
  188. if ((data[0] & 0xE0) == 0xC0 &&
  189. (data[1] & 0xC0) == 0x80)
  190. {
  191. return 2;
  192. }
  193. if ((data[0] & 0xF0) == 0xE0 &&
  194. (data[1] & 0xC0) == 0x80 &&
  195. (data[2] & 0xC0) == 0x80)
  196. {
  197. return 3;
  198. }
  199. return 0;
  200. }
  201. static int get_string_width(const char* s)
  202. {
  203. u8_t* t = (u8_t*)s;
  204. int w = 0;
  205. while (*t != '\0')
  206. {
  207. int n = is_mbc_utf8(t);
  208. if (n > 0)
  209. {
  210. t += n;
  211. w += 2;
  212. }
  213. else
  214. {
  215. t += 1;
  216. w += 1;
  217. }
  218. }
  219. return w;
  220. }
  221. static int get_width(unsigned data, int type)
  222. {
  223. char sbuf[16];
  224. int width;
  225. if (type == 's')
  226. width = get_string_width((char*)data);
  227. else if (type == 'x')
  228. width = sprintf(sbuf, "0x%x", data);
  229. else if (type == 'u')
  230. width = sprintf(sbuf, "%u", data);
  231. else
  232. width = sprintf(sbuf, "%d", (int)data);
  233. return width;
  234. }
  235. static int get_align(void* array, int size, int count, int offs, int type)
  236. {
  237. int align = 0;
  238. int i;
  239. for (i = 0; i < count; i++)
  240. {
  241. void* data = (char*)array + i * size + offs;
  242. int len;
  243. if (type == 's')
  244. len = get_string_width(data);
  245. else
  246. len = get_width(*(unsigned*)data, type);
  247. if (align < len)
  248. align = len;
  249. }
  250. return (align + 1);
  251. }
  252. static int get_file_size(elf_obj_t* obj, int num_cfgs, int start_cfg_id)
  253. {
  254. int size;
  255. int i;
  256. size = sizeof(config_header_t) + num_cfgs * sizeof(config_info_new_t);
  257. for (i = 0; i < num_cfgs; i++)
  258. {
  259. void* data = get_config_data(obj, start_cfg_id + i);
  260. char* t;
  261. class_type_t* c_type = data;
  262. if ((t = strstr(c_type->c_attr, "fixed_size=")) != NULL)
  263. {
  264. c_type->c_size = strtol(t + 11, NULL, 0);
  265. }
  266. size += c_type->c_size;
  267. free(data);
  268. }
  269. return size;
  270. }
  271. #define get_align_e(_m, _t) \
  272. \
  273. get_align(e_items, sizeof(enum_item_t), e_type->e_items, offsetof(enum_item_t, _m), _t)
  274. #define get_align_s(_m, _t) \
  275. \
  276. get_align(s_items, sizeof(struct_item_t), s_type->s_items, offsetof(struct_item_t, _m), _t)
  277. #define get_align_c(_m, _t) \
  278. \
  279. get_align(c_items, sizeof(class_item_t), c_type->c_items, offsetof(class_item_t, _m), _t)
  280. #define make_align(_x, _m, _t) \
  281. do \
  282. { \
  283. int _a = get_align_##_x(_m, _t); \
  284. \
  285. out_len += sprintf(&out_buf[out_len], \
  286. "%*c", \
  287. _a - get_width((unsigned)item->_m, _t), \
  288. ' '); \
  289. } \
  290. while (0)
  291. static int make_category(elf_obj_t* obj, Elf_Sym* sym, char* out_buf)
  292. {
  293. void* data = get_object_data(obj, sym);
  294. enum_type_t* e_type = data;
  295. enum_item_t* e_items = (void*)((char*)data + sizeof(enum_type_t));
  296. int i;
  297. int out_len = 0;
  298. int hide = 0;
  299. for (i = 0; i < e_type->e_items; i++)
  300. {
  301. enum_item_t* item = &e_items[i];
  302. if (strstr(item->m_attr, "hide") != NULL)
  303. hide += 1;
  304. }
  305. out_len += sprintf(&out_buf[out_len],
  306. "<category num_items=\"%u\">\r\n",
  307. e_type->e_items - hide);
  308. for (i = 0; i < e_type->e_items; i++)
  309. {
  310. enum_item_t* item = &e_items[i];
  311. if (strstr(item->m_attr, "hide") != NULL)
  312. continue;
  313. out_len += sprintf(&out_buf[out_len],
  314. "\t<item name=\"%s\"",
  315. item->m_name);
  316. make_align(e, m_name, 's');
  317. out_len += sprintf(&out_buf[out_len],
  318. "title=\"%s\"",
  319. item->m_title);
  320. make_align(e, m_title, 's');
  321. out_len += sprintf(&out_buf[out_len],
  322. "parent=\"%s\"",
  323. item->m_refer);
  324. make_align(e, m_refer, 's');
  325. if (item->m_attr[0] != '\0')
  326. {
  327. out_len += sprintf(&out_buf[out_len],
  328. "attr=\"%s\" ",
  329. item->m_attr);
  330. }
  331. if (item->comment[0] != '\0')
  332. {
  333. out_len += sprintf(&out_buf[out_len],
  334. "comment=\"%s\" ",
  335. item->comment);
  336. }
  337. out_len += sprintf(&out_buf[out_len],
  338. "/>\r\n");
  339. }
  340. out_len += sprintf(&out_buf[out_len],
  341. "</category>\r\n"
  342. "\r\n");
  343. free(data);
  344. return out_len;
  345. }
  346. static int make_enum(elf_obj_t* obj, Elf_Sym* sym, char* out_buf)
  347. {
  348. void* data = get_object_data(obj, sym);
  349. enum_type_t* e_type = data;
  350. enum_item_t* e_items = (void*)((char*)data + sizeof(enum_type_t));
  351. int i;
  352. int out_len = 0;
  353. int hide = 0;
  354. if (strcasecmp(e_type->e_name, "category") == 0)
  355. {
  356. return make_category(obj, sym, out_buf);
  357. }
  358. for (i = 0; i < e_type->e_items; i++)
  359. {
  360. enum_item_t* item = &e_items[i];
  361. if (strstr(item->m_attr, "hide") != NULL)
  362. hide += 1;
  363. }
  364. out_len += sprintf(&out_buf[out_len],
  365. "<enum name=\"%s\" title=\"%s\" num_items=\"%u\"",
  366. e_type->e_name,
  367. e_type->e_title,
  368. e_type->e_items - hide);
  369. if (e_type->e_attr[0] != '\0')
  370. {
  371. out_len += sprintf(&out_buf[out_len],
  372. " attr=\"%s\"",
  373. e_type->e_attr);
  374. }
  375. if (e_type->comment[0] != '\0')
  376. {
  377. out_len += sprintf(&out_buf[out_len],
  378. " comment=\"%s\"",
  379. e_type->comment);
  380. }
  381. out_len += sprintf(&out_buf[out_len],
  382. ">\r\n");
  383. for (i = 0; i < e_type->e_items; i++)
  384. {
  385. enum_item_t* item = &e_items[i];
  386. if (strstr(item->m_attr, "hide") != NULL)
  387. continue;
  388. out_len += sprintf(&out_buf[out_len],
  389. "\t<item name=\"%s\"",
  390. item->m_name);
  391. make_align(e, m_name, 's');
  392. out_len += sprintf(&out_buf[out_len],
  393. "title=\"%s\"",
  394. item->m_title);
  395. make_align(e, m_title, 's');
  396. out_len += sprintf(&out_buf[out_len],
  397. "value=\"0x%x\"",
  398. item->m_value);
  399. make_align(e, m_value, 'x');
  400. if (item->m_attr[0] != '\0')
  401. {
  402. out_len += sprintf(&out_buf[out_len],
  403. "attr=\"%s\" ",
  404. item->m_attr);
  405. }
  406. if (item->comment[0] != '\0')
  407. {
  408. out_len += sprintf(&out_buf[out_len],
  409. "comment=\"%s\" ",
  410. item->comment);
  411. }
  412. out_len += sprintf(&out_buf[out_len],
  413. "/>\r\n");
  414. }
  415. out_len += sprintf(&out_buf[out_len],
  416. "</enum>\r\n"
  417. "\r\n");
  418. free(data);
  419. return out_len;
  420. }
  421. static int make_struct(elf_obj_t* obj, Elf_Sym* sym, char* out_buf)
  422. {
  423. void* data = get_object_data(obj, sym);
  424. struct_type_t* s_type = data;
  425. struct_item_t* s_items = (void*)((char*)data + sizeof(struct_type_t));
  426. int i;
  427. int out_len = 0;
  428. int hide = 0;
  429. for (i = 0; i < s_type->s_items; i++)
  430. {
  431. struct_item_t* item = &s_items[i];
  432. if (strstr(item->m_attr, "hide") != NULL)
  433. hide += 1;
  434. }
  435. out_len += sprintf(&out_buf[out_len],
  436. "<struct name=\"%s\" title=\"%s\" size=\"%u\" num_items=\"%u\"",
  437. s_type->s_name,
  438. s_type->s_title,
  439. s_type->s_size,
  440. s_type->s_items - hide);
  441. if (s_type->s_attr[0] != '\0')
  442. {
  443. out_len += sprintf(&out_buf[out_len],
  444. " attr=\"%s\"",
  445. s_type->s_attr);
  446. }
  447. if (s_type->comment[0] != '\0')
  448. {
  449. out_len += sprintf(&out_buf[out_len],
  450. " comment=\"%s\"",
  451. s_type->comment);
  452. }
  453. out_len += sprintf(&out_buf[out_len],
  454. ">\r\n");
  455. for (i = 0; i < s_type->s_items; i++)
  456. {
  457. struct_item_t* item = &s_items[i];
  458. int align;
  459. int a, b;
  460. if (strstr(item->m_attr, "hide") != NULL)
  461. continue;
  462. out_len += sprintf(&out_buf[out_len],
  463. "\t<item type=\"%s\"",
  464. item->m_type);
  465. make_align(s, m_type, 's');
  466. out_len += sprintf(&out_buf[out_len],
  467. "name=\"%s\"",
  468. item->m_name);
  469. make_align(s, m_name, 's');
  470. out_len += sprintf(&out_buf[out_len],
  471. "title=\"%s\"",
  472. item->m_title);
  473. make_align(s, m_title, 's');
  474. out_len += sprintf(&out_buf[out_len],
  475. "offs=\"%u\"",
  476. item->m_offs);
  477. make_align(s, m_offs, 'u');
  478. out_len += sprintf(&out_buf[out_len],
  479. "size=\"%u\"",
  480. item->m_size);
  481. make_align(s, m_size, 'u');
  482. a = get_align_s(m_refer, 's');
  483. b = get_align_s(m_range, 's');
  484. align = (a > b) ? a : b;
  485. if (item->m_refer[0] != '\0')
  486. {
  487. out_len += sprintf(&out_buf[out_len],
  488. "refer=\"%s\"",
  489. item->m_refer);
  490. out_len += sprintf(&out_buf[out_len],
  491. "%*c",
  492. align - strlen(item->m_refer),
  493. ' ');
  494. }
  495. else
  496. {
  497. out_len += sprintf(&out_buf[out_len],
  498. "range=\"%s\"",
  499. item->m_range);
  500. out_len += sprintf(&out_buf[out_len],
  501. "%*c",
  502. align - strlen(item->m_range),
  503. ' ');
  504. }
  505. if (strcasecmp(item->m_type, "string") == 0)
  506. {
  507. out_len += sprintf(&out_buf[out_len],
  508. "max_len=\"%u\" ",
  509. item->m_array);
  510. }
  511. else if (item->m_array > 1)
  512. {
  513. out_len += sprintf(&out_buf[out_len],
  514. "array=\"%u\" ",
  515. item->m_array);
  516. }
  517. if (item->m_attr[0] != '\0')
  518. {
  519. out_len += sprintf(&out_buf[out_len],
  520. "attr=\"%s\" ",
  521. item->m_attr);
  522. }
  523. if (item->comment[0] != '\0')
  524. {
  525. out_len += sprintf(&out_buf[out_len],
  526. "comment=\"%s\" ",
  527. item->comment);
  528. }
  529. out_len += sprintf(&out_buf[out_len],
  530. "/>\r\n");
  531. }
  532. out_len += sprintf(&out_buf[out_len],
  533. "</struct>\r\n"
  534. "\r\n");
  535. free(data);
  536. return out_len;
  537. }
  538. static int make_config(void* data, int* offs, char* out_buf)
  539. {
  540. class_type_t* c_type = data;
  541. class_item_t* c_items = (void*)((char*)data + sizeof(class_type_t));
  542. int i;
  543. int out_len = 0;
  544. int hide = 0;
  545. if (strstr(c_type->c_attr, "hide") != NULL)
  546. {
  547. goto end;
  548. }
  549. for (i = 0; i < c_type->c_items; i++)
  550. {
  551. class_item_t* item = &c_items[i];
  552. if (strstr(item->m_attr, "hide") != NULL)
  553. hide += 1;
  554. }
  555. out_len += sprintf(&out_buf[out_len],
  556. "<config name=\"%s\" title=\"%s\" cfg_id=\"0x%02X\" offs=\"0x%x\" size=\"%u\" num_items=\"%u\" category=\"%s\"",
  557. c_type->c_name,
  558. c_type->c_title,
  559. c_type->cfg_id,
  560. *offs,
  561. c_type->c_size,
  562. c_type->c_items - hide,
  563. c_type->c_refer);
  564. if (c_type->c_attr[0] != '\0')
  565. {
  566. out_len += sprintf(&out_buf[out_len],
  567. " attr=\"%s\"",
  568. c_type->c_attr);
  569. }
  570. if (c_type->comment[0] != '\0')
  571. {
  572. out_len += sprintf(&out_buf[out_len],
  573. " comment=\"%s\"",
  574. c_type->comment);
  575. }
  576. out_len += sprintf(&out_buf[out_len],
  577. ">\r\n");
  578. for (i = 0; i < c_type->c_items; i++)
  579. {
  580. class_item_t* item = &c_items[i];
  581. int align;
  582. int a, b;
  583. if (strstr(item->m_attr, "hide") != NULL)
  584. continue;
  585. out_len += sprintf(&out_buf[out_len],
  586. "\t<item type=\"%s\"",
  587. item->m_type);
  588. make_align(c, m_type, 's');
  589. out_len += sprintf(&out_buf[out_len],
  590. "name=\"%s\"",
  591. item->m_name);
  592. make_align(c, m_name, 's');
  593. out_len += sprintf(&out_buf[out_len],
  594. "title=\"%s\"",
  595. item->m_title);
  596. make_align(c, m_title, 's');
  597. out_len += sprintf(&out_buf[out_len],
  598. "offs=\"%u\"",
  599. item->m_offs);
  600. make_align(c, m_offs, 'u');
  601. out_len += sprintf(&out_buf[out_len],
  602. "size=\"%u\"",
  603. item->m_size);
  604. make_align(c, m_size, 'u');
  605. a = get_align_c(m_refer, 's');
  606. b = get_align_c(m_range, 's');
  607. align = (a > b) ? a : b;
  608. if (item->m_refer[0] != '\0')
  609. {
  610. out_len += sprintf(&out_buf[out_len],
  611. "refer=\"%s\"",
  612. item->m_refer);
  613. out_len += sprintf(&out_buf[out_len],
  614. "%*c",
  615. align - strlen(item->m_refer),
  616. ' ');
  617. }
  618. else
  619. {
  620. out_len += sprintf(&out_buf[out_len],
  621. "range=\"%s\"",
  622. item->m_range);
  623. out_len += sprintf(&out_buf[out_len],
  624. "%*c",
  625. align - strlen(item->m_range),
  626. ' ');
  627. }
  628. if (strcasecmp(item->m_type, "string") == 0)
  629. {
  630. out_len += sprintf(&out_buf[out_len],
  631. "max_len=\"%u\" ",
  632. item->m_array);
  633. }
  634. else if (item->m_array > 1)
  635. {
  636. out_len += sprintf(&out_buf[out_len],
  637. "array=\"%u\" ",
  638. item->m_array);
  639. }
  640. if (item->m_attr[0] != '\0')
  641. {
  642. out_len += sprintf(&out_buf[out_len],
  643. "attr=\"%s\" ",
  644. item->m_attr);
  645. }
  646. if (item->comment[0] != '\0')
  647. {
  648. out_len += sprintf(&out_buf[out_len],
  649. "comment=\"%s\" ",
  650. item->comment);
  651. }
  652. out_len += sprintf(&out_buf[out_len],
  653. "/>\r\n");
  654. }
  655. out_len += sprintf(&out_buf[out_len],
  656. "</config>\r\n"
  657. "\r\n");
  658. end:
  659. *offs += c_type->c_size;
  660. free(data);
  661. return out_len;
  662. }
  663. static int make_xml(void)
  664. {
  665. xml_maker_t* p = &xml_maker;
  666. elf_obj_t* obj;
  667. FILE* xml_file;
  668. char* xml_data;
  669. int xml_size;
  670. int offs;
  671. int i;
  672. int num_cfgs;
  673. int cfg_id = 1;
  674. if ((obj = elf_obj_load(p->obj_file)) == NULL)
  675. goto err;
  676. if ((xml_file = fopen(p->xml_file, "wb")) == NULL)
  677. goto err;
  678. //set start cfg_id if it is valid
  679. if (p->start_cfg_id > 0)
  680. cfg_id = p->start_cfg_id;
  681. xml_data = malloc(2*1024*1024);
  682. xml_size = 0;
  683. num_cfgs = get_config_num(obj);
  684. offs = sizeof(config_header_t) + num_cfgs * sizeof(config_info_new_t);
  685. xml_size += sprintf(&xml_data[xml_size],
  686. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
  687. "\r\n"
  688. "<config_file version=\"%s\" size=\"%u\" num_cfgs=\"%u\">\r\n"
  689. "\r\n",
  690. p->version,
  691. get_file_size(obj, num_cfgs, cfg_id),
  692. num_cfgs);
  693. for (i = 0; i < obj->num_syms; i++)
  694. {
  695. Elf_Sym* sym = &obj->symtab[i];
  696. if (get_symbol_type(obj, sym, "enum_") > 0)
  697. {
  698. xml_size += make_enum(obj, sym, &xml_data[xml_size]);
  699. }
  700. if (get_symbol_type(obj, sym, "struct_") > 0)
  701. {
  702. xml_size += make_struct(obj, sym, &xml_data[xml_size]);
  703. }
  704. }
  705. for (i = 0; i < num_cfgs; i++)
  706. {
  707. void* data = get_config_data(obj, cfg_id + i);
  708. char* t;
  709. class_type_t* c_type = data;
  710. if ((t = strstr(c_type->c_attr, "fixed_size=")) != NULL)
  711. {
  712. c_type->c_size = strtol(t + 11, NULL, 0);
  713. }
  714. xml_size += make_config(data, &offs, &xml_data[xml_size]);
  715. }
  716. xml_size += sprintf(&xml_data[xml_size],
  717. "</config_file>\r\n"
  718. "\r\n");
  719. fwrite(xml_data, 1, xml_size, xml_file);
  720. fclose(xml_file);
  721. return 0;
  722. err:
  723. printf(" failed %s\n", __FUNCTION__);
  724. return -1;
  725. }
  726. int main(int argc, char* argv[])
  727. {
  728. if (get_args(argc, argv) < 0)
  729. goto err;
  730. if (make_xml() < 0)
  731. goto err;
  732. return 0;
  733. err:
  734. return -1;
  735. }