Re-organized sub-directory by category
[staging/basesystem.git] / service / system / task_manager / client / libtskmcfg / src / parsexml.c
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdint.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <libgen.h>
26
27 #include <expat.h>
28
29 #define BUFSIZE 4096
30 #define OUTFILE "tskm_auto_build.h"
31 #define TMPFILE "parsexml.tmp"
32
33 typedef uint32_t        ELE_STATE_t;
34 #define ELE_NONE                0x00000000U
35 #define ELE_TSKM_CFG            0x10000000U
36 #define ELE_SERVICE_LIST        0x11000000U
37 #define ELE_SERVICE             0x11100000U
38 #define ELE_SUBGID_LIST         0x11110000U
39
40 #define ELE_COMMON_GSTEP        0x00100000U
41 #define ELE_COMMON_EXEC         0x00010000U
42 #define ELE_COMMON_REQ          0x00020000U
43
44 #define ELE_NORMAL_WAKEUP       0x12000000U
45 #define ELE_NORMAL_W_GSTEP      (ELE_NORMAL_WAKEUP|ELE_COMMON_GSTEP)
46 #define ELE_NORMAL_W_EXEC       (ELE_NORMAL_WAKEUP|ELE_COMMON_GSTEP|ELE_COMMON_EXEC)
47 #define ELE_NORMAL_W_REQ        (ELE_NORMAL_WAKEUP|ELE_COMMON_GSTEP|ELE_COMMON_REQ)
48
49 #define ELE_NORMAL_SHUTDOWN     0x13000000U
50 #define ELE_NORMAL_D_GSTEP      (ELE_NORMAL_SHUTDOWN|ELE_COMMON_GSTEP)
51 #define ELE_NORMAL_D_REQ        (ELE_NORMAL_SHUTDOWN|ELE_COMMON_GSTEP|ELE_COMMON_REQ)
52
53 #define ELE_VUP_WAKEUP          0x14000000U
54 #define ELE_VUP_W_GSTEP         (ELE_VUP_WAKEUP|ELE_COMMON_GSTEP)
55 #define ELE_VUP_W_EXEC          (ELE_VUP_WAKEUP|ELE_COMMON_GSTEP|ELE_COMMON_EXEC)
56 #define ELE_VUP_W_REQ           (ELE_VUP_WAKEUP|ELE_COMMON_GSTEP|ELE_COMMON_REQ)
57
58 #define ELE_VUP_SHUTDOWN        0x15000000U
59 #define ELE_VUP_D_GSTEP         (ELE_VUP_SHUTDOWN|ELE_COMMON_GSTEP)
60 #define ELE_VUP_D_REQ           (ELE_VUP_SHUTDOWN|ELE_COMMON_GSTEP|ELE_COMMON_REQ)
61
62
63 #define ELE_MASK0               0xF0000000U
64 #define ELE_MASK1               0x0F000000U
65 #define ELE_MASK2               0x00F00000U
66 #define ELE_MASK3               0x000F0000U
67
68 #define PARSE_ASSERT_EXIT(x)  \
69         if(!(x)){ \
70           printf("ASSERT %s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); \
71           exit(-1); \
72         }
73
74 #define VALUE_NAME_MAX 255
75 typedef struct {
76   int  step;
77   char gstepIdStr[VALUE_NAME_MAX];
78   int  execSvcNum;
79   int  reqNum;
80   char nextStepCondStr[VALUE_NAME_MAX];
81   char execSvcName[VALUE_NAME_MAX];
82   char reqTableName[VALUE_NAME_MAX];
83 } PARSE_GSTEP_t;
84
85
86 typedef struct {
87   char svcid[VALUE_NAME_MAX];
88   char name[VALUE_NAME_MAX];
89   char path[VALUE_NAME_MAX];
90   char type[VALUE_NAME_MAX];
91   char life_cycle[VALUE_NAME_MAX];
92   char retry_cnt[VALUE_NAME_MAX];
93   char cpu_assign[VALUE_NAME_MAX];
94   char prio[VALUE_NAME_MAX];
95   char policy[VALUE_NAME_MAX];
96   char user[VALUE_NAME_MAX];
97   char runtime_limit[VALUE_NAME_MAX];
98   char cpu_limit[VALUE_NAME_MAX];
99   char mem_limit[VALUE_NAME_MAX];
100   int  subgidNum;
101   char args[VALUE_NAME_MAX];
102   char shutdown_wait[VALUE_NAME_MAX];
103 } PARSE_SVC_t;
104
105 /***************************************
106  * Context
107  **************************************/
108 typedef struct {
109   FILE* fp;     // Output file pointer
110   FILE* tmpFp;  // Temporary file
111   ELE_STATE_t   state;
112
113   PARSE_SVC_t   svc;
114
115   int   svcNum; // Number of services
116   PARSE_GSTEP_t gstep;
117 } PARSE_CTX_t;
118
119
120 /***************************************
121  * entryTskmCfg
122  **************************************/
123 void
124 entryTskmCfg(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
125   p_ctx->state = ELE_TSKM_CFG;
126 }
127
128 /***************************************
129  * exitTskmCfg
130  **************************************/
131 void
132 exitTskmCfg(PARSE_CTX_t* p_ctx) {
133   p_ctx->state = ELE_NONE;
134 }
135
136
137 /***************************************
138  * entryServiceList
139  **************************************/
140 void
141 entryServiceList(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
142   p_ctx->state = ELE_SERVICE_LIST;
143
144   p_ctx->tmpFp = fopen(TMPFILE,"w");
145
146   fprintf(p_ctx->tmpFp,
147           "static TSKM_SVC_ATTR_t serviceAttr[]={"
148           "\n");
149 }
150
151 /***************************************
152  * exitServiceList
153  **************************************/
154 void
155 exitServiceList(PARSE_CTX_t* p_ctx) {
156   fprintf(p_ctx->tmpFp,
157           "};"
158           "\n\n");
159
160   fprintf(p_ctx->tmpFp, "#define TSKM_SVC_NUM (%d) \n\n",p_ctx->svcNum);
161
162   fprintf(p_ctx->tmpFp, "static TSKM_SVC_CTX_t serviceList[TSKM_SVC_NUM]; \n\n");
163
164   fclose(p_ctx->tmpFp);
165
166   fprintf(p_ctx->fp,"\n\n");
167
168   p_ctx->state = ELE_TSKM_CFG;
169 }
170
171 /***************************************
172  * handleServiceList
173  **************************************/
174 void
175 entryService(PARSE_CTX_t* p_ctx,const XML_Char *name,const XML_Char* atts[]) {
176   PARSE_ASSERT_EXIT(strcmp(name,"service") == 0);
177   int ii;
178   char* tp;
179   p_ctx->state = ELE_SERVICE;
180
181   memset(&p_ctx->svc,0,sizeof(p_ctx->svc));
182
183   for(ii=0; atts[ii]; ii+=2) {
184     const char* attr = atts[ii];
185     const char* value = atts[ii+1];
186     if(strcmp(attr,"svcid")==0) {
187       strcpy(p_ctx->svc.svcid,value);
188     } else if(strcmp(attr,"name")==0) {
189       strcpy(p_ctx->svc.name,value);
190     } else if(strcmp(attr,"path")==0) {
191       strcpy(p_ctx->svc.path,value);
192     } else if(strcmp(attr,"type")==0) {
193       const char* typeName = (strcmp(value,"native")==0) ? "TSKM_SVC_TYPE_NATIVE" : "TSKM_SVC_TYPE_UNKNONW";
194       strcpy(p_ctx->svc.type,typeName);
195     } else if(strcmp(attr,"prio")==0) {
196       strcpy(p_ctx->svc.prio,value);
197     } else if(strcmp(attr,"policy")==0) {
198       const char* polName  = (strcmp(value,"fifo")==0) ? "TSKM_SVC_POLICY_FIFO" :
199                              (strcmp(value,"tss")==0)  ? "TSKM_SVC_POLICY_TSS"  :
200                              (strcmp(value,"rr")==0)   ? "TSKM_SVC_POLICY_RR"   : "ERROR";
201       strcpy(p_ctx->svc.policy,polName);
202     } else if(strcmp(attr,"life_cycle")==0) {
203       const char* lcName  = (strcmp(value,"always")==0)             ?  "TSKM_SVC_LC_ALWAYS" :
204                             (strcmp(value,"always_recoverable")==0) ?  "TSKM_SVC_LC_ALWAYS_RECOVERABLE" :
205                             (strcmp(value,"dynamic")==0)            ?  "TSKM_SVC_LC_DYNAMIC" : "ERROR";
206       strcpy(p_ctx->svc.life_cycle,lcName);
207     } else if(strcmp(attr,"retry_cnt")==0) {
208       strcpy(p_ctx->svc.retry_cnt,value);
209     } else if(strcmp(attr,"cpu_assign")==0) {
210       const char* caName  = (strcmp(value,"cpu0")==0) ? "TSKM_SVC_ASSIGN_CPU_0" :
211                             (strcmp(value,"cpu1")==0) ? "TSKM_SVC_ASSIGN_CPU_1" :
212                             (strcmp(value,"auto")==0) ? "TSKM_SVC_ASSIGN_CPU_AUTO" : "ERROR";
213       strcpy(p_ctx->svc.cpu_assign,caName);
214     } else if(strcmp(attr,"user")==0) {
215       strcpy(p_ctx->svc.user,value);
216     } else if(strcmp(attr,"runtime_limit")==0) {
217       strcpy(p_ctx->svc.runtime_limit,value);
218     } else if(strcmp(attr,"cpu_limit")==0) {
219       strcpy(p_ctx->svc.cpu_limit,value);
220     } else if(strcmp(attr,"mem_limit")==0) {
221       strcpy(p_ctx->svc.mem_limit,value);
222     } else if(strcmp(attr,"args")==0) {
223       strcpy(p_ctx->svc.args,value);
224     } else if(strcmp(attr,"shutdown_wait")==0) {
225       const char* swStr  = (strcmp(value,"yes")==0) ? "TSKM_TRUE"  :
226                            (strcmp(value,"no")==0)  ? "TSKM_FALSE" : "ERROR";
227       strcpy(p_ctx->svc.shutdown_wait,swStr);
228     }
229   }
230
231   fprintf(p_ctx->fp,"char const *svcArgs%d[] = {",p_ctx->svcNum);
232   fprintf(p_ctx->fp,"\"%s\",",p_ctx->svc.path);
233
234   // Output arguments
235   tp = strtok(p_ctx->svc.args," ");
236   while(tp != NULL) {
237     fprintf(p_ctx->fp,"\"%s\",",tp);
238     tp = strtok(NULL," ");
239   }
240
241   fprintf(p_ctx->fp,"NULL");
242   fprintf(p_ctx->fp,"};\n");
243 }
244
245 /***************************************
246  * exitService
247  **************************************/
248 void
249 exitService(PARSE_CTX_t* p_ctx) {
250   uint32_t ii;
251   fprintf(p_ctx->tmpFp,"{" );
252
253   fprintf(p_ctx->tmpFp,"%s",p_ctx->svc.svcid);
254   fprintf(p_ctx->tmpFp,", (const char *)\"%s\"",p_ctx->svc.name);
255   fprintf(p_ctx->tmpFp,", (const char *)\"%s\"",p_ctx->svc.path);
256   fprintf(p_ctx->tmpFp,", (char**)svcArgs%d",p_ctx->svcNum);
257   fprintf(p_ctx->tmpFp,", %s",p_ctx->svc.type);
258   fprintf(p_ctx->tmpFp,", %s",p_ctx->svc.prio);
259   fprintf(p_ctx->tmpFp,", %s",p_ctx->svc.policy);
260   fprintf(p_ctx->tmpFp,", %s",p_ctx->svc.life_cycle);
261   fprintf(p_ctx->tmpFp,", (uint32_t)%s",p_ctx->svc.retry_cnt);
262   fprintf(p_ctx->tmpFp,", %s",p_ctx->svc.cpu_assign);
263   fprintf(p_ctx->tmpFp,", (const char *)\"%s\"",p_ctx->svc.user);
264   fprintf(p_ctx->tmpFp,", %s",(p_ctx->svc.runtime_limit[0] != '\0') ? p_ctx->svc.runtime_limit : "0");
265   fprintf(p_ctx->tmpFp,", %s",(p_ctx->svc.cpu_limit[0]     != '\0') ? p_ctx->svc.cpu_limit     : "0");
266   fprintf(p_ctx->tmpFp,", %s",(p_ctx->svc.mem_limit[0]     != '\0') ? p_ctx->svc.mem_limit     : "0");
267   fprintf(p_ctx->tmpFp,", %s",p_ctx->svc.shutdown_wait);
268   fprintf(p_ctx->tmpFp,", %d",p_ctx->svc.subgidNum);
269   if(p_ctx->svc.subgidNum) {
270     fprintf(p_ctx->tmpFp,", subgidList%d",p_ctx->svcNum);
271   } else {
272     fprintf(p_ctx->tmpFp,", NULL");
273   }
274
275   fprintf(p_ctx->tmpFp,"},\n");
276
277   p_ctx->svcNum++;
278
279   p_ctx->state = ELE_SERVICE_LIST;
280 }
281
282 /***************************************
283  * entrySubgidList
284  **************************************/
285 void
286 entrySubgidList(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
287   p_ctx->state = ELE_SUBGID_LIST;
288
289   fprintf(p_ctx->fp,"static gid_t subgidList%d[] = {",p_ctx->svcNum);
290
291
292 }
293
294 /***************************************
295  * handleSubgidList
296  **************************************/
297 void
298 handleSubgidList(PARSE_CTX_t* p_ctx,const XML_Char *name,const XML_Char* atts[]) {
299   PARSE_ASSERT_EXIT(strcmp(name,"subgid") == 0);
300   int32_t ii;
301
302   if(p_ctx->svc.subgidNum > 0) {
303     fprintf(p_ctx->fp,",");
304   }
305   for(ii=0; atts[ii]; ii+=2) {
306     const char* attr = atts[ii];
307     const char* value = atts[ii+1];
308     if(strcmp(attr,"gid")==0) {
309       fprintf(p_ctx->fp,"%s",value);
310     } else {
311       PARSE_ASSERT_EXIT(0);
312     }
313   }
314   p_ctx->svc.subgidNum++;
315 }
316
317 /***************************************
318  * exitSubgidList
319  **************************************/
320 void
321 exitSubgidList(PARSE_CTX_t* p_ctx) {
322
323   fprintf(p_ctx->fp,"};\n");
324
325   p_ctx->state = ELE_SERVICE;
326 }
327
328
329 /***************************************
330  * entryNormalWakeup
331  **************************************/
332 void
333 entryNormalWakeup(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
334   p_ctx->state = ELE_NORMAL_WAKEUP;
335   memset(&p_ctx->gstep,0,sizeof(p_ctx->gstep));
336
337   sprintf(p_ctx->gstep.reqTableName,"wakeupReqList");
338   sprintf(p_ctx->gstep.execSvcName,"wakeupExecSvcId");
339   p_ctx->tmpFp = fopen(TMPFILE,"a");
340   PARSE_ASSERT_EXIT(p_ctx->tmpFp);
341
342   fprintf(p_ctx->tmpFp,"TSKM_GSTEP_t wakeupGstep[]={\n");
343 }
344
345 /***************************************
346  * exitNormalWakeup
347  **************************************/
348 void
349 exitNormalWakeup(PARSE_CTX_t* p_ctx) {
350   fprintf(p_ctx->tmpFp,"};\n\n");
351   fclose(p_ctx->tmpFp);
352
353   p_ctx->state = ELE_TSKM_CFG;
354 }
355
356 /***************************************
357  * entryVupWakeup
358  **************************************/
359 void
360 entryVupWakeup(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
361   p_ctx->state = ELE_VUP_WAKEUP;
362   memset(&p_ctx->gstep,0,sizeof(p_ctx->gstep));
363
364   sprintf(p_ctx->gstep.reqTableName,"wakeupReqListVup");
365   sprintf(p_ctx->gstep.execSvcName,"wakeupExecSvcIdVup");
366   p_ctx->tmpFp = fopen(TMPFILE,"a");
367   PARSE_ASSERT_EXIT(p_ctx->tmpFp);
368
369   fprintf(p_ctx->tmpFp,"TSKM_GSTEP_t wakeupGstepVup[]={\n");
370 }
371
372 /***************************************
373  * exitVupWakeup
374  **************************************/
375 void
376 exitVupWakeup(PARSE_CTX_t* p_ctx) {
377   fprintf(p_ctx->tmpFp,"};\n\n");
378   fclose(p_ctx->tmpFp);
379
380   p_ctx->state = ELE_TSKM_CFG;
381 }
382
383 void
384 entryGstep(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
385
386   p_ctx->state &= ~ELE_MASK2;
387   p_ctx->state |= ELE_COMMON_GSTEP;
388
389   PARSE_GSTEP_t *p_gstep = &p_ctx->gstep;
390
391   if(atts[0] && strcmp(atts[0],"stepid") == 0) {
392     sprintf(p_gstep->gstepIdStr,"%s",atts[1]);
393   } else {
394     sprintf(p_gstep->gstepIdStr,"TSKM_GSTEP_NONE");
395   }
396   p_gstep->execSvcNum = 0;
397   p_gstep->reqNum = 0;
398   sprintf(p_gstep->nextStepCondStr,"INI_INITCOMP_NONE");
399 }
400
401 void
402 handleGstep(PARSE_CTX_t* p_ctx,const XML_Char *name,const XML_Char* atts[]) {
403   PARSE_ASSERT_EXIT(strcmp(name,"next_trans_condition") == 0);
404   PARSE_GSTEP_t *p_gstep = &p_ctx->gstep;
405
406   if(atts[0] && strcmp(atts[0],"cond") == 0) {
407     sprintf(p_gstep->nextStepCondStr,"%s",atts[1]);
408   } else {
409     PARSE_ASSERT_EXIT(0);
410   }
411 }
412
413 void
414 exitGstep(PARSE_CTX_t* p_ctx) {
415   PARSE_GSTEP_t *p_gstep = &p_ctx->gstep;
416
417   fprintf(p_ctx->tmpFp,"{");
418   fprintf(p_ctx->tmpFp,"%s,",p_gstep->gstepIdStr);
419   fprintf(p_ctx->tmpFp,"%d,",p_gstep->execSvcNum);
420   if(p_gstep->execSvcNum) {
421     fprintf(p_ctx->tmpFp,"%s%d,",p_gstep->execSvcName,p_gstep->step);
422   } else {
423     fprintf(p_ctx->tmpFp,"NULL,");
424   }
425   fprintf(p_ctx->tmpFp,"%d,",p_gstep->reqNum);
426   if(p_gstep->reqNum) {
427     fprintf(p_ctx->tmpFp,"%s%d,",p_gstep->reqTableName,p_gstep->step);
428   } else {
429     fprintf(p_ctx->tmpFp,"NULL,");
430   }
431   fprintf(p_ctx->tmpFp,"%s",p_gstep->nextStepCondStr);
432   fprintf(p_ctx->tmpFp,"},\n");
433
434   p_gstep->step++;
435
436   p_ctx->state &= ~ELE_MASK2;
437 }
438
439 void
440 entryExec(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
441   p_ctx->state &= ~ELE_MASK3;
442   p_ctx->state |= ELE_COMMON_EXEC;
443
444   PARSE_GSTEP_t *p_gstep = &p_ctx->gstep;
445   fprintf(p_ctx->fp,
446           "static TSKM_SVCID_t %s%d[] = {",p_gstep->execSvcName,p_gstep->step);
447 }
448 void
449 handleExec(PARSE_CTX_t* p_ctx,const XML_Char *name,const XML_Char* atts[]) {
450   PARSE_ASSERT_EXIT(strcmp(name,"exec_svc") == 0);
451   PARSE_GSTEP_t *p_gstep = &p_ctx->gstep;
452   int ii;
453
454   if(p_gstep->execSvcNum > 0) {
455     fprintf(p_ctx->fp,",");
456   }
457
458   for(ii=0; atts[ii]; ii+=2) {
459     const char* attr = atts[ii];
460     const char* value = atts[ii+1];
461     PARSE_ASSERT_EXIT(strcmp(attr,"svcid") == 0);
462     fprintf(p_ctx->fp,"%s",value);
463   }
464   p_gstep->execSvcNum++;
465 }
466 void
467 exitExec(PARSE_CTX_t* p_ctx) {
468   fprintf(p_ctx->fp,"};\n\n");
469   p_ctx->state &= ~ELE_MASK3;
470 }
471
472 void
473 entryReq(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
474   p_ctx->state &= ~ELE_MASK3;
475   p_ctx->state |= ELE_COMMON_REQ;
476   PARSE_GSTEP_t *p_gstep = &p_ctx->gstep;
477
478   fprintf(p_ctx->fp,"static TSKM_GSTEP_REQ_INFO_t %s%d[] ={",p_gstep->reqTableName,p_gstep->step);
479 }
480 void
481 handleReq(PARSE_CTX_t* p_ctx,const XML_Char *name,const XML_Char* atts[]) {
482   PARSE_GSTEP_t *p_gstep = &p_ctx->gstep;
483   PARSE_ASSERT_EXIT(strcmp(name,"request") == 0);
484   int ii;
485
486   fprintf(p_ctx->fp,"  {");
487
488   for(ii=0; atts[ii]; ii+=2) {
489     const char* attr = atts[ii];
490     const char* value = atts[ii+1];
491     if(strcmp(attr,"local_step") == 0) {
492       if(strcmp(value,"shm") == 0) {
493         fprintf(p_ctx->fp,"TSKM_LSTEP_SHM");
494       } else if(strcmp(value,"bupchk") == 0) {
495         fprintf(p_ctx->fp,"TSKM_LSTEP_BUPCHK");
496       } else if(strcmp(value,"last") == 0) {
497         fprintf(p_ctx->fp,"TSKM_LSTEP_LAST");
498       } else if(strcmp(value,"all") == 0) {
499         fprintf(p_ctx->fp,"TSKM_LSTEP_ALL");
500       } else {
501         fprintf(p_ctx->fp,"%s",value);
502       }
503     } else {
504       fprintf(p_ctx->fp,"%s",value);  // Output of ","
505     }
506     fprintf(p_ctx->fp,"%s",(atts[ii+2])?",":"");  // Outoput of ","
507   }
508   fprintf(p_ctx->fp,"},");
509   p_gstep->reqNum++;
510 }
511 void
512 exitReq(PARSE_CTX_t* p_ctx) {
513   fprintf(p_ctx->fp,"};\n\n");
514   p_ctx->state &= ~ELE_MASK3;
515 }
516
517 /***************************************
518  * entryNormalShutdown
519  **************************************/
520 void
521 entryNormalShutdown(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
522   p_ctx->state = ELE_NORMAL_SHUTDOWN;
523
524   memset(&p_ctx->gstep,0,sizeof(p_ctx->gstep));
525   sprintf(p_ctx->gstep.reqTableName,"downReqList");
526   p_ctx->tmpFp = fopen(TMPFILE,"a");
527   PARSE_ASSERT_EXIT(p_ctx->tmpFp);
528
529   fprintf(p_ctx->tmpFp,"static TSKM_GSTEP_t downGstep[]={\n");
530 }
531
532 /***************************************
533  * exitNormalShutdown
534  **************************************/
535 void
536 exitNormalShutdown(PARSE_CTX_t* p_ctx) {
537
538   fprintf(p_ctx->tmpFp,"};\n\n");
539   fclose(p_ctx->tmpFp);
540
541   p_ctx->state = ELE_TSKM_CFG;
542 }
543
544 /***************************************
545  * entryVupShutdown
546  **************************************/
547 void
548 entryVupShutdown(PARSE_CTX_t* p_ctx,const XML_Char* atts[]) {
549   p_ctx->state = ELE_VUP_SHUTDOWN;
550   memset(&p_ctx->gstep,0,sizeof(p_ctx->gstep));
551
552   sprintf(p_ctx->gstep.reqTableName,"downReqListVup");
553   p_ctx->tmpFp = fopen(TMPFILE,"a");
554   PARSE_ASSERT_EXIT(p_ctx->tmpFp);
555
556   fprintf(p_ctx->tmpFp,"static TSKM_GSTEP_t downGstepVup[]={\n");
557 }
558
559 /***************************************
560  * exitVupShutdown
561  **************************************/
562 void
563 exitVupShutdown(PARSE_CTX_t* p_ctx) {
564   fprintf(p_ctx->tmpFp,"};\n\n");
565   fclose(p_ctx->tmpFp);
566
567   p_ctx->state = ELE_TSKM_CFG;
568 }
569
570 /***************************************
571  * elementStart
572  **************************************/
573 void
574 elementStart(void *userData, const XML_Char *name, const XML_Char *atts[]) {
575   PARSE_CTX_t *p_ctx = (PARSE_CTX_t*)userData;
576 #if 0
577   int ii;
578   printf("[ELEMENT] %s Start!\n", name);
579   for(ii=0; atts[ii]; ii+=2) {
580     printf("  %s:%s \n", atts[ii],atts[ii+1]);
581   }
582 #endif
583   switch(p_ctx->state) {
584   case ELE_NONE:
585     if(strcmp(name,"tskm_cfg") == 0) {
586       entryTskmCfg(p_ctx,atts);
587     } else {
588       PARSE_ASSERT_EXIT(0);
589     }
590     break;
591   case ELE_TSKM_CFG:
592     if(strcmp(name,"service_list") == 0) {
593       entryServiceList(p_ctx,atts);
594     } else if(strcmp(name,"normal_wakeup") == 0) {
595       entryNormalWakeup(p_ctx,atts);
596     } else if(strcmp(name,"normal_shutdown") == 0) {
597       entryNormalShutdown(p_ctx,atts);
598     } else if(strcmp(name,"vup_wakeup") == 0) {
599       entryVupWakeup(p_ctx,atts);
600     } else if(strcmp(name,"vup_shutdown") == 0) {
601       entryVupShutdown(p_ctx,atts);
602     } else {
603       PARSE_ASSERT_EXIT(0);
604     }
605     break;
606   case ELE_SERVICE_LIST:
607     if(strcmp(name,"service") == 0) {
608       entryService(p_ctx,name,atts);
609     }
610     break;
611   case ELE_SERVICE:
612     if(strcmp(name,"subgid_list") == 0) {
613       entrySubgidList(p_ctx,atts);
614     }
615     break;
616   case ELE_SUBGID_LIST:
617     handleSubgidList(p_ctx,name,atts);
618     break;
619   case ELE_NORMAL_WAKEUP:
620   case ELE_NORMAL_SHUTDOWN:
621   case ELE_VUP_WAKEUP:
622   case ELE_VUP_SHUTDOWN:
623     if(strcmp(name,"global_step") == 0) {
624       entryGstep(p_ctx,atts);
625     } else {
626       PARSE_ASSERT_EXIT(0);
627     }
628     break;
629   case ELE_NORMAL_W_GSTEP:
630   case ELE_NORMAL_D_GSTEP:
631   case ELE_VUP_W_GSTEP:
632   case ELE_VUP_D_GSTEP:
633     if(strcmp(name,"exec_list") == 0) {
634       entryExec(p_ctx,atts);
635     } else if(strcmp(name,"request_list") == 0) {
636       entryReq(p_ctx,atts);
637     } else {
638       handleGstep(p_ctx,name,atts);
639     }
640     break;
641   case ELE_NORMAL_W_EXEC:
642   case ELE_VUP_W_EXEC:
643     handleExec(p_ctx,name,atts);
644     break;
645   case ELE_NORMAL_W_REQ:
646   case ELE_NORMAL_D_REQ:
647   case ELE_VUP_W_REQ:
648   case ELE_VUP_D_REQ:
649     handleReq(p_ctx,name,atts);
650     break;
651   }
652 }
653
654
655 /***************************************
656  * elementEnd
657  **************************************/
658 void
659 elementEnd(void *userData, const XML_Char *name) {
660   PARSE_CTX_t *p_ctx = (PARSE_CTX_t*)userData;
661   switch(p_ctx->state) {
662   case ELE_NONE:
663     PARSE_ASSERT_EXIT(0);
664     break;
665   case ELE_TSKM_CFG:
666     if(strcmp(name,"tskm_cfg") == 0) {
667       exitTskmCfg(p_ctx);
668     } else {
669       PARSE_ASSERT_EXIT(0);
670     }
671     break;
672   case ELE_SERVICE_LIST:
673     if(strcmp(name,"service_list") == 0) {
674       exitServiceList(p_ctx);
675     }
676     break;
677   case ELE_SERVICE:
678     if(strcmp(name,"service") == 0) {
679       exitService(p_ctx);
680     }
681     break;
682   case ELE_SUBGID_LIST:
683     if(strcmp(name,"subgid_list") == 0) {
684       exitSubgidList(p_ctx);
685     }
686     break;
687   case ELE_NORMAL_WAKEUP:
688     if(strcmp(name,"normal_wakeup") == 0) {
689       exitNormalWakeup(p_ctx);
690     }
691     break;
692   case ELE_NORMAL_SHUTDOWN:
693     if(strcmp(name,"normal_shutdown") == 0) {
694       exitNormalShutdown(p_ctx);
695     }
696     break;
697   case ELE_VUP_WAKEUP:
698     if(strcmp(name,"vup_wakeup") == 0) {
699       exitVupWakeup(p_ctx);
700     }
701     break;
702   case ELE_VUP_SHUTDOWN:
703     if(strcmp(name,"vup_shutdown") == 0) {
704       exitVupShutdown(p_ctx);
705     }
706     break;
707   case ELE_NORMAL_D_GSTEP:
708   case ELE_NORMAL_W_GSTEP:
709   case ELE_VUP_D_GSTEP:
710   case ELE_VUP_W_GSTEP:
711     if(strcmp(name,"global_step") == 0) {
712       exitGstep(p_ctx);
713     }
714     break;
715   case ELE_NORMAL_W_EXEC:
716   case ELE_VUP_W_EXEC:
717     if(strcmp(name,"exec_list") == 0) {
718       exitExec(p_ctx);
719     }
720     break;
721   case ELE_NORMAL_D_REQ:
722   case ELE_NORMAL_W_REQ:
723   case ELE_VUP_D_REQ:
724   case ELE_VUP_W_REQ:
725     if(strcmp(name,"request_list") == 0) {
726       exitReq(p_ctx);
727     }
728     break;
729   }
730 }
731 /***************************************
732  * parseXmlFile
733  **************************************/
734 int
735 parseXmlFile(const char* file,XML_Parser parser) {
736   int ret = -1;
737   FILE* fp = fopen(file, "r");
738   if (fp == NULL) {
739     goto ERROR;
740   }
741
742   while(1) {
743     char *buf = (char*) XML_GetBuffer(parser, BUFSIZE);
744     if (!buf) {
745       goto ERROR;
746     }
747
748     size_t nread = fread(buf, sizeof(char), BUFSIZE, fp);
749     if (ferror(fp)) {
750       goto ERROR;
751     }
752
753     if (!XML_ParseBuffer(parser, nread, feof(fp))) {
754       goto ERROR;
755     }
756
757     if (feof(fp)) {
758       break;
759     }
760   }
761   ret = 0;
762 ERROR:
763   if(fp) {
764     fclose(fp);
765   }
766   return ret;
767 }
768
769 /***************************************
770  * externalHandler
771  **************************************/
772 int
773 externalHandler(XML_Parser parser,
774                 const XML_Char* content, const XML_Char* base,
775                 const XML_Char* systemId, const XML_Char* publicId) {
776   printf("parse %s \n",systemId);
777
778   int ret = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
779   XML_Parser extparser = NULL;
780
781   extparser = XML_ExternalEntityParserCreate(parser, content, NULL);
782   if(extparser ==NULL) {
783     goto ERROR;
784   }
785
786   if(parseXmlFile(systemId,extparser) != 0) {
787     goto ERROR;
788   }
789   ret = XML_STATUS_OK;
790 ERROR:
791   if(extparser) {
792     XML_ParserFree(extparser);
793   }
794   return ret;
795 }
796
797 /***************************************
798  * usage
799  **************************************/
800 void
801 usage(const char* cmd) {
802   printf("usage:%s xmlfile\n",cmd);
803 }
804
805 /***************************************
806  * main
807  **************************************/
808 int
809 main (int argc, char *argv[]) {
810   struct stat statinfo;
811   int ret=-1;
812   int xmlRet;
813   const char* inpath;
814   char  tmpstr1[255];
815   char  tmpstr2[255];
816   const char* workdir;
817   const char* infile;
818   XML_Parser parser;
819   PARSE_CTX_t ctx;
820
821   if(argc < 2) {
822     usage(argv[0]);
823     goto ERROR;
824   }
825
826   inpath = argv[1];
827   if(0 != stat(inpath,&statinfo)) {
828     fprintf(stderr, "%s:%s",strerror(errno),inpath);
829     goto ERROR;
830   }
831   memset(&ctx,0,sizeof(ctx));
832
833   strcpy(tmpstr1,inpath);
834   strcpy(tmpstr2,inpath);
835   workdir=dirname(tmpstr1);
836   infile=basename(tmpstr2);
837
838   if(0 != chdir(workdir)) {
839     fprintf(stderr, "%s:%s",strerror(errno),workdir);
840     goto ERROR;
841   }
842
843   ctx.fp = fopen(OUTFILE, "w");
844   if (ctx.fp == NULL) {
845     goto ERROR;
846   }
847   fprintf(ctx.fp,"//This file is created automatically from %s.\n",inpath);
848   fprintf(ctx.fp,"//So you shall not modify this file immediately.\n");
849
850   /* create XML parser */
851   if ((parser = XML_ParserCreate(NULL)) == NULL) {
852     fprintf(stderr, "parser creation error\n");
853     goto ERROR;
854   }
855   XML_SetUserData(parser,&ctx);
856   XML_SetParamEntityParsing(parser,XML_PARAM_ENTITY_PARSING_ALWAYS);  // Allow External Entities
857   XML_SetExternalEntityRefHandler(parser,externalHandler);
858   XML_SetElementHandler(parser, elementStart, elementEnd);
859
860   if(parseXmlFile(infile,parser) != 0) {
861     goto ERROR;
862   }
863   ret = 0;
864
865 ERROR:
866   if(parser) {
867     XML_ParserFree(parser);
868   }
869   if(ctx.fp) {
870     fclose(ctx.fp);
871   }
872   char buf[255];
873   sprintf(buf,"cat %s >> %s",TMPFILE,OUTFILE);
874   printf("%s\n",buf);
875   system(buf);
876   unlink(TMPFILE);
877   return ret;
878 }
879