PUBLIC void* (CSCsymtabEntryNext) ( CSCsymTableType const symTab, void* const lhPtr ) { CSChashEntryType nextHashEntry = NULL; ASSERT_RTN (symTab!=NULL, "CSCsymtabEntryNext: null symTab", NULL); ASSERT_RTN ( \ symTab->sig_lo == SYMTAB_SIG, \ "CSCsymtabEntryNext: symTab blows", \ NULL \ ); ASSERT_RTN ( \ symTab->sig_hi == SYMTAB_SIG, \ "CSCsymtabEntryNext: symTab blows", \ NULL \ ); MON_ENTER(symTab); nextHashEntry = (CSChashEntryType)lhPtr; nextHashEntry = CSChashEntryNext (symTab->table, nextHashEntry); MON_EXIT(symTab); return (nextHashEntry); }
PUBLIC int (CSCsymtabStat) ( CSCsymTableType const symTab, size_t* const sizePtr ) { int statStat = CSC_OK; ASSERT_RTN (symTab != NULL, "CSCsymtabStat: null symTab", CSC_BADARG); ASSERT_RTN ( \ symTab->sig_lo == SYMTAB_SIG, \ "CSCsymtabStat: symTab blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ symTab->sig_hi == SYMTAB_SIG, "CSCsymtabStat: symTab blows", \ CSC_CORRUPT \ ); MON_ENTER(symTab); if (sizePtr != NULL) *sizePtr = symTab->count; MON_EXIT(symTab); return (statStat); }
PUBLIC int (CSCtimerClear) (CSCtimerType const timer) { int clearStat = CSC_OK; struct S_timerType* t = timer; ASSERT_RTN (timer != NULL, "CSCtimerClear: NULL timer", CSC_BADARG); ASSERT_RTN ( \ t->sig_lo == TIMER_SIG, \ "CSCtimerClear: timer blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ t->sig_hi == TIMER_SIG, \ "CSCtimerClear: timer blows", \ CSC_CORRUPT \ ); if (t == NULL) return (CSC_BADARG); t->mark.tv_sec = 0; t->mark.tv_usec = 0; t->diffMark.tv_sec = 0; t->diffMark.tv_usec = 0; t->diffStat = 0.0; return (clearStat); }
PUBLIC int (CSCfileUnlock) (int fd, off_t offset, int whence, off_t length) { ASSERT_RTN (fd >= 0, "CSCfileUnlock: invalid file descriptor.\n", -1); ASSERT_RTN ( \ ((whence==SEEK_SET)||(whence==SEEK_CUR)||(whence==SEEK_END)),\ "CSCfileUnlock: invalid whence\n", \ -1 \ ); return (csc_flock(fd,F_SETLK,F_UNLCK,offset,whence,length)); }
PUBLIC char* (CSCfileExpandPath) ( const char* const path, const size_t pathMax, CSCmemListType const memList, int memTag ) { char* dstPtr = NULL; char* tmpPtr = NULL; char* srcPtr = (char*)path; size_t index; ASSERT_RTN (path != NULL, "CSCfileExpandPath: NULL path", NULL); ASSERT_RTN (pathMax > 0, "CSCfileExpandPath: no pathMax", NULL); ASSERT_RTN (memList != NULL, "CSCfileExpandPath: NULL memList", NULL); ASSERT (sizeof(ptrdiff_t) <= sizeof(size_t)); /* note #1 */ if ((path == NULL) || (pathMax == 0) || (memList == NULL)) return (NULL); if (CSCmemAlloc(memList,(void**)&dstPtr,1,pathMax+1,memTag) == CSC_OK) { (void)memset (dstPtr, '\0', pathMax+1); tmpPtr = expandTilde (dstPtr, &srcPtr, pathMax); if (tmpPtr != NULL) index = (size_t)(tmpPtr - dstPtr); /* note #1 */ else { index = (size_t)pathMax + 1; } while ((*srcPtr != '\0') && (index <= pathMax)) { while ((*srcPtr != '$') && (*srcPtr != '\0') && (index++ <= pathMax)) { *tmpPtr++ = *srcPtr++; } if (*srcPtr == '$') { tmpPtr = expandEnv (tmpPtr, &srcPtr, pathMax-index); index = (size_t)(tmpPtr - dstPtr); /* note #1 */ } } *tmpPtr = '\0'; if (*srcPtr != '\0') { (void)CSCmemFree (memList, (void**)&dstPtr, memTag); dstPtr = NULL; } } return (dstPtr); }
PUBLIC int (CSCtimerDiff) ( CSCtimerType const timer, double* const diffPtr ) { int diffStat = CSC_ERROR; struct S_timerType* t = timer; ASSERT_RTN (timer != NULL, "CSCtimerDiff: NULL timer", CSC_BADARG); ASSERT_RTN ( \ t->sig_lo == TIMER_SIG, \ "CSCtimerDiff: timer blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ t->sig_hi == TIMER_SIG, \ "CSCtimerDiff: timer blows", \ CSC_CORRUPT \ ); #define MARK1 (t->mark) #define MARK2 (t->diffMark) #define DIFF (t->diffStat) if (t == NULL) return (CSC_BADARG); if (timerisset(&MARK1)) { diffStat = gettimeofday (&MARK2, NULL); if (diffStat == 0) { double m1 = (double)MARK1.tv_sec + (double)MARK1.tv_usec / (1000*1000); double m2 = (double)MARK2.tv_sec + (double)MARK2.tv_usec / (1000*1000); DIFF = m2 - m1; if (diffPtr != NULL) *diffPtr = DIFF; diffStat = CSC_OK; } else { diffStat = CSC_ERROR; } } #undef MARK1 #undef MARK2 return (diffStat); }
PUBLIC int (CSCsymtabEntryPut) ( CSCsymTableType const symTab, CSCsymbolType* const symbol ) { int putStat = CSC_OK; CSCsymbolType* newSym; CSChashKeyUnion hashKey; ASSERT_RTN (symTab != NULL, "CSCsymtabEntryPut: null symTab", CSC_BADARG); ASSERT_RTN (symbol != NULL, "CSCsymtabEntryPut: null symbol", CSC_BADARG); ASSERT_RTN ( \ symTab->sig_lo == SYMTAB_SIG, \ "CSCsymtabEntryPut: symTab blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ symTab->sig_hi == SYMTAB_SIG, \ "CSCsymtabEntryPut: symTab blows", \ CSC_CORRUPT \ ); newSym = CSCsymbolDup (symbol, symTab->memLst, 0); if (newSym != NULL) { MON_ENTER(symTab); hashKey.asciiz = newSym->name; putStat = CSChashEntryPut ( symTab->table, &hashKey, &newSym, sizeof(CSCsymbolType*) ); ASSERT ((putStat == CSC_OK) || (putStat == CSC_DUPKEY)); if (putStat == CSC_OK) symTab->count += 1; MON_EXIT(symTab); } return (putStat); }
PUBLIC char* (CSCfileGetHomeDir) ( const size_t pathSize, CSCmemListType const memList, int memTag ) { char* homeDirPath = NULL; ASSERT_RTN (pathSize > 0, "CSCfileGetHomeDir: no pathSize", NULL); ASSERT_RTN (memList != NULL, "CSCfileGetHomeDir: NULL memList", NULL); if ((pathSize == 0) || (memList == NULL)) return (NULL); if (CSCmemAlloc(memList,(void**)&homeDirPath,1,pathSize,memTag) == CSC_OK) { homeDirPath = getHomeDir (homeDirPath, pathSize); } return (homeDirPath); }
PUBLIC CSCsymbolType* (CSCsymtabEntryGet) ( CSCsymTableType const symTab, char* const symName, CSCmemListType const memLst ) { CSCsymbolType* symPtr = NULL; CSChashKeyUnion hashKey; int getStat; size_t entrySize; ASSERT_RTN (symTab != NULL, "CSCsymtabEntryGet: null symTab", NULL); ASSERT_RTN (symName != NULL, "CSCsymtabEntryGet: null symName", NULL); ASSERT_RTN ( \ symTab->sig_lo == SYMTAB_SIG, \ "CSCsymtabEntryGet: symTab blows", \ NULL \ ); ASSERT_RTN ( \ symTab->sig_hi == SYMTAB_SIG, \ "CSCsymtabEntryGet: symTab blows", \ NULL \ ); MON_ENTER(symTab); hashKey.asciiz = (char*)symName; getStat = CSChashEntryGet ( symTab->table, &hashKey, (void**)&symPtr, &entrySize, memLst ); ASSERT ((getStat == CSC_OK) || (getStat == CSC_NOTFOUND)); ASSERT (entrySize == sizeof(CSCsymbolType*)); MON_EXIT(symTab); return (symPtr); }
PUBLIC char* (CSCfileBaseName) ( const char* const path, CSCmemListType const memList, int memTag ) { char* tempPtr = NULL; char* namePtr = NULL; ASSERT_RTN (path != NULL, "CSCfileBaseName: no path", NULL); ASSERT_RTN (memList != NULL, "CSCfileBaseName: NULL memList", NULL); if ((path == NULL) || (memList == NULL)) return (NULL); tempPtr = strrchr (path, '/'); if (tempPtr == NULL) tempPtr = (char*)path; else ++tempPtr; (void)CSCmemAlloc (memList,(void**)&namePtr,1,strlen(tempPtr)+1,memTag); if (namePtr != NULL) strcpy (namePtr, tempPtr); return (namePtr); }
PUBLIC int (CSCtimerMark) (CSCtimerType const timer) { int markStat = CSC_OK; struct S_timerType* t = timer; ASSERT_RTN (timer != NULL, "CSCtimerMark: NULL timer", CSC_BADARG); ASSERT_RTN ( \ t->sig_lo == TIMER_SIG, \ "CSCtimerMark: timer blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ t->sig_hi == TIMER_SIG, \ "CSCtimerMark: timer blows", \ CSC_CORRUPT \ ); if (t == NULL) return (CSC_BADARG); markStat = gettimeofday (&t->mark, NULL); if (markStat != 0) markStat = CSC_ERROR; return (markStat); }
PUBLIC int (CSCtimerDone) (CSCtimerType const timer) { int freeStat = CSC_OK; struct S_timerType* t = timer; ASSERT_RTN (timer != NULL, "CSCtimerDone: NULL timer", CSC_BADARG); ASSERT_RTN ( \ t->sig_lo == TIMER_SIG, \ "CSCtimerDone: timer blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ t->sig_hi == TIMER_SIG, \ "CSCtimerDone: timer blows", \ CSC_CORRUPT \ ); if (t == NULL) return (CSC_BADARG); (void)memset (t, 0xFF, sizeof(S_timerType)); (void)CSC_FREE_FUNC (t); return (freeStat); }
PUBLIC int (CSCsymtabEntryDel) ( CSCsymTableType const symTab, char* const symName ) { int delStat = CSC_OK; CSChashKeyUnion hashKey; ASSERT_RTN (symTab != NULL, "CSCsymtabEntryDel: null symTab", CSC_BADARG); ASSERT_RTN (symName != NULL, "CSCsymtabEntryDel: null symName", CSC_BADARG); ASSERT_RTN ( \ symTab->sig_lo == SYMTAB_SIG, \ "CSCsymtabEntryDel: symTab blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ symTab->sig_hi == SYMTAB_SIG, \ "CSCsymtabEntryDel: symTab blows", \ CSC_CORRUPT \ ); MON_ENTER(symTab); hashKey.asciiz = (char*)symName; delStat = CSChashEntryDel (symTab->table, &hashKey); ASSERT (delStat == CSC_OK); if (delStat == CSC_OK) { ASSERT(symTab->count>=1); symTab->count -= 1; } MON_EXIT(symTab); return (delStat); }
PUBLIC CSCsymTableType (CSCsymtabNew) ( const char* const name, size_t size, const char** keyWords, int keyWordSpec, CSCmonFnType monFunc, const void* monData, CSCprofileType profiling ) { CSCsymTableType symTab = NULL; CSCmemListType memList = NULL; size_t hashTableSize = 0; ASSERT_RTN (name != NULL, "CSCsymtabNew: no hash name", NULL); ASSERT_RTN ( \ ((profiling==CSC_DO_PROFILING)||(profiling==CSC_NO_PROFILING)),\ "CSCsymtabNew: illegal profile value", \ NULL \ ); memList = CSCmemInit (name, NULL, monFunc, monData, CSC_NO_PROFILING); if (memList != NULL) { (void)CSCmemAlloc (memList,(void**)&symTab,1,sizeof(S_symTableType),0); if (symTab != NULL) { symTab->name = name; symTab->memLst = memList; symTab->profiling = profiling; symTab->monFunc = monFunc; symTab->monData = monData; symTab->keyWordSpec = 0; symTab->table = NULL; symTab->count = 0; #ifdef DEBUG symTab->sig_lo = SYMTAB_SIG; symTab->sig_hi = SYMTAB_SIG; #endif hashTableSize = size > 0 ? size : SYMTAB_SIZE; symTab->table = CSChashNew ( name, CSC_HASH_ASCIIZ_KEY, hashTableSize, monFunc, monData, profiling ); if (symTab->table != NULL) { symTab->keyWordSpec = keyWordSpec; if (keyWords != NULL) { int keyWordStat = CSC_OK; CSCsymbolType* keyWordSym = NULL; CSChashKeyUnion hashKey; while ((**keyWords != '\0') && (keyWordStat == CSC_OK)) { keyWordSym = CSCsymbolIntNew ( *keyWords, /* symbol name */ keyWordSpec, /* symbol type */ 0, /* symbol value */ memList, /* memList */ 0 /* memTag */ ); hashKey.asciiz = (char*)*keyWords; keyWordStat = CSChashEntryPut ( symTab->table, &hashKey, &keyWordSym, sizeof(CSCsymbolType*) ); ++keyWords; } /* FIXME if keyWordStat != CSC_OK is not handled. */ } } else { (void)CSCmemFree (memList, (void**)&symTab, 0); (void)CSCmemDone (memList); symTab = NULL; } } else { (void)CSCmemDone (memList); } } return (symTab); }
PRIVATE char* expandEnv ( const char* destBuff, char** srcPtrPtr, const size_t destBuffSize ) { register char* dstPtr = (char*)destBuff; register char* srcPtr; ASSERT_RTN (destBuff != NULL, "expandEnv: no destBuff", NULL); ASSERT_RTN (srcPtrPtr != NULL, "expandEnv: no srcPtrPtr", NULL); ASSERT_RTN (destBuffSize > 0, "expandEnv: no destBuffSize", NULL); if ((destBuff == NULL) || (srcPtrPtr == NULL) || (destBuffSize == 0)) { return (NULL); } srcPtr = *srcPtrPtr; ASSERT_RTN (srcPtr != NULL, "expandEnv: no srcPtr", NULL); if (srcPtr == NULL) return (NULL); if ((*srcPtr == '$') && (destBuffSize > 0)) { int index; char* envName; char* envValue; register char* tmpDst; if ((envName=(char*)CSC_MALLOC_FUNC(1,80)) != NULL) /* bug #1 */ { tmpDst = envName; ++srcPtr; if ((*srcPtr == '(') || (*srcPtr == '{')) ++srcPtr; index = 79; while ( (*srcPtr != ')') && (*srcPtr != '}') && (*srcPtr != '\0') && (index-- > 0) ) *tmpDst++ = *srcPtr++; *tmpDst = '\0'; if ((*srcPtr == ')') || (*srcPtr == '}')) ++srcPtr; envValue = getenv (envName); ASSERT (envValue != NULL); ASSERT (envValue != NULL); if (envValue != NULL) { index = destBuffSize; while ((*envValue != '\0') && (index-- > 0)) *dstPtr++ = *envValue++; (void)CSC_FREE_FUNC (envName); } } } *srcPtrPtr = srcPtr; return (dstPtr); }
PUBLIC FILE* (CSCfileOpen) ( const char* const path, const int mask, const size_t pathMax, CSCmemListType const memList, int memTag ) { FILE* fileStream = NULL; int oldMask; char* fileName; register char* tmpPtr; ASSERT_RTN (path != NULL, "CSCfileOpen: NULL path", NULL); ASSERT_RTN (pathMax > 0, "CSCfileOpen: no pathMax", NULL); ASSERT_RTN (memList != NULL, "CSCfileOpen: NULL memList", NULL); if ((path == NULL) || (pathMax == 0) || (memList == NULL)) return (NULL); fileName = CSCfileExpandPath (path, pathMax, memList, memTag); tmpPtr = *fileName == '/' ? fileName+1 : fileName; oldMask = umask (mask); while (*tmpPtr != '\0') { while ((*tmpPtr != '/') && (*tmpPtr != '\0')) ++tmpPtr; if (*tmpPtr == '/') { *tmpPtr = '\0'; if (access(fileName,F_OK) == 0) /* There's something there... */ { if (access(fileName,(R_OK)|(X_OK)) != 0) /* should be directory. */ { (void)CSCmemFree (memList, (void**)&fileName, memTag); return (NULL); } } else { /* Nothing there; we must create the directory. */ if (mkdir(fileName,0755) == 0) { (void)CSCmemFree (memList, (void**)&fileName, memTag); return (NULL); } } *tmpPtr++ = '/'; } } /* * OK, we have a pathname to a file, the path part exists (we may have * created part of it) and it has the correct accessability. Now open the * file for writing. */ fileStream = fopen (fileName,"w"); (void)CSCmemFree (memList, (void**)&fileName, memTag); (void)umask (oldMask); return (fileStream); }
PUBLIC int (CSCsymtabDel) ( CSCsymTableType const symTab ) { int delStat = CSC_OK; CSChashEntryType entry = NULL; CSCsymbolType* symPtr = NULL; ASSERT_RTN (symTab != NULL, "CSCsymtabDel: null symTab", CSC_BADARG); ASSERT_RTN ( \ symTab->sig_lo == SYMTAB_SIG, \ "CSCsymtabDel: symTab blows", \ CSC_CORRUPT \ ); ASSERT_RTN ( \ symTab->sig_hi == SYMTAB_SIG, \ "CSCsymtabDel: symTab blows", \ CSC_CORRUPT \ ); MON_ENTER(symTab); /* * Things with pointers, like symbols, probably really shouldn't be put into a * hash table because the hash table duplicates the data it stores and can't * know that it is duplicating pointers. Since this symbol table subsystem uses * the hash table there is the problem of dangling pointers when the hash table * subsystem deletes a hash table (because it can't know about the pointers it * duplicated when entries were put into it). So, here we have to remove the * dynamically allocated things that would be left dangling when the hash table * is deleted. */ entry = NULL; while ((entry=CSCsymtabEntryNext(symTab,entry)) != NULL) { if (CSChashEntryStat(entry,NULL,(void**)&symPtr,NULL) == CSC_OK) { (void)CSCsymbolDel (&symPtr, symTab->memLst, 0); } } /* * Now, it should be safe to delete the hash. */ delStat = CSChashDel ((CSChashTableType)symTab->table); if (delStat == CSC_OK) { CSCmemListType memList = symTab->memLst; CSCmonFnType monFunc = symTab->monFunc; const void* monData = symTab->monData; symTab->name = NULL; symTab->memLst = NULL; symTab->profiling = -1; symTab->monFunc = NULL; symTab->monData = NULL; symTab->keyWordSpec = 0; symTab->table = NULL; symTab->count = 0; #ifdef DEBUG symTab->sig_lo = -1; symTab->sig_hi = -1; #endif (void)CSCmemFree (memList, (void**)&symTab, 0); (void)CSCmemDone (memList); if (monFunc != NULL) (*monFunc) (CSC_OUT, (void*)monData); } else { MON_EXIT(symTab); } return (delStat); }