# include # include # include # include # include "estreak.h" # define SWAP(a,b) temp=(a);(a)=(b);(b)=temp; /* G_LIB -- General-purpose functions: * * - data array memory allocation/deallocation * - assemble time stamp * - string parsing and dictionary search * - median (select) * - messaging at stdout * * * * Revision history: * ---------------- * 25 Apr 96 - Implementation (IB) * 07 Oct 96 - Revised after code review (IB) */ /* Data array memory allocation/deallocation. */ int allocArray (floatArray *array, int xsize, int ysize) { array->data = (float *)calloc(ysize*xsize,sizeof(float)); if (array->data == NULL) return (1); array->nx = xsize; array->ny = ysize; array->bufsize = (long)ysize * (long)xsize; return (0); } void freeArray (floatArray *array) { array->nx = 0; array->ny = 0; array->bufsize = 0; free (array->data); } /* Assemble a time stamp string. */ void g_timeStamp (char *time_stamp) { time_t now; now = time (NULL); strftime (time_stamp, SZ_TIMESTAMP-1, "%a %H:%M:%S %Z %d-%b-%Y", localtime(&now)); } /* Parse string into int-type vector. */ int g_parseIntString (char *string, int vector[], int *n) { char **ptr, *tmp; tmp = string; *n = 0; tmp--; ptr = &tmp; while ((vector[(*n)++] = (int) strtol (++(*ptr), ptr, 0)) != 0); (*n)--; return (0); } /* G_STRDIC -- Search a dictionary string for a match with an input string. * * The input string may be an abbreviation of a dictionary entry, however, * it is an error if the abbreviation is not unique. The entries in the * dictionary string are separated by a delimiter character which is the * first character of the dictionary string. The full name of the matched * dictionary entry found is returned in out_str; the function value is the * word index of the dictionary entry. The output string may be the same as * the input string. * * * This is an almost plain SPP->C translation of iraf$sys/fmtio/strdic.x * with minor modifications to deal with zero-indexed vectors (5/10/96 IB) * */ int g_strdic (char *in_str, char *out_str, int maxchars, char *dict) { /* * char in_str[ARB] # Input string * char out_str[ARB] # Output string as found in dictionary * int maxchars # Maximum length of output string * char dict[ARB] # Dictionary string */ char ch, fch; int start, len, ip, i, match, entry; if (dict[0] == '\0') return (0); i = 0; while (in_str[i++] == ' '); start = i-1; match = 0; ip = 1; len = strlen (in_str+start); fch = in_str[start]; /* Search the dictionary string. If the input string matches a * dictionary entry it is either an exact match (len = dictionary * entry length) or a legal abbreviation. If an abbreviation * matches two entries it is ambiguous and an error. */ for (entry=1; dict[ip] != '\0'; entry=entry+1) { if (dict[ip] == fch) { if (strncmp (dict+ip, in_str+start, len) == 0) { for (i=0; i < maxchars; i++) { ch = dict[ip+i]; if ((ch == dict[0]) || (ch == '\0')) break; out_str[i] = ch; } out_str[i] = '\0'; if ((dict[ip+len] == dict[0]) || (dict[ip+len] == '\0')) return (entry); /* exact match */ else { /* If we already have a match and the new match is * not exact, then the abbreviation is ambiguous. */ if (match != 0) return (0); else match = entry; } } } while (dict[ip] != dict[0] && dict[ip+1] != '\0') ip++; ip++; } return (match); } /* * G_SELECT - Selects k-th smallest value in vector. * * From "Numerical Recipes - The Art of Scientific Computing", * Press, W.H., Teukolsky, S.A., Vetterling, W.T. and Flannery, B.P., * 2nd edition, Cambridge University Press, 1995. * * Vectors are 1-indexed, thus the calling sequence should be * something as: * * med = g_select ((long)(n+1)/2, (long)n, temp-1); * * where `temp' is a standard, 0-indexed, 1-dimensional C array. * * */ float g_select (unsigned long k, unsigned long n, float arr[]) { unsigned long i, ir, j, l, mid; float a, temp; l = 1; ir = n; for (;;) { if (ir <= l+1) { if (ir == l+1 && arr[ir] < arr[l]) { SWAP(arr[l], arr[ir]) } return arr[k]; } else { mid = (l+ir) >> 1; SWAP(arr[mid], arr[l+1]) if (arr[l] > arr[ir]) { SWAP(arr[l], arr[ir]) } if (arr[l+1] > arr[ir]) { SWAP(arr[l+1], arr[ir]) } if (arr[l] > arr[l+1]) { SWAP(arr[l], arr[l+1]) } i = l+1; j = ir; a = arr[l+1]; for (;;) { do i++; while (arr[i] < a); do j--; while (arr[j] > a); if (j < i) break; SWAP(arr[i], arr[j]) } arr[l+1] = arr[j]; arr[j] = a; if (j >= k) ir = j - 1; if (j <= k) l = i; } } } /* Routines for handling messaging at stdout. * * g_message does NOT issue a newline after the message because it may be * used in more sophisticated formatting operations. These are needed in * order to simulate the output from the old streakflat task. */ void g_message (char *message) { printf ("%s", message); fflush(stdout); } void g_warn (char *message) { printf ("*** WARNING: %s\n", message); fflush(stdout); } void g_warn2 (char *message) { printf ("*** WARNING: %s Skipping file...\n", message); fflush(stdout); } void g_error (char *message) { printf ("*** ERROR: %s\n", message); fflush(stdout); }