From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/FC/ERROR.C | 16 + v4.0/src/CMD/FC/FC.C | 864 +++++++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/FC/FC.H | 14 + v4.0/src/CMD/FC/FC.LNK | 4 + v4.0/src/CMD/FC/FGETL.C | 52 +++ v4.0/src/CMD/FC/GETL.ASM | 146 ++++++++ v4.0/src/CMD/FC/INTERNAT.H | 30 ++ v4.0/src/CMD/FC/ITOUPPER.ASM | 119 ++++++ v4.0/src/CMD/FC/MAKEFILE | 64 ++++ v4.0/src/CMD/FC/MAXMIN.ASM | 37 ++ v4.0/src/CMD/FC/MESSAGES.ASM | 31 ++ v4.0/src/CMD/FC/MOVE.ASM | 73 ++++ v4.0/src/CMD/FC/NTOI.C | 37 ++ v4.0/src/CMD/FC/STRING.ASM | 115 ++++++ v4.0/src/CMD/FC/TOOLS.H | 94 +++++ v4.0/src/CMD/FC/TTYPES.H | 71 ++++ v4.0/src/CMD/FC/UPDATE.C | 128 +++++++ v4.0/src/CMD/FC/XTAB.ASM | 100 +++++ 18 files changed, 1995 insertions(+) create mode 100644 v4.0/src/CMD/FC/ERROR.C create mode 100644 v4.0/src/CMD/FC/FC.C create mode 100644 v4.0/src/CMD/FC/FC.H create mode 100644 v4.0/src/CMD/FC/FC.LNK create mode 100644 v4.0/src/CMD/FC/FGETL.C create mode 100644 v4.0/src/CMD/FC/GETL.ASM create mode 100644 v4.0/src/CMD/FC/INTERNAT.H create mode 100644 v4.0/src/CMD/FC/ITOUPPER.ASM create mode 100644 v4.0/src/CMD/FC/MAKEFILE create mode 100644 v4.0/src/CMD/FC/MAXMIN.ASM create mode 100644 v4.0/src/CMD/FC/MESSAGES.ASM create mode 100644 v4.0/src/CMD/FC/MOVE.ASM create mode 100644 v4.0/src/CMD/FC/NTOI.C create mode 100644 v4.0/src/CMD/FC/STRING.ASM create mode 100644 v4.0/src/CMD/FC/TOOLS.H create mode 100644 v4.0/src/CMD/FC/TTYPES.H create mode 100644 v4.0/src/CMD/FC/UPDATE.C create mode 100644 v4.0/src/CMD/FC/XTAB.ASM (limited to 'v4.0/src/CMD/FC') diff --git a/v4.0/src/CMD/FC/ERROR.C b/v4.0/src/CMD/FC/ERROR.C new file mode 100644 index 0000000..47bc02d --- /dev/null +++ b/v4.0/src/CMD/FC/ERROR.C @@ -0,0 +1,16 @@ +/* error.c - return text of error corresponding to the most recent DOS error */ + +#include "tools.h" + +extern int errno; +extern sys_nerr; +extern char *sys_errlist[]; +extern char UnKnown[]; + +char *error () +{ + if (errno < 0 || errno >= sys_nerr) + return UnKnown; + else + return sys_errlist[errno]; +} diff --git a/v4.0/src/CMD/FC/FC.C b/v4.0/src/CMD/FC/FC.C new file mode 100644 index 0000000..d1dc0f6 --- /dev/null +++ b/v4.0/src/CMD/FC/FC.C @@ -0,0 +1,864 @@ +/* file compare + + Fcom compares two files in either a line-by-line mode or in a strict + byte-by-byte mode. + + The byte-by-byte mode is simple; merely read both files and print the + offsets where they differ and the contents. + + The line compare mode attempts to isolate differences in ranges of lines. + Two buffers of lines are read and compared. No hashing of lines needs + to be done; hashing only speedily tells you when things are different, + not the same. Most files run through this are expected to be largely + the same. Thus, hashing buys nothing. + + +*********************************************************************** +The algorithm that immediately follows does not work. There is an error +somewhere in the range of lines 11 on. An alternative explanation follows. + KGS +************************************************************************ + + [0] Fill buffers + [1] If both buffers are empty then + [1.1] Done + [2] Adjust buffers so 1st differing lines are at top. + [3] If buffers are empty then + [3.1] Goto [0] + + This is the difficult part. We assume that there is a sequence of inserts, + deletes and replacements that will bring the buffers back into alignment. + + [4] xd = yd = FALSE + [5] xc = yc = 1 + [6] xp = yp = 1 + [7] If buffer1[xc] and buffer2[yp] begin a "sync" range then + [7.1] Output lines 1 through xc-1 in buffer 1 + [7.2] Output lines 1 through yp-1 in buffer 2 + [7.3] Adjust buffer 1 so line xc is at beginning + [7.4] Adjust buffer 2 so line yp is at beginning + [7.5] Goto [0] + [8] If buffer1[xp] and buffer2[yc] begin a "sync" range then + [8.1] Output lines 1 through xp-1 in buffer 1 + [8.2] Output lines 1 through yc-1 in buffer 2 + [8.3] Adjust buffer 1 so line xp is at beginning + [8.4] Adjust buffer 2 so line yc is at beginning + [8.5] Goto [0] + [9] xp = xp + 1 + [10] if xp > xc then + [10.1] xp = 1 + [10.2] xc = xc + 1 + [10.3] if xc > number of lines in buffer 1 then + [10.4] xc = number of lines + [10.5] xd = TRUE + [11] if yp > yc then + [11.1] yp = 1 + [11.2] yc = yc + 1 + [11.3] if yc > number of lines in buffer 2 then + [11.4] yc = number of lines + [11.5] yd = TRUE + [12] if not xd or not yd then + [12.1] goto [6] + + At this point there is no possible match between the buffers. For + simplicity, we punt. + + [13] Display error message. + +EXPLANATION 2 + + This is a variation of the Largest Common Subsequence problem. A + detailed explanation of this can be found on p 189 of Data Structures + and Algorithms by Aho Hopcroft and Ulman. + + + + FC maintains two buffers within which it tries to find the Largest Common + Subsequence (The largest common subsequence is simply the pattern in + buffer1 that yields the most matches with the pattern in buffer2, or the + pattern in buffer2 that yields the most matches with the pattern in buffer1) + + FC makes a simplifying assumption that the contents of one buffer can be + converted to the contents of the other buffer by deleting the lines that are + different between the two buffers. + + Two indices into each buffer are maintained: + + xc, yc == point to the last line that has been scanned up to now + + xp, yp == point to the first line that has not been exhaustively + compared to lines 0 - #c in the other buffer. + + FC now makes a second simplifying assumption: + It is unnecessary to do any calculations on lines that are equal. + + Hence FC scans File1 and File two line by line until a difference is + encountered. + + + When a difference is encountered the two buffers are filled such that + the line containing the first difference heads the buffer. The following + exhaustive search algorithm is applied to find the first "sync" occurance. + (The below is simplified to use == for comparison. In practice more than + one line needs to match for a "sync" to be established). + + + FOR xc,yc = 1; xc,yx <= sizeof( BUFFERS ); xc++, yc++ + + FOR xp,yp = 1; xp,yp <= xc,yc; xp++, yp++ + + IF ( BUFFER1[xp] == BUFFER2[yc] ) + + Then the range of lines BUFFER1[ 1 ... xp ] and + BUFFER2[ 1 ... yc ] need to be deleted for the + two files to be equal. Therefore DISPLAY these + ranges, and begin scanning both files starting at + the matching lines. + FI + + IF ( BUFFER1[yp] == BUFFER2[xc] ) + + Then the range of lines BUFFER2[ 1 ... yp ] and + BUFFER1[ 1 ... xc ] need to be deleted for the + two files to be equal. Therefore DISPLAY these + ranges, and begin scanning both files starting at + the matching lines. + FI + FOREND + FOREND + + If a match is not found within the buffers, the message "RESYNC FAILED" + is issued and further comparison is aborted since there is no valid way + to find further matching lines. + + + + +END EXPLANATION 2 + + + + + + Certain flags may be set to modify the behavior of the comparison: + + -a abbreviated output. Rather than displaying all of the modified + ranges, just display the beginning, ... and the ending difference + -b compare the files in binary (or byte-by-byte) mode. This mode is + default on .EXE, .OBJ, .LIB, .COM, .BIN, and .SYS files + -c ignore case on compare (cmp = strcmpi instead of strcmp) + -l compare files in line-by-line mode + -lb n set the size of the internal line buffer to n lines from default + of 100 + -w ignore blank lines and white space (ignore len 0, use strcmps) + -t do not untabify (use fgets instead of fgetl) + -n output the line number also + -NNNN set the number of lines to resynchronize to n which defaults + to 2. Failure to have this value set correctly can result in + odd output: + file1: file2: + abcdefg abcdefg + aaaaaaa aaaaaab + aaaaaaa aaaaaaa + aaaaaaa aaaaaaa + abcdefg abcdefg + + with default sync of 2 yields: with sync => 3 yields: + + *****f1 *****f1 + abcdefg abcdefg + aaaaaaa aaaaaaa + *****f2 aaaaaaa + abcdefg *****f2 + aaaaaab abcdefg + aaaaaaa aaaaaab + aaaaaaa + *****f1 + aaaaaaa + aaaaaaa + abcdefg + *****f2 + aaaaaaa + abcdefg + + + + + + +WARNING: + This program makes use of GOTO's and hence is not as straightforward + as it could be! CAVEAT PROGRAMMER. + + + + + + + + + + + + + + + + */ + + +#include "tools.h" +#include "fc.h" + +/* #define DEBUG FALSE */ + +extern int fgetl(), + strcmp (); + +extern byte toupper (); + +int (*funcRead) (), /* function to use to read lines */ + (*fCmp) (); /* function to use to compare lines */ + +extern byte BadSw[], + Bad_ver[], + BadOpn[], + LngFil[], + NoDif[], + NoMem[], + UseMes[], + ReSyncMes[]; + +int ctSync = -1, /* number of lines required to sync */ + cLine = -1; /* number of lines in internal buffs */ + +flagType fAbbrev = FALSE, /* abbreviated output */ + fBinary = FALSE, /* binary comparison */ + fLine = FALSE, /* line comparison */ + fNumb = FALSE, /* display line numbers */ + fCase = TRUE, /* case is significant */ + fIgnore = FALSE; /* ignore spaces and blank lines */ + +#ifdef DEBUG + +flagType fDebug = FALSE; +#endif + +struct lineType *buffer1, + *buffer2; + +byte line[MAXARG]; /* single line buffer */ + +byte *extBin[] = { ".EXE", ".OBJ", ".LIB", + ".COM", ".BIN", ".SYS", NULL }; + + +main (c, v) +int c; +byte *v[]; +{ + + int i; + int j; + int fileargs; + char *strpbrk(), + *slash; + char n[2][80]; + char temp; + + + + extern byte _osmajor, _osminor; + word version; /* _osmajor._osminor, used for */ + /* version binding checks. */ + + + + /* Issue error message if DOS version is not within valid range. */ + version = ((word)_osmajor << 8) + (word)_osminor; + if (( LOWVERSION > version) || (version > HIGHVERSION)) + { + usage (Bad_ver, 1); + } + + funcRead = (int (*) ())FNADDR(fgetl); + + fileargs=0; + + for (i=1; i < c ; i++) + { +/** + * If argument doesn't begin with a /, parse a filename off of it + * then examine the argument for following switches. + * +**/ + if (*v[i] != '/') + { + slash= strpbrk( v[i],"/" ); + + if ( slash ) + { + temp = *slash; + *slash='\0' ; + strcpy(n[fileargs++],v[i]); + *slash =temp ; + } + else + strcpy(n[fileargs++],v[i]); + } + + for ( j=0 ; j < strlen( v[i] ) ; j++) + { + if(*(v[i]+j)=='/') + { + switch(toupper( *(v[i]+j+1))) + { + case 'A' : + fAbbrev = TRUE; + break; + case 'B' : + fBinary = TRUE; + break; + case 'C' : + fCase = FALSE; + break; +#ifdef DEBUG + case 'D' : + fDebug = TRUE; + break; +#endif + case 'W' : + fIgnore = TRUE; + break; + case 'L' : + if (toupper(*(v[i]+j+2))=='B') + { + cLine = ntoi ((v[i]+j+3),10); + break; + } + else + fLine = TRUE; + break; + case 'N' : + fNumb = TRUE; + break; + case 'T' : + funcRead =(int (*) ())FNADDR(fgets); + break; + default: + if (*strbskip((v[i]+j+1),"0123456789") == 0) + { + ctSync = ntoi ((v[i]+j+1), 10); + } + else + { + usage (NULL, 1); + } + } /* end switch */ + } /* end if */ + } /* end parse of argument for '/' */ + } /* End ARGUMENT Search */ + + + + if (fileargs != 2) + usage (NULL, 1); + + if (ctSync != -1) + fLine = TRUE; + else + ctSync = 2; + + if (cLine == -1) + cLine = 100; + + if (!fBinary && !fLine) + { + extention (n[0], line); + + for (i = 0; extBin[i]; i++) + if (!strcmpi (extBin[i], line)) + fBinary = TRUE; + + if (!fBinary) + fLine = TRUE; + } + + if (fBinary && (fLine || fNumb)) + usage (BadSw, 1); + + if (fIgnore) + { + if (fCase) + fCmp = FNADDR(strcmps); + else + fCmp = FNADDR(strcmpis); + } + else + { + if (fCase) + fCmp = FNADDR(strcmp); + else + fCmp = FNADDR(strcmpi); + } + + if (fBinary) + BinaryCompare (n[0], n[1]); + else + LineCompare (n[0], n[1]); + +} + +usage (p, erc) +unsigned char *p; +{ + if (p) + printf ("fc: %s\n", p); + else + printf (UseMes); + + exit (erc); +} + +BinaryCompare (f1, f2) +unsigned char *f1, *f2; +{ + register int c1, c2; + long pos; + FILE *fh1, *fh2; + flagType fSame; + + fSame = TRUE; + + if ((fh1 = fopen (f1, "rb")) == NULL) + { + sprintf (line, BadOpn, f1, error ()); + usage (line, 1); + } + + if ((fh2 = fopen (f2, "rb")) == NULL) + { + sprintf (line, BadOpn, f2, error ()); + usage (line, 1); + } + pos = 0L; + + while (TRUE) + { + if ((c1 = getc (fh1)) != EOF) + { + if ((c2 = getc (fh2)) != EOF) + { + if (c1 == c2) + ; + else + { + fSame = FALSE; + printf ("%08lX: %02X %02X\n", pos, c1, c2); + } + } + else + { + sprintf (line, LngFil, f1, f2); + usage (line, 1); + } + } + else + { + if ((c2 = getc (fh2)) == EOF) + { + if (fSame) + usage (NoDif, 0); + else + exit (1); + } + else + { + sprintf (line, LngFil, f2, f1); + usage (line, 1); + } + } + pos++; + } +} + +/* compare a range of lines */ +flagType compare (l1, s1, l2, s2, ct) +int l1, l2, ct; +register int s1, s2; +{ + +#ifdef DEBUG + if (fDebug) + printf ("compare (%d, %d, %d, %d, %d)\n", l1, s1, l2, s2, ct); +#endif + + if (ct == 0 || s1+ct > l1 || s2+ct > l2) + return FALSE; + + while (ct--) + { + +#ifdef DEBUG + if (fDebug) + printf ("'%s' == '%s'? ", buffer1[s1].text, buffer2[s2].text); +#endif + + if ((*fCmp)(buffer1[s1++].text, buffer2[s2++].text)) + { + +#ifdef DEBUG + if (fDebug) + printf ("No\n"); +#endif + return FALSE; + } + } + +#ifdef DEBUG + if (fDebug) + printf ("Yes\n"); +#endif + + return TRUE; +} + +LineCompare (f1, f2) +unsigned char *f1, *f2; +{ + FILE *fh1, *fh2; + int l1, l2, i, xp, yp, xc, yc; + flagType xd, yd, fSame; + int line1, line2; + + fSame = TRUE; + + if ((fh1 = fopen (f1, "rb")) == NULL) + { + sprintf (line, BadOpn, f1, error ()); + usage (line, 1); + } + + if ((fh2 = fopen (f2, "rb")) == NULL) + { + sprintf (line, BadOpn, f2, error ()); + usage (line, 1); + } + + if ((buffer1 = (struct lineType *)malloc (cLine * (sizeof *buffer1))) == NULL || + (buffer2 = (struct lineType *)malloc (cLine * (sizeof *buffer1))) == NULL) + usage (NoMem); + + l1 = l2 = 0; + line1 = line2 = 0; +l0: + +#ifdef DEBUG + if (fDebug) + printf ("At scan beginning\n"); +#endif + + l1 += xfill (buffer1+l1, fh1, cLine-l1, &line1); + l2 += xfill (buffer2+l2, fh2, cLine-l2, &line2); + + if (l1 == 0 && l2 == 0) + { + if (fSame) + usage (NoDif, 0); + return; + } + xc = min (l1, l2); + + for (i=0; i < xc; i++) + { + if (!compare (l1, i, l2, i, 1)) + break; + } + + if (i != xc) + i = max (i-1, 0); + + l1 = adjust (buffer1, l1, i); + l2 = adjust (buffer2, l2, i); + + /* KLUDGE ALERT!! GOTO USED */ + if (l1 == 0 && l2 == 0) + goto l0; + + l1 += xfill (buffer1+l1, fh1, cLine-l1, &line1); + l2 += xfill (buffer2+l2, fh2, cLine-l2, &line2); + +#ifdef DEBUG + if (fDebug) + printf ("buffers are adjusted, %d, %d remain\n", l1, l2); +#endif + + xd = yd = FALSE; + xc = yc = 1; + xp = yp = 1; + +l6: + +#ifdef DEBUG + if (fDebug) + printf ("Trying resync %d,%d %d,%d\n", xc, xp, yc, yp); +#endif + + i = min (l1-xc,l2-yp); + i = min (i, ctSync); + + if (compare (l1, xc, l2, yp, i)) + { + fSame = FALSE; + printf ("***** %s\n", f1); + dump (buffer1, 0, xc); + printf ("***** %s\n", f2); + dump (buffer2, 0, yp); + printf ("*****\n\n"); + + l1 = adjust (buffer1, l1, xc); + l2 = adjust (buffer2, l2, yp); + + /* KLUDGE ALERT!! GOTO USED */ + goto l0; + } + i = min (l1-xp, l2-yc); + i = min (i, ctSync); + + if (compare (l1, xp, l2, yc, i)) + { + fSame = FALSE; + printf ("***** %s\n", f1); + dump (buffer1, 0, xp); + printf ("***** %s\n", f2); + dump (buffer2, 0, yc); + printf ("*****\n\n"); + + l1 = adjust (buffer1, l1, xp); + l2 = adjust (buffer2, l2, yc); + + /* KLUDGE ALERT!! GOTO USED */ + goto l0; + } + + if (++xp > xc) + { + xp = 1; + if (++xc >= l1) + { + xc = l1; + xd = TRUE; + } + } + + if (++yp > yc) + { + yp = 1; + if (++yc >= l2) + { + yc = l1; + yd = TRUE; + } + } + + if (!xd || !yd) + goto l6; + fSame = FALSE; + + if (l1 >= cLine || l2 >= cLine) + printf ("%s", ReSyncMes); + + printf ("***** %s\n", f1); + dump (buffer1, 0, l1-1); + printf ("***** %s\n", f2); + dump (buffer2, 0, l2-1); + printf ("*****\n\n"); + exit (1); +} + + + +/* return number of lines read in */ +xfill (pl, fh, ct, plnum) +struct lineType *pl; +FILE *fh; +int ct; +int *plnum; +{ + int i; + +#ifdef DEBUG + if (fDebug) + printf ("xfill (%04x, %04x)\n", pl, fh); +#endif + + i = 0; + while (ct-- && (*funcRead) (pl->text, MAXARG, fh) != NULL) + { + if (funcRead == (int (*) ())FNADDR(fgets)) + pl->text[strlen(pl->text)-1] = 0; + if (fIgnore && !strcmps (pl->text, "")) + pl->text[0] = 0; + if (strlen (pl->text) != 0 || !fIgnore) + { + pl->line = ++*plnum; + pl++; + i++; + } + } + +#ifdef DEBUG + if (fDebug) + printf ("xfill returns %d\n", i); +#endif + + return i; +} + + +/* adjust returns number of lines in buffer */ +adjust (pl, ml, lt) +struct lineType *pl; +int ml; +int lt; +{ + +#ifdef DEBUG + if (fDebug) + printf ("adjust (%04x, %d, %d) = ", pl, ml, lt); + if (fDebug) + printf ("%d\n", ml-lt); +#endif + + if (ml <= lt) + return 0; + +#ifdef DEBUG + if (fDebug) + printf ("move (%04x, %04x, %04x)\n", &pl[lt], &pl[0], sizeof (*pl)*(ml-lt)); +#endif + + Move ((unsigned char far *)&pl[lt], (char far *)&pl[0], sizeof (*pl)*(ml-lt)); + return ml-lt; +} + + +/* dump + * dump outputs a range of lines. + * + * INPUTS + * pl pointer to current lineType structure + * start starting line number + * end ending line number + * + * CALLS + * pline, printf + * + */ +dump (pl, start, end) +struct lineType *pl; +int start, end; +{ + if (fAbbrev && end-start > 2) + { + pline (pl+start); + printf ("...\n"); + pline (pl+end); + } + else + while (start <= end) + pline (pl+start++); +} + + + + +/* PrintLINE + * pline prints a single line of output. If the /n flag + * has been specified, the line number of the printed text is added. + * + * Inputs + * pl pointer to current lineType structure + * fNumb TRUE if /n specified + * + */ +pline (pl) +struct lineType *pl; +{ + if (fNumb) + printf ("%5d: ", pl->line); + + printf ("%s\n", pl->text); +} + +/* + * strcmpi will compare two string lexically and return one of + * the following: + * - 0 if the strings are equal + * - 1 if first > the second + * - (-1) if first < the second + * + * This was written to replace the run time library version of + * strcmpi which does not correctly compare the european character set. + * This version relies on a version of toupper which uses IToupper. + */ + +int strcmpi(str1, str2) +unsigned char *str1, *str2; +{ + unsigned char c1, c2; + + while ((c1 = toupper(*str1++)) == (c2 = toupper(*str2++))) { + if (c1 == '\0') + return(0); + } + + if (c1 > c2) + return(1); + else + return(-1); +} + + +/* compare two strings, ignoring white space, case is significant, return + * 0 if identical, <>0 otherwise + */ +strcmps (p1, p2) +unsigned char *p1, *p2; +{ + while (TRUE) { + while (ISSPACE(*p1)) + p1++; + while (ISSPACE(*p2)) + p2++; + if (*p1 == *p2) + if (*p1++ == 0) + return 0; + else + p2++; + else + return *p1-*p2; + } +} + + +/* compare two strings, ignoring white space, case is not significant, return + * 0 if identical, <>0 otherwise + */ +int strcmpis (p1, p2) +unsigned char *p1, *p2; +{ + while (TRUE) { + while (ISSPACE(*p1)) + p1++; + while (ISSPACE(*p2)) + p2++; + if (toupper (*p1) == toupper (*p2)) + if (*p1++ == 0) + return 0; + else + p2++; + else + return *p1-*p2; + } +} diff --git a/v4.0/src/CMD/FC/FC.H b/v4.0/src/CMD/FC/FC.H new file mode 100644 index 0000000..aa826c3 --- /dev/null +++ b/v4.0/src/CMD/FC/FC.H @@ -0,0 +1,14 @@ +struct lineType { + int line; /* line number */ + unsigned char text[MAXARG]; /* body of line */ +}; + +#define byte unsigned char +#define word unsigned short + +#define LOWVERSION 0x0300 + 10 +#define HIGHVERSION 0x0400 + 00 + +extern unsigned char _ctype_[]; +#define _SPACE 0x8 /* tab, carriage return, new line, */ +#define ISSPACE(c) ( (_ctype_+1)[c] & _SPACE ) diff --git a/v4.0/src/CMD/FC/FC.LNK b/v4.0/src/CMD/FC/FC.LNK new file mode 100644 index 0000000..89d9fff --- /dev/null +++ b/v4.0/src/CMD/FC/FC.LNK @@ -0,0 +1,4 @@ +fc.obj error.obj fgetl.obj getl.obj itoupper.obj ..\..\inc\kstring.obj + +maxmin.obj move.obj ntoi.obj string.obj update.obj xtab.obj messages.obj +fc.exe + diff --git a/v4.0/src/CMD/FC/FGETL.C b/v4.0/src/CMD/FC/FGETL.C new file mode 100644 index 0000000..a425b39 --- /dev/null +++ b/v4.0/src/CMD/FC/FGETL.C @@ -0,0 +1,52 @@ +/* fgetl.c - expand tabs and return lines w/o separators */ + +#include "tools.h" + +/* returns line from file (no CRLFs); returns NULL if EOF */ +fgetl (buf, len, fh) +char *buf; +int len; +FILE *fh; +{ + register int c; + register char *p; + + /* remember NUL at end */ + len--; + p = buf; + while (len) { + c = getc (fh); + if (c == EOF || c == '\n') + break; +#if MSDOS + if (c != '\r') +#endif + if (c != '\t') { + *p++ = c; + len--; + } + else { + c = min (8 - ((p-buf) & 0x0007), len); + Fill (p, ' ', c); + p += c; + len -= c; + } + } + *p = 0; + return ! ( (c == EOF) && (p == buf) ); +} + +/* writes a line to file (with trailing CRLFs) from buf, return <> 0 if + * writes fail + */ +fputl (buf, len, fh) +char *buf; +int len; +FILE *fh; +{ +#if MSDOS + return (fwrite (buf, 1, len, fh) != len || fputs ("\r\n", fh) == EOF) ? EOF : 0; +#else + return (fwrite (buf, 1, len, fh) != len || fputs ("\n", fh) == EOF) ? EOF : 0; +#endif +} diff --git a/v4.0/src/CMD/FC/GETL.ASM b/v4.0/src/CMD/FC/GETL.ASM new file mode 100644 index 0000000..508eca9 --- /dev/null +++ b/v4.0/src/CMD/FC/GETL.ASM @@ -0,0 +1,146 @@ +; +; blindingly fast assembly help for Z +; + +.xlist +include version.inc +include cmacros.inc +.list + +sBegin data +assumes ds,data + +bufstart dd ? +staticW bufsrc,? +staticW buflen,? +staticW buflength,? +staticW buffh,? +globalB fGetlCR,? +bufpos dd ? + +sEnd +sBegin code + +assumes cs,code + +; +; getlpos returns current seek position in file +; +cProc getlpos, +cBegin + mov dx,word ptr bufpos+2 + mov ax,word ptr bufpos +cEnd + +; +; getlinit (buf, len, fh) initializes the getl routine for buffer buf and fh fh +; +cProc getlinit, +parmD buf +parmW len +parmW fh +cBegin + mov ax,off_buf + mov word ptr bufstart,ax + mov ax,seg_buf + mov word ptr bufstart+2,ax + mov ax,fh + mov buffh,ax + mov ax,len + mov buflength,ax + mov buflen,0 + mov word ptr bufpos,0 + mov word ptr bufpos+2,0 + mov fGetlCR,0 +cEnd + +; +; getl (dst, len) returns TRUE if a line was read. +; +cProc getl,, +parmW dst +parmW dstlen +cBegin + assumes ss,data + cld + push ds + pop es + mov ds,word ptr bufstart+2 + assumes ds,nothing + mov si,bufsrc + mov di,dst + mov cx,buflen + mov dx,dstlen + dec dx ; room for NUL at end + jcxz fill + +movc: lodsb ; get a byte + cmp al,13 ; is it special? + jbe spec ; yes, go handle special case +stoc: stosb ; put character in buffer + dec dx ; one less space in buffer +endl: loopnz movc ; go back for more characters + jnz fill ; no more characters => go fill buffer + ; cx = 0, buflen = length moved +fin: dec cx +fin1: xor ax,ax + stosb + mov bufsrc,si ; length moved = buflen - cx + xchg buflen,cx + sub cx,buflen + add word ptr bufpos,cx + adc word ptr bufpos+2,0 + not ax + jmp short getldone + +fill: + mov cx, buflen ; add length moved to bufpos + add word ptr bufpos,cx + adc word ptr bufpos+2,0 + push dx + mov dx,word ptr bufstart + mov cx,buflength + mov bx,buffh + mov ah,3Fh + int 21h + mov cx,ax + mov buflen,ax + mov si,dx + pop dx + or ax,ax + jnz movc +; if we've stored chars then terminate line else return with 0 + cmp di,dst + jnz fin1 + jmp short getldone + +setnz: or al,1 + mov fGetlCR,-1 ; indicate we've seen a CR + jmp endl + +spec: jz setnz + cmp al,10 + jz fin + cmp al,9 + jnz stoc + push cx + mov ax,di + sub ax,dst + and ax,7 + mov cx,8 + sub cx,ax + cmp cx,dx + jbe ok + mov cx,dx +ok: sub dx,cx + mov al," " + rep stosb + pop cx + jmp endl + +getldone: +cEnd + +sEnd + +end diff --git a/v4.0/src/CMD/FC/INTERNAT.H b/v4.0/src/CMD/FC/INTERNAT.H new file mode 100644 index 0000000..0cd839c --- /dev/null +++ b/v4.0/src/CMD/FC/INTERNAT.H @@ -0,0 +1,30 @@ +/* + Data structure for international table + */ + +struct InterTbl +{ + unsigned dateform ; /* Date format */ + char currsym[5] ; /* Currency symbol as ASCIZ string */ + char thousp[2] ; /* Thousands separator as ASCIZ string */ + char decsp[2] ; /* Decimal separator as ASCIZ string */ + char datesp[2] ; /* Date separator as ASCIZ string */ + char timesp[2] ; /* Time separator as ASCIZ string */ + unsigned char bits ; /* Bit field */ + unsigned char numdig ; /* Number of signifigant decimal digits */ + unsigned char timeform ;/* Time format */ + unsigned long casecall ;/* Case mapping call */ + char datasp[2] ; /* Data list separator as ASCIZ string */ + int reserv[5] ; /* RESERVED */ +} ; + + +#define DATEFORM_USA 0 +#define DATEFORM_EUROPE 1 +#define DATEFORM_JAPAN 2 + +#define BITS_CURRENCY 0x0001 +#define BITS_NUMSPC 0x0002 + +#define TIMEFORM_12 0 +#define TIMEFORM_24 1 diff --git a/v4.0/src/CMD/FC/ITOUPPER.ASM b/v4.0/src/CMD/FC/ITOUPPER.ASM new file mode 100644 index 0000000..289c691 --- /dev/null +++ b/v4.0/src/CMD/FC/ITOUPPER.ASM @@ -0,0 +1,119 @@ +.xlist +include version.inc +include cmacros.inc +.list + +sBegin code +assumes cs,code + +; +; c = IToupper (c, routine); +; +; c is char to be converted +; routine is case map call in international table +; + +cProc IToupper, +parmW c +parmD routine +cBegin + mov ax,c + or ah,ah + jnz donothing + cmp al,'a' + jb noconv + cmp al,'z' + ja noconv + sub al,20H +noconv: + call routine +donothing: +cEnd + + +;Get_Lbtbl +; +; Get pointer to LBTBL from DOS if we are running on a version +; of DOS which supports it. If not, initialize the table with +; a pointer to a local "default" table with KANJI lead bytes. +; +;Input: word pointer to LONG "Lbtbl" +;Output: long initialized to Lead byte pointer +; + +cProc get_lbtbl, + +parmW pointer_to_table + +; on entry, low word of DWORD pointer has offset of +; a default table of lead bytes defined within the C program +; If function 63 is supported, the DWORD pointer to DOS' +; table will be placed here instead. +cBegin + push si + push di + mov bx,pointer_to_table ;get pointer + mov si,[bx] ;default table pointer in DS:SI + push es + push ds + mov ax,6300h ;make Get Lead Byte call + int 21h + mov ss:[bx],si ;si didn't change if non ECS dos + mov ss:[bx+2],ds ;store segment + pop ds + pop es + pop di + pop si +cEnd + + +; +; test_ECS(char,DWORD_prt) test the char to find out if it is +; a valid lead byte using passed DWORD +; Input: char PTR to the Lead Byte table. +; DWORD PTR to table +; Output: AX=FFFF (is_lead) Lead byte table may be default in +; AX=0 (not_lead) program or ECS table in DOS when +; running on a version which supports it. +; +cProc test_ECS, ;test for lead byte ;if Lead, then + ; return AX=Is_lead + ; else + ; return AX=FALSE +Is_lead EQU 0FFFFH +Not_lead EQU 0 + +parmW char +parmD pointer ;DWORD PTR to Lead Byte Table +cBegin + mov ax,char + xchg ah,al + push SI + push DS + LDS SI,pointer +ktlop: + lodsb + or al,al + jz notlead + cmp al,ah + ja notlead + lodsb + cmp ah,al + ja ktlop + mov ax,Is_lead +notl_exit: + pop ds + pop si + jmp cexit +notlead: + mov ax,not_lead + jmp notl_exit +cexit: +cEnd + + + + +sEnd + +end diff --git a/v4.0/src/CMD/FC/MAKEFILE b/v4.0/src/CMD/FC/MAKEFILE new file mode 100644 index 0000000..393a2bb --- /dev/null +++ b/v4.0/src/CMD/FC/MAKEFILE @@ -0,0 +1,64 @@ +#** makefile for fc + +DEST =fc +MSG =messages + +# Path Definitions + +BIOS =..\..\BIOS +BOOT =..\..\BOOT +dos =..\..\DOS +inc =..\..\INC +hinc =..\..\h +H =..\..\H + +# List of object files required + +OBJ = fc.obj \ + error.obj \ + fgetl.obj \ + getl.obj \ + itoupper.obj \ + $(inc)\kstring.obj \ + maxmin.obj \ + move.obj \ + ntoi.obj \ + string.obj \ + update.obj \ + xtab.obj \ + messages.obj + +# Rules and Dependencies follow + +all: $(DEST).exe + +$(inc)\printf.obj: $(inc)\printf.asm + +$(inc)\kstring.obj: $(inc)\kstring.c $(hinc)\internat.h + +getl.obj: getl.asm $(inc)\cmacros.inc $(inc)\version.inc + +itoupper.obj: itoupper.asm $(inc)\cmacros.inc $(inc)\version.inc + +maxmin.obj: maxmin.asm $(inc)\cmacros.inc $(inc)\version.inc + +$(MSG).obj: $(MSG).asm + +move.obj: move.asm $(inc)\cmacros.inc $(inc)\version.inc + +string.obj: string.asm $(inc)\cmacros.inc $(inc)\version.inc + +xtab.obj: xtab.asm $(inc)\cmacros.inc $(inc)\version.inc + +error.obj: error.c tools.h ttypes.h + +$(DEST).obj: $(DEST).c $(DEST).h tools.h ttypes.h + +fgetl.obj: fgetl.c tools.h ttypes.h + +ntoi.obj: ntoi.c tools.h ttypes.h + +update.obj: update.c tools.h ttypes.h + +$(DEST).exe: $(OBJ) $(DEST).lnk + $(link) @$(DEST).lnk; diff --git a/v4.0/src/CMD/FC/MAXMIN.ASM b/v4.0/src/CMD/FC/MAXMIN.ASM new file mode 100644 index 0000000..eb9ce53 --- /dev/null +++ b/v4.0/src/CMD/FC/MAXMIN.ASM @@ -0,0 +1,37 @@ +; +; maximum and minimum routines. +; + +.xlist +include version.inc +include cmacros.inc +.list + +sBegin code +assumes cs,code + +cProc max, +parmW a +parmW b +cBegin + mov ax,a + cmp ax,b + jg maxdone + mov ax,b +maxdone: +cEnd + +cProc min, +parmW a +parmW b +cBegin + mov ax,a + cmp ax,b + jl mindone + mov ax,b +mindone: +cEnd + +sEnd + +end diff --git a/v4.0/src/CMD/FC/MESSAGES.ASM b/v4.0/src/CMD/FC/MESSAGES.ASM new file mode 100644 index 0000000..5b1879f --- /dev/null +++ b/v4.0/src/CMD/FC/MESSAGES.ASM @@ -0,0 +1,31 @@ +; +; message file for FC command +; + +CONST SEGMENT WORD PUBLIC 'DATA' +CONST ENDS + +_BSS SEGMENT WORD PUBLIC 'DATA' +_BSS ENDS + +_DATA SEGMENT WORD PUBLIC 'DATA' +_DATA ENDS + +DGROUP GROUP CONST, _BSS, _DATA + + ASSUME DS:DGROUP + +_DATA SEGMENT +PUBLIC _BadSw, _UseMes, _BadOpn, _LngFil, _NoDif, _NoMem, _Bad_ver, _ReSyncMes, _UnKnown + +_BadSw DB "Incompatible switches",0 +_Bad_ver DB "Incorrect DOS version",0 +_UseMes DB "usage: fc [/a] [/b] [/c] [/l] [/lbNN] [/w] [/t] [/n] [/NNNN] file1 file2",0ah,0 +_BadOpn DB "cannot open %s - %s",0 +_LngFil DB "%s longer than %s",0 +_NoDif DB "no differences encountered",0 +_NoMem DB "out of memory",0ah,0 +_ReSyncMes DB "Resync failed. Files are too different\n",0 +_UnKnown DB "Unknown error",0 +_DATA ENDS +END diff --git a/v4.0/src/CMD/FC/MOVE.ASM b/v4.0/src/CMD/FC/MOVE.ASM new file mode 100644 index 0000000..d40e5d6 --- /dev/null +++ b/v4.0/src/CMD/FC/MOVE.ASM @@ -0,0 +1,73 @@ +; +; memory routines +; + +.xlist +include version.inc +include cmacros.inc +.list + +sBegin code +assumes cs,code + +cProc Move,, +parmD src +parmD dst +parmW count +cBegin + mov cx,count + jcxz NoByte ; No characters to move + les di,dst ; grab pointers + lds si,src + cld + mov ax,ds + cmp ax,Seg_dst + jnz SimpleMove ; segments are NOT the same, no opt + cmp si,di ; is the start of source before dest + jb TestMove ; yes, try to optimize + +SimpleMove: + shr cx,1 + rep movsw + jnc NoByte + movsb + jmp short NoByte + +TestMove: + mov ax,di + sub ax,si ; ax = difference between regions + cmp ax,cx ; is difference greater than region? + jae SimpleMove ; yes, no optimize + mov ax,cx ; optimize by copying down from top + dec ax + add di,ax + add si,ax + std + rep movsb ; no word optimization here + +NoByte: + cld +cEnd + +cProc Fill,, +parmD dst +parmB value +parmW count +cBegin + cld + les di,dst + mov al,value + mov ah,value + mov cx,count + shr cx,1 + jcxz fill1 + rep stosw +fill1: + jnc fill2 + stosb +fill2: +cEnd + +sEnd + +end diff --git a/v4.0/src/CMD/FC/NTOI.C b/v4.0/src/CMD/FC/NTOI.C new file mode 100644 index 0000000..267fce7 --- /dev/null +++ b/v4.0/src/CMD/FC/NTOI.C @@ -0,0 +1,37 @@ +/* convert an arbitrary based number to an integer */ + +#include +#include "tools.h" + +/* p points to characters, return -1 if no good characters found + * and base is 2 <= base <= 16 + */ +int ntoi (p, base) +char *p; +int base; +{ + register int i, c; + flagType fFound; + + if (base < 2 || base > 16) + return -1; + i = 0; + fFound = FALSE; + while (c = *p++) { + c = tolower (c); + if (!isxdigit (c)) + break; + if (c <= '9') + c -= '0'; + else + c -= 'a'-10; + if (c >= base) + break; + i = i * base + c; + fFound = TRUE; + } + if (fFound) + return i; + else + return -1; +} diff --git a/v4.0/src/CMD/FC/STRING.ASM b/v4.0/src/CMD/FC/STRING.ASM new file mode 100644 index 0000000..d72f7a4 --- /dev/null +++ b/v4.0/src/CMD/FC/STRING.ASM @@ -0,0 +1,115 @@ +; +; string functions for lattice C +; + +.xlist +include version.inc +include cmacros.inc +.list + +sBegin data +assumes ds,data + +externB XLTab +externB XUTab + +sEnd + +sBegin code +assumes cs,code + +externP strlen + +; +; strbscan (string, set) returns pointer to 1st char in set or end +; +cProc strbscan,, +parmW str +parmW set +cBegin + push ds + pop es + cCall strlen, + inc ax + mov bx, ax + mov si,str + cld +bscan: + lodsb + mov cx,bx + mov di,set +; +; While not in the set +; + repnz scasb + jnz bscan + lea ax,[si-1] +cEnd + +; +; strbskip ( string, set ) returns pointer to 1st char not in set +; +cProc strbskip,, +parmW str +parmW set +cBegin + push ds + pop es + cCall strlen, + inc ax + mov bx, ax + mov si,str + cld +bskip: + lodsb + or al,al + jz eskip + mov cx,bx + mov di,set +; +; While not in the set +; + repnz scasb + jz bskip +eskip: + lea ax,[si-1] +cEnd + +; +; strpre (s1, s2) returns -1 if s1 is a prefix of s2, 0 otherwise. Ignores +; case. +; +cProc strpre,, +parmW pref +parmW str +cBegin + cld + mov si,pref + mov di,str + mov bx,dataOFFSET xltab +preCompare: + lodsb + mov ah,[di] + inc di + + xlat + xchg ah,al + xlat + + cmp ah,al + jnz preDif + or ah,ah + jnz preCompare +preYes: + mov ax,-1 + jmp short preDone +preDif: + or ah,ah + jz preYes + xor ax,ax +preDone: +cEnd + +sEnd + +end diff --git a/v4.0/src/CMD/FC/TOOLS.H b/v4.0/src/CMD/FC/TOOLS.H new file mode 100644 index 0000000..f6bc435 --- /dev/null +++ b/v4.0/src/CMD/FC/TOOLS.H @@ -0,0 +1,94 @@ +/* + * tools.h - Header file for accessing TOOLS.LIB routines + * includes stdio.h and ctype.h + * + * 4/14/86 dl added U_* flags for upd return values + * + * 31-Jul-1986 mz Add Connect definitions + */ + +#define TRUE -1 +#define FALSE 0 + +#if MSDOS +#define PSEPSTR "\\" +#define PSEPCHR '\\' +#else +#define PSEPSTR "/" +#define PSEPCHR '/' +#endif + +typedef char flagType; +typedef long ptrType; + +#define SETFLAG(l,f) ((l) |= (f)) +#define TESTFLAG(v,f) (((v)&(f))!=0) +#define RSETFLAG(l,f) ((l) &= ~(f)) + +#define SHIFT(c,v) {c--; v++;} + +#define LOW(w) ((int)(w)&0xFF) +#define HIGH(w) LOW((int)(w)>>8) +#define WORD(h,l) ((LOW((h))<<8)|LOW((l))) +#define POINTER(seg,off) ((((long)(seg))<<4)+ (long)(off)) + +#define FNADDR(f) (f) + +#define SELECT if(FALSE){ +#define CASE(x) }else if((x)){ +#define OTHERWISE }else{ +#define ENDSELECT } + +/* buffer description for findfirst and findnext */ + +struct findType { + char reserved[21]; /* reserved for start up */ + char attr; /* attribute found */ + unsigned time; /* time of last modify */ + unsigned date; /* date of last modify */ + long length; /* file size */ + char name[13]; /* asciz file name */ +}; + +/* attributes */ +#define A_RO 1 /* read only */ +#define A_H 2 /* hidden */ +#define A_S 4 /* system */ +#define A_V 8 /* volume id */ +#define A_D 16 /* directory */ +#define A_A 32 /* archive */ + +#define A_MOD (A_RO+A_H+A_S+A_A) /* changeable attributes */ + +#define HASATTR(a,v) TESTFLAG(a,v) /* true if a has attribute v */ + +extern char XLTab[], XUTab[]; + +#define MAXARG 128 +#define MAXPATHLEN 128 + +#include "ttypes.h" + +struct vectorType { + int max; /* max the vector can hold */ + int count; /* count of elements in vector */ + unsigned elem[1]; /* elements in vector */ +}; + +/* return flags for upd */ +#define U_DRIVE 0x8 +#define U_PATH 0x4 +#define U_NAME 0x2 +#define U_EXT 0x1 + +/* Connect definitions */ + +#define REALDRIVE 0x8000 +#define ISTMPDRIVE(x) (((x)&REALDRIVE)==0) +#define TOKTODRV(x) ((x)&~REALDRIVE) + +/* Heap Checking return codes */ + +#define HEAPOK 0 +#define HEAPBADBEGIN -1 +#define HEAPBADNODE -2 diff --git a/v4.0/src/CMD/FC/TTYPES.H b/v4.0/src/CMD/FC/TTYPES.H new file mode 100644 index 0000000..739df6f --- /dev/null +++ b/v4.0/src/CMD/FC/TTYPES.H @@ -0,0 +1,71 @@ +/* ttypes.h - type definitions for tools library */ + +#include + +/* assembly routines */ +flagType int25 (char, char far *, unsigned int, unsigned int); +flagType int26 (char, char far *, unsigned int, unsigned int); +flagType kbhit (); +char getch (); +void Move (char far *, char far *, unsigned int); +void Fill (char far *, char, unsigned int); +char *strbscan (char *, char *); +char *strbskip (char *, char *); +flagType strpre (char *, char *); +int strcmpi (unsigned char *, unsigned char *); +char *fcopy (char *, char *); +long getlpos (); +void getlinit ( char far *, int, int); +int getl (char *, int); + +/* c routines */ +/*global*/ char *lower(char *); +/*global*/ char *upper(char *); +/*global*/ char *error(void); +/*global*/ long fexpunge(char *,FILE *); +/*global*/ char *fcopy(char *,char *); +/*global*/ int fgetl(char *,int ,FILE *); +/*global*/ int fputl(char *,int ,FILE *); +/*global*/ int ffirst(char *,int ,struct findType *); +/*global*/ int fnext(struct findType *); +/*global*/ char forsemi(char *,char ( *)(), ); +/*global*/ long freespac(int ); +/*global*/ long sizeround(long ,int ); +/*global*/ int rspawnl(char *,char *,char *, ); +/*global*/ int rspawnv(char *,char *,char *,char *[0]); +/*global*/ char *MakeStr(char *); +/*global*/ int mapenv(char *,char *); +/*global*/ char *ismark(char *); +/*global*/ FILE *swopen(char *,char *); +/*global*/ int swclose(FILE *); +/*global*/ int swread(char *,int ,FILE *); +/*global*/ char *swfind(char *,FILE *,char *); +/*global*/ char *getenvini(char *,char *); +/*global*/ char fPathChr(int ); +/*global*/ char fSwitChr(int ); +/*global*/ char fPFind(char *,unsigned int * *); +/*global*/ char findpath(char *,char *,char ); +/*global*/ FILE *pathopen(char *,char *,char *); +/*global*/ int forfile(char *,int ,void ( *)(), ); +/*global*/ int rootpath(char *,char *); +/*global*/ int sti(char *,int ); +/*global*/ int ntoi(char *,int ); +/*global*/ int strcmps(unsigned char *,unsigned char *); +/*global*/ int strcmpis(unsigned char *,unsigned char *); +/*global*/ char *strend(char *); +/*global*/ int upd(char *,char *,char *); +/*global*/ int drive(char *,char *); +/*global*/ int extention(char *,char *); +/*global*/ int filename(char *,char *); +/*global*/ int filenamx(char *,char *); +/*global*/ int path(char *,char *); +/*global*/ int curdir(char *,char ); +/*global*/ int getattr(char *); +/*global*/ int fdelete(char *); +/*global*/ char *fmove(char *, char *); +/*global*/ char *fappend(char *, int); +/*global*/ long ctime2l(char *); +/*global*/ struct tm *ctime2tm(char *); +/*global*/ long date2l(int, int, int, int, int, int); +/*global*/ struct vectorType *VectorAlloc(int); +/*global*/ flagType fAppendVector(struct vectorType**, unsigned int); diff --git a/v4.0/src/CMD/FC/UPDATE.C b/v4.0/src/CMD/FC/UPDATE.C new file mode 100644 index 0000000..8263db1 --- /dev/null +++ b/v4.0/src/CMD/FC/UPDATE.C @@ -0,0 +1,128 @@ +/* + * update takes a def string and update and fills the + * update with missing defs the update allowing + * specification of missing parameters. + * the parts are: ^{[~:]#:}{%#}{[~.]#}{.[~./\:]}$ + * maximum size of MAXPATHLEN (80) bytes + * + * 4/14/86 dl use U_ flags + * + */ + +#include "tools.h" + +int upd (def, update, dst) +char *def, *update, *dst; +{ + char *p, buf[MAXPATHLEN]; + int f; + + f = 0; + p = buf; +#if MSDOS + if (drive(update, p) || drive (def, p)) + SETFLAG(f, U_DRIVE); + p += strlen (p); +#endif + + if (path(update, p) || path (def, p)) + SETFLAG(f, U_PATH); + p += strlen (p); + + if (filename(update, p) || filename (def, p)) + SETFLAG(f, U_NAME); + p += strlen (p); + + if (extention(update, p) || extention (def, p)) + SETFLAG(f, U_EXT); + + strcpy (dst, buf); + + return f; +} + +#if MSDOS +/* copy a drive from source to dest if present, return TRUE if we found one */ +drive (src, dst) +char *src, *dst; +{ + register char *p; + + p = strbscan (src, ":"); + if (*p++ == NULL) + p = src; + strcpy (dst, src); + dst[p-src] = 0; + return strlen (dst) != 0; +} +#endif + +/* copy an extention from source to dest if present. include the period. + Return TRUE if one found. + */ +extention (src, dst) +char *src, *dst; +{ + register char *p, *p1; + + p = src - 1; + while (*(p=strbscan(1+(p1=p), ".")) != NULL) + ; + /* p1 points to last . or begin of string p points to eos */ + if (*strbscan (p1, "\\/:") != NULL || *p1 != '.') + p1 = p; + strcpy (dst, p1); + return strlen (dst) != 0; +} + +/* copy a filename part from source to dest if present. return true if one + is found + */ +filename (src, dst) +char *src, *dst; +{ + register char *p, *p1; + + p = src-1; + while (*(p=strbscan (p1=p+1, "\\/:")) != NULL) + ; + /* p1 points after last / or at bos */ + p = strbscan (p1, "."); + strcpy (dst, p1); + dst[p-p1] = 0; + return strlen (dst) != 0; +} + +/* copy a filename.ext part from source to dest if present. return true if one + is found + */ +fileext (src, dst) +char *src, *dst; +{ + *dst = '\0'; + if ( filename (src, dst) ) { + dst += strlen (dst); + extention (src, dst); + return TRUE; + } + return FALSE; +} + +/* copy the paths part of the file description. return true if found + */ +path (src, dst) +char *src, *dst; +{ + register char *p, *p1; + + if (*(p=strbscan (src, ":")) != NULL) + src = p+1; + p = src-1; + /* p points to beginning of possible path (after potential drive spec) */ + while (*(p=strbscan (p1=p+1, "\\/:")) != NULL) + ; + /* p1 points after final / or bos */; + strcpy (dst, src); + dst[p1-src] = 0; + return strlen (dst) != 0; +} diff --git a/v4.0/src/CMD/FC/XTAB.ASM b/v4.0/src/CMD/FC/XTAB.ASM new file mode 100644 index 0000000..3b42529 --- /dev/null +++ b/v4.0/src/CMD/FC/XTAB.ASM @@ -0,0 +1,100 @@ +; +; xlat tables for case conversion +; + +.xlist +include version.inc +include cmacros.inc +.list + +sBegin data + +public _XLTab, _XUTab + +assumes ds,data + +; +; table for lowercase translation +; + +_XLTab LABEL BYTE + + db 000h, 001h, 002h, 003h, 004h, 005h, 006h, 007h + db 008h, 009h, 00Ah, 00Bh, 00Ch, 00Dh, 00Eh, 00Fh + + db 010h, 011h, 012h, 013h, 014h, 015h, 016h, 017h + db 018h, 019h, 01Ah, 01Bh, 01Ch, 01Dh, 01Eh, 01Fh + + db ' !"#$%&', 027h + db '()*+,-./' + + db '01234567' + db '89:;<=>?' + + db '@abcdefg' + db 'hijklmno' + + db 'pqrstuvw' + db 'xyz[\]^_' + + db '`abcdefg' + db 'hijklmno' + + db 'pqrstuvw' + db 'xyz{|}~', 07Fh + + db 080h, 081h, 082h, 083h, 084h, 085h, 086h, 087h + db 088h, 089h, 08Ah, 08Bh, 08Ch, 08Dh, 08Eh, 08Fh + db 090h, 091h, 092h, 093h, 094h, 095h, 096h, 097h + db 098h, 099h, 09Ah, 09Bh, 09Ch, 09Dh, 09Eh, 09Fh + db 0A0h, 0A1h, 0A2h, 0A3h, 0A4h, 0A5h, 0A6h, 0A7h + db 0A8h, 0A9h, 0AAh, 0ABh, 0ACh, 0ADh, 0AEh, 0AFh + db 0B0h, 0B1h, 0B2h, 0B3h, 0B4h, 0B5h, 0B6h, 0B7h + db 0B8h, 0B9h, 0BAh, 0BBh, 0BCh, 0BDh, 0BEh, 0BFh + db 0C0h, 0C1h, 0C2h, 0C3h, 0C4h, 0C5h, 0C6h, 0C7h + db 0C8h, 0C9h, 0CAh, 0CBh, 0CCh, 0CDh, 0CEh, 0CFh + db 0D0h, 0D1h, 0D2h, 0D3h, 0D4h, 0D5h, 0D6h, 0D7h + db 0D8h, 0D9h, 0DAh, 0DBh, 0DCh, 0DDh, 0DEh, 0DFh + db 0E0h, 0E1h, 0E2h, 0E3h, 0E4h, 0E5h, 0E6h, 0E7h + db 0E8h, 0E9h, 0EAh, 0EBh, 0ECh, 0EDh, 0EEh, 0EFh + db 0F0h, 0F1h, 0F2h, 0F3h, 0F4h, 0F5h, 0F6h, 0F7h + db 0F8h, 0F9h, 0FAh, 0FBh, 0FCh, 0FDh, 0FEh, 0FFh + +_XUTab LABEL BYTE + + db 000h, 001h, 002h, 003h, 004h, 005h, 006h, 007h + db 008h, 009h, 00Ah, 00Bh, 00Ch, 00Dh, 00Eh, 00Fh + db 010h, 011h, 012h, 013h, 014h, 015h, 016h, 017h + db 018h, 019h, 01Ah, 01Bh, 01Ch, 01Dh, 01Eh, 01Fh + db ' !"#$%&', 027h + db '()*+,-./' + db '01234567' + db '89:;<=>?' + db '@ABCDEFG' + db 'HIJKLMNO' + db 'PQRSTUVW' + db 'XYZ[\]^_' + db '`ABCDEFG' + db 'HIJKLMNO' + db 'PQRSTUVW' + db 'XYZ{|}~', 07Fh + db 080h, 081h, 082h, 083h, 084h, 085h, 086h, 087h + db 088h, 089h, 08Ah, 08Bh, 08Ch, 08Dh, 08Eh, 08Fh + db 090h, 091h, 092h, 093h, 094h, 095h, 096h, 097h + db 098h, 099h, 09Ah, 09Bh, 09Ch, 09Dh, 09Eh, 09Fh + db 0A0h, 0A1h, 0A2h, 0A3h, 0A4h, 0A5h, 0A6h, 0A7h + db 0A8h, 0A9h, 0AAh, 0ABh, 0ACh, 0ADh, 0AEh, 0AFh + db 0B0h, 0B1h, 0B2h, 0B3h, 0B4h, 0B5h, 0B6h, 0B7h + db 0B8h, 0B9h, 0BAh, 0BBh, 0BCh, 0BDh, 0BEh, 0BFh + db 0C0h, 0C1h, 0C2h, 0C3h, 0C4h, 0C5h, 0C6h, 0C7h + db 0C8h, 0C9h, 0CAh, 0CBh, 0CCh, 0CDh, 0CEh, 0CFh + db 0D0h, 0D1h, 0D2h, 0D3h, 0D4h, 0D5h, 0D6h, 0D7h + db 0D8h, 0D9h, 0DAh, 0DBh, 0DCh, 0DDh, 0DEh, 0DFh + db 0E0h, 0E1h, 0E2h, 0E3h, 0E4h, 0E5h, 0E6h, 0E7h + db 0E8h, 0E9h, 0EAh, 0EBh, 0ECh, 0EDh, 0EEh, 0EFh + db 0F0h, 0F1h, 0F2h, 0F3h, 0F4h, 0F5h, 0F6h, 0F7h + db 0F8h, 0F9h, 0FAh, 0FBh, 0FCh, 0FDh, 0FEh, 0FFh + +sEnd + +end -- cgit v1.2.3