#include #include #include #include #include #include #include #include #include #include #include #include #ifndef BASE_VERSION /* This is R3.14.* */ extern int iocshCmd (const char *cmd); #endif int dbLoadDatabase(char *filename, char *path, char *substitutions); int require(char* lib, char* version) { char** path; char* loaded; SYM_TYPE type; struct stat filestat; if (symFindByName(sysSymTbl, "LIB", (char**)&path, &type) != OK) { static char* here = "."; path = &here; } if (!lib) { printf("Usage: require \"\" [, \"\"]\n"); printf("Loads Lib[-] and dbd/[-].dbd\n"); printf("Directory is LIB = %s\n", *path); return ERROR; } loaded = getLibVersion(lib); if (!loaded) { char libname[256]; char dbdname[256]; /* first try local library */ if (version) { sprintf(libname, "bin/%sLib-%s.munch", lib, version); sprintf(dbdname, "dbd/%s-%s.dbd", lib, version); } else { sprintf(libname, "bin/%sLib.munch", lib); sprintf(dbdname, "dbd/%s.dbd", lib); } if (stat(libname, &filestat) == ERROR) { /* no munched local lib */ libname[strlen(libname)-6]=0; /* skip ".munch" */ } if (stat(libname, &filestat) == ERROR) { /* no local lib at all */ libname[strlen(libname)-6]=0; /* skip ".munch" */ if (version) { sprintf(libname, "%s/%sLib-%s.munch", *path, lib, version); sprintf(dbdname, "%s/dbd/%s-%s.dbd", *path, lib, version); } else { sprintf(libname, "%s/%sLib.munch", *path, lib); sprintf(dbdname, "%s/dbd/%s.dbd", *path, lib); } if (stat(libname, &filestat) == ERROR) { /* no munched lib */ libname[strlen(libname)-6]=0; /* skip ".munch" */ } if (stat(libname, &filestat) == ERROR) { /* still no library found */ printf("Library %s not found\n", libname); printf("Aborting startup stript.\n"); shellScriptAbort(); return ERROR; } } errno = 0; printf("loading %s\n", libname); if (ld(0, 0, libname) == NULL) { printf("Aborting startup stript.\n"); shellScriptAbort(); return ERROR; } if (errno == S_symLib_SYMBOL_NOT_FOUND) { printf("Library requires some other library\n"); printf("Aborting startup stript.\n"); shellScriptAbort(); return ERROR; } loaded = getLibVersion(lib); if (stat(dbdname, &filestat) != ERROR) { /* If file exists */ printf("loading %s\n", dbdname); if (dbLoadDatabase(dbdname, NULL, NULL) != OK) { taskDelay(sysClkRateGet()); printf ("Aborting startup stript.\n"); shellScriptAbort(); return ERROR; } #ifndef BASE_VERSION { char initfunc[256]; sprintf (initfunc, "%s_registerRecordDeviceDriver", lib); iocshCmd (initfunc); } #endif } if (loaded) printf("%s version is %s\n", lib, loaded); return OK; } else { /* Library already loaded. Check Version. */ if (version && strcmp(loaded, version) != 0) { int lmajor, lminor, lpatch, lmatches; int major, minor, patch, matches; lmatches = sscanf(loaded, "%d.%d.%d", &lmajor, &lminor, &lpatch); matches = sscanf(version, "%d.%d.%d", &major, &minor, &patch); if (matches == 0 || lmatches == 0 /* non-numerical version*/ || major != lmajor || (matches >= 2 && minor != lminor) || (matches > 2 && patch != lpatch)) { printf("Version conflict between requested %s\n" "and already loaded version %s.\n" "Aborting startup stript.\n", lib, loaded); shellScriptAbort(); return ERROR; } } /* Loaded version is ok */ printf("%sLib-%s already loaded\n", lib, loaded); return OK; } } char* getLibVersion(char* lib) { char symbol[256]; char* loaded; SYM_TYPE type; sprintf(symbol, "_%sLibRelease", lib); if (symFindByName(sysSymTbl, symbol, &loaded, &type) != OK) return NULL; return loaded; }