Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

924 lines
17 KiB

4 years ago
  1. /* dos prompting-style user interface
  2. **
  3. ** currently supports interfaces for:
  4. ** masm, cref
  5. **
  6. ** written by:
  7. ** randy nevin, microsoft, 5/15/85
  8. **
  9. ** 10/90 - Quick conversion to 32 bit by Jeff Spencer
  10. **
  11. ** (c)copyright microsoft corp 1985
  12. */
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. #if defined OS2_2 || defined OS2_NT /* OS2 2.0 or NT? */
  17. /* Use common MSDOS code also */
  18. # define MSDOS
  19. # define FLATMODEL
  20. # define FAR
  21. # define PASCAL
  22. #else
  23. # define FAR far
  24. # define PASCAL pascal
  25. #endif
  26. #ifdef MSDOS
  27. # include <dos.h>
  28. #endif
  29. #ifdef MASM
  30. # include "asmmsg.h"
  31. #else
  32. # include "crefmsg.h"
  33. #endif
  34. #define GLOBAL /* C functions and external vars global by default */
  35. #define LOCAL static
  36. #define EXTERNAL extern
  37. #define MASTER 0 /* file name must be present, and is inherited */
  38. #define INHERIT 1 /* if no file name, inherit from Master */
  39. #define NUL 2 /* file name is NUL.ext if not given */
  40. #define NULL 0
  41. #define SLASHORDASH 0
  42. #define SLASHONLY 1
  43. #define DASHONLY 2
  44. #define TOLOWER(c) (c | 0x20) /* works only for alpha inputs */
  45. #ifdef MSDOS
  46. # define SEPARATOR '\\'
  47. # define ALTSEPARATOR '/'
  48. # if !defined CPDOS && !defined OS2_2 && !defined OS2_NT
  49. # define ARGMAX 128 /* maximum length of all arguments */
  50. # else
  51. # define ARGMAX 512 /* maximum length of all arguments */
  52. # endif
  53. LOCAL char Nul[] = "NUL";
  54. extern char *getenv();
  55. # ifdef MASM
  56. LOCAL unsigned char switchar = SLASHORDASH;
  57. EXTERNAL errorcode;
  58. # else
  59. LOCAL unsigned char switchar = SLASHONLY;
  60. # endif
  61. # define ERRFILE stdout
  62. #else
  63. # define SEPARATOR '/'
  64. # define ARGMAX 5120 /* maximum length of all arguments */
  65. LOCAL char Nul[] = "nul";
  66. LOCAL unsigned char switchar = DASHONLY;
  67. # define ERRFILE stderr
  68. #endif
  69. #if defined MSDOS && !defined FLATMODEL
  70. extern char near * pascal __NMSG_TEXT();
  71. extern char FAR * pascal __FMSG_TEXT();
  72. #endif
  73. #if defined MSDOS && defined FLATMODEL
  74. /* For FLATMODEL map message functions to the replacements */
  75. #define __NMSG_TEXT NMsgText
  76. #define __FMSG_TEXT FMsgText
  77. extern char * NMsgText();
  78. extern char * FMsgText();
  79. #endif
  80. #ifdef MASM
  81. # define FILES 4 /* number to prompt for */
  82. # define EX_HEAP 8 /* exit code if heap fails */
  83. #define EX_DSYM 10 /* error defining symbol from command line */
  84. #define PX87 1
  85. #define CVLINE 1
  86. #define CVSYMBOLS 2
  87. #define TERMINATE(message, exitCode)\
  88. terminate((exitCode << 12) | message)
  89. #define TERMINATE1(message, exitCode, a1)\
  90. terminate((exitCode << 12) | message, a1)
  91. # ifdef MSDOS
  92. LOCAL char *Prompt[FILES] = {
  93. "Source filename [",
  94. "Object filename [",
  95. "Source listing [",
  96. "Cross-reference ["
  97. };
  98. # endif
  99. LOCAL char *Ext[FILES] = { /* default extensions */
  100. # ifdef MSDOS
  101. ".ASM",
  102. ".OBJ",
  103. ".LST",
  104. ".CRF"
  105. # else
  106. ".asm",
  107. ".obj",
  108. ".lst",
  109. ".crf"
  110. # endif
  111. };
  112. LOCAL unsigned char Default[FILES] = { /* default root file name */
  113. MASTER,
  114. INHERIT,
  115. NUL,
  116. NUL
  117. };
  118. #endif
  119. #ifdef CREF
  120. # define FILES 2 /* number to prompt for */
  121. # define EX_HEAP 1 /* exit code if heap fails */
  122. # ifdef MSDOS
  123. LOCAL char *Prompt[FILES] = {
  124. "Cross-reference [",
  125. "Listing ["
  126. };
  127. # endif
  128. LOCAL char *Ext[FILES] = { /* default extensions */
  129. # ifdef MSDOS
  130. ".CRF",
  131. ".REF"
  132. # else
  133. ".crf",
  134. ".ref"
  135. # endif
  136. };
  137. LOCAL unsigned char Default[FILES] = { /* default root file name */
  138. MASTER,
  139. INHERIT
  140. };
  141. #endif
  142. GLOBAL char *file[FILES]; /* results show up here; caller knows how many */
  143. LOCAL char *Buffer;
  144. LOCAL char *Master = NULL;
  145. LOCAL unsigned char Nfile = 0; /* file[Nfile] is the next one to set */
  146. LOCAL unsigned char FirstLine = 1; /* defaults are different for first line */
  147. extern unsigned short warnlevel; /* warning level */
  148. extern unsigned short codeview; /* codeview obj level */
  149. extern char loption; /* listing options */
  150. extern char crefopt; /* cross reference options */
  151. #ifdef MSDOS
  152. # if defined OS2_2 || defined OS2_NT
  153. /* OS2 2.0 command line variables will go here */
  154. # else
  155. # if defined CPDOS
  156. /* OS2 1.X variables */
  157. EXTERNAL unsigned _aenvseg;
  158. EXTERNAL unsigned _acmdln;
  159. # else
  160. /* DOS variables */
  161. EXTERNAL unsigned _psp; /* segment addr of program segment prefix */
  162. # endif
  163. # endif
  164. #endif
  165. #ifdef MASM
  166. LOCAL unsigned char lflag = 0;
  167. LOCAL unsigned char cflag = 0;
  168. EXTERNAL char terse;
  169. EXTERNAL unsigned short errornum;
  170. EXTERNAL char lbuf[256 + 512 + 1];
  171. void PASCAL error_line (struct _iobuf *, unsigned char *, short);
  172. #else
  173. char lbuf[512];
  174. #endif
  175. #ifndef MSDOS
  176. EXTERNAL char *gets();
  177. #endif
  178. EXTERNAL char *malloc();
  179. EXTERNAL char *strcat(), *strcpy(), *_strdup(), *strchr(), *strrchr();
  180. LOCAL int DoArgs(); /* defined below */
  181. LOCAL int DoName(); /* defined below */
  182. LOCAL int DoNull(); /* defined below */
  183. LOCAL char *DoSwitch(); /* defined below */
  184. LOCAL HeapError(); /* defined below */
  185. #ifdef MSDOS
  186. LOCAL DoPrompt(); /* defined below */
  187. LOCAL TryAgain(); /* defined below */
  188. #endif
  189. GLOBAL void
  190. UserInterface (
  191. /* get file names & switches from args and subsequent prompts */
  192. int argc,
  193. char **argv,
  194. char *banner
  195. ){
  196. register char *p;
  197. register unsigned length;
  198. #if defined MSDOS && !defined OS2_2 && !defined OS2_NT
  199. char FAR *q;
  200. #else
  201. unsigned count;
  202. #endif
  203. Buffer = lbuf;
  204. #ifdef MASM
  205. # ifdef MSDOS
  206. if ((p = getenv("MASM"))) { /* do initialization vars first */
  207. strcpy( Buffer, p ); /* fetch them into the buffer */
  208. DoArgs(); /* process them */
  209. }
  210. # endif
  211. #endif
  212. p = Buffer;
  213. #if defined MSDOS && !defined OS2_2 && !defined OS2_NT
  214. #if defined CPDOS
  215. /* this is how we get the command line if we're on CPDOS */
  216. FP_SEG( q ) = _aenvseg;
  217. FP_OFF( q ) = _acmdln;
  218. while(*q++) ; /* skip argv[0] */
  219. while (isspace( *q )) /* skip blanks between argv[0] and argv[1] */
  220. q++;
  221. length = sizeof(lbuf) - 1;
  222. while (length-- && (*p++ = *q++)) /* copy command line arguments */
  223. ;
  224. # else
  225. /* this is how we get the command line if we're on MSDOS */
  226. FP_SEG( q ) = _psp;
  227. FP_OFF( q ) = 0x80;
  228. length = *q++ & 0xFF;
  229. while (length--)
  230. *p++ = *q++;
  231. *p = '\0';
  232. # endif
  233. #else
  234. /* this is how we get the command line if we're on XENIX or OS2 2.0 */
  235. argv++;
  236. count = ARGMAX - 1;
  237. while (--argc) { /* concatenate args */
  238. if ((length = strlen( *argv )) > count) /* don't overflow */
  239. length = count;
  240. strncpy( p, *argv++, length );
  241. p += length;
  242. if ((count -= length) && *argv) { /* separator */
  243. *p++ = ' ';
  244. count--;
  245. }
  246. }
  247. # if !defined OS2_2 && !defined OS2_NT
  248. *p++ = ';';
  249. # endif
  250. *p = '\0';
  251. #endif
  252. #ifdef CREF
  253. printf( "%s", banner );
  254. #endif
  255. DoArgs();
  256. #ifdef MASM
  257. if (!terse)
  258. printf( "%s", banner );
  259. #endif
  260. #ifdef MSDOS
  261. FirstLine = 0;
  262. while (Nfile < FILES)
  263. DoPrompt();
  264. #endif
  265. if (Master && Master != Nul)
  266. free( Master );
  267. }
  268. LOCAL int
  269. DoArgs ()
  270. /* process concatenated args looking for file names and switches */
  271. {
  272. register char *p;
  273. register char *q;
  274. char *filename = NULL;
  275. for (p = Buffer; *p; p++)
  276. #ifdef MSDOS
  277. if (*p == '/'
  278. && (switchar == SLASHONLY || switchar == SLASHORDASH)
  279. || *p == '-'
  280. && (switchar == DASHONLY || switchar == SLASHORDASH))
  281. #else
  282. if (*p == '-')
  283. #endif
  284. { /* application dependent switch */
  285. #ifdef MSDOS
  286. if (switchar == SLASHORDASH)
  287. switchar = *p == '/' ? SLASHONLY : DASHONLY;
  288. #endif
  289. p = DoSwitch( p );
  290. }
  291. else if (*p == ';') { /* use defaults for everything else */
  292. if (DoName( filename )) { /* possibly NULL */
  293. #ifdef MSDOS
  294. TryAgain();
  295. return( 1 );
  296. #else
  297. # ifdef MASM
  298. printf( __NMSG_TEXT(ER_EXS) );
  299. # else
  300. printf( __NMSG_TEXT(ER_EXC) );
  301. # endif
  302. exit( 1 );
  303. #endif
  304. }
  305. FirstLine = 0; /* ...and away we go! */
  306. while (Nfile < FILES)
  307. if (DoNull()) {
  308. #ifdef MSDOS
  309. TryAgain();
  310. return( 1 );
  311. #else
  312. # ifdef MASM
  313. printf( __NMSG_TEXT(ER_EXS) );
  314. # else
  315. printf( __NMSG_TEXT(ER_EXC) );
  316. # endif
  317. exit( 1 );
  318. #endif
  319. }
  320. return( 0 );
  321. }
  322. else if (*p == ',') { /* file name separator */
  323. if (DoName( filename )) { /* possibly NULL */
  324. #ifdef MSDOS
  325. TryAgain();
  326. return( 1 );
  327. #else
  328. # ifdef MASM
  329. printf( __NMSG_TEXT(ER_EXS) );
  330. # else
  331. printf( __NMSG_TEXT(ER_EXC) );
  332. # endif
  333. exit( 1 );
  334. #endif
  335. }
  336. filename = NULL;
  337. }
  338. else if (!isspace( *p )) { /* gather filename */
  339. q = p + 1;
  340. while (*q && *q != ';' && *q != ',' && !isspace( *q )) {
  341. #ifdef MSDOS
  342. if (*q == '/')
  343. if (switchar == SLASHONLY)
  344. break;
  345. else if (switchar == SLASHORDASH) {
  346. switchar = SLASHONLY;
  347. break;
  348. }
  349. #endif
  350. q++;
  351. }
  352. if (filename) { /* already have one */
  353. if (DoName( filename )) {
  354. #ifdef MSDOS
  355. TryAgain();
  356. return( 1 );
  357. #else
  358. # ifdef MASM
  359. printf( __NMSG_TEXT(ER_EXS) );
  360. # else
  361. printf( __NMSG_TEXT(ER_EXC) );
  362. # endif
  363. exit( 1 );
  364. #endif
  365. }
  366. }
  367. if (!(filename = malloc( q - p + 1 )))
  368. HeapError();
  369. else { /* remember file name */
  370. strncpy( filename, p, q - p );
  371. filename[q - p] = '\0';
  372. }
  373. p = q - 1; /* go to end of file name */
  374. }
  375. if (filename && DoName( filename )) {
  376. #ifdef MSDOS
  377. TryAgain();
  378. return( 1 );
  379. #else
  380. # ifdef MASM
  381. printf( __NMSG_TEXT(ER_EXS) );
  382. # else
  383. printf( __NMSG_TEXT(ER_EXC) );
  384. # endif
  385. exit( 1 );
  386. #endif
  387. }
  388. return( 0 );
  389. }
  390. LOCAL int
  391. DoName ( filename )
  392. /* enter filename as next file name, if appropriate (possibly NULL) */
  393. char *filename;
  394. {
  395. register char *p;
  396. register char *q;
  397. int cb;
  398. if (Nfile >= FILES) { /* too many file names */
  399. if (filename) {
  400. fprintf(ERRFILE,__NMSG_TEXT(ER_EXT) );
  401. free( filename );
  402. }
  403. return( 0 );
  404. }
  405. if (!filename) /* try (MASTER)/INHERIT/NUL */
  406. return( DoNull() );
  407. if (p = strrchr( filename, SEPARATOR ))
  408. p++;
  409. #ifdef MSDOS
  410. else if ((p = strrchr( filename, ':' )) && /* look for drive specifier */
  411. p[1] != NULL )
  412. p++;
  413. #endif
  414. else
  415. p = filename;
  416. #ifdef MSDOS
  417. if (q = strrchr( p, ALTSEPARATOR ))
  418. p = q + 1;
  419. #endif
  420. /* p points to first char of filename past last '\' or ':', if any */
  421. if (!*p) /* last char of filename is '\' or ':'; assume directory */
  422. switch (Default[Nfile]) {
  423. case MASTER:
  424. #ifdef MSDOS
  425. fprintf(ERRFILE,__NMSG_TEXT(ER_INV) );
  426. #endif
  427. free( filename );
  428. return( 1 );
  429. break;
  430. default:
  431. /* case NUL: */
  432. #ifdef MSDOS
  433. if (!FirstLine) {
  434. if (!(p = malloc( strlen( filename )
  435. + strlen( Nul )
  436. + strlen( Ext[Nfile] ) + 1 )))
  437. HeapError();
  438. strcat( strcat( strcpy( p, filename ), Nul ), Ext[Nfile] );
  439. break;
  440. }
  441. /* else just treat as inherited from Master */
  442. #endif
  443. case INHERIT:
  444. if (!Master)
  445. Master = Nul;
  446. if (!(p = malloc( strlen( filename )
  447. + strlen( Master )
  448. + strlen( Ext[Nfile] ) + 1 )))
  449. HeapError();
  450. strcat( strcat( strcpy( p, filename ), Master ), Ext[Nfile] );
  451. break;
  452. }
  453. else { /* some sort of file name is present */
  454. if (Default[Nfile] == MASTER) /* save Master file name */
  455. if (q = strchr( p, '.' )) {
  456. if (!(Master = malloc( q - p + 1 )))
  457. HeapError();
  458. strncpy( Master, p, q - p );
  459. Master[q - p] = '\0';
  460. }
  461. else if (!(Master = _strdup( p )))
  462. HeapError();
  463. if (strchr( p, '.' )) { /* extension present */
  464. if (!(p = _strdup( filename )))
  465. HeapError();
  466. }
  467. else { /* supply default extension */
  468. cb = 0;
  469. if (p[1] == ':' && p[2] == NULL)
  470. cb = strlen(Master);
  471. if (!(p = malloc( strlen( filename )
  472. + strlen( Ext[Nfile] ) + 1 + cb ) ))
  473. HeapError();
  474. strcat(strcat(strcpy( p,
  475. filename ),
  476. (cb)? Master: ""),
  477. Ext[Nfile] );
  478. }
  479. }
  480. file[Nfile++] = p;
  481. free( filename );
  482. return( 0 );
  483. }
  484. LOCAL int
  485. DoNull ()
  486. /* select the default name (depends on if FirstLine or not) */
  487. {
  488. char *p;
  489. switch (Default[Nfile]) {
  490. case MASTER:
  491. #ifdef MSDOS
  492. fprintf(ERRFILE,__NMSG_TEXT(ER_INV) );
  493. #endif
  494. return( 1 );
  495. break;
  496. default:
  497. /* case NUL: */
  498. if (!FirstLine
  499. #ifdef MASM
  500. && !(lflag && Nfile == 2)
  501. && !(cflag && Nfile == 3)
  502. #endif
  503. ) {
  504. if (!(p = malloc( strlen( Nul ) + 1
  505. + strlen( Ext[Nfile] ) )))
  506. HeapError();
  507. strcat( strcpy( p, Nul ), Ext[Nfile] );
  508. break;
  509. }
  510. /* else just treat as inherited from Master */
  511. case INHERIT:
  512. if (!Master)
  513. Master = Nul;
  514. if (!(p = malloc( strlen( Master ) + 1
  515. + strlen( Ext[Nfile] ) )))
  516. HeapError();
  517. strcat( strcpy( p, Master ), Ext[Nfile] );
  518. break;
  519. }
  520. file[Nfile++] = p;
  521. return( 0 );
  522. }
  523. #ifdef MASM
  524. # define FALSE 0
  525. # define TRUE 1
  526. #ifdef MSDOS
  527. # define DEF_OBJBUFSIZ 8
  528. #endif
  529. # define CASEU 0
  530. # define CASEL 1
  531. # define CASEX 2
  532. # define INCLUDEMAX 10
  533. # define EX_ARGE 1
  534. # ifdef MSDOS
  535. EXTERNAL unsigned short obufsiz;
  536. # endif
  537. EXTERNAL char segalpha;
  538. EXTERNAL char debug;
  539. EXTERNAL char fltemulate;
  540. EXTERNAL char X87type;
  541. EXTERNAL char inclcnt;
  542. EXTERNAL char *inclpath[];
  543. EXTERNAL char caseflag;
  544. EXTERNAL char dumpsymbols;
  545. EXTERNAL char verbose;
  546. EXTERNAL char origcond;
  547. EXTERNAL char listconsole;
  548. EXTERNAL char checkpure;
  549. int PASCAL definesym();
  550. /* process masm switches */
  551. LOCAL char * DoSwitch ( p )
  552. register char *p;
  553. {
  554. char *q;
  555. char *r;
  556. char c;
  557. int i;
  558. switch (TOLOWER(*++p)) {
  559. case 'a':
  560. segalpha = TRUE;
  561. break;
  562. # ifdef MSDOS
  563. case 'b':
  564. for(p++; isdigit(p[1]); p++);
  565. break;
  566. # endif
  567. case 'c':
  568. cflag = TRUE;
  569. if (isalpha (p[1])) {
  570. if (TOLOWER(*++p) == 's')
  571. crefopt++;
  572. else {
  573. TERMINATE1(ER_UNS, EX_ARGE, *p );
  574. return;
  575. }
  576. }
  577. break;
  578. case 'd':
  579. if (!*++p || isspace( *p ) || *p == ',' || *p == ';') {
  580. debug = TRUE;
  581. p--;
  582. }
  583. else {
  584. for (q = p + 1; *q && !isspace( *q )
  585. && *q != '=' && *q != ','
  586. && *q != ';'; q++)
  587. ;
  588. if (*q == '=') {
  589. q++;
  590. while (*q && !isspace( *q )
  591. && *q != ',' && *q != ';')
  592. q++;
  593. }
  594. c = *q;
  595. *q = '\0';
  596. definesym( p );
  597. if (errorcode){
  598. error_line (ERRFILE, "command line", 0);
  599. if (errornum)
  600. exit (EX_DSYM);
  601. }
  602. *q = c;
  603. p = q - 1;
  604. }
  605. break;
  606. case 'e':
  607. fltemulate = TRUE;
  608. X87type = PX87;
  609. break;
  610. case 'h':
  611. #ifdef FLATMODEL
  612. printf("%s\n", __FMSG_TEXT(ER_HDUSE));
  613. #else
  614. printf("%Fs\n", __FMSG_TEXT(ER_HDUSE));
  615. #endif
  616. for (i = ER_H01; i <= ER_H18; i++)
  617. #ifdef FLATMODEL
  618. printf( "\n/%s", __FMSG_TEXT(i));
  619. #else
  620. printf( "\n/%Fs", __FMSG_TEXT(i));
  621. #endif
  622. exit( 0 ); /* let him start again */
  623. break;
  624. case 'i':
  625. for (q = ++p; *q &&
  626. !isspace( *q ) && *q != ',' && *q != ';' &&
  627. *q != (switchar == DASHONLY? '-': '/'); q++)
  628. ;
  629. if (q == p)
  630. TERMINATE(ER_PAT, EX_ARGE );
  631. if (inclcnt < INCLUDEMAX - 1) {
  632. if (!(r = malloc( q - p + 1 )))
  633. HeapError();
  634. strncpy( r, p, q - p );
  635. r[q - p] = '\0';
  636. inclpath[inclcnt++] = r;
  637. }
  638. p = q - 1;
  639. break;
  640. case 'l':
  641. lflag = TRUE;
  642. if (isalpha (p[1])) {
  643. if (TOLOWER(*++p) == 'a')
  644. loption++;
  645. else {
  646. TERMINATE1(ER_UNS, EX_ARGE, *p );
  647. return;
  648. }
  649. }
  650. break;
  651. case 'm':
  652. switch (TOLOWER(*++p)) {
  653. case 'l':
  654. caseflag = CASEL;
  655. break;
  656. case 'u':
  657. caseflag = CASEU;
  658. break;
  659. case 'x':
  660. caseflag = CASEX;
  661. break;
  662. default:
  663. TERMINATE1(ER_UNC, EX_ARGE, *p );
  664. return;
  665. }
  666. break;
  667. case 'n':
  668. dumpsymbols = FALSE;
  669. break;
  670. case 'p':
  671. checkpure = TRUE;
  672. break;
  673. case 'r': /* old switch ignored */
  674. break;
  675. case 's':
  676. segalpha = FALSE;
  677. break;
  678. case 't':
  679. terse = TRUE;
  680. verbose = FALSE;
  681. break;
  682. case 'v':
  683. verbose = TRUE;
  684. terse = FALSE;
  685. break;
  686. case 'w':
  687. if (! isdigit(p[1]) ||
  688. (warnlevel = atoi(&p[1])) > 2){
  689. TERMINATE(ER_WAN, EX_ARGE );
  690. return;
  691. }
  692. for(p++; isdigit(p[1]); p++);
  693. break;
  694. case 'x':
  695. origcond = TRUE;
  696. break;
  697. case 'z': /* Zd or Zi apply to codeview */
  698. if (TOLOWER(p[1]) == 'd'){
  699. codeview = CVLINE;
  700. p++;
  701. break;
  702. }
  703. else if (TOLOWER(p[1]) == 'i'){
  704. codeview = CVSYMBOLS;
  705. p++;
  706. break;
  707. }
  708. /* else its just a Z */
  709. listconsole = TRUE;
  710. break;
  711. default:
  712. TERMINATE1(ER_UNS, EX_ARGE, *p );
  713. return;
  714. }
  715. return( p );
  716. }
  717. #endif
  718. #ifdef CREF
  719. LOCAL char *
  720. DoSwitch ( /* p */ )
  721. /* process cref switches (presently, none) */
  722. /* char *p; */
  723. {
  724. fprintf( stderr, "cref has no switches\n" );
  725. exit( 1 );
  726. }
  727. #endif
  728. #ifdef MSDOS
  729. LOCAL
  730. DoPrompt ()
  731. /* prompt user for a file name (any number of optional switches) */
  732. {
  733. unsigned char oldNfile;
  734. fprintf(stderr, Prompt[Nfile] );
  735. switch (Default[Nfile]) {
  736. case MASTER:
  737. break;
  738. case INHERIT:
  739. fprintf(stderr, Master );
  740. break;
  741. default:
  742. /* case NUL: */
  743. fprintf(stderr, Nul );
  744. break;
  745. }
  746. fprintf(stderr, "%s]: ", Ext[Nfile] );
  747. if (!gets( Buffer )) {
  748. fprintf(ERRFILE,__NMSG_TEXT(ER_SIN) );
  749. # ifdef MASM
  750. exit( EX_ARGE );
  751. # else
  752. exit( 1 );
  753. # endif
  754. }
  755. oldNfile = Nfile;
  756. if (!DoArgs() && oldNfile == Nfile && DoNull())
  757. TryAgain();
  758. }
  759. #endif
  760. LOCAL
  761. HeapError ()
  762. /* malloc() has failed; exit program */
  763. {
  764. #ifdef CREF
  765. fprintf(ERRFILE,__NMSG_TEXT(ER_HEP));
  766. exit(EX_HEAP);
  767. #else
  768. TERMINATE(ER_HEP, EX_HEAP);
  769. #endif
  770. }
  771. #ifdef MSDOS
  772. LOCAL
  773. TryAgain ()
  774. /* user caused fatal error; start reprompting from beginning */
  775. {
  776. if (Master && Master != Nul) {
  777. free( Master );
  778. Master = NULL;
  779. }
  780. while (Nfile)
  781. free( file[--Nfile] );
  782. }
  783. #endif