/* Time Series Analyzer Eric R. Nelson * * Link with VERBS, PVERBS and MISC * */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <io.h> #include <time.h> #include <dos.h> #include <process.h> #include <ctype.h> #include <signal.h> #include "MAIN.H" #define Advstrnm 45 /* ** Define Functions */ void ADVINIT(void); void PVINIT(void); void VERBINIT(void); short HANDEL(void); short PROCESS(void); short ADVCHK(char *); short VERBCHK(char *); short PVERBCHK(char *); char *SEVAL(char *); short ADVERB(short); short GETADV(char *); short CALLDOS(void); short SIMPLE(short,short,short); double GETVAL(char *,short,short); void PUTVAL(char *,short,short,double); /* ** Define Adverbs */ double TRANGE[2], YRANGE[2], ZRANGE[2]; double TMAJOR[2], YMAJOR[2], ZMAJOR[2]; double PARMS[10], POINT[2], ZFACTOR[2]; short WINDOW[4]; char TASKNAME[9]; char INNAME[_MAX_FNAME], INCLASS[_MAX_EXT-1], INPATH[_MAX_DRIVE+_MAX_DIR-1]; char IN2NAME[_MAX_FNAME], IN2CLASS[_MAX_EXT-1], IN2PATH[_MAX_DRIVE+_MAX_DIR-1]; char IN3NAME[_MAX_FNAME], IN3CLASS[_MAX_EXT-1], IN3PATH[_MAX_DRIVE+_MAX_DIR-1]; char OUTNAME[_MAX_FNAME], OUTCLASS[_MAX_EXT-1], OUTPATH[_MAX_DRIVE+_MAX_DIR-1]; char TFORMAT[24], YFORMAT[24], ZFORMAT[24]; char PARITY[6], DEVICE[5]; char TLABEL[133], YLABEL[133], ZLABEL[133], TITLE[133]; double FACTOR; short CODE, BAUD, STOPBITS, DATABITS; short TMINOR, YMINOR, ZMINOR, FRAME, BORDER, QUIET, ITYPE; long COLOR; short LogFlag; /* ** Define Globals that are not adverbs */ extern char *VERBSTR[], *PVERBSTR[]; double TM, TB; short ADVSIZE[Advstrnm]; char *ADVSTR[Advstrnm]; char *ADVPNTR[Advstrnm]; char ILINE[256],*IPNTR, JLINE[256],*JPNTR, KLINE[256],*KPNTR; char CPA[256]; short MATCH, INDEX; short ERRTYPE=0, ECHO=1; short GF1, GF2, GF3, CS1, CS2; BOOL InterruptFlag; union REGS REGISTER; short EVLFLG, TASKFLG; /* ** Commonly Displayed Messages */ char *MSP[] = {"TISAN", "TISAN : ", "\nTISAN : ", "TISAN ", "TISAN : Ambiguous Entry '%s'\n", "Environment Too Big\n", "%sError Opening File '%s'\n", "Error Opening ", "Error Reading ", "File '%s' not found\n", "Insufficient Memory to Execute %s\n", "TISAN : Invalid File Specification\n", "Invalid Mode\n", "TISAN : Sorry, No Graphics Display Available\n", "Not an Executable File\n", "TISAN : Sorry, Inputs File '%s' is not Available.\n" }; /****************************************** ** Arrays for the Full Path for the TISAN ** Program on startup so wew know where to ** find the INPUTS and RUN files. */ char TisanDrive[_MAX_DRIVE]; char TisanDir[_MAX_DIR]; /* ** Character strings used throughout the program */ char *NullString = ""; char *Space = " "; char *CrLf = "\n"; main(argc,argv) short argc; char *argv[]; { short I; char C; signal(SIGINT,HANDEL); _splitpath(argv[0],TisanDrive,TisanDir,CPA,CPA); printf("'%s'\n",argv[0]); unlink("TISAN.LOG"); printf("\nWelcome to the Time Series Analyzer Version 2.2\n"); if (!GETADV(MSP[0])) printf("%sPevious Environment Restored\n",MSP[1]); else { printf("%sNo Previous Environment.\n",MSP[1]); printf("%sTASKNAME is undefined.\n",MSP[1]); Config(); Defaults(); } /* ** Build ADVSTR, VERBSTR, PVERBSTR and ADVPNTR, ADVSIZE */ ADVINIT(); PVINIT(); VERBINIT(); /* ** Process any arguments passed */ if (--argc) { strcpy(ILINE,argv[1]); PROCESS(); } while (1) { I = 0; memset(ILINE,0,256); printf("%s>",MSP[0]); do { if (InterruptFlag) { I=0; InterruptFlag=FALSE; } C=getch(); if (!C) getch(); if (C == 27) /* Escape Pressed */ { I=0; printf("\\"); C=13; memset(ILINE,0,256); } if (C == (char)26) { printf("\n"); CALLDOS(); I=0; C=13; memset(ILINE,0,256); } if ((C == 8) && (I > 0)) { ILINE[--I] = 0; putchar(C); putchar(' '); putchar(C); } else if ((I < 256) && (C != 0) && (C != 8)) { ILINE[I] = C; ++I; putchar(C); } } while (C != 13); printf("\n"); if (C != 27) { if (I>0) ILINE[--I] = 0; PROCESS(); } } } /******************************************************************** * * Initialize ADVERBS * */ void ADVINIT() { ADVSTR[0] = "TASKNAME"; ADVSTR[1] = "INNAME"; ADVSTR[2] = "INCLASS"; ADVSTR[3] = "INPATH"; ADVSTR[4] = "IN2NAME"; ADVSTR[5] = "IN2CLASS"; ADVSTR[6] = "IN2PATH"; ADVSTR[7] = "IN3NAME"; ADVSTR[8] = "IN3CLASS"; ADVSTR[9] = "IN3PATH"; ADVSTR[10] = "OUTNAME"; ADVSTR[11] = "OUTCLASS"; ADVSTR[12] = "OUTPATH"; ADVSTR[13] = "CODE"; ADVSTR[14] = "ITYPE"; ADVSTR[15] = "FACTOR"; ADVSTR[16] = "TRANGE"; ADVSTR[17] = "YRANGE"; ADVSTR[18] = "ZRANGE"; ADVSTR[19] = "WINDOW"; ADVSTR[20] = "TFORMAT"; ADVSTR[21] = "YFORMAT"; ADVSTR[22] = "ZFORMAT"; ADVSTR[23] = "DEVICE"; ADVSTR[24] = "BAUD"; ADVSTR[25] = "STOPBITS"; ADVSTR[26] = "DATABITS"; ADVSTR[27] = "PARITY"; ADVSTR[28] = "FRAME"; ADVSTR[29] = "BORDER"; ADVSTR[30] = "COLOR"; ADVSTR[31] = "TMINOR"; ADVSTR[32] = "YMINOR"; ADVSTR[33] = "ZMINOR"; ADVSTR[34] = "TMAJOR"; ADVSTR[35] = "YMAJOR"; ADVSTR[36] = "ZMAJOR"; ADVSTR[37] = "TLABEL"; ADVSTR[38] = "YLABEL"; ADVSTR[39] = "ZLABEL"; ADVSTR[40] = "TITLE"; ADVSTR[41] = "PARMS"; ADVSTR[42] = "QUIET"; ADVSTR[43] = "POINT"; ADVSTR[44] = "ZFACTOR"; ADVPNTR[0] = TASKNAME; ADVSIZE[0] = 8; ADVPNTR[1] = INNAME; ADVSIZE[1] = 8; ADVPNTR[2] = INCLASS; ADVSIZE[2] = 3; ADVPNTR[3] = INPATH; ADVSIZE[3] = 63; ADVPNTR[4] = IN2NAME; ADVSIZE[4] = 8; ADVPNTR[5] = IN2CLASS; ADVSIZE[5] = 3; ADVPNTR[6] = IN2PATH; ADVSIZE[6] = 63; ADVPNTR[7] = IN3NAME; ADVSIZE[7] = 8; ADVPNTR[8] = IN3CLASS; ADVSIZE[8] = 3; ADVPNTR[9] = IN3PATH; ADVSIZE[9] = 63; ADVPNTR[10] = OUTNAME; ADVSIZE[10]= 8; ADVPNTR[11] = OUTCLASS; ADVSIZE[11]= 3; ADVPNTR[12] = OUTPATH; ADVSIZE[12]= 63; ADVPNTR[13] = (char *)&CODE; ADVSIZE[13] = 1; ADVPNTR[14] = (char *)&ITYPE; ADVSIZE[14] = 1; ADVPNTR[15] = (char *)&FACTOR; ADVSIZE[15] = 1; ADVPNTR[16] = (char *)TRANGE; ADVSIZE[16] = 2; ADVPNTR[17] = (char *)YRANGE; ADVSIZE[17] = 2; ADVPNTR[18] = (char *)ZRANGE; ADVSIZE[18] = 2; ADVPNTR[19] = (char *)WINDOW; ADVSIZE[19] = 4; ADVPNTR[20] = TFORMAT; ADVSIZE[20] = 23; ADVPNTR[21] = YFORMAT; ADVSIZE[21] = 23; ADVPNTR[22] = ZFORMAT; ADVSIZE[22] = 23; ADVPNTR[23] = DEVICE; ADVSIZE[23] = 4; ADVPNTR[24] = (char *)&BAUD; ADVSIZE[24] = 1; ADVPNTR[25] = (char *)&STOPBITS; ADVSIZE[25] = 1; ADVPNTR[26] = (char *)&DATABITS; ADVSIZE[26] = 1; ADVPNTR[27] = PARITY; ADVSIZE[27] = 5; ADVPNTR[28] = (char *)&FRAME; ADVSIZE[28] = 1; ADVPNTR[29] = (char *)&BORDER; ADVSIZE[29] = 1; ADVPNTR[30] = (char *)&COLOR; ADVSIZE[30] = 1; ADVPNTR[31] = (char *)&TMINOR; ADVSIZE[31] = 1; ADVPNTR[32] = (char *)&YMINOR; ADVSIZE[32] = 1; ADVPNTR[33] = (char *)&ZMINOR; ADVSIZE[33] = 1; ADVPNTR[34] = (char *)TMAJOR; ADVSIZE[34] = 2; ADVPNTR[35] = (char *)YMAJOR; ADVSIZE[35] = 2; ADVPNTR[36] = (char *)ZMAJOR; ADVSIZE[36] = 2; ADVPNTR[37] = TLABEL; ADVSIZE[37] = 132; ADVPNTR[38] = YLABEL; ADVSIZE[38] = 132; ADVPNTR[39] = ZLABEL; ADVSIZE[39] = 132; ADVPNTR[40] = TITLE; ADVSIZE[40] = 132; ADVPNTR[41] = (char *)PARMS; ADVSIZE[41] = 10; ADVPNTR[42] = (char *)&QUIET; ADVSIZE[42] = 1; ADVPNTR[43] = (char *)POINT; ADVSIZE[43] = 2; ADVPNTR[44] = (char *)ZFACTOR; ADVSIZE[44] = 2; return; } /********************************************************************* * * Process the Input Line * */ short PROCESS() { short FLAG, I, F1=0, F2=0, F3; unsigned short LEN; IPNTR = ILINE; PSTART: JPNTR=memset(JLINE,0,256); KPNTR=memset(KLINE,0,256); /* Strip leading spaces from ILINE */ while (isspace(*IPNTR)) ++IPNTR; /* Find semicolon or single quote, whichever is first */ if ((LEN = strlen(IPNTR)) == 0) return(0); for (F1=F2=I=0;I<LEN;++I) { if ((*(IPNTR + I) == ';') && (!F1)) /* Semicolon */ F1 = I; else if ((*(IPNTR + I) ==(char)39) && (!F2)) /* Single Quote */ F2 = I; if (F1 && F2) break; } if ((F1 <= F2) || (!F2)) /* Semicolon was first or none at all*/ { if (!F1) F1 = LEN; strncpy(JLINE,IPNTR,F1); /* extract command line */ JLINE[F1] = (char)0; IPNTR += (++F1); /* advance pointer to new CL */ } else /* Single Quote was first, ; is in a string? */ { ++F2; for (I=F2;I<LEN;++I) /* Find end of string */ if (*(IPNTR + I) == (char)39) break; F2 = ++I; /* Now find semicolon */ for (I=F2;I<LEN;++I) if (*(IPNTR + I) ==(char)59) break; /* Semicolon */ strncpy(JLINE,IPNTR,F2); /* extract command line */ JLINE[F2] = (char)0; IPNTR += (++I); /* advance pointer to new CL */ } /* * At this point JLINE has the currnet CL and IPNTR points * to the next CL in ILINE. * Now seperate the possible two parts of the CL. */ while (isspace(*JPNTR)) ++JPNTR; /* Remove Leading Spaces */ LEN = strlen(JPNTR); for (I=0;I<LEN;++I) if (isspace(*(JPNTR + I)) || (*(JPNTR + I) == '=')) break; strncpy(KLINE,JPNTR,I); /* extract first word of CL */ KLINE[I] = (char)0; JPNTR += (++I); /* advance pointer to expression */ while (isspace(*JPNTR)) ++JPNTR; /* Remove Leading Spaces */ /* * At this point KPNTR points to the stripped first word * and JPNTR points to the stripped remaining expression in JLINE * so now process KPNTR */ MATCH = 0; /* First Check for an Ambigious Match */ ERRTYPE = 0; F1 = ADVCHK(KPNTR); /* While getting command index */ F2 = VERBCHK(KPNTR); F3 = PVERBCHK(KPNTR); if (MATCH > 1) /* Ambiguous Entry */ { MATCH = -1; /* Set MATCH is -1 as flag */ ADVCHK(KPNTR); VERBCHK(KPNTR); PVERBCHK(KPNTR); printf(MSP[4],KPNTR); return(1); } if (F1>=0) /* ADVERB */ { if (I=ADVERB(F1)) return(I); /* Place Value into Adverb */ } else if (F2) /* VERB */ { if (strlen(JPNTR)) { printf("%sArgument following a VERB\n",MSP[1]); return(1); } if (I=VERB(F2)) return(I); } else if (F3) /* PSEUDOVERB */ { if (I=PVERB(F3)) return(I); } else if (!ERRTYPE) { printf("%sUnknown command '%s'\n",MSP[1],KPNTR); return(1); } goto PSTART; } /********************************************************************* * * Search for an ADVERB * INDEX is used to determine a specific array element. * if INDEX=-1 then the array name was given without an index. * returns adverb number if found, returns -1 if no match, -2 if error. * NOTE: a return value of zero is TASKNAME * also -1 means that no argument was in JPNTR * */ short ADVCHK(PNTR) char *PNTR; { unsigned short I, LEN; short ADV=-1, F1=0, F2=0; if (!strlen(strupr(PNTR))) return(-1); /* * First see if there are [] */ INDEX = -1; LEN = strlen(PNTR); for (I=0;I<LEN;++I) { if (*(PNTR+I) == '[') F1 = I; else if (*(PNTR+I) == ']') F2 = I; if (F1 && F2) break; } if ((F1 && !F2) || (F1 > F2)) { printf("%sMissing ']'\n",MSP[1]); ERRTYPE = 1; return(-2); } else if (!F1 && F2) { printf("%sMissing '['\n",MSP[1]); ERRTYPE = 1; return(-2); } if (F1) { if (*(PNTR + F2 + 1)) return(-1); /*Stuff Following ] */ INDEX = atoi((PNTR+F1 + 1)) - 1; *(PNTR + F1) = (char)0; /* Mask off [ */ } LEN = strlen(PNTR); if (MATCH < 0) { for (I=0;I<Advstrnm ;++I) { if (!strncmp(ADVSTR[I],PNTR,LEN)) printf("%sCould be %-.8s\n",MSP[1],ADVSTR[I]); } return(-1); } for (I=0;I<Advstrnm;++I) { if (!strncmp(ADVSTR[I],PNTR,LEN)) { ADV = I; ++MATCH; if (LEN == strlen(ADVSTR[I])) /* Exact Match */ { MATCH = 1; break; } } } if (!strlen(JPNTR)) EVLFLG=1; else EVLFLG=0; if (!ADV) TASKFLG = 1; else TASKFLG = 0; return(ADV); } /********************************************************************* * * Evaluate PNTR and return a string literal */ char *SEVAL(cPointer) char *cPointer; { char *AdverbPointer; short I=0, N, J; if ((*cPointer == (char)39) || TASKFLG) /* ' is First Character */ { if (*cPointer == (char)39) ++cPointer; while ((*(cPointer + I) != (char)39) && (*(cPointer + I) != (char)0)) { CPA[I] = *(cPointer + I); ++I; } CPA[I] = (char)0; return(CPA); } MATCH=0; N = ADVCHK(cPointer); if (MATCH > 1) { MATCH = -1; ADVCHK(cPointer); printf(MSP[4],cPointer); return(NULL); } if (N < 0) return(NULL); /* Error */ if (INDEX < 0) INDEX = 0; if (INDEX > ADVSIZE[N]) INDEX=ADVSIZE[N]; switch (N) { case 0: /* String Adverbs */ AdverbPointer = TASKNAME; break; case 1: AdverbPointer = INNAME; break; case 2: AdverbPointer = INCLASS; break; case 3: AdverbPointer = INPATH; break; case 4: AdverbPointer = IN2NAME; break; case 5: AdverbPointer = IN2CLASS; break; case 6: AdverbPointer = IN2PATH; break; case 7: AdverbPointer = IN3NAME; break; case 8: AdverbPointer = IN3CLASS; break; case 9: AdverbPointer = IN3PATH; break; case 10: AdverbPointer = OUTNAME; break; case 11: AdverbPointer = OUTCLASS; break; case 12: AdverbPointer = OUTPATH; break; case 20: AdverbPointer = TFORMAT; break; case 21: AdverbPointer = YFORMAT; break; case 22: AdverbPointer = ZFORMAT; break; case 23: AdverbPointer = DEVICE; break; case 37: AdverbPointer = TLABEL; break; case 38: AdverbPointer = YLABEL; break; case 39: AdverbPointer = ZLABEL; break; case 40: AdverbPointer = TITLE; break; case 13: /* Integer Numeric Adverbs */ case 14: case 19: case 24: case 25: case 26: case 28: case 29: case 30: case 31: case 32: case 33: case 42: case 15: /* Double Numeric Adverbs */ case 16: case 17: case 18: case 34: case 35: case 36: case 41: case 43: case 44: printf("%sNumeric Adverb Unexpected '%s'\n",MSP[1],cPointer); default: return(NULL); } strcpy(CPA+I,AdverbPointer + INDEX); return(CPA); } /*************************************************************** ** ** Process ^C Interrupt */ short HANDEL() { signal(SIGINT,HANDEL); InterruptFlag = TRUE; memset(ILINE,0,256); memset(JLINE,0,256); memset(KLINE,0,256); IPNTR = ILINE; JPNTR = JLINE; KPNTR = KLINE; return(0); } /*************************************************************** ** ** Simple Adverb Eqaute */ short SIMPLE(N,F1,IDX) short N, F1, IDX; { short M, I; switch (F1) { case 0: /* String Adverbs */ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 20: case 21: case 22: case 23: case 37: case 38: case 39: case 40: printf("%sString Adverb Unexpected '%s'\n",MSP[1],KPNTR); return(1); break; default: if ((IDX <= 0) && (INDEX <= 0)) /* ARRAY1 = ARRAY2 */ { M = Min(ADVSIZE[N],ADVSIZE[F1]); for (I=0;I<M;++I) PUTVAL(ADVPNTR[N],I,N,GETVAL(ADVPNTR[F1],I,F1)); return(0); } else if ((IDX > 0) && (INDEX <= 0)) /* ARRAY1[] = ARRAY2 */ { if (IDX>ADVSIZE[N]) IDX = ADVSIZE[N]; M = Min(ADVSIZE[N]-IDX,ADVSIZE[F1]); for (I=0;I<M;++I) PUTVAL(ADVPNTR[N],I+IDX,N,GETVAL(ADVPNTR[F1],I,F1)); return(0); } else if ((IDX <= 0) && (INDEX > 0)) /* ARRAY1 = ARRAY2[] */ { if (INDEX>ADVSIZE[F1]) INDEX = ADVSIZE[F1]; M = ADVSIZE[N]; for (I=0;I<M;++I) PUTVAL(ADVPNTR[N],I,N,GETVAL(ADVPNTR[F1],INDEX,F1)); return(0); } else /* ARRAY1[] = ARRAY2[] */ { if (INDEX>ADVSIZE[F1]) INDEX = ADVSIZE[F1]-1; if (IDX>ADVSIZE[N]) IDX = ADVSIZE[N]-1; PUTVAL(ADVPNTR[N],IDX,N,GETVAL(ADVPNTR[F1],INDEX,F1)); } break; } return(0); } /*************************************************************** ** ** Get a numeric adverb value and return double */ double GETVAL(PNTR,I,N) char *PNTR; short I, N; { double D; switch (N) { case 13: /* Integer Numeric Adverbs */ case 14: case 19: case 24: case 25: case 26: case 28: case 29: case 30: case 31: case 32: case 33: case 42: D = (double) *( (short *)PNTR + I); break; case 15: /* Double Numeric Adverbs */ case 16: case 17: case 18: case 34: case 35: case 36: case 41: case 43: case 44: D = *( (double *)PNTR + I ); } return(D); } /*************************************************************** ** ** Put a value into a numeric adverb */ void PUTVAL(PNTR,I,N,D) char *PNTR; short I,N; double D; { switch (N) { case 13: /* Integer Numeric Adverbs */ case 14: case 19: case 24: case 25: case 26: case 28: case 29: case 30: case 31: case 32: case 33: case 42: *( (short *)PNTR + I ) = (short)D; break; case 15: /* Double Numeric Adverbs */ case 16: case 17: case 18: case 34: case 35: case 36: case 41: case 43: case 44: *( (double *)PNTR + I ) = D; } return; } /********************************************************************* * * Process an ADVERB number N with an argument JPNTR * Place Value of Expression JPNTR into ADVERB(N) * */ short ADVERB(N) short N; { double D; char *P; short IDX, I, M, F1; IDX = INDEX; /* Get current array index */ switch (N) { case 0: /* String Adverbs */ strupr(JPNTR); case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 20: case 21: case 22: case 23: case 37: case 38: case 39: case 40: if (IDX<0) IDX = 0; if (EVLFLG) { printf("%s'%s'\n",MSP[1],ADVPNTR[N]+IDX); return(0); } P = SEVAL(JPNTR); if (!P) { printf("%sInvalid string expression\n",MSP[1]); return(1); } if (IDX>ADVSIZE[N]) IDX = 0; *(P + ADVSIZE[N] - IDX) = 0; strcpy(ADVPNTR[N]+IDX,P); break; case 13: /* Integer Numeric Adverbs */ case 14: case 19: case 24: case 25: case 26: case 28: case 29: case 30: case 31: case 32: case 33: case 42: case 15: /* Double Numeric Adverbs */ case 16: case 17: case 18: case 34: case 35: case 36: case 41: case 43: case 44: /* ** Array into Array ** Array into Array[] ** Value into Array ** Value into Array[] */ if (EVLFLG) { if (IDX<0) { IDX=0; M=ADVSIZE[N]; } else M=IDX; printf(MSP[1]); for (I=IDX;I<M;++I) { printf("%G",GETVAL(ADVPNTR[N],I,N)); if (I <(M-1)) printf(", "); } printf("\n"); return(0); } MATCH = 0; F1 = ADVCHK(JPNTR); /* Check for ARRAY to ?? */ if (MATCH > 1) /* Ambiguous Entry */ { MATCH = -1; /* Set MATCH is -1 as flag */ ADVCHK(JPNTR); printf(MSP[4],JPNTR); return(1); } if (F1 >=0) /* Adverb Found so go to work and equate */ return(SIMPLE(N,F1,IDX)); if (IDX < 0) /* ?? into ARRAY */ { P = strtok(JPNTR," ,"); for (I=0;I<ADVSIZE[N];++I) { if (P) D = atof(P); PUTVAL(ADVPNTR[N],I,N,D); P = strtok(NULL," ,"); } } else /* ?? into ARRAY[] */ { if (IDX>ADVSIZE[N]) IDX=ADVSIZE[N]-1; P = strtok(JPNTR," ,"); do { if (P) { D = atof(P); PUTVAL(ADVPNTR[N],IDX,N,D); } P = strtok(NULL," ,"); } while (P && (++IDX < ADVSIZE[N])); } } return(0); }