driver-gen/xml-lib: Search for version header files in the correct dir
[driver-gen.git] / translation.c
blobd23c858ecfd4fcf84a2a714ceb6140a5c38d0dcc
1 /**
2 * @file translation.c
4 * @brief Template translation functions are here.
6 * @author Copyright (C) 2002 CERN. Stuart Baird
7 * @author Copyright (C) 2003 - 2010 CERN. Georgievskiy Yury <ygeorgie@cern.ch>
9 * @date Created on 27/02/2004
11 * @section license_sec License
12 * Released under the GPL
14 #define _GNU_SOURCE /* asprintf rocks */
15 #include "driverGen.h"
16 #include "utilities.h"
17 #include "translation.h"
19 #define FIND 0
20 #define REPLACE 1
21 #define INT_LEN 16
23 /* Here comes all tokens, that are used in code generation */
24 typedef enum tag_Tokens {
25 /* indexes */
26 SYS_LOWER = 0, /* 00 */
27 MOD_NAME, /* 01 */
28 BUS_UPPER, /* 02 */
29 INT_NUM, /* 03 */
30 PLAIN_NUM, /* 04 */
31 HEX_NUM, /* 05 */
32 FANCY_NUM, /* 06 */
33 EXTRA_NUM, /* 07 */
34 DEC_NUM, /* 08 */
35 DDD_NUM, /* 09 */
36 REG_NAME, /* 10 */
37 REG_COMM, /* 11 */
38 REG_TYPE, /* 12 */
39 REG_DEPTH, /* 13 */
40 REG_LOOP, /* 14 */
41 REG_ID, /* 15 */
42 IOCTL_CONST, /* 16 */
43 PRECISION, /* 17 */
44 BASE_ADDR, /* 18 */
45 FANCY_STR, /* 19 */
46 DG_DUMMY_STR, /* 20 */
47 DRVR_TYPE, /* 21 */
48 DG_COMMENT, /* 22 */
49 DG_FREE_FMT, /* 23 */
50 DG_CHAR, /* 24 */
51 DG_STRING, /* 25 */
52 DG_REG_SZ, /* 26 */
53 NUM_TOKENS /* add new tokens BEFORE this */
54 } Tokens;
56 static char *tokenNames[NUM_TOKENS] = {
57 [SYS_LOWER] = "<sys_lower>",
58 [MOD_NAME] = "<mod_name>",
59 [BUS_UPPER] = "<bus_upper>",
60 [INT_NUM] = "<int_num>",
61 [PLAIN_NUM] = "<plain_num>",
62 [HEX_NUM] = "<hex_num>",
63 [FANCY_NUM] = "<fancy_num>",
64 [EXTRA_NUM] = "<extra_num>",
65 [DEC_NUM] = "<dec_num>",
66 [DDD_NUM] = "<ddd_num>",
67 [REG_NAME] = "<reg_name>",
68 [REG_COMM] = "<reg_comment>",
69 [REG_TYPE] = "<reg_type>",
70 [REG_DEPTH] = "<reg_depth>",
71 [REG_LOOP] = "<reg_loop>",
72 [REG_ID] = "<reg_id>",
73 [IOCTL_CONST] = "<ioctl_const>",
74 [PRECISION] = "<precision>",
75 [BASE_ADDR] = "<base_addr>",
76 [FANCY_STR] = "<fancy_str>",
77 [DG_DUMMY_STR] = "<dg_dummy_str>",
78 [DRVR_TYPE] = "<drvr_type>",
79 [DG_COMMENT] = "<dg_comment>",
80 [DG_FREE_FMT] = "<dg_free_fmt>",
81 [DG_CHAR] = "<dg_char>",
82 [DG_STRING] = "<dg_string>",
83 [DG_REG_SZ] = "<dg_reg_sz>"
86 static int ModNameLen;
87 static char ***GetFindReplace();
88 static int *GetFindLengths();
89 static void GlobalReplace(FILE *, FILE *);
91 /**
92 * @brief find/replace table container.
94 * @param none
96 * All possible templates are checked here for validity.
98 * @return find/replace table pointer
100 static char ***GetFindReplace(void)
102 static char*** findReplace = NULL;
104 if (!findReplace) { /* init only once */
106 findReplace = (char ***)calloc(2, sizeof(char **));
108 findReplace[FIND] =
109 (char **)calloc(NUM_TOKENS, sizeof(char *));
110 findReplace[REPLACE] =
111 (char **)calloc(NUM_TOKENS, sizeof(char *));
114 return findReplace;
118 * @brief Token names length container
120 * @param none
122 * @return pointer to token length container
124 static int *GetFindLengths()
126 static int findLengths[NUM_TOKENS] = { 0 };
127 int i;
129 if (!findLengths[0]) {
130 for (i = 0; i < NUM_TOKENS; i++)
131 findLengths[i] = strlen((const char *)tokenNames[i]);
134 return findLengths;
138 * @brief Search for a template in the text and replace it with current
139 * template value.
141 * @param template - template file
142 * @param output - results goes here
144 * @return void
146 static void GlobalReplace(FILE * template, FILE * output)
148 char line[2048];
149 char *location, *start;
150 int swapped, i;
152 while (fgets(line, 2048, template) != NULL) {
153 start = location = line;
155 while ((location = (char *)index(start, '<')) != NULL) {
157 /* Dump the characters parsed so far */
158 swapped = 0;
159 fwrite(start, 1, (int)(location - start), output);
160 start = location + 1;
162 /* Check if the '<' character found is an interesting
163 token. If so replace it with the appropriate string
164 and skip the input pointer to just past the token. */
165 for (i = 0; i < NUM_TOKENS; i++) {
166 if (GetFindReplace()[FIND][i] != NULL) {
167 if (strncmp
168 (location,
169 GetFindReplace()[FIND][i],
170 GetFindLengths()[i]) == 0) {
171 fprintf(output, "%s",
172 (char *)
173 GetFindReplace()
174 [REPLACE][i]);
175 start =
176 location +
177 GetFindLengths()[i];
178 swapped = 1;
179 break;
184 /* No tokens were found so dump the '<' */
185 if (!swapped)
186 fputc('<', output);
188 /* Dump the remaining characters */
189 fprintf(output, "%s", start);
194 * @brief Naming convetion factory
196 * @param nm -- module name _exactly_ as in the DB
198 * Naming convention is the following:
200 * TST_CIBC --> TstCibc
201 * A4032VXIVME --> A4032vxivme
202 * SHARED_CIBC_TST --> SharedCibcTst
203 * RF_IRQ_TEST --> RfIrqTest
204 * etc...
206 * @b NOTE returned pointer should be freed by the caller
208 * @return converted module name
210 char *naming_convention(char *nm)
212 char *buf, *bptr;
213 char *p, i = 0;
214 char *tmp = nm;
216 /* count uderscores */
217 while ((tmp = index(tmp, (int)'_'))) {
218 ++i; ++tmp;
221 /* will hold new name */
222 buf = calloc(strlen(nm)-i + 1, 1);
223 bptr = buf;
225 tmp = strdup(nm); /* prevent corruption */
226 StrToLower(tmp);
227 p = strtok(tmp, "_");
228 while (p) {
229 *p = toupper(*p);
230 strcpy(bptr, p);
231 bptr += strlen(p);
232 p = strtok(NULL, "_");
234 free(tmp);
235 return buf;
239 * @brief Template table initialization.
241 * @param moduleName -- Module Name _exactly_ as in the DataBase
242 * @param bus -- @b pci or @b vme buses are supproted
244 * @return void
246 void TranslationInit(char *moduleName, char *bus)
248 char ***fr = GetFindReplace(); /* find&&replace */
249 ModNameLen = strlen(moduleName);
251 fr[REPLACE][MOD_NAME] = (char *)strdup(moduleName);
252 fr[REPLACE][BUS_UPPER] = (char *)strdup(bus);
253 fr[REPLACE][SYS_LOWER] = naming_convention(moduleName);
254 fr[REPLACE][INT_NUM] = (char *)calloc(INT_LEN, sizeof(char));
255 fr[REPLACE][PLAIN_NUM] = (char *)calloc(INT_LEN, sizeof(char));
256 fr[REPLACE][HEX_NUM] = (char *)calloc(INT_LEN, sizeof(char));
257 fr[REPLACE][FANCY_NUM] = (char *)calloc(INT_LEN, sizeof(char));
258 fr[REPLACE][EXTRA_NUM] = (char *)calloc(INT_LEN, sizeof(char));
259 fr[REPLACE][DEC_NUM] = (char *)calloc(INT_LEN, sizeof(char));
260 fr[REPLACE][DDD_NUM] = (char *)calloc(INT_LEN, sizeof(char));
261 fr[REPLACE][REG_DEPTH] = (char *)calloc(INT_LEN, sizeof(char));
262 fr[REPLACE][REG_LOOP] = (char *)calloc(INT_LEN, sizeof(char));
263 fr[REPLACE][REG_ID] = (char *)calloc(NAME_LEN + 3, sizeof(char));
264 fr[REPLACE][PRECISION] = (char *)calloc(INT_LEN, sizeof(char));
265 fr[REPLACE][IOCTL_CONST] = (char *)calloc(NAME_LEN + ModNameLen, sizeof(char));
266 fr[REPLACE][REG_NAME] = NULL;
267 fr[REPLACE][REG_TYPE] = NULL;
268 fr[REPLACE][REG_COMM] = NULL;
269 fr[REPLACE][BASE_ADDR] = NULL;
270 fr[REPLACE][FANCY_STR] = NULL;
271 fr[REPLACE][DG_DUMMY_STR] = NULL;
272 fr[REPLACE][DRVR_TYPE] = NULL;
273 fr[REPLACE][DG_COMMENT] = NULL;
274 fr[REPLACE][DG_FREE_FMT] = NULL;
275 fr[REPLACE][DG_CHAR] = (char *)calloc(2, sizeof(char));
276 fr[REPLACE][DG_STRING] = NULL;
277 fr[REPLACE][DG_REG_SZ] = (char *)calloc(INT_LEN, sizeof(char));
279 /* <bus_upper> */
280 StrToUpper(fr[REPLACE][BUS_UPPER]);
282 TranslationReset();
286 * @brief Reset some translation table values to default one.
288 * @param none
290 * @return void
292 void TranslationReset()
294 int i;
296 for (i = 0; i < NUM_TOKENS; i++)
297 GetFindReplace()[FIND][i] = NULL;
299 GetFindReplace()[FIND][SYS_LOWER] = (char *)tokenNames[SYS_LOWER];
300 GetFindReplace()[FIND][MOD_NAME] = (char *)tokenNames[MOD_NAME];
301 GetFindReplace()[FIND][BUS_UPPER] = (char *)tokenNames[BUS_UPPER];
304 /*---------------- GET and SET access functions -----------------------------*/
306 /* Returns modified module name Example: SHARED_CIBC => SharedCibc */
307 char *TranslationGetSysLower()
309 return GetFindReplace()[REPLACE][SYS_LOWER];
312 /* Returns module name EXACTLY as in the dataBase */
313 char *TranslationGetModName()
315 return GetFindReplace()[REPLACE][MOD_NAME];
318 /* Returns bus (VME or PCI) */
319 char *TranslationGetBus()
321 return GetFindReplace()[REPLACE][BUS_UPPER];
324 /* <int_num> */
325 char *TranslationGetIntNum()
327 return GetFindReplace()[REPLACE][INT_NUM];
329 void TranslationSetIntNum(int newNum)
331 GetFindReplace()[FIND][INT_NUM] = (char *)tokenNames[INT_NUM];
332 snprintf(GetFindReplace()[REPLACE][INT_NUM], INT_LEN, "%d", newNum);
335 /* <plain_num> */
336 char *TranslationGetPlainNum()
338 return GetFindReplace()[REPLACE][PLAIN_NUM];
340 void TranslationSetPlainNum(int newNum)
342 GetFindReplace()[FIND][PLAIN_NUM] = (char *)tokenNames[PLAIN_NUM];
343 snprintf(GetFindReplace()[REPLACE][PLAIN_NUM], INT_LEN, "%d", newNum);
346 /* <hex_num> */
347 char *TranslationGetHexNum()
349 return GetFindReplace()[REPLACE][HEX_NUM];
351 void TranslationSetHexNum(int newNum)
353 GetFindReplace()[FIND][HEX_NUM] = (char *)tokenNames[HEX_NUM];
354 snprintf(GetFindReplace()[REPLACE][HEX_NUM], INT_LEN, "0x%x", newNum);
357 /* <fancy_num> */
358 char *TranslationGetFancyNum()
360 return GetFindReplace()[REPLACE][FANCY_NUM];
362 void TranslationSetFancyNum(int newNum)
364 GetFindReplace()[FIND][FANCY_NUM] = (char *)tokenNames[FANCY_NUM];
365 snprintf(GetFindReplace()[REPLACE][FANCY_NUM], INT_LEN, "%02d", newNum);
368 /* <extra_num> */
369 char *TranslationGetExtraNum()
371 return GetFindReplace()[REPLACE][EXTRA_NUM];
373 void TranslationSetExtraNum(int newNum)
375 GetFindReplace()[FIND][EXTRA_NUM] = (char *)tokenNames[EXTRA_NUM];
376 snprintf(GetFindReplace()[REPLACE][EXTRA_NUM], INT_LEN, "0x%X", newNum);
379 /* <dec_num> */
380 char *TranslationGetDecNum()
382 return GetFindReplace()[REPLACE][DEC_NUM];
384 void TranslationSetDecNum(int newNum)
386 GetFindReplace()[FIND][DEC_NUM] = (char *)tokenNames[DEC_NUM];
387 snprintf(GetFindReplace()[REPLACE][DEC_NUM], INT_LEN, "%d", newNum);
390 /* <ddd_num> */
391 char *TranslationGetDDDNum()
393 return GetFindReplace()[REPLACE][DDD_NUM];
395 void TranslationSetDDDNum(int newNum)
397 GetFindReplace()[FIND][DDD_NUM] = (char *)tokenNames[DDD_NUM];
398 snprintf(GetFindReplace()[REPLACE][DDD_NUM], INT_LEN, "%d", newNum);
401 /* <reg_loop> */
402 char *TranslationGetRegLoop()
404 return GetFindReplace()[REPLACE][REG_LOOP];
406 void TranslationSetRegLoop(int newRegLoop)
408 GetFindReplace()[FIND][REG_LOOP] = (char *)tokenNames[REG_LOOP];
409 snprintf(GetFindReplace()[REPLACE][REG_LOOP], INT_LEN, "%d",
410 newRegLoop);
413 /* <reg_id> */
414 char *TranslationGetRegId()
416 return GetFindReplace()[REPLACE][REG_ID];
418 void TranslationSetRegId(char *newToken)
420 GetFindReplace()[FIND][REG_ID] = (char *)tokenNames[REG_ID];
421 snprintf(GetFindReplace()[REPLACE][REG_ID], NAME_LEN, "%s_ID",
422 newToken);
425 /* <reg_depth> */
426 char *TranslationGetRegDepth()
428 return GetFindReplace()[REPLACE][REG_DEPTH];
430 void TranslationSetRegDepth(int newRegDepth)
432 GetFindReplace()[FIND][REG_DEPTH] = (char *)tokenNames[REG_DEPTH];
433 snprintf(GetFindReplace()[REPLACE][REG_DEPTH], INT_LEN, "%d",
434 newRegDepth);
437 /* <reg_name> */
438 char *TranslationGetRegName()
440 return GetFindReplace()[REPLACE][REG_NAME];
442 void TranslationSetRegName(char *newToken)
444 GetFindReplace()[FIND][REG_NAME] = (char *)tokenNames[REG_NAME];
445 GetFindReplace()[REPLACE][REG_NAME] = newToken;
448 /* <reg_comment> */
449 char *TranslationGetRegComm()
451 return GetFindReplace()[REPLACE][REG_COMM];
453 void TranslationSetRegComm(char *newToken)
455 GetFindReplace()[FIND][REG_COMM] = (char *)tokenNames[REG_COMM];
456 GetFindReplace()[REPLACE][REG_COMM] = newToken;
459 /* <reg_type> */
460 char *TranslationGetRegType()
462 return GetFindReplace()[REPLACE][REG_TYPE];
464 void TranslationSetRegType(char *newToken)
466 GetFindReplace()[FIND][REG_TYPE] = (char *)tokenNames[REG_TYPE];
467 GetFindReplace()[REPLACE][REG_TYPE] = newToken;
470 /* <dg_reg_sz> */
471 char* TranslationGetRegSize()
473 return GetFindReplace()[REPLACE][DG_REG_SZ];
475 void TranslationSetRegSize(int newRegSz)
477 GetFindReplace()[FIND][DG_REG_SZ] = (char *)tokenNames[DG_REG_SZ];
478 snprintf(GetFindReplace()[REPLACE][DG_REG_SZ], INT_LEN, "%d", newRegSz);
481 /* <ioctl_const> */
482 char *TranslationGetIoctlConst()
484 return GetFindReplace()[REPLACE][IOCTL_CONST];
486 void TranslationSetIoctlConst(char *token, char *regName)
488 GetFindReplace()[FIND][IOCTL_CONST] = (char *)tokenNames[IOCTL_CONST];
489 if (!strncmp(regName, SRVREGPREF, strlen(SRVREGPREF))) /* service register */
490 snprintf(GetFindReplace()[REPLACE][IOCTL_CONST],
491 NAME_LEN + ModNameLen, "SRV_%s_%s", token,
492 regName + strlen(SRVREGPREF));
493 else /* normal module register */
494 snprintf(GetFindReplace()[REPLACE][IOCTL_CONST],
495 NAME_LEN + ModNameLen, "%s_%s_%s",
496 TranslationGetModName(), token, regName);
499 /* <precision> */
500 char *TranslationGetPrecision()
502 return GetFindReplace()[REPLACE][PRECISION];
504 void TranslationSetPrecision(int newPrecision)
506 GetFindReplace()[FIND][PRECISION] = (char *)tokenNames[PRECISION];
507 snprintf(GetFindReplace()[REPLACE][PRECISION], INT_LEN, "%d",
508 newPrecision);
511 /* <base_addr> */
512 char *TranslationGetBaseAddr()
514 return GetFindReplace()[REPLACE][BASE_ADDR];
516 void TranslationSetBaseAddr(char *newToken)
518 GetFindReplace()[FIND][BASE_ADDR] = (char *)tokenNames[BASE_ADDR];
519 GetFindReplace()[REPLACE][BASE_ADDR] = newToken;
522 /* <fancy_str> */
523 char *TranslationGetFancyString()
525 return GetFindReplace()[REPLACE][FANCY_STR];
527 void TranslationSetFancyString(char *newToken)
529 GetFindReplace()[FIND][FANCY_STR] = (char *)tokenNames[FANCY_STR];
530 GetFindReplace()[REPLACE][FANCY_STR] = newToken;
533 /* <dg_dummy_str> */
534 char *TranslationGetDummyString()
536 return GetFindReplace()[REPLACE][DG_DUMMY_STR];
538 void TranslationSetDummyString(char *newToken)
540 GetFindReplace()[FIND][DG_DUMMY_STR] = (char *)tokenNames[DG_DUMMY_STR];
541 GetFindReplace()[REPLACE][DG_DUMMY_STR] = newToken;
544 /* <drvr_type> */
545 char *TranslationGetDriverType()
547 return GetFindReplace()[REPLACE][DRVR_TYPE];
549 void TranslationSetDriverType(char *newToken)
551 GetFindReplace()[FIND][DRVR_TYPE] = (char *)tokenNames[DRVR_TYPE];
552 GetFindReplace()[REPLACE][DRVR_TYPE] = newToken;
555 /* <dg_comment> */
556 char *TranslationGetComment()
558 return GetFindReplace()[REPLACE][DG_COMMENT];
560 void TranslationSetComment(char *newToken)
562 GetFindReplace()[FIND][DG_COMMENT] = (char *)tokenNames[DG_COMMENT];
563 GetFindReplace()[REPLACE][DG_COMMENT] = newToken;
566 /* <dg_free_fmt> */
567 char *TranslationGetFreeFormat()
569 return GetFindReplace()[REPLACE][DG_FREE_FMT];
571 void TranslationSetFreeFormat(char *newToken, ...)
573 va_list ap;
574 static char formatStr[MAX_STR];
576 memset(formatStr, 0, sizeof(formatStr));
578 GetFindReplace()[FIND][DG_FREE_FMT] = (char *)tokenNames[DG_FREE_FMT];
580 va_start(ap, newToken);
581 vsnprintf((char *)formatStr, MAX_STR, newToken, ap);
582 va_end(ap);
584 GetFindReplace()[REPLACE][DG_FREE_FMT] = (char *)formatStr;
587 /* <dg_char> */
588 char *TranslationGetChar()
590 return GetFindReplace()[REPLACE][DG_CHAR];
592 void TranslationSetChar(char newToken)
594 GetFindReplace()[FIND][DG_CHAR] = (char *)tokenNames[DG_CHAR];
595 snprintf(GetFindReplace()[REPLACE][DG_CHAR], 2, "%c", newToken);
598 /* <dg_string> */
599 char *TranslationGetString()
601 return GetFindReplace()[REPLACE][DG_STRING];
603 void TranslationSetString(char *newToken)
605 GetFindReplace()[FIND][DG_STRING] = (char *)tokenNames[DG_STRING];
606 GetFindReplace()[REPLACE][DG_STRING] = newToken;
609 /*----------------- END of get and set access functions ---------------------*/
612 * @brief Template translation is performed in this function.
614 * @param output - where to put
615 * @param path - template file path directory in the template
616 * root directory
617 * @param templateFileName - template
618 * @param ... -
620 * @return void
622 void Translate(FILE * output, char *path, char *templateFileName, ...)
624 va_list ap;
625 char inputName[MAXPATHLEN];
626 char *bufferStart;
627 int templateRootLen;
628 FILE *template; /* template file */
630 templateRootLen =
631 snprintf(inputName, MAXPATHLEN, "%s/%s/", TEMPLATE_ROOT, path);
632 bufferStart = inputName + templateRootLen;
634 va_start(ap, templateFileName);
635 vsnprintf(bufferStart, MAXPATHLEN - templateRootLen, templateFileName,
636 ap);
637 va_end(ap);
639 template = fopen(inputName, "r");
640 if (template == NULL) {
641 fprintf(stderr,
642 "%s Couldn't open file \"%s\" for translation.\n",
643 ERROR_MSG, inputName);
644 return;
647 GlobalReplace(template, output);
648 fclose(template);