/***************************************************************************** * Replacements for missing functions. * ****************************************************************************** * (C) Gershon Elber, Technion, Israel Institute of Technology * ****************************************************************************** * Written by: Gershon Elber Ver 1.0, Aug. 1991 * *****************************************************************************/ #include #include #include #include #ifndef __WINCE__ # include #endif /* __WINCE__ */ #ifdef OS2GCC # define INCL_DOSPROCESS # include #endif /* OS2GCC */ #ifdef SGINAP # include # include #endif /* SGINAP */ #if defined(__WINNT__) || defined(__WINCE__) # include #else # include # ifndef AMIGA # include # include # else # include # endif # ifndef HZ # define HZ 60 # endif /* HZ */ #endif /* __WINNT__ || __WINCE__ */ #include "irit_sm.h" #include "misc_loc.h" STATIC_DATA int GlblWasIritRandomInit = FALSE; /***************************************************************************** * DESCRIPTION: M * Routine to duplicate a string. Exists in some computer environments. M * * * PARAMETERS: M * s: String to duplicate. M * * * RETURN VALUE: M * char *: Duplicated string. M * * * KEYWORDS: M * IritStrdup, strdup M *****************************************************************************/ char *IritStrdup(char *s) { char *p = IritMalloc(strlen(s) + 1); if (p == NULL) return NULL; strcpy(p, s); return p; } #ifdef ITIMERVAL /***************************************************************************** * DESCRIPTION: * * Dummy routine to catch signals for IritSleep below. * * * * PARAMETERS: * * None * * * * RETURN VALUE: * * void * *****************************************************************************/ static void TrapSignal(void) { } #endif /* ITIMERVAL */ /***************************************************************************** * DESCRIPTION: M * Routine to force a process to sleep. M * * * PARAMETERS: M * MilliSeconds: Sleeping time required, in miliseconds. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IritSleep, sleep M *****************************************************************************/ void IritSleep(int MilliSeconds) { #ifdef NANOSLEEP struct timespec rqtp; rqtp.tv_sec = MilliSeconds / 1000; rqtp.tv_nsec = (MilliSeconds % 1000) * 1000000; nanosleep(&rqtp, NULL); #else #ifdef USLEEP usleep(MilliSeconds * 1000); #else #ifdef SGINAP sginap((long) (MAX(CLK_TCK * MilliSeconds / 1000, 1))); #else #ifdef OS2GCC DosSleep(MilliSeconds); #else #if defined(__WINNT__) || defined(__WINCE__) Sleep(MilliSeconds); #else #ifdef USLEEP_SELECT int nfds = 0, readfds = 0, writefds = 0, exceptfds = 0; struct timeval Timer; Timer.tv_sec = MilliSeconds / 1000; Timer.tv_usec = (MilliSeconds % 1000) * 1000; if (select(nfds, &readfds, &writefds, &exceptfds, &Timer) < 0) perror( "usleep (select) failed" ); #else #ifdef ITIMERVAL /* Sometimes fail on hpux (sleeps forever in sigpause). Use with care. */ struct itimerval Tmr; void (*OldTrapSignal)(void); Tmr.it_interval.tv_sec = 0; Tmr.it_interval.tv_usec = 0; Tmr.it_value.tv_sec = MilliSeconds / 1000; Tmr.it_value.tv_usec = (MilliSeconds % 1000) * 1000; OldTrapSignal = (void (*)(void)) signal(SIGALRM, (void (*)(void)) TrapSignal); setitimer(ITIMER_REAL, &Tmr, NULL); sigpause(~sigmask(SIGALRM)); signal(SIGALRM, OldTrapSignal); #else /* No way to milli-sleep. */ int i; if (MilliSeconds >= 1000) { sleep(MilliSeconds / 1000); MilliSeconds = MilliSeconds % 1000; } for (i = MilliSeconds * 10000; i > 0; i--); #endif /* ITIMERVAL */ #endif /* USLEEP_SELECT */ #endif /* __WINNT__ */ #endif /* OS2GCC */ #endif /* SGINAP */ #endif /* USLEEP */ #endif /* NANOSLEEP */ } /***************************************************************************** * DESCRIPTION: M * Provides an approximated comparison between two strings. M * M * * * PARAMETERS: M * Str1, Str2: The two strings to compare. M * IgnoreCase: TRUE to ignore case, FALSE to consider as different. M * * * RETURN VALUE: M * RealType: Perfect match returns 1.0, otherwise match estimation M * between 0.0 and 1.0. M * * * KEYWORDS: M * IritApproxStrStrMatch M *****************************************************************************/ RealType IritApproxStrStrMatch(char *Str1, char *Str2, int IgnoreCase) { int i, Len1 = (int) strlen(Str1), Len2 = (int) strlen(Str2); RealType RetVal; Str1 = IritStrdup(Str1); Str2 = IritStrdup(Str2); if (IgnoreCase) { for (i = 0; i < Len1; i++) if (isupper(Str1[i])) Str1[i] = tolower(Str1[i]); for (i = 0; i < Len2; i++) if (isupper(Str2[i])) Str2[i] = tolower(Str2[i]); } if (strcmp(Str1, Str2) == 0) { /* Perfect match. */ RetVal = 1.0; } else { RetVal = 0.0; /* Half a match for inclusion, less so if single chars' inclusion. */ if (strstr(Str1, Str2)) RetVal += 0.5; else { for (i = 0; i < Len1; i++) if (strchr(Str2, Str1[i])) RetVal += 0.5 / (Len1 + 1.0); } if (strstr(Str2, Str1)) RetVal += 0.5; else { for (i = 0; i < Len2; i++) if (strchr(Str1, Str2[i])) RetVal += 0.5 / (Len2 + 1.0); } } IritFree(Str1); IritFree(Str2); return RetVal; } /***************************************************************************** * DESCRIPTION: M * Routine to initialize the random number generator. M * * * PARAMETERS: M * Seed: To initialize the random number generator with. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IritRandomInit, random numbers M *****************************************************************************/ void IritRandomInit(long Seed) { #ifdef RAND srand(Seed); #else #ifdef RAND48 srand48(Seed); #else srandom(Seed); #endif /* RAND48 */ #endif /* RAND */ GlblWasIritRandomInit = TRUE; } /***************************************************************************** * DESCRIPTION: M * Routine to compute a random number in a specified range. M * See also IritRandomInit. M * * * PARAMETERS: M * Min: Minimum range of random number requested. M * Max: Maximum range of random number requested. M * * * RETURN VALUE: M * RealType: A random number between Min andMax. M * * * KEYWORDS: M * IritRandom, random numbers M *****************************************************************************/ RealType IritRandom(RealType Min, RealType Max) { long R; if (!GlblWasIritRandomInit) { IritRandomInit(1964); GlblWasIritRandomInit = TRUE; } #ifdef RAND R = rand(); #else #ifdef RAND48 R = lrand48(); #else R = random(); #endif /* RAND48 */ #endif /* RAND */ #if defined(OS2GCC) || defined(sgi) || defined(__WINNT__) return Min + (Max - Min) * ((double) (R & RAND_MAX)) / ((double) RAND_MAX); #else return Min + (Max - Min) * ((double) (R & 0x7fffffff)) / ((double) 0x7fffffff); #endif /* OS2GCC || sgi */ } /***************************************************************************** * DESCRIPTION: M * Routine to compute the cpu time of the running process. M * * * PARAMETERS: M * Reset: If TRUE, clock is reset back to zero. M * * * RETURN VALUE: M * RealType: CPU time since last reset or beginning of execution. M * * * KEYWORDS: M * IritCPUTime, time M *****************************************************************************/ RealType IritCPUTime(int Reset) { STATIC_DATA RealType LastTime = 0.0; RealType Time; if (Reset) { #ifndef AMIGA #ifdef TIMES struct tms tim; times(&tim); LastTime = (tim.tms_utime + tim.tms_stime) / ((RealType) HZ); #else #ifdef __WINNT__ LastTime = (RealType) GetTickCount(); #else LastTime = time(NULL); /* No real timing routines!? */ #endif /* __WINNT__ */ #endif /* TIMES */ #else struct DateStamp ds; DateStamp(&ds); LastTime = (double) ds.ds_Days * (24.0 * 60.0 * 60.0) + (double) ds.ds_Minute * 60.0 + (double) ds.ds_Tick / 50.0; #endif /* AMIGA */ return 0.0; } #ifndef AMIGA #ifdef TIMES { struct tms tim; times(&tim); Time = (tim.tms_utime + tim.tms_stime) / ((RealType) HZ) - LastTime; } #else #ifdef __WINNT__ { Time = (((RealType) GetTickCount()) - LastTime) * 0.001; } #else Time = time(NULL) - LastTime; #endif /* __WINNT__ */ #endif /* TIMES */ #else { struct DateStamp ds; DateStamp(&ds); Time = (double) ds.ds_Days * (24.0 * 60.0 * 60.0) + (double) ds.ds_Minute * 60.0 + (double) ds.ds_Tick / 50.0 - LastTime; } #endif /* AMIGA */ return Time; } /***************************************************************************** * DESCRIPTION: M * Routine to create and return a string describing current date and time. M * * * PARAMETERS: M * None * * * * RETURN VALUE: M * char *: A string describing current date and time. M * * * KEYWORDS: M * IritRealTimeDate, date, time M *****************************************************************************/ char *IritRealTimeDate(void) { STATIC_DATA char StrTime[LINE_LEN]; int i; time_t t = (time_t) time(NULL); strncpy(StrTime, ctime(&t), LINE_LEN - 1); /* Remove trailing EOL. */ for (i = (int) strlen(StrTime) - 1; i >= 0 && StrTime[i] < ' '; i--); StrTime[i + 1] = 0; return StrTime; } #if !(defined(AMIGA) && defined(__SASC)) /***************************************************************************** * DESCRIPTION: M * Routine to move a block in memory. Unlike memcpy/bcopy, this routine M * should support overlaying blocks. This stupid implemetation will copy it M * twice - to a temporary block and back again. The temporary block size will M * be allocated by demand. M * * * PARAMETERS: M * Src: Of block to copy. M * Dest: Of block to copy. M * Len: Of block to copy. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * movmem, copy M *****************************************************************************/ void movmem(VoidPtr Src, VoidPtr Dest, int Len) { VoidPtr p = IritMalloc(Len); memcpy(p, Src, Len); memcpy(Dest, p, Len); IritFree(p); } #endif /* !(defined(AMIGA) && defined(__SASC)) */ /***************************************************************************** * DESCRIPTION: M * RRoutine to search for a given file name. M * * * PARAMETERS: M * Name: Of file to search for. M * * * RETURN VALUE: M * char *: Complete file name of Name. M * * * KEYWORDS: M * searchpath M *****************************************************************************/ char *searchpath(char *Name) { STATIC_DATA char FullPath[LINE_LEN_LONG]; char *p; if ((p = getenv("IRIT_PATH")) != NULL) { strcpy(FullPath, p); if (p[strlen(p) - 1] != '/' && p[strlen(p) - 1] != '\\') strcat(FullPath, "/"); strcat(FullPath, Name); } else { STATIC_DATA int Printed = FALSE; strcpy(FullPath, Name); if (!Printed) { fprintf(stderr, IRIT_EXP_STR("IRIT_PATH env. not set. Only current directory is being searched.\n")); Printed = TRUE; } } return FullPath; } #ifdef STRICMP /***************************************************************************** * DESCRIPTION: M * Routine to compare two strings, ignoring case, up to given length. M * * * PARAMETERS: M * s1, s2: The two strings to compare. M * n: maximum number of characters to compare. M * * * RETURN VALUE: M * int: <0, 0, >0 according to the relation between s1 and s2. M * * * KEYWORDS: M * strnicmp M *****************************************************************************/ int strnicmp(char *s1, char *s2, int n) { /* Use to be simply 'return strncasecmp(s1, s2, n);' but seems that some */ /* unix systems (sun4?) does have it so here it is explicitly. */ /* Written by Reiner Wilhelms . */ int i; char c1, c2; for (i = 0; i < n; i++) { if (islower(s1[i])) c1 = toupper(s1[i]); else c1 = s1[i]; if (islower(s2[i])) c2 = toupper(s2[i]); else c2 = s2[i]; if (c1 != c2) { if (c1 > c2) return 1; if (c1 < c2) return -1; } } return 0; } /***************************************************************************** * DESCRIPTION: M * Routine to compare two strings, ignoring case. M * * * PARAMETERS: M * s1, s2: The two strings to compare. M * * * RETURN VALUE: M * int: <0, 0, >0 according to the relation between s1 and s2. M * * * KEYWORDS: M * stricmp M *****************************************************************************/ int stricmp(char *s1, char *s2) { int i; char *u1, *u2; if (s1 == NULL) return s2 != NULL; else if (s2 == NULL) return 1; u1 = IritStrdup(s1); u2 = IritStrdup(s2); for (i = 0; i < (int) strlen(u1); i++) if (islower(u1[i])) u1[i] = toupper(u1[i]); for (i = 0; i < (int) strlen(u2); i++) if (islower(u2[i])) u2[i] = toupper(u2[i]); i = strcmp(u1, u2); IritFree(u1); IritFree(u2); return i; } #endif /* STRICMP */ #ifdef STRSTR /***************************************************************************** * DESCRIPTION: M * Routine to search for a Pattern (no regular expression) in s. Returns M * address in s of first occurance of Pattern, NULL if non found. M * M * * * PARAMETERS: M * s: To search for Pattern in. M * Pattern: To search in s. M * * * RETURN VALUE: M * char *: Address in s where Pattern was first found, NULL otherwise. M * * * KEYWORDS: M * strstr M *****************************************************************************/ char *strstr(char *s, char *Pattern) { int Len = strlen(Pattern); char *p = (char *) s; while (p = strchr(p, Pattern[0])) if (strncmp(p, Pattern, Len) == 0) return p; else p++; return NULL; } #endif /* STRSTR */ #ifdef GETCWD /***************************************************************************** * DESCRIPTION: M * Get current working directory - BSD4.3 style. * * * * PARAMETERS: M * s: Where to save current working direction. M * Len: Length of s. M * * * RETURN VALUE: M * char *: Same as s. M * * * KEYWORDS: M * getcwd M *****************************************************************************/ char *getcwd(char *s, int Len) { getwd(s); return s; } #endif /* GETCWD */