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"
23 /* Here comes all tokens, that are used in code generation */
24 typedef enum tag_Tokens
{
26 SYS_LOWER
= 0, /* 00 */
46 DG_DUMMY_STR
, /* 20 */
53 NUM_TOKENS
/* add new tokens BEFORE this */
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 *);
92 * @brief find/replace table container.
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 **));
109 (char **)calloc(NUM_TOKENS
, sizeof(char *));
110 findReplace
[REPLACE
] =
111 (char **)calloc(NUM_TOKENS
, sizeof(char *));
118 * @brief Token names length container
122 * @return pointer to token length container
124 static int *GetFindLengths()
126 static int findLengths
[NUM_TOKENS
] = { 0 };
129 if (!findLengths
[0]) {
130 for (i
= 0; i
< NUM_TOKENS
; i
++)
131 findLengths
[i
] = strlen((const char *)tokenNames
[i
]);
138 * @brief Search for a template in the text and replace it with current
141 * @param template - template file
142 * @param output - results goes here
146 static void GlobalReplace(FILE * template, FILE * output
)
149 char *location
, *start
;
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 */
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
) {
169 GetFindReplace()[FIND
][i
],
170 GetFindLengths()[i
]) == 0) {
171 fprintf(output
, "%s",
184 /* No tokens were found so dump the '<' */
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
206 * @b NOTE returned pointer should be freed by the caller
208 * @return converted module name
210 char *naming_convention(char *nm
)
216 /* count uderscores */
217 while ((tmp
= index(tmp
, (int)'_'))) {
221 /* will hold new name */
222 buf
= calloc(strlen(nm
)-i
+ 1, 1);
225 tmp
= strdup(nm
); /* prevent corruption */
227 p
= strtok(tmp
, "_");
232 p
= strtok(NULL
, "_");
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
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));
280 StrToUpper(fr
[REPLACE
][BUS_UPPER
]);
286 * @brief Reset some translation table values to default one.
292 void TranslationReset()
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
];
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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",
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",
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",
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
;
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
;
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
;
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
);
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
);
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",
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
;
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
;
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
;
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
;
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
;
567 char *TranslationGetFreeFormat()
569 return GetFindReplace()[REPLACE
][DG_FREE_FMT
];
571 void TranslationSetFreeFormat(char *newToken
, ...)
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
);
584 GetFindReplace()[REPLACE
][DG_FREE_FMT
] = (char *)formatStr
;
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
);
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
617 * @param templateFileName - template
622 void Translate(FILE * output
, char *path
, char *templateFileName
, ...)
625 char inputName
[MAXPATHLEN
];
628 FILE *template; /* template file */
631 snprintf(inputName
, MAXPATHLEN
, "%s/%s/", TEMPLATE_ROOT
, path
);
632 bufferStart
= inputName
+ templateRootLen
;
634 va_start(ap
, templateFileName
);
635 vsnprintf(bufferStart
, MAXPATHLEN
- templateRootLen
, templateFileName
,
639 template = fopen(inputName
, "r");
640 if (template == NULL
) {
642 "%s Couldn't open file \"%s\" for translation.\n",
643 ERROR_MSG
, inputName
);
647 GlobalReplace(template, output
);