[driver-gen-git] Add git library files.
[driver-gen.git] / translation.c
blob7b67375e7890a45c397cbaf0f562b2ab1e9204f8
1 /**
2 * @file translation.c
4 * @brief Template translation functions are here.
6 * @author Copyright (c) 2004 - 2009 CERN. Georgievskiy Yury
8 * @date Created on 27/02/2004
9 */
10 #define _GNU_SOURCE /* asprintf rocks */
11 #include "driverGen.h"
12 #include "utilities.h"
13 #include "translation.h"
15 #define FIND 0
16 #define REPLACE 1
17 #define INT_LEN 16
19 /* Here comes all tokens, that are used in code generation */
20 typedef enum tag_Tokens {
21 /* indexes */
22 SYS_LOWER = 0, /* 00 */
23 MOD_NAME, /* 01 */
24 BUS_UPPER, /* 02 */
25 INT_NUM, /* 03 */
26 PLAIN_NUM, /* 04 */
27 HEX_NUM, /* 05 */
28 FANCY_NUM, /* 06 */
29 EXTRA_NUM, /* 07 */
30 DEC_NUM, /* 08 */
31 DDD_NUM, /* 09 */
32 REG_NAME, /* 10 */
33 REG_COMM, /* 11 */
34 REG_TYPE, /* 12 */
35 REG_DEPTH, /* 13 */
36 REG_LOOP, /* 14 */
37 REG_ID, /* 15 */
38 IOCTL_CONST, /* 16 */
39 PRECISION, /* 17 */
40 BASE_ADDR, /* 18 */
41 FANCY_STR, /* 19 */
42 DG_DUMMY_STR, /* 20 */
43 DRVR_TYPE, /* 21 */
44 DG_COMMENT, /* 22 */
45 DG_FREE_FMT, /* 23 */
46 DG_CHAR, /* 24 */
47 DG_STRING, /* 25 */
48 DG_REG_SZ, /* 26 */
49 NUM_TOKENS /* add new tokens BEFORE this */
50 } Tokens;
52 static char *tokenNames[NUM_TOKENS] = {
53 [SYS_LOWER] = "<sys_lower>",
54 [MOD_NAME] = "<mod_name>",
55 [BUS_UPPER] = "<bus_upper>",
56 [INT_NUM] = "<int_num>",
57 [PLAIN_NUM] = "<plain_num>",
58 [HEX_NUM] = "<hex_num>",
59 [FANCY_NUM] = "<fancy_num>",
60 [EXTRA_NUM] = "<extra_num>",
61 [DEC_NUM] = "<dec_num>",
62 [DDD_NUM] = "<ddd_num>",
63 [REG_NAME] = "<reg_name>",
64 [REG_COMM] = "<reg_comment>",
65 [REG_TYPE] = "<reg_type>",
66 [REG_DEPTH] = "<reg_depth>",
67 [REG_LOOP] = "<reg_loop>",
68 [REG_ID] = "<reg_id>",
69 [IOCTL_CONST] = "<ioctl_const>",
70 [PRECISION] = "<precision>",
71 [BASE_ADDR] = "<base_addr>",
72 [FANCY_STR] = "<fancy_str>",
73 [DG_DUMMY_STR] = "<dg_dummy_str>",
74 [DRVR_TYPE] = "<drvr_type>",
75 [DG_COMMENT] = "<dg_comment>",
76 [DG_FREE_FMT] = "<dg_free_fmt>",
77 [DG_CHAR] = "<dg_char>",
78 [DG_STRING] = "<dg_string>",
79 [DG_REG_SZ] = "<dg_reg_sz>"
82 static int ModNameLen;
83 static char ***GetFindReplace();
84 static int *GetFindLengths();
85 static void GlobalReplace(FILE *, FILE *);
87 /**
88 * @brief find/replace table container.
90 * @param none
92 * All possible templates are checked here for validity.
94 * @return find/replace table pointer
96 static char ***GetFindReplace(void)
98 static char*** findReplace = NULL;
100 if (!findReplace) { /* init only once */
102 findReplace = (char ***)calloc(2, sizeof(char **));
104 findReplace[FIND] =
105 (char **)calloc(NUM_TOKENS, sizeof(char *));
106 findReplace[REPLACE] =
107 (char **)calloc(NUM_TOKENS, sizeof(char *));
110 return findReplace;
114 * @brief Token names length container
116 * @param none
118 * @return pointer to token length container
120 static int *GetFindLengths()
122 static int findLengths[NUM_TOKENS] = { 0 };
123 int i;
125 if (!findLengths[0]) {
126 for (i = 0; i < NUM_TOKENS; i++)
127 findLengths[i] = strlen((const char *)tokenNames[i]);
130 return findLengths;
134 * @brief Search for a template in the text and replace it with current
135 * template value.
137 * @param template - template file
138 * @param output - results goes here
140 * @return void
142 static void GlobalReplace(FILE * template, FILE * output)
144 char line[2048];
145 char *location, *start;
146 int swapped, i;
148 while (fgets(line, 2048, template) != NULL) {
149 start = location = line;
151 while ((location = (char *)index(start, '<')) != NULL) {
153 /* Dump the characters parsed so far */
154 swapped = 0;
155 fwrite(start, 1, (int)(location - start), output);
156 start = location + 1;
158 /* Check if the '<' character found is an interesting
159 token. If so replace it with the appropriate string
160 and skip the input pointer to just past the token. */
161 for (i = 0; i < NUM_TOKENS; i++) {
162 if (GetFindReplace()[FIND][i] != NULL) {
163 if (strncmp
164 (location,
165 GetFindReplace()[FIND][i],
166 GetFindLengths()[i]) == 0) {
167 fprintf(output, "%s",
168 (char *)
169 GetFindReplace()
170 [REPLACE][i]);
171 start =
172 location +
173 GetFindLengths()[i];
174 swapped = 1;
175 break;
180 /* No tokens were found so dump the '<' */
181 if (!swapped)
182 fputc('<', output);
184 /* Dump the remaining characters */
185 fprintf(output, "%s", start);
190 * @brief Naming convetion factory
192 * @param nm -- module name _exactly_ as in the DB
194 * Naming convention is the following:
196 * TST_CIBC --> TstCibc
197 * A4032VXIVME --> A4032vxivme
198 * SHARED_CIBC_TST --> SharedCibcTst
199 * RF_IRQ_TEST --> RfIrqTest
200 * etc...
202 * @b NOTE returned pointer should be freed by the caller
204 * @return converted module name
206 char *naming_convention(char *nm)
208 char *buf, *bptr;
209 char *p, i = 0;
210 char *tmp = nm;
212 /* count uderscores */
213 while ((tmp = index(tmp, (int)'_'))) {
214 ++i; ++tmp;
217 /* will hold new name */
218 buf = calloc(strlen(nm)-i + 1, 1);
219 bptr = buf;
221 tmp = strdup(nm); /* prevent corruption */
222 StrToLower(tmp);
223 p = strtok(tmp, "_");
224 while (p) {
225 *p = toupper(*p);
226 strcpy(bptr, p);
227 bptr += strlen(p);
228 p = strtok(NULL, "_");
230 free(tmp);
231 return buf;
235 * @brief Template table initialization.
237 * @param moduleName -- Module Name _exactly_ as in the DataBase
238 * @param bus -- @b pci or @b vme buses are supproted
240 * @return void
242 void TranslationInit(char *moduleName, char *bus)
244 char ***fr = GetFindReplace(); /* find&&replace */
245 ModNameLen = strlen(moduleName);
247 fr[REPLACE][MOD_NAME] = (char *)strdup(moduleName);
248 fr[REPLACE][BUS_UPPER] = (char *)strdup(bus);
249 fr[REPLACE][SYS_LOWER] = naming_convention(moduleName);
250 fr[REPLACE][INT_NUM] = (char *)calloc(INT_LEN, sizeof(char));
251 fr[REPLACE][PLAIN_NUM] = (char *)calloc(INT_LEN, sizeof(char));
252 fr[REPLACE][HEX_NUM] = (char *)calloc(INT_LEN, sizeof(char));
253 fr[REPLACE][FANCY_NUM] = (char *)calloc(INT_LEN, sizeof(char));
254 fr[REPLACE][EXTRA_NUM] = (char *)calloc(INT_LEN, sizeof(char));
255 fr[REPLACE][DEC_NUM] = (char *)calloc(INT_LEN, sizeof(char));
256 fr[REPLACE][DDD_NUM] = (char *)calloc(INT_LEN, sizeof(char));
257 fr[REPLACE][REG_DEPTH] = (char *)calloc(INT_LEN, sizeof(char));
258 fr[REPLACE][REG_LOOP] = (char *)calloc(INT_LEN, sizeof(char));
259 fr[REPLACE][REG_ID] = (char *)calloc(NAME_LEN + 3, sizeof(char));
260 fr[REPLACE][PRECISION] = (char *)calloc(INT_LEN, sizeof(char));
261 fr[REPLACE][IOCTL_CONST] = (char *)calloc(NAME_LEN + ModNameLen, sizeof(char));
262 fr[REPLACE][REG_NAME] = NULL;
263 fr[REPLACE][REG_TYPE] = NULL;
264 fr[REPLACE][REG_COMM] = NULL;
265 fr[REPLACE][BASE_ADDR] = NULL;
266 fr[REPLACE][FANCY_STR] = NULL;
267 fr[REPLACE][DG_DUMMY_STR] = NULL;
268 fr[REPLACE][DRVR_TYPE] = NULL;
269 fr[REPLACE][DG_COMMENT] = NULL;
270 fr[REPLACE][DG_FREE_FMT] = NULL;
271 fr[REPLACE][DG_CHAR] = (char *)calloc(2, sizeof(char));
272 fr[REPLACE][DG_STRING] = NULL;
273 fr[REPLACE][DG_REG_SZ] = (char *)calloc(INT_LEN, sizeof(char));
275 /* <bus_upper> */
276 StrToUpper(fr[REPLACE][BUS_UPPER]);
278 TranslationReset();
282 * @brief Reset some translation table values to default one.
284 * @param none
286 * @return void
288 void TranslationReset()
290 int i;
292 for (i = 0; i < NUM_TOKENS; i++)
293 GetFindReplace()[FIND][i] = NULL;
295 GetFindReplace()[FIND][SYS_LOWER] = (char *)tokenNames[SYS_LOWER];
296 GetFindReplace()[FIND][MOD_NAME] = (char *)tokenNames[MOD_NAME];
297 GetFindReplace()[FIND][BUS_UPPER] = (char *)tokenNames[BUS_UPPER];
300 /*---------------- GET and SET access functions -----------------------------*/
302 /* Returns modified module name Example: SHARED_CIBC => SharedCibc */
303 char *TranslationGetSysLower()
305 return GetFindReplace()[REPLACE][SYS_LOWER];
308 /* Returns module name EXACTLY as in the dataBase */
309 char *TranslationGetModName()
311 return GetFindReplace()[REPLACE][MOD_NAME];
314 /* Returns bus (VME or PCI) */
315 char *TranslationGetBus()
317 return GetFindReplace()[REPLACE][BUS_UPPER];
320 /* <int_num> */
321 char *TranslationGetIntNum()
323 return GetFindReplace()[REPLACE][INT_NUM];
325 void TranslationSetIntNum(int newNum)
327 GetFindReplace()[FIND][INT_NUM] = (char *)tokenNames[INT_NUM];
328 snprintf(GetFindReplace()[REPLACE][INT_NUM], INT_LEN, "%d", newNum);
331 /* <plain_num> */
332 char *TranslationGetPlainNum()
334 return GetFindReplace()[REPLACE][PLAIN_NUM];
336 void TranslationSetPlainNum(int newNum)
338 GetFindReplace()[FIND][PLAIN_NUM] = (char *)tokenNames[PLAIN_NUM];
339 snprintf(GetFindReplace()[REPLACE][PLAIN_NUM], INT_LEN, "%d", newNum);
342 /* <hex_num> */
343 char *TranslationGetHexNum()
345 return GetFindReplace()[REPLACE][HEX_NUM];
347 void TranslationSetHexNum(int newNum)
349 GetFindReplace()[FIND][HEX_NUM] = (char *)tokenNames[HEX_NUM];
350 snprintf(GetFindReplace()[REPLACE][HEX_NUM], INT_LEN, "0x%x", newNum);
353 /* <fancy_num> */
354 char *TranslationGetFancyNum()
356 return GetFindReplace()[REPLACE][FANCY_NUM];
358 void TranslationSetFancyNum(int newNum)
360 GetFindReplace()[FIND][FANCY_NUM] = (char *)tokenNames[FANCY_NUM];
361 snprintf(GetFindReplace()[REPLACE][FANCY_NUM], INT_LEN, "%02d", newNum);
364 /* <extra_num> */
365 char *TranslationGetExtraNum()
367 return GetFindReplace()[REPLACE][EXTRA_NUM];
369 void TranslationSetExtraNum(int newNum)
371 GetFindReplace()[FIND][EXTRA_NUM] = (char *)tokenNames[EXTRA_NUM];
372 snprintf(GetFindReplace()[REPLACE][EXTRA_NUM], INT_LEN, "0x%X", newNum);
375 /* <dec_num> */
376 char *TranslationGetDecNum()
378 return GetFindReplace()[REPLACE][DEC_NUM];
380 void TranslationSetDecNum(int newNum)
382 GetFindReplace()[FIND][DEC_NUM] = (char *)tokenNames[DEC_NUM];
383 snprintf(GetFindReplace()[REPLACE][DEC_NUM], INT_LEN, "%d", newNum);
386 /* <ddd_num> */
387 char *TranslationGetDDDNum()
389 return GetFindReplace()[REPLACE][DDD_NUM];
391 void TranslationSetDDDNum(int newNum)
393 GetFindReplace()[FIND][DDD_NUM] = (char *)tokenNames[DDD_NUM];
394 snprintf(GetFindReplace()[REPLACE][DDD_NUM], INT_LEN, "%d", newNum);
397 /* <reg_loop> */
398 char *TranslationGetRegLoop()
400 return GetFindReplace()[REPLACE][REG_LOOP];
402 void TranslationSetRegLoop(int newRegLoop)
404 GetFindReplace()[FIND][REG_LOOP] = (char *)tokenNames[REG_LOOP];
405 snprintf(GetFindReplace()[REPLACE][REG_LOOP], INT_LEN, "%d",
406 newRegLoop);
409 /* <reg_id> */
410 char *TranslationGetRegId()
412 return GetFindReplace()[REPLACE][REG_ID];
414 void TranslationSetRegId(char *newToken)
416 GetFindReplace()[FIND][REG_ID] = (char *)tokenNames[REG_ID];
417 snprintf(GetFindReplace()[REPLACE][REG_ID], NAME_LEN, "%s_ID",
418 newToken);
421 /* <reg_depth> */
422 char *TranslationGetRegDepth()
424 return GetFindReplace()[REPLACE][REG_DEPTH];
426 void TranslationSetRegDepth(int newRegDepth)
428 GetFindReplace()[FIND][REG_DEPTH] = (char *)tokenNames[REG_DEPTH];
429 snprintf(GetFindReplace()[REPLACE][REG_DEPTH], INT_LEN, "%d",
430 newRegDepth);
433 /* <reg_name> */
434 char *TranslationGetRegName()
436 return GetFindReplace()[REPLACE][REG_NAME];
438 void TranslationSetRegName(char *newToken)
440 GetFindReplace()[FIND][REG_NAME] = (char *)tokenNames[REG_NAME];
441 GetFindReplace()[REPLACE][REG_NAME] = newToken;
444 /* <reg_comment> */
445 char *TranslationGetRegComm()
447 return GetFindReplace()[REPLACE][REG_COMM];
449 void TranslationSetRegComm(char *newToken)
451 GetFindReplace()[FIND][REG_COMM] = (char *)tokenNames[REG_COMM];
452 GetFindReplace()[REPLACE][REG_COMM] = newToken;
455 /* <reg_type> */
456 char *TranslationGetRegType()
458 return GetFindReplace()[REPLACE][REG_TYPE];
460 void TranslationSetRegType(char *newToken)
462 GetFindReplace()[FIND][REG_TYPE] = (char *)tokenNames[REG_TYPE];
463 GetFindReplace()[REPLACE][REG_TYPE] = newToken;
466 /* <dg_reg_sz> */
467 char* TranslationGetRegSize()
469 return GetFindReplace()[REPLACE][DG_REG_SZ];
471 void TranslationSetRegSize(int newRegSz)
473 GetFindReplace()[FIND][DG_REG_SZ] = (char *)tokenNames[DG_REG_SZ];
474 snprintf(GetFindReplace()[REPLACE][DG_REG_SZ], INT_LEN, "%d", newRegSz);
477 /* <ioctl_const> */
478 char *TranslationGetIoctlConst()
480 return GetFindReplace()[REPLACE][IOCTL_CONST];
482 void TranslationSetIoctlConst(char *token, char *regName)
484 GetFindReplace()[FIND][IOCTL_CONST] = (char *)tokenNames[IOCTL_CONST];
485 if (!strncmp(regName, SRVREGPREF, strlen(SRVREGPREF))) /* service register */
486 snprintf(GetFindReplace()[REPLACE][IOCTL_CONST],
487 NAME_LEN + ModNameLen, "SRV_%s_%s", token,
488 regName + strlen(SRVREGPREF));
489 else /* normal module register */
490 snprintf(GetFindReplace()[REPLACE][IOCTL_CONST],
491 NAME_LEN + ModNameLen, "%s_%s_%s",
492 TranslationGetModName(), token, regName);
495 /* <precision> */
496 char *TranslationGetPrecision()
498 return GetFindReplace()[REPLACE][PRECISION];
500 void TranslationSetPrecision(int newPrecision)
502 GetFindReplace()[FIND][PRECISION] = (char *)tokenNames[PRECISION];
503 snprintf(GetFindReplace()[REPLACE][PRECISION], INT_LEN, "%d",
504 newPrecision);
507 /* <base_addr> */
508 char *TranslationGetBaseAddr()
510 return GetFindReplace()[REPLACE][BASE_ADDR];
512 void TranslationSetBaseAddr(char *newToken)
514 GetFindReplace()[FIND][BASE_ADDR] = (char *)tokenNames[BASE_ADDR];
515 GetFindReplace()[REPLACE][BASE_ADDR] = newToken;
518 /* <fancy_str> */
519 char *TranslationGetFancyString()
521 return GetFindReplace()[REPLACE][FANCY_STR];
523 void TranslationSetFancyString(char *newToken)
525 GetFindReplace()[FIND][FANCY_STR] = (char *)tokenNames[FANCY_STR];
526 GetFindReplace()[REPLACE][FANCY_STR] = newToken;
529 /* <dg_dummy_str> */
530 char *TranslationGetDummyString()
532 return GetFindReplace()[REPLACE][DG_DUMMY_STR];
534 void TranslationSetDummyString(char *newToken)
536 GetFindReplace()[FIND][DG_DUMMY_STR] = (char *)tokenNames[DG_DUMMY_STR];
537 GetFindReplace()[REPLACE][DG_DUMMY_STR] = newToken;
540 /* <drvr_type> */
541 char *TranslationGetDriverType()
543 return GetFindReplace()[REPLACE][DRVR_TYPE];
545 void TranslationSetDriverType(char *newToken)
547 GetFindReplace()[FIND][DRVR_TYPE] = (char *)tokenNames[DRVR_TYPE];
548 GetFindReplace()[REPLACE][DRVR_TYPE] = newToken;
551 /* <dg_comment> */
552 char *TranslationGetComment()
554 return GetFindReplace()[REPLACE][DG_COMMENT];
556 void TranslationSetComment(char *newToken)
558 GetFindReplace()[FIND][DG_COMMENT] = (char *)tokenNames[DG_COMMENT];
559 GetFindReplace()[REPLACE][DG_COMMENT] = newToken;
562 /* <dg_free_fmt> */
563 char *TranslationGetFreeFormat()
565 return GetFindReplace()[REPLACE][DG_FREE_FMT];
567 void TranslationSetFreeFormat(char *newToken, ...)
569 va_list ap;
570 static char formatStr[MAX_STR];
572 memset(formatStr, 0, sizeof(formatStr));
574 GetFindReplace()[FIND][DG_FREE_FMT] = (char *)tokenNames[DG_FREE_FMT];
576 va_start(ap, newToken);
577 vsnprintf((char *)formatStr, MAX_STR, newToken, ap);
578 va_end(ap);
580 GetFindReplace()[REPLACE][DG_FREE_FMT] = (char *)formatStr;
583 /* <dg_char> */
584 char *TranslationGetChar()
586 return GetFindReplace()[REPLACE][DG_CHAR];
588 void TranslationSetChar(char newToken)
590 GetFindReplace()[FIND][DG_CHAR] = (char *)tokenNames[DG_CHAR];
591 snprintf(GetFindReplace()[REPLACE][DG_CHAR], 2, "%c", newToken);
594 /* <dg_string> */
595 char *TranslationGetString()
597 return GetFindReplace()[REPLACE][DG_STRING];
599 void TranslationSetString(char *newToken)
601 GetFindReplace()[FIND][DG_STRING] = (char *)tokenNames[DG_STRING];
602 GetFindReplace()[REPLACE][DG_STRING] = newToken;
605 /*----------------- END of get and set access functions ---------------------*/
608 * @brief Template translation is performed in this function.
610 * @param output - where to put
611 * @param path - template file path directory in the template
612 * root directory
613 * @param templateFileName - template
614 * @param ... -
616 * @return void
618 void Translate(FILE * output, char *path, char *templateFileName, ...)
620 va_list ap;
621 char inputName[MAXPATHLEN];
622 char *bufferStart;
623 int templateRootLen;
624 FILE *template; /* template file */
626 templateRootLen =
627 snprintf(inputName, MAXPATHLEN, "%s/%s/", TEMPLATE_ROOT, path);
628 bufferStart = inputName + templateRootLen;
630 va_start(ap, templateFileName);
631 vsnprintf(bufferStart, MAXPATHLEN - templateRootLen, templateFileName,
632 ap);
633 va_end(ap);
635 template = fopen(inputName, "r");
636 if (template == NULL) {
637 fprintf(stderr,
638 "%s Couldn't open file \"%s\" for translation.\n",
639 ERROR_MSG, inputName);
640 return;
643 GlobalReplace(template, output);
644 fclose(template);