diff options
Diffstat (limited to 'v4.0/src/CMD/FC')
| -rw-r--r-- | v4.0/src/CMD/FC/ERROR.C | 16 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/FC.C | 864 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/FC.H | 14 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/FC.LNK | 4 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/FGETL.C | 52 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/GETL.ASM | 146 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/INTERNAT.H | 30 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/ITOUPPER.ASM | 119 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/MAKEFILE | 64 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/MAXMIN.ASM | 37 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/MESSAGES.ASM | 31 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/MOVE.ASM | 73 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/NTOI.C | 37 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/STRING.ASM | 115 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/TOOLS.H | 94 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/TTYPES.H | 71 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/UPDATE.C | 128 | ||||
| -rw-r--r-- | v4.0/src/CMD/FC/XTAB.ASM | 100 |
18 files changed, 1995 insertions, 0 deletions
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 @@ | |||
| 1 | /* error.c - return text of error corresponding to the most recent DOS error */ | ||
| 2 | |||
| 3 | #include "tools.h" | ||
| 4 | |||
| 5 | extern int errno; | ||
| 6 | extern sys_nerr; | ||
| 7 | extern char *sys_errlist[]; | ||
| 8 | extern char UnKnown[]; | ||
| 9 | |||
| 10 | char *error () | ||
| 11 | { | ||
| 12 | if (errno < 0 || errno >= sys_nerr) | ||
| 13 | return UnKnown; | ||
| 14 | else | ||
| 15 | return sys_errlist[errno]; | ||
| 16 | } | ||
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 @@ | |||
| 1 | /* file compare | ||
| 2 | |||
| 3 | Fcom compares two files in either a line-by-line mode or in a strict | ||
| 4 | byte-by-byte mode. | ||
| 5 | |||
| 6 | The byte-by-byte mode is simple; merely read both files and print the | ||
| 7 | offsets where they differ and the contents. | ||
| 8 | |||
| 9 | The line compare mode attempts to isolate differences in ranges of lines. | ||
| 10 | Two buffers of lines are read and compared. No hashing of lines needs | ||
| 11 | to be done; hashing only speedily tells you when things are different, | ||
| 12 | not the same. Most files run through this are expected to be largely | ||
| 13 | the same. Thus, hashing buys nothing. | ||
| 14 | |||
| 15 | |||
| 16 | *********************************************************************** | ||
| 17 | The algorithm that immediately follows does not work. There is an error | ||
| 18 | somewhere in the range of lines 11 on. An alternative explanation follows. | ||
| 19 | KGS | ||
| 20 | ************************************************************************ | ||
| 21 | |||
| 22 | [0] Fill buffers | ||
| 23 | [1] If both buffers are empty then | ||
| 24 | [1.1] Done | ||
| 25 | [2] Adjust buffers so 1st differing lines are at top. | ||
| 26 | [3] If buffers are empty then | ||
| 27 | [3.1] Goto [0] | ||
| 28 | |||
| 29 | This is the difficult part. We assume that there is a sequence of inserts, | ||
| 30 | deletes and replacements that will bring the buffers back into alignment. | ||
| 31 | |||
| 32 | [4] xd = yd = FALSE | ||
| 33 | [5] xc = yc = 1 | ||
| 34 | [6] xp = yp = 1 | ||
| 35 | [7] If buffer1[xc] and buffer2[yp] begin a "sync" range then | ||
| 36 | [7.1] Output lines 1 through xc-1 in buffer 1 | ||
| 37 | [7.2] Output lines 1 through yp-1 in buffer 2 | ||
| 38 | [7.3] Adjust buffer 1 so line xc is at beginning | ||
| 39 | [7.4] Adjust buffer 2 so line yp is at beginning | ||
| 40 | [7.5] Goto [0] | ||
| 41 | [8] If buffer1[xp] and buffer2[yc] begin a "sync" range then | ||
| 42 | [8.1] Output lines 1 through xp-1 in buffer 1 | ||
| 43 | [8.2] Output lines 1 through yc-1 in buffer 2 | ||
| 44 | [8.3] Adjust buffer 1 so line xp is at beginning | ||
| 45 | [8.4] Adjust buffer 2 so line yc is at beginning | ||
| 46 | [8.5] Goto [0] | ||
| 47 | [9] xp = xp + 1 | ||
| 48 | [10] if xp > xc then | ||
| 49 | [10.1] xp = 1 | ||
| 50 | [10.2] xc = xc + 1 | ||
| 51 | [10.3] if xc > number of lines in buffer 1 then | ||
| 52 | [10.4] xc = number of lines | ||
| 53 | [10.5] xd = TRUE | ||
| 54 | [11] if yp > yc then | ||
| 55 | [11.1] yp = 1 | ||
| 56 | [11.2] yc = yc + 1 | ||
| 57 | [11.3] if yc > number of lines in buffer 2 then | ||
| 58 | [11.4] yc = number of lines | ||
| 59 | [11.5] yd = TRUE | ||
| 60 | [12] if not xd or not yd then | ||
| 61 | [12.1] goto [6] | ||
| 62 | |||
| 63 | At this point there is no possible match between the buffers. For | ||
| 64 | simplicity, we punt. | ||
| 65 | |||
| 66 | [13] Display error message. | ||
| 67 | |||
| 68 | EXPLANATION 2 | ||
| 69 | |||
| 70 | This is a variation of the Largest Common Subsequence problem. A | ||
| 71 | detailed explanation of this can be found on p 189 of Data Structures | ||
| 72 | and Algorithms by Aho Hopcroft and Ulman. | ||
| 73 | |||
| 74 | |||
| 75 | |||
| 76 | FC maintains two buffers within which it tries to find the Largest Common | ||
| 77 | Subsequence (The largest common subsequence is simply the pattern in | ||
| 78 | buffer1 that yields the most matches with the pattern in buffer2, or the | ||
| 79 | pattern in buffer2 that yields the most matches with the pattern in buffer1) | ||
| 80 | |||
| 81 | FC makes a simplifying assumption that the contents of one buffer can be | ||
| 82 | converted to the contents of the other buffer by deleting the lines that are | ||
| 83 | different between the two buffers. | ||
| 84 | |||
| 85 | Two indices into each buffer are maintained: | ||
| 86 | |||
| 87 | xc, yc == point to the last line that has been scanned up to now | ||
| 88 | |||
| 89 | xp, yp == point to the first line that has not been exhaustively | ||
| 90 | compared to lines 0 - #c in the other buffer. | ||
| 91 | |||
| 92 | FC now makes a second simplifying assumption: | ||
| 93 | It is unnecessary to do any calculations on lines that are equal. | ||
| 94 | |||
| 95 | Hence FC scans File1 and File two line by line until a difference is | ||
| 96 | encountered. | ||
| 97 | |||
| 98 | |||
| 99 | When a difference is encountered the two buffers are filled such that | ||
| 100 | the line containing the first difference heads the buffer. The following | ||
| 101 | exhaustive search algorithm is applied to find the first "sync" occurance. | ||
| 102 | (The below is simplified to use == for comparison. In practice more than | ||
| 103 | one line needs to match for a "sync" to be established). | ||
| 104 | |||
| 105 | |||
| 106 | FOR xc,yc = 1; xc,yx <= sizeof( BUFFERS ); xc++, yc++ | ||
| 107 | |||
| 108 | FOR xp,yp = 1; xp,yp <= xc,yc; xp++, yp++ | ||
| 109 | |||
| 110 | IF ( BUFFER1[xp] == BUFFER2[yc] ) | ||
| 111 | |||
| 112 | Then the range of lines BUFFER1[ 1 ... xp ] and | ||
| 113 | BUFFER2[ 1 ... yc ] need to be deleted for the | ||
| 114 | two files to be equal. Therefore DISPLAY these | ||
| 115 | ranges, and begin scanning both files starting at | ||
| 116 | the matching lines. | ||
| 117 | FI | ||
| 118 | |||
| 119 | IF ( BUFFER1[yp] == BUFFER2[xc] ) | ||
| 120 | |||
| 121 | Then the range of lines BUFFER2[ 1 ... yp ] and | ||
| 122 | BUFFER1[ 1 ... xc ] need to be deleted for the | ||
| 123 | two files to be equal. Therefore DISPLAY these | ||
| 124 | ranges, and begin scanning both files starting at | ||
| 125 | the matching lines. | ||
| 126 | FI | ||
| 127 | FOREND | ||
| 128 | FOREND | ||
| 129 | |||
| 130 | If a match is not found within the buffers, the message "RESYNC FAILED" | ||
| 131 | is issued and further comparison is aborted since there is no valid way | ||
| 132 | to find further matching lines. | ||
| 133 | |||
| 134 | |||
| 135 | |||
| 136 | |||
| 137 | END EXPLANATION 2 | ||
| 138 | |||
| 139 | |||
| 140 | |||
| 141 | |||
| 142 | |||
| 143 | Certain flags may be set to modify the behavior of the comparison: | ||
| 144 | |||
| 145 | -a abbreviated output. Rather than displaying all of the modified | ||
| 146 | ranges, just display the beginning, ... and the ending difference | ||
| 147 | -b compare the files in binary (or byte-by-byte) mode. This mode is | ||
| 148 | default on .EXE, .OBJ, .LIB, .COM, .BIN, and .SYS files | ||
| 149 | -c ignore case on compare (cmp = strcmpi instead of strcmp) | ||
| 150 | -l compare files in line-by-line mode | ||
| 151 | -lb n set the size of the internal line buffer to n lines from default | ||
| 152 | of 100 | ||
| 153 | -w ignore blank lines and white space (ignore len 0, use strcmps) | ||
| 154 | -t do not untabify (use fgets instead of fgetl) | ||
| 155 | -n output the line number also | ||
| 156 | -NNNN set the number of lines to resynchronize to n which defaults | ||
| 157 | to 2. Failure to have this value set correctly can result in | ||
| 158 | odd output: | ||
| 159 | file1: file2: | ||
| 160 | abcdefg abcdefg | ||
| 161 | aaaaaaa aaaaaab | ||
| 162 | aaaaaaa aaaaaaa | ||
| 163 | aaaaaaa aaaaaaa | ||
| 164 | abcdefg abcdefg | ||
| 165 | |||
| 166 | with default sync of 2 yields: with sync => 3 yields: | ||
| 167 | |||
| 168 | *****f1 *****f1 | ||
| 169 | abcdefg abcdefg | ||
| 170 | aaaaaaa aaaaaaa | ||
| 171 | *****f2 aaaaaaa | ||
| 172 | abcdefg *****f2 | ||
| 173 | aaaaaab abcdefg | ||
| 174 | aaaaaaa aaaaaab | ||
| 175 | aaaaaaa | ||
| 176 | *****f1 | ||
| 177 | aaaaaaa | ||
| 178 | aaaaaaa | ||
| 179 | abcdefg | ||
| 180 | *****f2 | ||
| 181 | aaaaaaa | ||
| 182 | abcdefg | ||
| 183 | |||
| 184 | |||
| 185 | |||
| 186 | |||
| 187 | |||
| 188 | |||
| 189 | WARNING: | ||
| 190 | This program makes use of GOTO's and hence is not as straightforward | ||
| 191 | as it could be! CAVEAT PROGRAMMER. | ||
| 192 | |||
| 193 | |||
| 194 | |||
| 195 | |||
| 196 | |||
| 197 | |||
| 198 | |||
| 199 | |||
| 200 | |||
| 201 | |||
| 202 | |||
| 203 | |||
| 204 | |||
| 205 | |||
| 206 | |||
| 207 | */ | ||
| 208 | |||
| 209 | |||
| 210 | #include "tools.h" | ||
| 211 | #include "fc.h" | ||
| 212 | |||
| 213 | /* #define DEBUG FALSE */ | ||
| 214 | |||
| 215 | extern int fgetl(), | ||
| 216 | strcmp (); | ||
| 217 | |||
| 218 | extern byte toupper (); | ||
| 219 | |||
| 220 | int (*funcRead) (), /* function to use to read lines */ | ||
| 221 | (*fCmp) (); /* function to use to compare lines */ | ||
| 222 | |||
| 223 | extern byte BadSw[], | ||
| 224 | Bad_ver[], | ||
| 225 | BadOpn[], | ||
| 226 | LngFil[], | ||
| 227 | NoDif[], | ||
| 228 | NoMem[], | ||
| 229 | UseMes[], | ||
| 230 | ReSyncMes[]; | ||
| 231 | |||
| 232 | int ctSync = -1, /* number of lines required to sync */ | ||
| 233 | cLine = -1; /* number of lines in internal buffs */ | ||
| 234 | |||
| 235 | flagType fAbbrev = FALSE, /* abbreviated output */ | ||
| 236 | fBinary = FALSE, /* binary comparison */ | ||
| 237 | fLine = FALSE, /* line comparison */ | ||
| 238 | fNumb = FALSE, /* display line numbers */ | ||
| 239 | fCase = TRUE, /* case is significant */ | ||
| 240 | fIgnore = FALSE; /* ignore spaces and blank lines */ | ||
| 241 | |||
| 242 | #ifdef DEBUG | ||
| 243 | |||
| 244 | flagType fDebug = FALSE; | ||
| 245 | #endif | ||
| 246 | |||
| 247 | struct lineType *buffer1, | ||
| 248 | *buffer2; | ||
| 249 | |||
| 250 | byte line[MAXARG]; /* single line buffer */ | ||
| 251 | |||
| 252 | byte *extBin[] = { ".EXE", ".OBJ", ".LIB", | ||
| 253 | ".COM", ".BIN", ".SYS", NULL }; | ||
| 254 | |||
| 255 | |||
| 256 | main (c, v) | ||
| 257 | int c; | ||
| 258 | byte *v[]; | ||
| 259 | { | ||
| 260 | |||
| 261 | int i; | ||
| 262 | int j; | ||
| 263 | int fileargs; | ||
| 264 | char *strpbrk(), | ||
| 265 | *slash; | ||
| 266 | char n[2][80]; | ||
| 267 | char temp; | ||
| 268 | |||
| 269 | |||
| 270 | |||
| 271 | extern byte _osmajor, _osminor; | ||
| 272 | word version; /* _osmajor._osminor, used for */ | ||
| 273 | /* version binding checks. */ | ||
| 274 | |||
| 275 | |||
| 276 | |||
| 277 | /* Issue error message if DOS version is not within valid range. */ | ||
| 278 | version = ((word)_osmajor << 8) + (word)_osminor; | ||
| 279 | if (( LOWVERSION > version) || (version > HIGHVERSION)) | ||
| 280 | { | ||
| 281 | usage (Bad_ver, 1); | ||
| 282 | } | ||
| 283 | |||
| 284 | funcRead = (int (*) ())FNADDR(fgetl); | ||
| 285 | |||
| 286 | fileargs=0; | ||
| 287 | |||
| 288 | for (i=1; i < c ; i++) | ||
| 289 | { | ||
| 290 | /** | ||
| 291 | * If argument doesn't begin with a /, parse a filename off of it | ||
| 292 | * then examine the argument for following switches. | ||
| 293 | * | ||
| 294 | **/ | ||
| 295 | if (*v[i] != '/') | ||
| 296 | { | ||
| 297 | slash= strpbrk( v[i],"/" ); | ||
| 298 | |||
| 299 | if ( slash ) | ||
| 300 | { | ||
| 301 | temp = *slash; | ||
| 302 | *slash='\0' ; | ||
| 303 | strcpy(n[fileargs++],v[i]); | ||
| 304 | *slash =temp ; | ||
| 305 | } | ||
| 306 | else | ||
| 307 | strcpy(n[fileargs++],v[i]); | ||
| 308 | } | ||
| 309 | |||
| 310 | for ( j=0 ; j < strlen( v[i] ) ; j++) | ||
| 311 | { | ||
| 312 | if(*(v[i]+j)=='/') | ||
| 313 | { | ||
| 314 | switch(toupper( *(v[i]+j+1))) | ||
| 315 | { | ||
| 316 | case 'A' : | ||
| 317 | fAbbrev = TRUE; | ||
| 318 | break; | ||
| 319 | case 'B' : | ||
| 320 | fBinary = TRUE; | ||
| 321 | break; | ||
| 322 | case 'C' : | ||
| 323 | fCase = FALSE; | ||
| 324 | break; | ||
| 325 | #ifdef DEBUG | ||
| 326 | case 'D' : | ||
| 327 | fDebug = TRUE; | ||
| 328 | break; | ||
| 329 | #endif | ||
| 330 | case 'W' : | ||
| 331 | fIgnore = TRUE; | ||
| 332 | break; | ||
| 333 | case 'L' : | ||
| 334 | if (toupper(*(v[i]+j+2))=='B') | ||
| 335 | { | ||
| 336 | cLine = ntoi ((v[i]+j+3),10); | ||
| 337 | break; | ||
| 338 | } | ||
| 339 | else | ||
| 340 | fLine = TRUE; | ||
| 341 | break; | ||
| 342 | case 'N' : | ||
| 343 | fNumb = TRUE; | ||
| 344 | break; | ||
| 345 | case 'T' : | ||
| 346 | funcRead =(int (*) ())FNADDR(fgets); | ||
| 347 | break; | ||
| 348 | default: | ||
| 349 | if (*strbskip((v[i]+j+1),"0123456789") == 0) | ||
| 350 | { | ||
| 351 | ctSync = ntoi ((v[i]+j+1), 10); | ||
| 352 | } | ||
| 353 | else | ||
| 354 | { | ||
| 355 | usage (NULL, 1); | ||
| 356 | } | ||
| 357 | } /* end switch */ | ||
| 358 | } /* end if */ | ||
| 359 | } /* end parse of argument for '/' */ | ||
| 360 | } /* End ARGUMENT Search */ | ||
| 361 | |||
| 362 | |||
| 363 | |||
| 364 | if (fileargs != 2) | ||
| 365 | usage (NULL, 1); | ||
| 366 | |||
| 367 | if (ctSync != -1) | ||
| 368 | fLine = TRUE; | ||
| 369 | else | ||
| 370 | ctSync = 2; | ||
| 371 | |||
| 372 | if (cLine == -1) | ||
| 373 | cLine = 100; | ||
| 374 | |||
| 375 | if (!fBinary && !fLine) | ||
| 376 | { | ||
| 377 | extention (n[0], line); | ||
| 378 | |||
| 379 | for (i = 0; extBin[i]; i++) | ||
| 380 | if (!strcmpi (extBin[i], line)) | ||
| 381 | fBinary = TRUE; | ||
| 382 | |||
| 383 | if (!fBinary) | ||
| 384 | fLine = TRUE; | ||
| 385 | } | ||
| 386 | |||
| 387 | if (fBinary && (fLine || fNumb)) | ||
| 388 | usage (BadSw, 1); | ||
| 389 | |||
| 390 | if (fIgnore) | ||
| 391 | { | ||
| 392 | if (fCase) | ||
| 393 | fCmp = FNADDR(strcmps); | ||
| 394 | else | ||
| 395 | fCmp = FNADDR(strcmpis); | ||
| 396 | } | ||
| 397 | else | ||
| 398 | { | ||
| 399 | if (fCase) | ||
| 400 | fCmp = FNADDR(strcmp); | ||
| 401 | else | ||
| 402 | fCmp = FNADDR(strcmpi); | ||
| 403 | } | ||
| 404 | |||
| 405 | if (fBinary) | ||
| 406 | BinaryCompare (n[0], n[1]); | ||
| 407 | else | ||
| 408 | LineCompare (n[0], n[1]); | ||
| 409 | |||
| 410 | } | ||
| 411 | |||
| 412 | usage (p, erc) | ||
| 413 | unsigned char *p; | ||
| 414 | { | ||
| 415 | if (p) | ||
| 416 | printf ("fc: %s\n", p); | ||
| 417 | else | ||
| 418 | printf (UseMes); | ||
| 419 | |||
| 420 | exit (erc); | ||
| 421 | } | ||
| 422 | |||
| 423 | BinaryCompare (f1, f2) | ||
| 424 | unsigned char *f1, *f2; | ||
| 425 | { | ||
| 426 | register int c1, c2; | ||
| 427 | long pos; | ||
| 428 | FILE *fh1, *fh2; | ||
| 429 | flagType fSame; | ||
| 430 | |||
| 431 | fSame = TRUE; | ||
| 432 | |||
| 433 | if ((fh1 = fopen (f1, "rb")) == NULL) | ||
| 434 | { | ||
| 435 | sprintf (line, BadOpn, f1, error ()); | ||
| 436 | usage (line, 1); | ||
| 437 | } | ||
| 438 | |||
| 439 | if ((fh2 = fopen (f2, "rb")) == NULL) | ||
| 440 | { | ||
| 441 | sprintf (line, BadOpn, f2, error ()); | ||
| 442 | usage (line, 1); | ||
| 443 | } | ||
| 444 | pos = 0L; | ||
| 445 | |||
| 446 | while (TRUE) | ||
| 447 | { | ||
| 448 | if ((c1 = getc (fh1)) != EOF) | ||
| 449 | { | ||
| 450 | if ((c2 = getc (fh2)) != EOF) | ||
| 451 | { | ||
| 452 | if (c1 == c2) | ||
| 453 | ; | ||
| 454 | else | ||
| 455 | { | ||
| 456 | fSame = FALSE; | ||
| 457 | printf ("%08lX: %02X %02X\n", pos, c1, c2); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | else | ||
| 461 | { | ||
| 462 | sprintf (line, LngFil, f1, f2); | ||
| 463 | usage (line, 1); | ||
| 464 | } | ||
| 465 | } | ||
| 466 | else | ||
| 467 | { | ||
| 468 | if ((c2 = getc (fh2)) == EOF) | ||
| 469 | { | ||
| 470 | if (fSame) | ||
| 471 | usage (NoDif, 0); | ||
| 472 | else | ||
| 473 | exit (1); | ||
| 474 | } | ||
| 475 | else | ||
| 476 | { | ||
| 477 | sprintf (line, LngFil, f2, f1); | ||
| 478 | usage (line, 1); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | pos++; | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 485 | /* compare a range of lines */ | ||
| 486 | flagType compare (l1, s1, l2, s2, ct) | ||
| 487 | int l1, l2, ct; | ||
| 488 | register int s1, s2; | ||
| 489 | { | ||
| 490 | |||
| 491 | #ifdef DEBUG | ||
| 492 | if (fDebug) | ||
| 493 | printf ("compare (%d, %d, %d, %d, %d)\n", l1, s1, l2, s2, ct); | ||
| 494 | #endif | ||
| 495 | |||
| 496 | if (ct == 0 || s1+ct > l1 || s2+ct > l2) | ||
| 497 | return FALSE; | ||
| 498 | |||
| 499 | while (ct--) | ||
| 500 | { | ||
| 501 | |||
| 502 | #ifdef DEBUG | ||
| 503 | if (fDebug) | ||
| 504 | printf ("'%s' == '%s'? ", buffer1[s1].text, buffer2[s2].text); | ||
| 505 | #endif | ||
| 506 | |||
| 507 | if ((*fCmp)(buffer1[s1++].text, buffer2[s2++].text)) | ||
| 508 | { | ||
| 509 | |||
| 510 | #ifdef DEBUG | ||
| 511 | if (fDebug) | ||
| 512 | printf ("No\n"); | ||
| 513 | #endif | ||
| 514 | return FALSE; | ||
| 515 | } | ||
| 516 | } | ||
| 517 | |||
| 518 | #ifdef DEBUG | ||
| 519 | if (fDebug) | ||
| 520 | printf ("Yes\n"); | ||
| 521 | #endif | ||
| 522 | |||
| 523 | return TRUE; | ||
| 524 | } | ||
| 525 | |||
| 526 | LineCompare (f1, f2) | ||
| 527 | unsigned char *f1, *f2; | ||
| 528 | { | ||
| 529 | FILE *fh1, *fh2; | ||
| 530 | int l1, l2, i, xp, yp, xc, yc; | ||
| 531 | flagType xd, yd, fSame; | ||
| 532 | int line1, line2; | ||
| 533 | |||
| 534 | fSame = TRUE; | ||
| 535 | |||
| 536 | if ((fh1 = fopen (f1, "rb")) == NULL) | ||
| 537 | { | ||
| 538 | sprintf (line, BadOpn, f1, error ()); | ||
| 539 | usage (line, 1); | ||
| 540 | } | ||
| 541 | |||
| 542 | if ((fh2 = fopen (f2, "rb")) == NULL) | ||
| 543 | { | ||
| 544 | sprintf (line, BadOpn, f2, error ()); | ||
| 545 | usage (line, 1); | ||
| 546 | } | ||
| 547 | |||
| 548 | if ((buffer1 = (struct lineType *)malloc (cLine * (sizeof *buffer1))) == NULL || | ||
| 549 | (buffer2 = (struct lineType *)malloc (cLine * (sizeof *buffer1))) == NULL) | ||
| 550 | usage (NoMem); | ||
| 551 | |||
| 552 | l1 = l2 = 0; | ||
| 553 | line1 = line2 = 0; | ||
| 554 | l0: | ||
| 555 | |||
| 556 | #ifdef DEBUG | ||
| 557 | if (fDebug) | ||
| 558 | printf ("At scan beginning\n"); | ||
| 559 | #endif | ||
| 560 | |||
| 561 | l1 += xfill (buffer1+l1, fh1, cLine-l1, &line1); | ||
| 562 | l2 += xfill (buffer2+l2, fh2, cLine-l2, &line2); | ||
| 563 | |||
| 564 | if (l1 == 0 && l2 == 0) | ||
| 565 | { | ||
| 566 | if (fSame) | ||
| 567 | usage (NoDif, 0); | ||
| 568 | return; | ||
| 569 | } | ||
| 570 | xc = min (l1, l2); | ||
| 571 | |||
| 572 | for (i=0; i < xc; i++) | ||
| 573 | { | ||
| 574 | if (!compare (l1, i, l2, i, 1)) | ||
| 575 | break; | ||
| 576 | } | ||
| 577 | |||
| 578 | if (i != xc) | ||
| 579 | i = max (i-1, 0); | ||
| 580 | |||
| 581 | l1 = adjust (buffer1, l1, i); | ||
| 582 | l2 = adjust (buffer2, l2, i); | ||
| 583 | |||
| 584 | /* KLUDGE ALERT!! GOTO USED */ | ||
| 585 | if (l1 == 0 && l2 == 0) | ||
| 586 | goto l0; | ||
| 587 | |||
| 588 | l1 += xfill (buffer1+l1, fh1, cLine-l1, &line1); | ||
| 589 | l2 += xfill (buffer2+l2, fh2, cLine-l2, &line2); | ||
| 590 | |||
| 591 | #ifdef DEBUG | ||
| 592 | if (fDebug) | ||
| 593 | printf ("buffers are adjusted, %d, %d remain\n", l1, l2); | ||
| 594 | #endif | ||
| 595 | |||
| 596 | xd = yd = FALSE; | ||
| 597 | xc = yc = 1; | ||
| 598 | xp = yp = 1; | ||
| 599 | |||
| 600 | l6: | ||
| 601 | |||
| 602 | #ifdef DEBUG | ||
| 603 | if (fDebug) | ||
| 604 | printf ("Trying resync %d,%d %d,%d\n", xc, xp, yc, yp); | ||
| 605 | #endif | ||
| 606 | |||
| 607 | i = min (l1-xc,l2-yp); | ||
| 608 | i = min (i, ctSync); | ||
| 609 | |||
| 610 | if (compare (l1, xc, l2, yp, i)) | ||
| 611 | { | ||
| 612 | fSame = FALSE; | ||
| 613 | printf ("***** %s\n", f1); | ||
| 614 | dump (buffer1, 0, xc); | ||
| 615 | printf ("***** %s\n", f2); | ||
| 616 | dump (buffer2, 0, yp); | ||
| 617 | printf ("*****\n\n"); | ||
| 618 | |||
| 619 | l1 = adjust (buffer1, l1, xc); | ||
| 620 | l2 = adjust (buffer2, l2, yp); | ||
| 621 | |||
| 622 | /* KLUDGE ALERT!! GOTO USED */ | ||
| 623 | goto l0; | ||
| 624 | } | ||
| 625 | i = min (l1-xp, l2-yc); | ||
| 626 | i = min (i, ctSync); | ||
| 627 | |||
| 628 | if (compare (l1, xp, l2, yc, i)) | ||
| 629 | { | ||
| 630 | fSame = FALSE; | ||
| 631 | printf ("***** %s\n", f1); | ||
| 632 | dump (buffer1, 0, xp); | ||
| 633 | printf ("***** %s\n", f2); | ||
| 634 | dump (buffer2, 0, yc); | ||
| 635 | printf ("*****\n\n"); | ||
| 636 | |||
| 637 | l1 = adjust (buffer1, l1, xp); | ||
| 638 | l2 = adjust (buffer2, l2, yc); | ||
| 639 | |||
| 640 | /* KLUDGE ALERT!! GOTO USED */ | ||
| 641 | goto l0; | ||
| 642 | } | ||
| 643 | |||
| 644 | if (++xp > xc) | ||
| 645 | { | ||
| 646 | xp = 1; | ||
| 647 | if (++xc >= l1) | ||
| 648 | { | ||
| 649 | xc = l1; | ||
| 650 | xd = TRUE; | ||
| 651 | } | ||
| 652 | } | ||
| 653 | |||
| 654 | if (++yp > yc) | ||
| 655 | { | ||
| 656 | yp = 1; | ||
| 657 | if (++yc >= l2) | ||
| 658 | { | ||
| 659 | yc = l1; | ||
| 660 | yd = TRUE; | ||
| 661 | } | ||
| 662 | } | ||
| 663 | |||
| 664 | if (!xd || !yd) | ||
| 665 | goto l6; | ||
| 666 | fSame = FALSE; | ||
| 667 | |||
| 668 | if (l1 >= cLine || l2 >= cLine) | ||
| 669 | printf ("%s", ReSyncMes); | ||
| 670 | |||
| 671 | printf ("***** %s\n", f1); | ||
| 672 | dump (buffer1, 0, l1-1); | ||
| 673 | printf ("***** %s\n", f2); | ||
| 674 | dump (buffer2, 0, l2-1); | ||
| 675 | printf ("*****\n\n"); | ||
| 676 | exit (1); | ||
| 677 | } | ||
| 678 | |||
| 679 | |||
| 680 | |||
| 681 | /* return number of lines read in */ | ||
| 682 | xfill (pl, fh, ct, plnum) | ||
| 683 | struct lineType *pl; | ||
| 684 | FILE *fh; | ||
| 685 | int ct; | ||
| 686 | int *plnum; | ||
| 687 | { | ||
| 688 | int i; | ||
| 689 | |||
| 690 | #ifdef DEBUG | ||
| 691 | if (fDebug) | ||
| 692 | printf ("xfill (%04x, %04x)\n", pl, fh); | ||
| 693 | #endif | ||
| 694 | |||
| 695 | i = 0; | ||
| 696 | while (ct-- && (*funcRead) (pl->text, MAXARG, fh) != NULL) | ||
| 697 | { | ||
| 698 | if (funcRead == (int (*) ())FNADDR(fgets)) | ||
| 699 | pl->text[strlen(pl->text)-1] = 0; | ||
| 700 | if (fIgnore && !strcmps (pl->text, "")) | ||
| 701 | pl->text[0] = 0; | ||
| 702 | if (strlen (pl->text) != 0 || !fIgnore) | ||
| 703 | { | ||
| 704 | pl->line = ++*plnum; | ||
| 705 | pl++; | ||
| 706 | i++; | ||
| 707 | } | ||
| 708 | } | ||
| 709 | |||
| 710 | #ifdef DEBUG | ||
| 711 | if (fDebug) | ||
| 712 | printf ("xfill returns %d\n", i); | ||
| 713 | #endif | ||
| 714 | |||
| 715 | return i; | ||
| 716 | } | ||
| 717 | |||
| 718 | |||
| 719 | /* adjust returns number of lines in buffer */ | ||
| 720 | adjust (pl, ml, lt) | ||
| 721 | struct lineType *pl; | ||
| 722 | int ml; | ||
| 723 | int lt; | ||
| 724 | { | ||
| 725 | |||
| 726 | #ifdef DEBUG | ||
| 727 | if (fDebug) | ||
| 728 | printf ("adjust (%04x, %d, %d) = ", pl, ml, lt); | ||
| 729 | if (fDebug) | ||
| 730 | printf ("%d\n", ml-lt); | ||
| 731 | #endif | ||
| 732 | |||
| 733 | if (ml <= lt) | ||
| 734 | return 0; | ||
| 735 | |||
| 736 | #ifdef DEBUG | ||
| 737 | if (fDebug) | ||
| 738 | printf ("move (%04x, %04x, %04x)\n", &pl[lt], &pl[0], sizeof (*pl)*(ml-lt)); | ||
| 739 | #endif | ||
| 740 | |||
| 741 | Move ((unsigned char far *)&pl[lt], (char far *)&pl[0], sizeof (*pl)*(ml-lt)); | ||
| 742 | return ml-lt; | ||
| 743 | } | ||
| 744 | |||
| 745 | |||
| 746 | /* dump | ||
| 747 | * dump outputs a range of lines. | ||
| 748 | * | ||
| 749 | * INPUTS | ||
| 750 | * pl pointer to current lineType structure | ||
| 751 | * start starting line number | ||
| 752 | * end ending line number | ||
| 753 | * | ||
| 754 | * CALLS | ||
| 755 | * pline, printf | ||
| 756 | * | ||
| 757 | */ | ||
| 758 | dump (pl, start, end) | ||
| 759 | struct lineType *pl; | ||
| 760 | int start, end; | ||
| 761 | { | ||
| 762 | if (fAbbrev && end-start > 2) | ||
| 763 | { | ||
| 764 | pline (pl+start); | ||
| 765 | printf ("...\n"); | ||
| 766 | pline (pl+end); | ||
| 767 | } | ||
| 768 | else | ||
| 769 | while (start <= end) | ||
| 770 | pline (pl+start++); | ||
| 771 | } | ||
| 772 | |||
| 773 | |||
| 774 | |||
| 775 | |||
| 776 | /* PrintLINE | ||
| 777 | * pline prints a single line of output. If the /n flag | ||
| 778 | * has been specified, the line number of the printed text is added. | ||
| 779 | * | ||
| 780 | * Inputs | ||
| 781 | * pl pointer to current lineType structure | ||
| 782 | * fNumb TRUE if /n specified | ||
| 783 | * | ||
| 784 | */ | ||
| 785 | pline (pl) | ||
| 786 | struct lineType *pl; | ||
| 787 | { | ||
| 788 | if (fNumb) | ||
| 789 | printf ("%5d: ", pl->line); | ||
| 790 | |||
| 791 | printf ("%s\n", pl->text); | ||
| 792 | } | ||
| 793 | |||
| 794 | /* | ||
| 795 | * strcmpi will compare two string lexically and return one of | ||
| 796 | * the following: | ||
| 797 | * - 0 if the strings are equal | ||
| 798 | * - 1 if first > the second | ||
| 799 | * - (-1) if first < the second | ||
| 800 | * | ||
| 801 | * This was written to replace the run time library version of | ||
| 802 | * strcmpi which does not correctly compare the european character set. | ||
| 803 | * This version relies on a version of toupper which uses IToupper. | ||
| 804 | */ | ||
| 805 | |||
| 806 | int strcmpi(str1, str2) | ||
| 807 | unsigned char *str1, *str2; | ||
| 808 | { | ||
| 809 | unsigned char c1, c2; | ||
| 810 | |||
| 811 | while ((c1 = toupper(*str1++)) == (c2 = toupper(*str2++))) { | ||
| 812 | if (c1 == '\0') | ||
| 813 | return(0); | ||
| 814 | } | ||
| 815 | |||
| 816 | if (c1 > c2) | ||
| 817 | return(1); | ||
| 818 | else | ||
| 819 | return(-1); | ||
| 820 | } | ||
| 821 | |||
| 822 | |||
| 823 | /* compare two strings, ignoring white space, case is significant, return | ||
| 824 | * 0 if identical, <>0 otherwise | ||
| 825 | */ | ||
| 826 | strcmps (p1, p2) | ||
| 827 | unsigned char *p1, *p2; | ||
| 828 | { | ||
| 829 | while (TRUE) { | ||
| 830 | while (ISSPACE(*p1)) | ||
| 831 | p1++; | ||
| 832 | while (ISSPACE(*p2)) | ||
| 833 | p2++; | ||
| 834 | if (*p1 == *p2) | ||
| 835 | if (*p1++ == 0) | ||
| 836 | return 0; | ||
| 837 | else | ||
| 838 | p2++; | ||
| 839 | else | ||
| 840 | return *p1-*p2; | ||
| 841 | } | ||
| 842 | } | ||
| 843 | |||
| 844 | |||
| 845 | /* compare two strings, ignoring white space, case is not significant, return | ||
| 846 | * 0 if identical, <>0 otherwise | ||
| 847 | */ | ||
| 848 | int strcmpis (p1, p2) | ||
| 849 | unsigned char *p1, *p2; | ||
| 850 | { | ||
| 851 | while (TRUE) { | ||
| 852 | while (ISSPACE(*p1)) | ||
| 853 | p1++; | ||
| 854 | while (ISSPACE(*p2)) | ||
| 855 | p2++; | ||
| 856 | if (toupper (*p1) == toupper (*p2)) | ||
| 857 | if (*p1++ == 0) | ||
| 858 | return 0; | ||
| 859 | else | ||
| 860 | p2++; | ||
| 861 | else | ||
| 862 | return *p1-*p2; | ||
| 863 | } | ||
| 864 | } | ||
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 @@ | |||
| 1 | struct lineType { | ||
| 2 | int line; /* line number */ | ||
| 3 | unsigned char text[MAXARG]; /* body of line */ | ||
| 4 | }; | ||
| 5 | |||
| 6 | #define byte unsigned char | ||
| 7 | #define word unsigned short | ||
| 8 | |||
| 9 | #define LOWVERSION 0x0300 + 10 | ||
| 10 | #define HIGHVERSION 0x0400 + 00 | ||
| 11 | |||
| 12 | extern unsigned char _ctype_[]; | ||
| 13 | #define _SPACE 0x8 /* tab, carriage return, new line, */ | ||
| 14 | #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 @@ | |||
| 1 | fc.obj error.obj fgetl.obj getl.obj itoupper.obj ..\..\inc\kstring.obj + | ||
| 2 | maxmin.obj move.obj ntoi.obj string.obj update.obj xtab.obj messages.obj | ||
| 3 | fc.exe | ||
| 4 | |||
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 @@ | |||
| 1 | /* fgetl.c - expand tabs and return lines w/o separators */ | ||
| 2 | |||
| 3 | #include "tools.h" | ||
| 4 | |||
| 5 | /* returns line from file (no CRLFs); returns NULL if EOF */ | ||
| 6 | fgetl (buf, len, fh) | ||
| 7 | char *buf; | ||
| 8 | int len; | ||
| 9 | FILE *fh; | ||
| 10 | { | ||
| 11 | register int c; | ||
| 12 | register char *p; | ||
| 13 | |||
| 14 | /* remember NUL at end */ | ||
| 15 | len--; | ||
| 16 | p = buf; | ||
| 17 | while (len) { | ||
| 18 | c = getc (fh); | ||
| 19 | if (c == EOF || c == '\n') | ||
| 20 | break; | ||
| 21 | #if MSDOS | ||
| 22 | if (c != '\r') | ||
| 23 | #endif | ||
| 24 | if (c != '\t') { | ||
| 25 | *p++ = c; | ||
| 26 | len--; | ||
| 27 | } | ||
| 28 | else { | ||
| 29 | c = min (8 - ((p-buf) & 0x0007), len); | ||
| 30 | Fill (p, ' ', c); | ||
| 31 | p += c; | ||
| 32 | len -= c; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | *p = 0; | ||
| 36 | return ! ( (c == EOF) && (p == buf) ); | ||
| 37 | } | ||
| 38 | |||
| 39 | /* writes a line to file (with trailing CRLFs) from buf, return <> 0 if | ||
| 40 | * writes fail | ||
| 41 | */ | ||
| 42 | fputl (buf, len, fh) | ||
| 43 | char *buf; | ||
| 44 | int len; | ||
| 45 | FILE *fh; | ||
| 46 | { | ||
| 47 | #if MSDOS | ||
| 48 | return (fwrite (buf, 1, len, fh) != len || fputs ("\r\n", fh) == EOF) ? EOF : 0; | ||
| 49 | #else | ||
| 50 | return (fwrite (buf, 1, len, fh) != len || fputs ("\n", fh) == EOF) ? EOF : 0; | ||
| 51 | #endif | ||
| 52 | } | ||
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 @@ | |||
| 1 | ; | ||
| 2 | ; blindingly fast assembly help for Z | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | include version.inc | ||
| 7 | include cmacros.inc | ||
| 8 | .list | ||
| 9 | |||
| 10 | sBegin data | ||
| 11 | assumes ds,data | ||
| 12 | |||
| 13 | bufstart dd ? | ||
| 14 | staticW bufsrc,? | ||
| 15 | staticW buflen,? | ||
| 16 | staticW buflength,? | ||
| 17 | staticW buffh,? | ||
| 18 | globalB fGetlCR,? | ||
| 19 | bufpos dd ? | ||
| 20 | |||
| 21 | sEnd | ||
| 22 | sBegin code | ||
| 23 | |||
| 24 | assumes cs,code | ||
| 25 | |||
| 26 | ; | ||
| 27 | ; getlpos returns current seek position in file | ||
| 28 | ; | ||
| 29 | cProc getlpos,<PUBLIC> | ||
| 30 | cBegin | ||
| 31 | mov dx,word ptr bufpos+2 | ||
| 32 | mov ax,word ptr bufpos | ||
| 33 | cEnd | ||
| 34 | |||
| 35 | ; | ||
| 36 | ; getlinit (buf, len, fh) initializes the getl routine for buffer buf and fh fh | ||
| 37 | ; | ||
| 38 | cProc getlinit,<PUBLIC> | ||
| 39 | parmD buf | ||
| 40 | parmW len | ||
| 41 | parmW fh | ||
| 42 | cBegin | ||
| 43 | mov ax,off_buf | ||
| 44 | mov word ptr bufstart,ax | ||
| 45 | mov ax,seg_buf | ||
| 46 | mov word ptr bufstart+2,ax | ||
| 47 | mov ax,fh | ||
| 48 | mov buffh,ax | ||
| 49 | mov ax,len | ||
| 50 | mov buflength,ax | ||
| 51 | mov buflen,0 | ||
| 52 | mov word ptr bufpos,0 | ||
| 53 | mov word ptr bufpos+2,0 | ||
| 54 | mov fGetlCR,0 | ||
| 55 | cEnd | ||
| 56 | |||
| 57 | ; | ||
| 58 | ; getl (dst, len) returns TRUE if a line was read. | ||
| 59 | ; | ||
| 60 | cProc getl,<PUBLIC>,<DS,SI,DI> | ||
| 61 | parmW dst | ||
| 62 | parmW dstlen | ||
| 63 | cBegin | ||
| 64 | assumes ss,data | ||
| 65 | cld | ||
| 66 | push ds | ||
| 67 | pop es | ||
| 68 | mov ds,word ptr bufstart+2 | ||
| 69 | assumes ds,nothing | ||
| 70 | mov si,bufsrc | ||
| 71 | mov di,dst | ||
| 72 | mov cx,buflen | ||
| 73 | mov dx,dstlen | ||
| 74 | dec dx ; room for NUL at end | ||
| 75 | jcxz fill | ||
| 76 | |||
| 77 | movc: lodsb ; get a byte | ||
| 78 | cmp al,13 ; is it special? | ||
| 79 | jbe spec ; yes, go handle special case | ||
| 80 | stoc: stosb ; put character in buffer | ||
| 81 | dec dx ; one less space in buffer | ||
| 82 | endl: loopnz movc ; go back for more characters | ||
| 83 | jnz fill ; no more characters => go fill buffer | ||
| 84 | ; cx = 0, buflen = length moved | ||
| 85 | fin: dec cx | ||
| 86 | fin1: xor ax,ax | ||
| 87 | stosb | ||
| 88 | mov bufsrc,si ; length moved = buflen - cx | ||
| 89 | xchg buflen,cx | ||
| 90 | sub cx,buflen | ||
| 91 | add word ptr bufpos,cx | ||
| 92 | adc word ptr bufpos+2,0 | ||
| 93 | not ax | ||
| 94 | jmp short getldone | ||
| 95 | |||
| 96 | fill: | ||
| 97 | mov cx, buflen ; add length moved to bufpos | ||
| 98 | add word ptr bufpos,cx | ||
| 99 | adc word ptr bufpos+2,0 | ||
| 100 | push dx | ||
| 101 | mov dx,word ptr bufstart | ||
| 102 | mov cx,buflength | ||
| 103 | mov bx,buffh | ||
| 104 | mov ah,3Fh | ||
| 105 | int 21h | ||
| 106 | mov cx,ax | ||
| 107 | mov buflen,ax | ||
| 108 | mov si,dx | ||
| 109 | pop dx | ||
| 110 | or ax,ax | ||
| 111 | jnz movc | ||
| 112 | ; if we've stored chars then terminate line else return with 0 | ||
| 113 | cmp di,dst | ||
| 114 | jnz fin1 | ||
| 115 | jmp short getldone | ||
| 116 | |||
| 117 | setnz: or al,1 | ||
| 118 | mov fGetlCR,-1 ; indicate we've seen a CR | ||
| 119 | jmp endl | ||
| 120 | |||
| 121 | spec: jz setnz | ||
| 122 | cmp al,10 | ||
| 123 | jz fin | ||
| 124 | cmp al,9 | ||
| 125 | jnz stoc | ||
| 126 | push cx | ||
| 127 | mov ax,di | ||
| 128 | sub ax,dst | ||
| 129 | and ax,7 | ||
| 130 | mov cx,8 | ||
| 131 | sub cx,ax | ||
| 132 | cmp cx,dx | ||
| 133 | jbe ok | ||
| 134 | mov cx,dx | ||
| 135 | ok: sub dx,cx | ||
| 136 | mov al," " | ||
| 137 | rep stosb | ||
| 138 | pop cx | ||
| 139 | jmp endl | ||
| 140 | |||
| 141 | getldone: | ||
| 142 | cEnd | ||
| 143 | |||
| 144 | sEnd | ||
| 145 | |||
| 146 | 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 @@ | |||
| 1 | /* | ||
| 2 | Data structure for international table | ||
| 3 | */ | ||
| 4 | |||
| 5 | struct InterTbl | ||
| 6 | { | ||
| 7 | unsigned dateform ; /* Date format */ | ||
| 8 | char currsym[5] ; /* Currency symbol as ASCIZ string */ | ||
| 9 | char thousp[2] ; /* Thousands separator as ASCIZ string */ | ||
| 10 | char decsp[2] ; /* Decimal separator as ASCIZ string */ | ||
| 11 | char datesp[2] ; /* Date separator as ASCIZ string */ | ||
| 12 | char timesp[2] ; /* Time separator as ASCIZ string */ | ||
| 13 | unsigned char bits ; /* Bit field */ | ||
| 14 | unsigned char numdig ; /* Number of signifigant decimal digits */ | ||
| 15 | unsigned char timeform ;/* Time format */ | ||
| 16 | unsigned long casecall ;/* Case mapping call */ | ||
| 17 | char datasp[2] ; /* Data list separator as ASCIZ string */ | ||
| 18 | int reserv[5] ; /* RESERVED */ | ||
| 19 | } ; | ||
| 20 | |||
| 21 | |||
| 22 | #define DATEFORM_USA 0 | ||
| 23 | #define DATEFORM_EUROPE 1 | ||
| 24 | #define DATEFORM_JAPAN 2 | ||
| 25 | |||
| 26 | #define BITS_CURRENCY 0x0001 | ||
| 27 | #define BITS_NUMSPC 0x0002 | ||
| 28 | |||
| 29 | #define TIMEFORM_12 0 | ||
| 30 | #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 @@ | |||
| 1 | .xlist | ||
| 2 | include version.inc | ||
| 3 | include cmacros.inc | ||
| 4 | .list | ||
| 5 | |||
| 6 | sBegin code | ||
| 7 | assumes cs,code | ||
| 8 | |||
| 9 | ; | ||
| 10 | ; c = IToupper (c, routine); | ||
| 11 | ; | ||
| 12 | ; c is char to be converted | ||
| 13 | ; routine is case map call in international table | ||
| 14 | ; | ||
| 15 | |||
| 16 | cProc IToupper,<PUBLIC> | ||
| 17 | parmW c | ||
| 18 | parmD routine | ||
| 19 | cBegin | ||
| 20 | mov ax,c | ||
| 21 | or ah,ah | ||
| 22 | jnz donothing | ||
| 23 | cmp al,'a' | ||
| 24 | jb noconv | ||
| 25 | cmp al,'z' | ||
| 26 | ja noconv | ||
| 27 | sub al,20H | ||
| 28 | noconv: | ||
| 29 | call routine | ||
| 30 | donothing: | ||
| 31 | cEnd | ||
| 32 | |||
| 33 | |||
| 34 | ;Get_Lbtbl | ||
| 35 | ; | ||
| 36 | ; Get pointer to LBTBL from DOS if we are running on a version | ||
| 37 | ; of DOS which supports it. If not, initialize the table with | ||
| 38 | ; a pointer to a local "default" table with KANJI lead bytes. | ||
| 39 | ; | ||
| 40 | ;Input: word pointer to LONG "Lbtbl" | ||
| 41 | ;Output: long initialized to Lead byte pointer | ||
| 42 | ; | ||
| 43 | |||
| 44 | cProc get_lbtbl,<PUBLIC> | ||
| 45 | |||
| 46 | parmW pointer_to_table | ||
| 47 | |||
| 48 | ; on entry, low word of DWORD pointer has offset of | ||
| 49 | ; a default table of lead bytes defined within the C program | ||
| 50 | ; If function 63 is supported, the DWORD pointer to DOS' | ||
| 51 | ; table will be placed here instead. | ||
| 52 | cBegin | ||
| 53 | push si | ||
| 54 | push di | ||
| 55 | mov bx,pointer_to_table ;get pointer | ||
| 56 | mov si,[bx] ;default table pointer in DS:SI | ||
| 57 | push es | ||
| 58 | push ds | ||
| 59 | mov ax,6300h ;make Get Lead Byte call | ||
| 60 | int 21h | ||
| 61 | mov ss:[bx],si ;si didn't change if non ECS dos | ||
| 62 | mov ss:[bx+2],ds ;store segment | ||
| 63 | pop ds | ||
| 64 | pop es | ||
| 65 | pop di | ||
| 66 | pop si | ||
| 67 | cEnd | ||
| 68 | |||
| 69 | |||
| 70 | ; | ||
| 71 | ; test_ECS(char,DWORD_prt) test the char to find out if it is | ||
| 72 | ; a valid lead byte using passed DWORD | ||
| 73 | ; Input: char PTR to the Lead Byte table. | ||
| 74 | ; DWORD PTR to table | ||
| 75 | ; Output: AX=FFFF (is_lead) Lead byte table may be default in | ||
| 76 | ; AX=0 (not_lead) program or ECS table in DOS when | ||
| 77 | ; running on a version which supports it. | ||
| 78 | ; | ||
| 79 | cProc test_ECS,<PUBLIC> ;test for lead byte ;if Lead, then | ||
| 80 | ; return AX=Is_lead | ||
| 81 | ; else | ||
| 82 | ; return AX=FALSE | ||
| 83 | Is_lead EQU 0FFFFH | ||
| 84 | Not_lead EQU 0 | ||
| 85 | |||
| 86 | parmW char | ||
| 87 | parmD pointer ;DWORD PTR to Lead Byte Table | ||
| 88 | cBegin | ||
| 89 | mov ax,char | ||
| 90 | xchg ah,al | ||
| 91 | push SI | ||
| 92 | push DS | ||
| 93 | LDS SI,pointer | ||
| 94 | ktlop: | ||
| 95 | lodsb | ||
| 96 | or al,al | ||
| 97 | jz notlead | ||
| 98 | cmp al,ah | ||
| 99 | ja notlead | ||
| 100 | lodsb | ||
| 101 | cmp ah,al | ||
| 102 | ja ktlop | ||
| 103 | mov ax,Is_lead | ||
| 104 | notl_exit: | ||
| 105 | pop ds | ||
| 106 | pop si | ||
| 107 | jmp cexit | ||
| 108 | notlead: | ||
| 109 | mov ax,not_lead | ||
| 110 | jmp notl_exit | ||
| 111 | cexit: | ||
| 112 | cEnd | ||
| 113 | |||
| 114 | |||
| 115 | |||
| 116 | |||
| 117 | sEnd | ||
| 118 | |||
| 119 | 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 @@ | |||
| 1 | #** makefile for fc | ||
| 2 | |||
| 3 | DEST =fc | ||
| 4 | MSG =messages | ||
| 5 | |||
| 6 | # Path Definitions | ||
| 7 | |||
| 8 | BIOS =..\..\BIOS | ||
| 9 | BOOT =..\..\BOOT | ||
| 10 | dos =..\..\DOS | ||
| 11 | inc =..\..\INC | ||
| 12 | hinc =..\..\h | ||
| 13 | H =..\..\H | ||
| 14 | |||
| 15 | # List of object files required | ||
| 16 | |||
| 17 | OBJ = fc.obj \ | ||
| 18 | error.obj \ | ||
| 19 | fgetl.obj \ | ||
| 20 | getl.obj \ | ||
| 21 | itoupper.obj \ | ||
| 22 | $(inc)\kstring.obj \ | ||
| 23 | maxmin.obj \ | ||
| 24 | move.obj \ | ||
| 25 | ntoi.obj \ | ||
| 26 | string.obj \ | ||
| 27 | update.obj \ | ||
| 28 | xtab.obj \ | ||
| 29 | messages.obj | ||
| 30 | |||
| 31 | # Rules and Dependencies follow | ||
| 32 | |||
| 33 | all: $(DEST).exe | ||
| 34 | |||
| 35 | $(inc)\printf.obj: $(inc)\printf.asm | ||
| 36 | |||
| 37 | $(inc)\kstring.obj: $(inc)\kstring.c $(hinc)\internat.h | ||
| 38 | |||
| 39 | getl.obj: getl.asm $(inc)\cmacros.inc $(inc)\version.inc | ||
| 40 | |||
| 41 | itoupper.obj: itoupper.asm $(inc)\cmacros.inc $(inc)\version.inc | ||
| 42 | |||
| 43 | maxmin.obj: maxmin.asm $(inc)\cmacros.inc $(inc)\version.inc | ||
| 44 | |||
| 45 | $(MSG).obj: $(MSG).asm | ||
| 46 | |||
| 47 | move.obj: move.asm $(inc)\cmacros.inc $(inc)\version.inc | ||
| 48 | |||
| 49 | string.obj: string.asm $(inc)\cmacros.inc $(inc)\version.inc | ||
| 50 | |||
| 51 | xtab.obj: xtab.asm $(inc)\cmacros.inc $(inc)\version.inc | ||
| 52 | |||
| 53 | error.obj: error.c tools.h ttypes.h | ||
| 54 | |||
| 55 | $(DEST).obj: $(DEST).c $(DEST).h tools.h ttypes.h | ||
| 56 | |||
| 57 | fgetl.obj: fgetl.c tools.h ttypes.h | ||
| 58 | |||
| 59 | ntoi.obj: ntoi.c tools.h ttypes.h | ||
| 60 | |||
| 61 | update.obj: update.c tools.h ttypes.h | ||
| 62 | |||
| 63 | $(DEST).exe: $(OBJ) $(DEST).lnk | ||
| 64 | $(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 @@ | |||
| 1 | ; | ||
| 2 | ; maximum and minimum routines. | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | include version.inc | ||
| 7 | include cmacros.inc | ||
| 8 | .list | ||
| 9 | |||
| 10 | sBegin code | ||
| 11 | assumes cs,code | ||
| 12 | |||
| 13 | cProc max,<PUBLIC> | ||
| 14 | parmW a | ||
| 15 | parmW b | ||
| 16 | cBegin | ||
| 17 | mov ax,a | ||
| 18 | cmp ax,b | ||
| 19 | jg maxdone | ||
| 20 | mov ax,b | ||
| 21 | maxdone: | ||
| 22 | cEnd | ||
| 23 | |||
| 24 | cProc min,<PUBLIC> | ||
| 25 | parmW a | ||
| 26 | parmW b | ||
| 27 | cBegin | ||
| 28 | mov ax,a | ||
| 29 | cmp ax,b | ||
| 30 | jl mindone | ||
| 31 | mov ax,b | ||
| 32 | mindone: | ||
| 33 | cEnd | ||
| 34 | |||
| 35 | sEnd | ||
| 36 | |||
| 37 | 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 @@ | |||
| 1 | ; | ||
| 2 | ; message file for FC command | ||
| 3 | ; | ||
| 4 | |||
| 5 | CONST SEGMENT WORD PUBLIC 'DATA' | ||
| 6 | CONST ENDS | ||
| 7 | |||
| 8 | _BSS SEGMENT WORD PUBLIC 'DATA' | ||
| 9 | _BSS ENDS | ||
| 10 | |||
| 11 | _DATA SEGMENT WORD PUBLIC 'DATA' | ||
| 12 | _DATA ENDS | ||
| 13 | |||
| 14 | DGROUP GROUP CONST, _BSS, _DATA | ||
| 15 | |||
| 16 | ASSUME DS:DGROUP | ||
| 17 | |||
| 18 | _DATA SEGMENT | ||
| 19 | PUBLIC _BadSw, _UseMes, _BadOpn, _LngFil, _NoDif, _NoMem, _Bad_ver, _ReSyncMes, _UnKnown | ||
| 20 | |||
| 21 | _BadSw DB "Incompatible switches",0 | ||
| 22 | _Bad_ver DB "Incorrect DOS version",0 | ||
| 23 | _UseMes DB "usage: fc [/a] [/b] [/c] [/l] [/lbNN] [/w] [/t] [/n] [/NNNN] file1 file2",0ah,0 | ||
| 24 | _BadOpn DB "cannot open %s - %s",0 | ||
| 25 | _LngFil DB "%s longer than %s",0 | ||
| 26 | _NoDif DB "no differences encountered",0 | ||
| 27 | _NoMem DB "out of memory",0ah,0 | ||
| 28 | _ReSyncMes DB "Resync failed. Files are too different\n",0 | ||
| 29 | _UnKnown DB "Unknown error",0 | ||
| 30 | _DATA ENDS | ||
| 31 | 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 @@ | |||
| 1 | ; | ||
| 2 | ; memory routines | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | include version.inc | ||
| 7 | include cmacros.inc | ||
| 8 | .list | ||
| 9 | |||
| 10 | sBegin code | ||
| 11 | assumes cs,code | ||
| 12 | |||
| 13 | cProc Move,<PUBLIC>,<DS,SI,DI> | ||
| 14 | parmD src | ||
| 15 | parmD dst | ||
| 16 | parmW count | ||
| 17 | cBegin | ||
| 18 | mov cx,count | ||
| 19 | jcxz NoByte ; No characters to move | ||
| 20 | les di,dst ; grab pointers | ||
| 21 | lds si,src | ||
| 22 | cld | ||
| 23 | mov ax,ds | ||
| 24 | cmp ax,Seg_dst | ||
| 25 | jnz SimpleMove ; segments are NOT the same, no opt | ||
| 26 | cmp si,di ; is the start of source before dest | ||
| 27 | jb TestMove ; yes, try to optimize | ||
| 28 | |||
| 29 | SimpleMove: | ||
| 30 | shr cx,1 | ||
| 31 | rep movsw | ||
| 32 | jnc NoByte | ||
| 33 | movsb | ||
| 34 | jmp short NoByte | ||
| 35 | |||
| 36 | TestMove: | ||
| 37 | mov ax,di | ||
| 38 | sub ax,si ; ax = difference between regions | ||
| 39 | cmp ax,cx ; is difference greater than region? | ||
| 40 | jae SimpleMove ; yes, no optimize | ||
| 41 | mov ax,cx ; optimize by copying down from top | ||
| 42 | dec ax | ||
| 43 | add di,ax | ||
| 44 | add si,ax | ||
| 45 | std | ||
| 46 | rep movsb ; no word optimization here | ||
| 47 | |||
| 48 | NoByte: | ||
| 49 | cld | ||
| 50 | cEnd | ||
| 51 | |||
| 52 | cProc Fill,<PUBLIC>,<DI> | ||
| 53 | parmD dst | ||
| 54 | parmB value | ||
| 55 | parmW count | ||
| 56 | cBegin | ||
| 57 | cld | ||
| 58 | les di,dst | ||
| 59 | mov al,value | ||
| 60 | mov ah,value | ||
| 61 | mov cx,count | ||
| 62 | shr cx,1 | ||
| 63 | jcxz fill1 | ||
| 64 | rep stosw | ||
| 65 | fill1: | ||
| 66 | jnc fill2 | ||
| 67 | stosb | ||
| 68 | fill2: | ||
| 69 | cEnd | ||
| 70 | |||
| 71 | sEnd | ||
| 72 | |||
| 73 | 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 @@ | |||
| 1 | /* convert an arbitrary based number to an integer */ | ||
| 2 | |||
| 3 | #include <ctype.h> | ||
| 4 | #include "tools.h" | ||
| 5 | |||
| 6 | /* p points to characters, return -1 if no good characters found | ||
| 7 | * and base is 2 <= base <= 16 | ||
| 8 | */ | ||
| 9 | int ntoi (p, base) | ||
| 10 | char *p; | ||
| 11 | int base; | ||
| 12 | { | ||
| 13 | register int i, c; | ||
| 14 | flagType fFound; | ||
| 15 | |||
| 16 | if (base < 2 || base > 16) | ||
| 17 | return -1; | ||
| 18 | i = 0; | ||
| 19 | fFound = FALSE; | ||
| 20 | while (c = *p++) { | ||
| 21 | c = tolower (c); | ||
| 22 | if (!isxdigit (c)) | ||
| 23 | break; | ||
| 24 | if (c <= '9') | ||
| 25 | c -= '0'; | ||
| 26 | else | ||
| 27 | c -= 'a'-10; | ||
| 28 | if (c >= base) | ||
| 29 | break; | ||
| 30 | i = i * base + c; | ||
| 31 | fFound = TRUE; | ||
| 32 | } | ||
| 33 | if (fFound) | ||
| 34 | return i; | ||
| 35 | else | ||
| 36 | return -1; | ||
| 37 | } | ||
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 @@ | |||
| 1 | ; | ||
| 2 | ; string functions for lattice C | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | include version.inc | ||
| 7 | include cmacros.inc | ||
| 8 | .list | ||
| 9 | |||
| 10 | sBegin data | ||
| 11 | assumes ds,data | ||
| 12 | |||
| 13 | externB XLTab | ||
| 14 | externB XUTab | ||
| 15 | |||
| 16 | sEnd | ||
| 17 | |||
| 18 | sBegin code | ||
| 19 | assumes cs,code | ||
| 20 | |||
| 21 | externP strlen | ||
| 22 | |||
| 23 | ; | ||
| 24 | ; strbscan (string, set) returns pointer to 1st char in set or end | ||
| 25 | ; | ||
| 26 | cProc strbscan,<PUBLIC>,<SI,DI> | ||
| 27 | parmW str | ||
| 28 | parmW set | ||
| 29 | cBegin | ||
| 30 | push ds | ||
| 31 | pop es | ||
| 32 | cCall strlen,<set> | ||
| 33 | inc ax | ||
| 34 | mov bx, ax | ||
| 35 | mov si,str | ||
| 36 | cld | ||
| 37 | bscan: | ||
| 38 | lodsb | ||
| 39 | mov cx,bx | ||
| 40 | mov di,set | ||
| 41 | ; | ||
| 42 | ; While not in the set | ||
| 43 | ; | ||
| 44 | repnz scasb | ||
| 45 | jnz bscan | ||
| 46 | lea ax,[si-1] | ||
| 47 | cEnd | ||
| 48 | |||
| 49 | ; | ||
| 50 | ; strbskip ( string, set ) returns pointer to 1st char not in set | ||
| 51 | ; | ||
| 52 | cProc strbskip,<PUBLIC>,<SI,DI> | ||
| 53 | parmW str | ||
| 54 | parmW set | ||
| 55 | cBegin | ||
| 56 | push ds | ||
| 57 | pop es | ||
| 58 | cCall strlen,<set> | ||
| 59 | inc ax | ||
| 60 | mov bx, ax | ||
| 61 | mov si,str | ||
| 62 | cld | ||
| 63 | bskip: | ||
| 64 | lodsb | ||
| 65 | or al,al | ||
| 66 | jz eskip | ||
| 67 | mov cx,bx | ||
| 68 | mov di,set | ||
| 69 | ; | ||
| 70 | ; While not in the set | ||
| 71 | ; | ||
| 72 | repnz scasb | ||
| 73 | jz bskip | ||
| 74 | eskip: | ||
| 75 | lea ax,[si-1] | ||
| 76 | cEnd | ||
| 77 | |||
| 78 | ; | ||
| 79 | ; strpre (s1, s2) returns -1 if s1 is a prefix of s2, 0 otherwise. Ignores | ||
| 80 | ; case. | ||
| 81 | ; | ||
| 82 | cProc strpre,<PUBLIC>,<si,di> | ||
| 83 | parmW pref | ||
| 84 | parmW str | ||
| 85 | cBegin | ||
| 86 | cld | ||
| 87 | mov si,pref | ||
| 88 | mov di,str | ||
| 89 | mov bx,dataOFFSET xltab | ||
| 90 | preCompare: | ||
| 91 | lodsb | ||
| 92 | mov ah,[di] | ||
| 93 | inc di | ||
| 94 | |||
| 95 | xlat | ||
| 96 | xchg ah,al | ||
| 97 | xlat | ||
| 98 | |||
| 99 | cmp ah,al | ||
| 100 | jnz preDif | ||
| 101 | or ah,ah | ||
| 102 | jnz preCompare | ||
| 103 | preYes: | ||
| 104 | mov ax,-1 | ||
| 105 | jmp short preDone | ||
| 106 | preDif: | ||
| 107 | or ah,ah | ||
| 108 | jz preYes | ||
| 109 | xor ax,ax | ||
| 110 | preDone: | ||
| 111 | cEnd | ||
| 112 | |||
| 113 | sEnd | ||
| 114 | |||
| 115 | 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 @@ | |||
| 1 | /* | ||
| 2 | * tools.h - Header file for accessing TOOLS.LIB routines | ||
| 3 | * includes stdio.h and ctype.h | ||
| 4 | * | ||
| 5 | * 4/14/86 dl added U_* flags for upd return values | ||
| 6 | * | ||
| 7 | * 31-Jul-1986 mz Add Connect definitions | ||
| 8 | */ | ||
| 9 | |||
| 10 | #define TRUE -1 | ||
| 11 | #define FALSE 0 | ||
| 12 | |||
| 13 | #if MSDOS | ||
| 14 | #define PSEPSTR "\\" | ||
| 15 | #define PSEPCHR '\\' | ||
| 16 | #else | ||
| 17 | #define PSEPSTR "/" | ||
| 18 | #define PSEPCHR '/' | ||
| 19 | #endif | ||
| 20 | |||
| 21 | typedef char flagType; | ||
| 22 | typedef long ptrType; | ||
| 23 | |||
| 24 | #define SETFLAG(l,f) ((l) |= (f)) | ||
| 25 | #define TESTFLAG(v,f) (((v)&(f))!=0) | ||
| 26 | #define RSETFLAG(l,f) ((l) &= ~(f)) | ||
| 27 | |||
| 28 | #define SHIFT(c,v) {c--; v++;} | ||
| 29 | |||
| 30 | #define LOW(w) ((int)(w)&0xFF) | ||
| 31 | #define HIGH(w) LOW((int)(w)>>8) | ||
| 32 | #define WORD(h,l) ((LOW((h))<<8)|LOW((l))) | ||
| 33 | #define POINTER(seg,off) ((((long)(seg))<<4)+ (long)(off)) | ||
| 34 | |||
| 35 | #define FNADDR(f) (f) | ||
| 36 | |||
| 37 | #define SELECT if(FALSE){ | ||
| 38 | #define CASE(x) }else if((x)){ | ||
| 39 | #define OTHERWISE }else{ | ||
| 40 | #define ENDSELECT } | ||
| 41 | |||
| 42 | /* buffer description for findfirst and findnext */ | ||
| 43 | |||
| 44 | struct findType { | ||
| 45 | char reserved[21]; /* reserved for start up */ | ||
| 46 | char attr; /* attribute found */ | ||
| 47 | unsigned time; /* time of last modify */ | ||
| 48 | unsigned date; /* date of last modify */ | ||
| 49 | long length; /* file size */ | ||
| 50 | char name[13]; /* asciz file name */ | ||
| 51 | }; | ||
| 52 | |||
| 53 | /* attributes */ | ||
| 54 | #define A_RO 1 /* read only */ | ||
| 55 | #define A_H 2 /* hidden */ | ||
| 56 | #define A_S 4 /* system */ | ||
| 57 | #define A_V 8 /* volume id */ | ||
| 58 | #define A_D 16 /* directory */ | ||
| 59 | #define A_A 32 /* archive */ | ||
| 60 | |||
| 61 | #define A_MOD (A_RO+A_H+A_S+A_A) /* changeable attributes */ | ||
| 62 | |||
| 63 | #define HASATTR(a,v) TESTFLAG(a,v) /* true if a has attribute v */ | ||
| 64 | |||
| 65 | extern char XLTab[], XUTab[]; | ||
| 66 | |||
| 67 | #define MAXARG 128 | ||
| 68 | #define MAXPATHLEN 128 | ||
| 69 | |||
| 70 | #include "ttypes.h" | ||
| 71 | |||
| 72 | struct vectorType { | ||
| 73 | int max; /* max the vector can hold */ | ||
| 74 | int count; /* count of elements in vector */ | ||
| 75 | unsigned elem[1]; /* elements in vector */ | ||
| 76 | }; | ||
| 77 | |||
| 78 | /* return flags for upd */ | ||
| 79 | #define U_DRIVE 0x8 | ||
| 80 | #define U_PATH 0x4 | ||
| 81 | #define U_NAME 0x2 | ||
| 82 | #define U_EXT 0x1 | ||
| 83 | |||
| 84 | /* Connect definitions */ | ||
| 85 | |||
| 86 | #define REALDRIVE 0x8000 | ||
| 87 | #define ISTMPDRIVE(x) (((x)&REALDRIVE)==0) | ||
| 88 | #define TOKTODRV(x) ((x)&~REALDRIVE) | ||
| 89 | |||
| 90 | /* Heap Checking return codes */ | ||
| 91 | |||
| 92 | #define HEAPOK 0 | ||
| 93 | #define HEAPBADBEGIN -1 | ||
| 94 | #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 @@ | |||
| 1 | /* ttypes.h - type definitions for tools library */ | ||
| 2 | |||
| 3 | #include <stdio.h> | ||
| 4 | |||
| 5 | /* assembly routines */ | ||
| 6 | flagType int25 (char, char far *, unsigned int, unsigned int); | ||
| 7 | flagType int26 (char, char far *, unsigned int, unsigned int); | ||
| 8 | flagType kbhit (); | ||
| 9 | char getch (); | ||
| 10 | void Move (char far *, char far *, unsigned int); | ||
| 11 | void Fill (char far *, char, unsigned int); | ||
| 12 | char *strbscan (char *, char *); | ||
| 13 | char *strbskip (char *, char *); | ||
| 14 | flagType strpre (char *, char *); | ||
| 15 | int strcmpi (unsigned char *, unsigned char *); | ||
| 16 | char *fcopy (char *, char *); | ||
| 17 | long getlpos (); | ||
| 18 | void getlinit ( char far *, int, int); | ||
| 19 | int getl (char *, int); | ||
| 20 | |||
| 21 | /* c routines */ | ||
| 22 | /*global*/ char *lower(char *); | ||
| 23 | /*global*/ char *upper(char *); | ||
| 24 | /*global*/ char *error(void); | ||
| 25 | /*global*/ long fexpunge(char *,FILE *); | ||
| 26 | /*global*/ char *fcopy(char *,char *); | ||
| 27 | /*global*/ int fgetl(char *,int ,FILE *); | ||
| 28 | /*global*/ int fputl(char *,int ,FILE *); | ||
| 29 | /*global*/ int ffirst(char *,int ,struct findType *); | ||
| 30 | /*global*/ int fnext(struct findType *); | ||
| 31 | /*global*/ char forsemi(char *,char ( *)(), ); | ||
| 32 | /*global*/ long freespac(int ); | ||
| 33 | /*global*/ long sizeround(long ,int ); | ||
| 34 | /*global*/ int rspawnl(char *,char *,char *, ); | ||
| 35 | /*global*/ int rspawnv(char *,char *,char *,char *[0]); | ||
| 36 | /*global*/ char *MakeStr(char *); | ||
| 37 | /*global*/ int mapenv(char *,char *); | ||
| 38 | /*global*/ char *ismark(char *); | ||
| 39 | /*global*/ FILE *swopen(char *,char *); | ||
| 40 | /*global*/ int swclose(FILE *); | ||
| 41 | /*global*/ int swread(char *,int ,FILE *); | ||
| 42 | /*global*/ char *swfind(char *,FILE *,char *); | ||
| 43 | /*global*/ char *getenvini(char *,char *); | ||
| 44 | /*global*/ char fPathChr(int ); | ||
| 45 | /*global*/ char fSwitChr(int ); | ||
| 46 | /*global*/ char fPFind(char *,unsigned int * *); | ||
| 47 | /*global*/ char findpath(char *,char *,char ); | ||
| 48 | /*global*/ FILE *pathopen(char *,char *,char *); | ||
| 49 | /*global*/ int forfile(char *,int ,void ( *)(), ); | ||
| 50 | /*global*/ int rootpath(char *,char *); | ||
| 51 | /*global*/ int sti(char *,int ); | ||
| 52 | /*global*/ int ntoi(char *,int ); | ||
| 53 | /*global*/ int strcmps(unsigned char *,unsigned char *); | ||
| 54 | /*global*/ int strcmpis(unsigned char *,unsigned char *); | ||
| 55 | /*global*/ char *strend(char *); | ||
| 56 | /*global*/ int upd(char *,char *,char *); | ||
| 57 | /*global*/ int drive(char *,char *); | ||
| 58 | /*global*/ int extention(char *,char *); | ||
| 59 | /*global*/ int filename(char *,char *); | ||
| 60 | /*global*/ int filenamx(char *,char *); | ||
| 61 | /*global*/ int path(char *,char *); | ||
| 62 | /*global*/ int curdir(char *,char ); | ||
| 63 | /*global*/ int getattr(char *); | ||
| 64 | /*global*/ int fdelete(char *); | ||
| 65 | /*global*/ char *fmove(char *, char *); | ||
| 66 | /*global*/ char *fappend(char *, int); | ||
| 67 | /*global*/ long ctime2l(char *); | ||
| 68 | /*global*/ struct tm *ctime2tm(char *); | ||
| 69 | /*global*/ long date2l(int, int, int, int, int, int); | ||
| 70 | /*global*/ struct vectorType *VectorAlloc(int); | ||
| 71 | /*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 @@ | |||
| 1 | /* | ||
| 2 | * update takes a def string and update and fills the | ||
| 3 | * update with missing defs the update allowing | ||
| 4 | * specification of missing parameters. | ||
| 5 | * the parts are: ^{[~:]#:}{%#</|\>}{[~.]#}{.[~./\:]}$ | ||
| 6 | * maximum size of MAXPATHLEN (80) bytes | ||
| 7 | * | ||
| 8 | * 4/14/86 dl use U_ flags | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include "tools.h" | ||
| 13 | |||
| 14 | int upd (def, update, dst) | ||
| 15 | char *def, *update, *dst; | ||
| 16 | { | ||
| 17 | char *p, buf[MAXPATHLEN]; | ||
| 18 | int f; | ||
| 19 | |||
| 20 | f = 0; | ||
| 21 | p = buf; | ||
| 22 | #if MSDOS | ||
| 23 | if (drive(update, p) || drive (def, p)) | ||
| 24 | SETFLAG(f, U_DRIVE); | ||
| 25 | p += strlen (p); | ||
| 26 | #endif | ||
| 27 | |||
| 28 | if (path(update, p) || path (def, p)) | ||
| 29 | SETFLAG(f, U_PATH); | ||
| 30 | p += strlen (p); | ||
| 31 | |||
| 32 | if (filename(update, p) || filename (def, p)) | ||
| 33 | SETFLAG(f, U_NAME); | ||
| 34 | p += strlen (p); | ||
| 35 | |||
| 36 | if (extention(update, p) || extention (def, p)) | ||
| 37 | SETFLAG(f, U_EXT); | ||
| 38 | |||
| 39 | strcpy (dst, buf); | ||
| 40 | |||
| 41 | return f; | ||
| 42 | } | ||
| 43 | |||
| 44 | #if MSDOS | ||
| 45 | /* copy a drive from source to dest if present, return TRUE if we found one */ | ||
| 46 | drive (src, dst) | ||
| 47 | char *src, *dst; | ||
| 48 | { | ||
| 49 | register char *p; | ||
| 50 | |||
| 51 | p = strbscan (src, ":"); | ||
| 52 | if (*p++ == NULL) | ||
| 53 | p = src; | ||
| 54 | strcpy (dst, src); | ||
| 55 | dst[p-src] = 0; | ||
| 56 | return strlen (dst) != 0; | ||
| 57 | } | ||
| 58 | #endif | ||
| 59 | |||
| 60 | /* copy an extention from source to dest if present. include the period. | ||
| 61 | Return TRUE if one found. | ||
| 62 | */ | ||
| 63 | extention (src, dst) | ||
| 64 | char *src, *dst; | ||
| 65 | { | ||
| 66 | register char *p, *p1; | ||
| 67 | |||
| 68 | p = src - 1; | ||
| 69 | while (*(p=strbscan(1+(p1=p), ".")) != NULL) | ||
| 70 | ; | ||
| 71 | /* p1 points to last . or begin of string p points to eos */ | ||
| 72 | if (*strbscan (p1, "\\/:") != NULL || *p1 != '.') | ||
| 73 | p1 = p; | ||
| 74 | strcpy (dst, p1); | ||
| 75 | return strlen (dst) != 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | /* copy a filename part from source to dest if present. return true if one | ||
| 79 | is found | ||
| 80 | */ | ||
| 81 | filename (src, dst) | ||
| 82 | char *src, *dst; | ||
| 83 | { | ||
| 84 | register char *p, *p1; | ||
| 85 | |||
| 86 | p = src-1; | ||
| 87 | while (*(p=strbscan (p1=p+1, "\\/:")) != NULL) | ||
| 88 | ; | ||
| 89 | /* p1 points after last / or at bos */ | ||
| 90 | p = strbscan (p1, "."); | ||
| 91 | strcpy (dst, p1); | ||
| 92 | dst[p-p1] = 0; | ||
| 93 | return strlen (dst) != 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | /* copy a filename.ext part from source to dest if present. return true if one | ||
| 97 | is found | ||
| 98 | */ | ||
| 99 | fileext (src, dst) | ||
| 100 | char *src, *dst; | ||
| 101 | { | ||
| 102 | *dst = '\0'; | ||
| 103 | if ( filename (src, dst) ) { | ||
| 104 | dst += strlen (dst); | ||
| 105 | extention (src, dst); | ||
| 106 | return TRUE; | ||
| 107 | } | ||
| 108 | return FALSE; | ||
| 109 | } | ||
| 110 | |||
| 111 | /* copy the paths part of the file description. return true if found | ||
| 112 | */ | ||
| 113 | path (src, dst) | ||
| 114 | char *src, *dst; | ||
| 115 | { | ||
| 116 | register char *p, *p1; | ||
| 117 | |||
| 118 | if (*(p=strbscan (src, ":")) != NULL) | ||
| 119 | src = p+1; | ||
| 120 | p = src-1; | ||
| 121 | /* p points to beginning of possible path (after potential drive spec) */ | ||
| 122 | while (*(p=strbscan (p1=p+1, "\\/:")) != NULL) | ||
| 123 | ; | ||
| 124 | /* p1 points after final / or bos */; | ||
| 125 | strcpy (dst, src); | ||
| 126 | dst[p1-src] = 0; | ||
| 127 | return strlen (dst) != 0; | ||
| 128 | } | ||
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 @@ | |||
| 1 | ; | ||
| 2 | ; xlat tables for case conversion | ||
| 3 | ; | ||
| 4 | |||
| 5 | .xlist | ||
| 6 | include version.inc | ||
| 7 | include cmacros.inc | ||
| 8 | .list | ||
| 9 | |||
| 10 | sBegin data | ||
| 11 | |||
| 12 | public _XLTab, _XUTab | ||
| 13 | |||
| 14 | assumes ds,data | ||
| 15 | |||
| 16 | ; | ||
| 17 | ; table for lowercase translation | ||
| 18 | ; | ||
| 19 | |||
| 20 | _XLTab LABEL BYTE | ||
| 21 | |||
| 22 | db 000h, 001h, 002h, 003h, 004h, 005h, 006h, 007h | ||
| 23 | db 008h, 009h, 00Ah, 00Bh, 00Ch, 00Dh, 00Eh, 00Fh | ||
| 24 | |||
| 25 | db 010h, 011h, 012h, 013h, 014h, 015h, 016h, 017h | ||
| 26 | db 018h, 019h, 01Ah, 01Bh, 01Ch, 01Dh, 01Eh, 01Fh | ||
| 27 | |||
| 28 | db ' !"#$%&', 027h | ||
| 29 | db '()*+,-./' | ||
| 30 | |||
| 31 | db '01234567' | ||
| 32 | db '89:;<=>?' | ||
| 33 | |||
| 34 | db '@abcdefg' | ||
| 35 | db 'hijklmno' | ||
| 36 | |||
| 37 | db 'pqrstuvw' | ||
| 38 | db 'xyz[\]^_' | ||
| 39 | |||
| 40 | db '`abcdefg' | ||
| 41 | db 'hijklmno' | ||
| 42 | |||
| 43 | db 'pqrstuvw' | ||
| 44 | db 'xyz{|}~', 07Fh | ||
| 45 | |||
| 46 | db 080h, 081h, 082h, 083h, 084h, 085h, 086h, 087h | ||
| 47 | db 088h, 089h, 08Ah, 08Bh, 08Ch, 08Dh, 08Eh, 08Fh | ||
| 48 | db 090h, 091h, 092h, 093h, 094h, 095h, 096h, 097h | ||
| 49 | db 098h, 099h, 09Ah, 09Bh, 09Ch, 09Dh, 09Eh, 09Fh | ||
| 50 | db 0A0h, 0A1h, 0A2h, 0A3h, 0A4h, 0A5h, 0A6h, 0A7h | ||
| 51 | db 0A8h, 0A9h, 0AAh, 0ABh, 0ACh, 0ADh, 0AEh, 0AFh | ||
| 52 | db 0B0h, 0B1h, 0B2h, 0B3h, 0B4h, 0B5h, 0B6h, 0B7h | ||
| 53 | db 0B8h, 0B9h, 0BAh, 0BBh, 0BCh, 0BDh, 0BEh, 0BFh | ||
| 54 | db 0C0h, 0C1h, 0C2h, 0C3h, 0C4h, 0C5h, 0C6h, 0C7h | ||
| 55 | db 0C8h, 0C9h, 0CAh, 0CBh, 0CCh, 0CDh, 0CEh, 0CFh | ||
| 56 | db 0D0h, 0D1h, 0D2h, 0D3h, 0D4h, 0D5h, 0D6h, 0D7h | ||
| 57 | db 0D8h, 0D9h, 0DAh, 0DBh, 0DCh, 0DDh, 0DEh, 0DFh | ||
| 58 | db 0E0h, 0E1h, 0E2h, 0E3h, 0E4h, 0E5h, 0E6h, 0E7h | ||
| 59 | db 0E8h, 0E9h, 0EAh, 0EBh, 0ECh, 0EDh, 0EEh, 0EFh | ||
| 60 | db 0F0h, 0F1h, 0F2h, 0F3h, 0F4h, 0F5h, 0F6h, 0F7h | ||
| 61 | db 0F8h, 0F9h, 0FAh, 0FBh, 0FCh, 0FDh, 0FEh, 0FFh | ||
| 62 | |||
| 63 | _XUTab LABEL BYTE | ||
| 64 | |||
| 65 | db 000h, 001h, 002h, 003h, 004h, 005h, 006h, 007h | ||
| 66 | db 008h, 009h, 00Ah, 00Bh, 00Ch, 00Dh, 00Eh, 00Fh | ||
| 67 | db 010h, 011h, 012h, 013h, 014h, 015h, 016h, 017h | ||
| 68 | db 018h, 019h, 01Ah, 01Bh, 01Ch, 01Dh, 01Eh, 01Fh | ||
| 69 | db ' !"#$%&', 027h | ||
| 70 | db '()*+,-./' | ||
| 71 | db '01234567' | ||
| 72 | db '89:;<=>?' | ||
| 73 | db '@ABCDEFG' | ||
| 74 | db 'HIJKLMNO' | ||
| 75 | db 'PQRSTUVW' | ||
| 76 | db 'XYZ[\]^_' | ||
| 77 | db '`ABCDEFG' | ||
| 78 | db 'HIJKLMNO' | ||
| 79 | db 'PQRSTUVW' | ||
| 80 | db 'XYZ{|}~', 07Fh | ||
| 81 | db 080h, 081h, 082h, 083h, 084h, 085h, 086h, 087h | ||
| 82 | db 088h, 089h, 08Ah, 08Bh, 08Ch, 08Dh, 08Eh, 08Fh | ||
| 83 | db 090h, 091h, 092h, 093h, 094h, 095h, 096h, 097h | ||
| 84 | db 098h, 099h, 09Ah, 09Bh, 09Ch, 09Dh, 09Eh, 09Fh | ||
| 85 | db 0A0h, 0A1h, 0A2h, 0A3h, 0A4h, 0A5h, 0A6h, 0A7h | ||
| 86 | db 0A8h, 0A9h, 0AAh, 0ABh, 0ACh, 0ADh, 0AEh, 0AFh | ||
| 87 | db 0B0h, 0B1h, 0B2h, 0B3h, 0B4h, 0B5h, 0B6h, 0B7h | ||
| 88 | db 0B8h, 0B9h, 0BAh, 0BBh, 0BCh, 0BDh, 0BEh, 0BFh | ||
| 89 | db 0C0h, 0C1h, 0C2h, 0C3h, 0C4h, 0C5h, 0C6h, 0C7h | ||
| 90 | db 0C8h, 0C9h, 0CAh, 0CBh, 0CCh, 0CDh, 0CEh, 0CFh | ||
| 91 | db 0D0h, 0D1h, 0D2h, 0D3h, 0D4h, 0D5h, 0D6h, 0D7h | ||
| 92 | db 0D8h, 0D9h, 0DAh, 0DBh, 0DCh, 0DDh, 0DEh, 0DFh | ||
| 93 | db 0E0h, 0E1h, 0E2h, 0E3h, 0E4h, 0E5h, 0E6h, 0E7h | ||
| 94 | db 0E8h, 0E9h, 0EAh, 0EBh, 0ECh, 0EDh, 0EEh, 0EFh | ||
| 95 | db 0F0h, 0F1h, 0F2h, 0F3h, 0F4h, 0F5h, 0F6h, 0F7h | ||
| 96 | db 0F8h, 0F9h, 0FAh, 0FBh, 0FCh, 0FDh, 0FEh, 0FFh | ||
| 97 | |||
| 98 | sEnd | ||
| 99 | |||
| 100 | end | ||