4 * @brief Pulling everything together.
6 * Device Driver Generator (aka DriverGen) tool designed to produce
7 * device drivers for a given architecture based on an abstract description
8 * of a piece of hardware.
10 * @author Copyright (C) 2002 CERN. Stuart Baird
11 * @author Copyright (C) 2003 CERN. Alain Gagnaire
12 * @author Copyright (C) 2003 - 2010 CERN. Georgievskiy Yury <ygeorgie@cern.ch>
14 * @date Created on 27/02/2004
16 * @section license_sec License
17 * Released under the GPL
19 #define _GNU_SOURCE /* asprintf rocks */
21 #include "driverGen.h"
22 #include "utilities.h"
23 #include "serviceOptions.h"
24 #include "dg-version.h"
25 #include "dg-git-lib.h"
27 struct mdescr dgmd
= { 0 }; /* Driver-Gen Module Description */
29 bool verboseMode
; /* denotes verbose driver generation */
30 static dgopt genOpt
; /* possible command line options */
31 static srvarg glob_srv_arg
; /* possible service option arguments */
32 char *driverName
; /* Driver Name. Exactly as in the DataBase */
33 char *busType
; /* bus type. 'vme' or 'pci' */
34 time_t mod_creation_time
; /* driver creation time of the currently
38 static char *allBuses
[] = {
46 /* supported command line options */
47 static struct option allLongOptions
[] = {
48 { "git", no_argument
, NULL
, 'g' },
49 { "gall", no_argument
, NULL
, 'a' },
50 { "ginfo", no_argument
, NULL
, 'i' },
51 { "general", required_argument
, NULL
, 'e' },
52 { "verbose", no_argument
, NULL
, 'n' },
53 { "srv", required_argument
, NULL
, 's' }, /* see 'serviceOptions.h'
54 for more information */
55 { "dir", required_argument
, NULL
, 'd' },
56 { "version", no_argument
, NULL
, 'v' },
57 { "help", no_argument
, NULL
, 'h' },
60 .has_arg
= no_argument
, /* 0 */
66 static int CheckAndPrepareRegs(RegisterDef_t
*, int, VmeInfo_t
*);
67 static int CheckAndPrepareBlocks(BlockDef_t
*, int);
68 static void SortRegisters(RegisterDef_t
*, VmeInfo_t
*, int, int);
69 static int LessThan(RegisterDef_t
*, RegisterDef_t
*);
70 static int GreaterThan(RegisterDef_t
*, RegisterDef_t
*);
71 static void SortBlocks(BlockDef_t
*, int, int);
72 static bool CheckBusType(char *);
73 static void DisplayUsage(char *);
74 static void ParseProgArgs(int, char *[], struct mdescr
*);
75 static void free_md(struct mdescr
*);
77 int main(int argc
, char *argv
[], char *envp
[])
82 RegisterDef_t registers
[MAX_REG
] = { {0} };
83 BlockDef_t blocks
[MAX_BLK
] = { {0} };
87 time(&mod_creation_time
);
88 printf("%s <vers. %s> started on %s\n", basename(argv
[0]), dg_version
,
89 ctime(&mod_creation_time
));
91 /* Init default parameters */
92 vmeInfo
.CheckRegister
= -1; /* no checking register */
93 verboseMode
= FALSE
; /* by default - no verbose mode */
95 ParseProgArgs(argc
, argv
, &dgmd
); /* check if provided params are valid */
97 /* init global template values for further use */
98 TranslationInit(driverName
, busType
);
100 /* setup Master installation directory */
103 /* if only general shared code should be build */
104 if (genOpt
== OPT_G_SHARED
) {
106 printf("%s: All done.\n", basename(argv
[0]));
110 /* if it's one of the service calls */
111 if (genOpt
== OPT_G_SERVICE
) {
112 if (ProcessSrvOpt(glob_srv_arg
, basename(argv
[0]))) {
113 printf("%s: service option processing fails\n",
117 printf("%s: service option processing done.\n",
123 /* get block configuration from database */
124 if (!(numBlocks
= GetBlockConfig(driverName
, blocks
, argv
[0]))) {
125 fprintf(stderr
, "%s No Blocks found for %s Module\n", ERROR_MSG
,
130 /* check if block configuration is correct */
131 if (CheckAndPrepareBlocks(blocks
, numBlocks
) != DRIVER_GEN_OK
)
134 /* get register configuration from database */
135 numRegisters
= GetRegisterConfig(driverName
, registers
, blocks
,
138 fprintf(stderr
, "%s No Registers found for %s Module\n",
139 ERROR_MSG
, driverName
);
143 /* check if register configuration is correct */
144 if (CheckAndPrepareRegs(registers
, numRegisters
, &vmeInfo
) !=
148 /* we need to compute block sizes and their register amount */
149 set_extra_block_data(registers
);
151 /* get general board information from the database */
152 if (!strcmp(TranslationGetBus(), "VME"))
153 result
= GetVmeInfo(driverName
, &vmeInfo
);
155 result
= GetPciInfo(driverName
, &pciInfo
);
158 exit(EXIT_FAILURE
); /* 1 */
160 /* setup Module source directory */
163 /* now we can start Driver/Simulator code generation */
164 if (!strcmp(TranslationGetBus(), "VME")) { /* we need VME driver */
167 if (do_git_vme_driver(driverName
, &dgmd
, registers
, numRegisters
,
168 blocks
, numBlocks
, &vmeInfo
))
171 case OPT_G_ALL
: /* generate all, include user-defined files */
172 printf("Creating %s source code directory.\n", driverName
);
173 GenerateVmeDriver(registers
, numRegisters
, blocks
,
174 numBlocks
, &vmeInfo
);
176 case OPT_G_INFO
: /* generate only info files */
177 printf("Creating %s source code directory.\n", driverName
);
178 GenerateVmeInfoFile(registers
, numRegisters
, blocks
,
179 numBlocks
, &vmeInfo
);
183 break; /* not reached */
185 } else { /* we need PCI driver */
189 do_git_pci_driver(driverName
, &dgmd
, registers
, numRegisters
,
190 blocks
, numBlocks
, &pciInfo
);
192 case OPT_G_ALL
: /* generate all, include user-defined files */
193 printf("Creating %s source code directory.\n", driverName
);
194 GenerateDrmDriver(registers
, numRegisters
, blocks
,
195 numBlocks
, &pciInfo
);
197 case OPT_G_INFO
: /* generate only install files */
198 printf("Creating %s source code directory.\n", driverName
);
199 /* TODO. Should be removed. */
200 GenerateDrmInstallFilesOLD(&pciInfo
, blocks
, numBlocks
);
204 break; /* not reached */
209 printf("All done.\n");
210 exit(EXIT_SUCCESS
); /* 0 */
214 * @brief Checks if module configuration is correct and supported.
216 * @param registers -- register description
217 * @param numRegisters -- register amount
218 * @param vmeInfo -- @b VME description
220 * @return DRIVER_GEN_OK - if configuration is ok.
221 * @return DRIVER_GEN_BAD - othervise.
223 static int CheckAndPrepareRegs(RegisterDef_t
* registers
, int numRegisters
,
227 int badConfig
= DRIVER_GEN_OK
;
228 int mappedAddr
= 0; /* checked address range */
229 int regDepth
; /* register depth, in elements */
231 for (i
= 0; i
< numRegisters
; i
++) { /* Sanitise register definition */
232 StrToLower(registers
[i
].size
);
233 StrToLower(registers
[i
].mode
);
234 registers
[i
].rar
= 0;
235 for (j
= 0; j
< strlen(registers
[i
].mode
); j
++) {
236 if (registers
[i
].mode
[j
] == 'w') {
237 registers
[i
].rar
|= AMWR
;
238 } else if (registers
[i
].mode
[j
] == 'r') {
239 registers
[i
].rar
|= AMRD
;
240 } else if (registers
[i
].mode
[j
] == 'e') {
241 registers
[i
].rar
|= AMEX
;
242 } else if (registers
[i
].mode
[j
] == 'c') {
243 vmeInfo
->CheckRegister
= i
;
245 badConfig
= DRIVER_GEN_BAD
;
246 fprintf(stderr
, "%s Register '%s' has unknown"
247 " access mode '%c'\n",
248 ERROR_MSG
, registers
[i
].name
,
249 registers
[i
].mode
[j
]);
253 strcpy(registers
[i
].upperName
, registers
[i
].name
);
254 StrToUpper(registers
[i
].upperName
);
256 if (!strcmp(registers
[i
].size
, "char"))
257 registers
[i
].regSize
= SZCHAR
;
258 else if (!strcmp(registers
[i
].size
, "short"))
259 registers
[i
].regSize
= SZSHORT
;
260 else if (!strcmp(registers
[i
].size
, "long"))
261 registers
[i
].regSize
= SZLONG
;
263 badConfig
= DRIVER_GEN_BAD
;
264 fprintf(stderr
, "%s Register '%s' has incorrect size"
266 ERROR_MSG
, registers
[i
].name
,
270 /* Check if the data is valid */
271 if (registers
[i
].timeLoop
< 0) {
272 badConfig
= DRIVER_GEN_BAD
;
273 fprintf(stderr
, "%s Register '%s' has a negative"
275 ERROR_MSG
, registers
[i
].name
,
276 registers
[i
].timeLoop
);
279 for (j
= 0; j
< strlen(registers
[i
].name
); j
++)
280 if (isspace(registers
[i
].name
[j
]))
281 /* replace wite spaces with underscore */
282 registers
[i
].name
[j
] = '_';
284 for (j
= i
+ 1; j
< numRegisters
; j
++)
285 if (!strcmp(registers
[i
].name
, registers
[j
].name
)) {
286 badConfig
= DRIVER_GEN_BAD
;
287 fprintf(stderr
, "%s Register definitions %d"
288 " and %d share the name \"%s\"\n",
289 ERROR_MSG
, i
, j
, registers
[i
].name
);
292 if (registers
[i
].rar
> AMEX
) {
293 fprintf(stderr
, "%s Register '%s' has a conflicting"
294 " access mode '%s'\n",
295 ERROR_MSG
, registers
[i
].name
,
297 sprintf(registers
[i
].mode
, "e");
298 registers
[i
].rar
= AMEX
;
301 if ((!registers
[i
].blockP
)) {
302 badConfig
= DRIVER_GEN_BAD
;
303 fprintf(stderr
, "%s Register '%s' doesn't belong to"
305 ERROR_MSG
, registers
[i
].name
);
308 if (registers
[i
].offset
< 0) {
309 badConfig
= DRIVER_GEN_BAD
;
310 fprintf(stderr
, "%s Register '%s' has negative offset"
312 ERROR_MSG
, registers
[i
].name
,
313 registers
[i
].offset
);
317 if (badConfig
== DRIVER_GEN_BAD
)
320 /* sort registers by their address */
321 SortRegisters(registers
, vmeInfo
, 0, numRegisters
- 1);
323 for (i
= 0; i
< numRegisters
- 1; i
++) {
325 if (registers
[i
].depth
<= 0)
328 regDepth
= registers
[i
].depth
;
330 /* check registers that belong to the same block only */
331 if (registers
[i
].blockP
->blockID
==
332 registers
[i
+ 1].blockP
->blockID
) {
333 /* check if there is duplicate register addresses
335 if (registers
[i
].offset
== registers
[i
+ 1].offset
) {
336 badConfig
= DRIVER_GEN_BAD
;
337 fprintf(stderr
, "%s Registers '%s' and '%s' in"
338 " Block#%d have the same offset %#x\n",
339 ERROR_MSG
, registers
[i
].name
,
340 registers
[i
+ 1].name
,
341 registers
[i
].blockP
->blockID
,
342 registers
[i
].offset
);
345 registers
[i
].offset
+
346 registers
[i
].regSize
* regDepth
;
347 if (mappedAddr
> registers
[i
+ 1].offset
) {
348 fprintf(stderr
, "%s Overlapping between '%s'"
349 " and '%s' register massives\n"
350 "\tdetected in Block#%d. Incorrect "
351 "device memory mapping. Try to "
352 "change\n\tmemory layout in the Data"
354 ERROR_MSG
, registers
[i
].name
,
355 registers
[i
+ 1].name
,
356 registers
[i
].blockP
->blockID
);
357 badConfig
= DRIVER_GEN_BAD
;
364 if (badConfig
== DRIVER_GEN_BAD
)
367 /* Check if device checking address is provided */
368 if (vmeInfo
->CheckRegister
== -1) {
369 fprintf(stderr
, "%sChecking Register is NOT provided!\n"
370 " Module availability will NOT be checked"
371 " during device driver\n installation!\n\n",
373 sleep(2); /* let user see it */
380 * @brief Checks if block configuration is correct and supported.
382 * @param blocks -- block description
383 * @param numBlocks -- block amount
385 * @return DRIVER_GEN_OK - if configuration is ok.
386 * @return DRIVER_GEN_BAD - othervise.
388 static int CheckAndPrepareBlocks(BlockDef_t
* blocks
, int numBlocks
)
391 int configState
= DRIVER_GEN_OK
;
393 for (i
= 0; i
< numBlocks
; i
++) {
394 if (blocks
[i
].blockID
< 0) {
395 fprintf(stderr
, "%s GetBlockConfig() has returned a"
396 " record with a negative block number\n",
398 configState
= DRIVER_GEN_BAD
;
401 if ((blocks
[i
].blkBaseAddr
< 1) ||
402 (blocks
[i
].blkBaseAddr
> 2)) {
403 fprintf(stderr
, "%s Block#%d is associated with"
404 " invalid base address value '%d'\n",
405 ERROR_MSG
, blocks
[i
].blockID
,
406 blocks
[i
].blkBaseAddr
);
407 configState
= DRIVER_GEN_BAD
;
410 if (blocks
[i
].offset
< 0) {
411 fprintf(stderr
, "%s Block#%d has a negative offset"
413 ERROR_MSG
, blocks
[i
].blockID
);
414 configState
= DRIVER_GEN_BAD
;
418 if (configState
== DRIVER_GEN_OK
) {
419 SortBlocks(blocks
, 0, numBlocks
- 1);
420 for (i
= 0; i
< numBlocks
- 1; i
++)
421 if (blocks
[i
].blockID
== blocks
[i
+ 1].blockID
) {
422 fprintf(stderr
, "%s GetBlockConfig() has"
423 " returned two records with block ID's"
425 ERROR_MSG
, blocks
[i
].blockID
);
426 configState
= DRIVER_GEN_BAD
;
434 * @brief Sort registers by their block indexes && addresses.
436 * @param registers -- register description table
437 * @param vmeInfo -- VME description
438 * @param low -- lowest index
439 * @param high -- highest index
441 static void SortRegisters(RegisterDef_t
*registers
, VmeInfo_t
*vmeInfo
,
445 RegisterDef_t buffer
;
446 RegisterDef_t
*median
;
451 median
= ®isters
[low
];
453 while (right
>= low
) {
454 while (LessThan(&(registers
[left
]), median
))
457 while (GreaterThan(&(registers
[right
]), median
))
463 buffer
= registers
[left
];
464 registers
[left
] = registers
[right
];
465 registers
[right
] = buffer
;
467 /* move checking register index */
468 if (vmeInfo
->CheckRegister
== left
)
469 vmeInfo
->CheckRegister
= right
;
470 else if (vmeInfo
->CheckRegister
== right
)
471 vmeInfo
->CheckRegister
= left
;
477 SortRegisters(registers
, vmeInfo
, low
, right
);
478 SortRegisters(registers
, vmeInfo
, left
, high
);
483 * @brief Check if register a is smaller then register b
485 * @param a -- reg descr
486 * @param b -- reg descr
488 * @return 1 - if first regID is smaller then the second one.
489 * @return 0 - otherwise.
491 static int LessThan(RegisterDef_t
*a
, RegisterDef_t
*b
)
493 if (a
->blockP
->blockID
< b
->blockP
->blockID
)
495 else if ((a
->blockP
->blockID
== b
->blockP
->blockID
) &&
496 (a
->offset
< b
->offset
))
503 * @brief Check if register a is greater then register b
505 * @param a -- reg descr
506 * @param b -- reg descr
508 * @return 1 - if first regID is greater then the second one.
509 * @return 0 - otherwise.
511 static int GreaterThan(RegisterDef_t
*a
, RegisterDef_t
*b
)
513 if ((a
->blockP
->blockID
== b
->blockP
->blockID
)
514 && (a
->offset
== b
->offset
))
517 return (!LessThan(a
, b
));
521 * @brief Sort blocks by their index
523 * @param blocks -- block description
524 * @param low -- low block idx
525 * @param high -- high block idx
529 static void SortBlocks(BlockDef_t
*blocks
, int low
, int high
)
538 median
= &(blocks
[low
]);
540 while (right
>= low
) {
541 while (blocks
[left
].blockID
< median
->blockID
)
544 while (blocks
[right
].blockID
> median
->blockID
)
550 buffer
= blocks
[left
];
551 blocks
[left
] = blocks
[right
];
552 blocks
[right
] = buffer
;
557 SortBlocks(blocks
, low
, right
);
558 SortBlocks(blocks
, left
, high
);
563 * @brief Checks if the bus type parameter is correct.
565 * If it is not, than error is printed out on stderr.
567 * @param str -- string to check
569 * @return TRUE - if parameter is valid.
570 * @return FALSE - otherwise.
572 static bool CheckBusType(char *str
)
575 char **ptr
, errMsg
[64];
578 snprintf(errMsg
, sizeof(errMsg
), "Bus type \'%s\' not supported.\n",
582 if (!(strcmp(*ptr
, str
))) { /* option matches */
586 ptr
++; /* move pointer */
590 fprintf(stderr
, errMsg
); /* printout error message. */
596 * @brief Educate user
598 * @param progName -- program name
602 static void DisplayUsage(char *progName
)
604 progName
= basename(progName
);
605 printf("%s %s\n\n", progName
, dg_version
);
606 printf("Usage: %s <module_name> <bus> -g[it | all | info] "
607 "<-verbose> -d <root_dir>\n", progName
);
608 printf(" %s <-general> <bus>\n", progName
);
609 printf(" %s <-h> <--version> (to get help && version info)\n",
614 printf(" <module_name> %sCompulsory%s\n", WHITE_CLR
, END_CLR
);
615 printf(" It is the name of the module for which Driver/Simulator "
616 "should be generated.\n");
617 printf(" Should be exactly as in the DataBase. See DataBase for"
618 " more info about\n Module Names.\n\n");
621 printf(" <bus> %sCompulsory%s\n", WHITE_CLR
, END_CLR
);
622 printf(" Select the bus architecture supported by the card.\n");
623 printf(" Supported buses are 'pci' or 'vme'.\n\n");
625 /* '-g' mode description */
626 printf(" -g %sOptional%s\n"
627 " What to generate (if not provided -- default will be"
628 " used):\n", WHITE_CLR
, END_CLR
);
630 " Generate complete driver framework\n");
631 printf(" -g[it] %sDefault%s\n"
632 " Generate git-controlled Driver, i.e. user-defined files"
634 " only if driver directory does not yet exist (otherwise"
635 " user-defined files\n"
636 " left intact), driver dir name doesn't have time prefix,"
638 " performed. (All files, that've got \"UserDefined\""
639 " subword in their\n"
640 " name -- are considered to be user-defined files)\n",
644 " Generate only info file for current module.\n\n");
646 /* '-verbose' mode description */
647 printf(" <-verbose> %sOptional%s\n"
648 " This enables verbose driver/simulator source code"
650 " Useful for debugging purposes.\n\n", WHITE_CLR
, END_CLR
);
652 /* '-dir' mode description */
653 printf(" <-d> %sOptional%s\n"
654 " Change root directory, where generated driver source code"
656 " Default one is 'genDriverDeposit'\n\n",
659 /* '-general' mode description */
660 printf(" <-general> %sOptional%s\n", WHITE_CLR
, END_CLR
);
661 printf(" Normal users should ignore this option.\n If all that you"
662 " want - is to generate a Driver/Simulator framework for a\n"
663 " given module, and you didn't make any changes in"
664 " installation procedure\n and library code (that is usially"
665 " the case), than you should ignore\n this option. Only"
666 " general purpose files (i.e. identical for all types of \n"
667 " Driver/Simulator) will be generated. These are module"
668 " Driver/Simulator\n installation and unistallaion programs,"
669 " 'DriverAccess' library and general\n header files. Normally,"
670 " general purpose part should be rebuild by 'driverGen'\n"
671 " software developer, and only in case of it's modification."
672 " Bus type (pci or\n vme) should be provided.\n\n");
674 /* show some examples examples */
675 printf("EXAMPLES: %s BNLDSP vme -gall\n"
676 " %s SHARED_CIBC vme\n\n",
680 #define OPT_COLLIDE(__opt) \
683 if (genOpt & (~__opt)) { \
684 genOpt = OPT_COLLIDE; \
690 #define MAX_NON_OPT_ARGS 3 /* max non-option arguments amount */
693 * @brief Parses command line arguments.
695 * @param argc -- command line argument count
696 * @param argv -- command line argument array
697 * @param md -- module description
701 static void ParseProgArgs(int argc
, char *argv
[], struct mdescr
*md
)
703 int cur_opt
; /* currently parsed option */
704 char arg_mas
[MAX_NON_OPT_ARGS
][NAME_LEN
]; /* hold all non-option
706 int arg_cntr
= 0; /* non-option arguments counter */
707 int expected_arg_amount
= 0;
709 memset(arg_mas
, 0, sizeof(arg_mas
));
711 getopt_long_only(argc
, argv
, "-hv", allLongOptions
,
712 NULL
)) != EOF
) && (genOpt
!= OPT_COLLIDE
)
713 && (glob_srv_arg
!= SRV_ARG_ERROR
) && (arg_cntr
!= 27051977)) {
715 case 1: /* this is non-option arg */
716 if (arg_cntr
== MAX_NON_OPT_ARGS
) {
720 strncpy(arg_mas
[arg_cntr
], optarg
, NAME_LEN
);
721 arg_mas
[arg_cntr
][NAME_LEN
- 1] = 0; /* safety
725 case 'h': /* user need help */
726 DisplayUsage(argv
[0]);
727 exit(EXIT_SUCCESS
); /* 0 */
729 case 'g': /* generate driver, controlled by git */
730 if (OPT_COLLIDE(OPT_G_IT
))
733 expected_arg_amount
= 2;
736 case 'a': /* generate full driver (include user part) */
737 if (OPT_COLLIDE(OPT_G_ALL
))
740 expected_arg_amount
= 2;
742 case 'i': /* only info file */
743 if (OPT_COLLIDE(OPT_G_INFO
))
746 expected_arg_amount
= 2;
748 case 'e': /* general part only (-general) */
749 if (OPT_COLLIDE(OPT_G_SHARED
))
751 genOpt
= OPT_G_SHARED
;
752 expected_arg_amount
= 0;
753 busType
= strdup(optarg
); /* set bus type */
754 driverName
= strdup("GENERAL"); /* set name for
757 case 's': /* we have service option */
758 /* see serviceOptions.h for more info */
759 if (OPT_COLLIDE(OPT_G_SERVICE
))
761 genOpt
= OPT_G_SERVICE
;
762 /* they've got non-option arguments. set their amount */
763 if (!strcmp(optarg
, "drvrvers")) {
764 expected_arg_amount
= 3;
765 glob_srv_arg
= SRV_VF_DRVR
; /* Verion File for
767 } else if (!strcmp(optarg
, "simvers")) {
768 expected_arg_amount
= 3;
769 glob_srv_arg
= SRV_VF_SIM
; /* Version File for
772 expected_arg_amount
= 0;
773 glob_srv_arg
= SRV_ARG_ERROR
;
776 case 'n': /* verbose printout during code generation */
779 case 'd': /* root directory, where driver directory will be created */
780 asprintf(&md
->mdn
, "%s", optarg
);
782 case 'v': /* version string */
783 printf("%s [Compiled on %s %s]\n", dg_version
,
787 case '?': /* wrong option */
789 fprintf(stderr
, "Wrong option.\n");
790 fprintf(stderr
, "Try \'%s -h\' for more information.\n",
792 exit(EXIT_FAILURE
); /* 1 */
797 if (genOpt
== OPT_COLLIDE
) { /* check for option colliding */
798 fprintf(stderr
, "Option collision detected!\n");
799 fprintf(stderr
, "Try \'%s -h\' for more information.\n",
801 exit(EXIT_FAILURE
); /* 1 */
804 if (!genOpt
) { /* user didn't provide command line
805 option -- set default */
806 genOpt
= OPT_G_IT
; /* by default create git-controlled driver */
808 expected_arg_amount
= 2;
811 if (glob_srv_arg
== SRV_ARG_ERROR
) { /* check service option argument */
812 fprintf(stderr
, "Wrong service option argument.\n");
813 fprintf(stderr
, "Try \'%s -h\' for more information.\n",
815 exit(EXIT_FAILURE
); /* 1 */
818 if (arg_cntr
!= expected_arg_amount
) { /* check for argument amount */
819 fprintf(stderr
, "Wrong arguments.\n");
820 fprintf(stderr
, "Try \'%s -h\' for more information.\n",
822 exit(EXIT_FAILURE
); /* 1 */
825 /* now we handle all non-option arguments
826 (they are in 'arg_mas' massive) */
829 if (git_check_version())
833 driverName
= strdup(arg_mas
[0]); /* set DB driver name */
834 busType
= strdup(arg_mas
[1]); /* set bus type */
837 break; /* nothing to do */
839 switch (glob_srv_arg
) {
842 driverName
= strdup(arg_mas
[0]); /* set DB driver
844 busType
= strdup(arg_mas
[1]); /* set bus type */
845 SetSrvOptArgs(glob_srv_arg
, arg_mas
[2]);
854 if (!CheckBusType(busType
)) { /* check 'Bus Type' */
855 fprintf(stderr
, "Try \'%s -h\' for more information.\n",
857 exit(EXIT_FAILURE
); /* 1 */
861 asprintf(&md
->mdn
, "%s", DEFAULT_MASTER_DIR
);
865 * @brief Free allocated resources of module description.
867 * @param md -- module description.
870 static void free_md(struct mdescr
*md
)