4 * @brief Template translation functions are here.
6 * @author Copyright (c) 2004 - 2009 CERN. Georgievskiy Yury
8 * @date Created on 27/02/2004
10 #define _GNU_SOURCE /* asprintf rocks */
11 #include "driverGen.h"
12 #include "utilities.h"
13 #include "translation.h"
19 /* Here comes all tokens, that are used in code generation */
20 typedef enum tag_Tokens
{
22 SYS_LOWER
= 0, /* 00 */
42 DG_DUMMY_STR
, /* 20 */
49 NUM_TOKENS
/* add new tokens BEFORE this */
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 *);
88 * @brief find/replace table container.
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 **));
105 (char **)calloc(NUM_TOKENS
, sizeof(char *));
106 findReplace
[REPLACE
] =
107 (char **)calloc(NUM_TOKENS
, sizeof(char *));
114 * @brief Token names length container
118 * @return pointer to token length container
120 static int *GetFindLengths()
122 static int findLengths
[NUM_TOKENS
] = { 0 };
125 if (!findLengths
[0]) {
126 for (i
= 0; i
< NUM_TOKENS
; i
++)
127 findLengths
[i
] = strlen((const char *)tokenNames
[i
]);
134 * @brief Search for a template in the text and replace it with current
137 * @param template - template file
138 * @param output - results goes here
142 static void GlobalReplace(FILE * template, FILE * output
)
145 char *location
, *start
;
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 */
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
) {
165 GetFindReplace()[FIND
][i
],
166 GetFindLengths()[i
]) == 0) {
167 fprintf(output
, "%s",
180 /* No tokens were found so dump the '<' */
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
202 * @b NOTE returned pointer should be freed by the caller
204 * @return converted module name
206 char *naming_convention(char *nm
)
212 /* count uderscores */
213 while ((tmp
= index(tmp
, (int)'_'))) {
217 /* will hold new name */
218 buf
= calloc(strlen(nm
)-i
+ 1, 1);
221 tmp
= strdup(nm
); /* prevent corruption */
223 p
= strtok(tmp
, "_");
228 p
= strtok(NULL
, "_");
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
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));
276 StrToUpper(fr
[REPLACE
][BUS_UPPER
]);
282 * @brief Reset some translation table values to default one.
288 void TranslationReset()
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
];
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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",
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",
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",
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
;
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
;
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
;
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
);
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
);
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",
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
;
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
;
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
;
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
;
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
;
563 char *TranslationGetFreeFormat()
565 return GetFindReplace()[REPLACE
][DG_FREE_FMT
];
567 void TranslationSetFreeFormat(char *newToken
, ...)
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
);
580 GetFindReplace()[REPLACE
][DG_FREE_FMT
] = (char *)formatStr
;
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
);
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
613 * @param templateFileName - template
618 void Translate(FILE * output
, char *path
, char *templateFileName
, ...)
621 char inputName
[MAXPATHLEN
];
624 FILE *template; /* template file */
627 snprintf(inputName
, MAXPATHLEN
, "%s/%s/", TEMPLATE_ROOT
, path
);
628 bufferStart
= inputName
+ templateRootLen
;
630 va_start(ap
, templateFileName
);
631 vsnprintf(bufferStart
, MAXPATHLEN
- templateRootLen
, templateFileName
,
635 template = fopen(inputName
, "r");
636 if (template == NULL
) {
638 "%s Couldn't open file \"%s\" for translation.\n",
639 ERROR_MSG
, inputName
);
643 GlobalReplace(template, output
);