/** * * print * * CLI PRINT command * Version 1.2 * * (c) 1988 by John F. Zacharias, All rights reserved * * Permission granted for use by non-profit, non-commercial user * provided above copyright notice and these restrictions are * included with any copy. Any for profit use or use by a commericial * enterprise is strictly forbidden unless proper arrangements are * made with the author. * * This program is intended to run only under CLI. The CLI command line * syntax is: * * print {-i} file-name {...file-name} {rp=n} {OPT H | N | S} * * parameters: * * -i perform printer initialization (sets printer to Preferences * specifications). * * file-name the name of the file or directory to print. * * rp= start printing at page number n. This allows you to skip * over a portion of a printout they may have previously * been printed. The "rp=" applies ONLY to the filename that * precedes it. * * OPT H Printout is in hexadecimal. * * OPT N Sequence number each line of the printout. * * OPT S Show all control characters and printer ESC sequences. * * NOTE: multiple OPT operands can be given - any one option operand will * apply to all files that preceed that option operand. As an example: * * print file-1 opt h file-2 opt n file 3 * * will print file-1 in hex, file-2 with sequence numbers, and file-3 * without sequence numbers. * * MODIFIED FOR WORKBENCH 1.3 * * NOTICE: This program can not be used as a 'resident' command. It is not * re-entrant. * * THIS FILE IS WRITTEN FOR LATTICE V. 4.01 * **/ #include #include #include #include #include #define MAXFILES 25 /* change if different # files wanted */ #define TOP_MARGIN 4 /* number lines at top of page */ #define DIRLNSZ 76 /* size of full directory line */ #define DIRHD_LINES 14 /* body = page size minus this (files) */ #define FILHD_LINES 12 /* body = page size minus this (dir) */ #define EJECT -1 /* Eject code returned by GET_LINE() */ #define PARLINE -2 /* Partial line code rtrnd by GET_LINE() */ struct Dir_Entry { struct Dir_Entry *de_left; struct Dir_Entry *de_right; struct Dir_Entry *de_root; long de_Type; long de_Protect; long de_Size; long de_Blocks; struct DateStamp de_Date; char de_Name[32]; }; /* structure used to define each directory entry */ extern long IntuitionBase; /* global intuition base variable */ extern char *_ProgramName; /* Program Name */ extern int (*_ONBREAK)(); /* ONBREAK routine */ struct Preferences Prefs; /* for looking at preferences */ struct InfoData DiskInfo; /* for looking at disk volume info */ struct FileInfoBlock Fib; /* for looking at File Information Block */ struct DateStamp FileDate; /* for looking at file date/time */ struct DateStamp SysDate; /* for looking at system date/time */ static struct IntuiText Text1 = {-1,-1, 0, 16,14, NULL, "** Abort Current Print-Out? **", NULL}; static struct IntuiText Text2 = {-1,-1, 0, 16,14, NULL, "** Go on to next File? **", NULL}; static struct IntuiText NameText = {-1,-1, 0, 6,4, NULL, NULL, NULL}; static struct IntuiText NoText = {-1,-1, 0, 8,4, NULL, "NO", NULL}; static struct IntuiText YesText = {-1,-1, 0, 8,4, NULL, "YES", NULL}; /* Global Variables - accessed by more than one function */ long FileProtect, FileSize, FileBlocks; FILE *Prt; FILE *Inp; unsigned int SeqNo; int lmargn, lnsz, pgsz, lncnt, Abort_Print, nfiles; int nmbrfiles = 0; int page_no = 0; int init_prtr = 0; char heading_buf[132]; char FullPath[160]; char FileComments[80]; char FileName[MAXFILES][160]; char Option[MAXFILES]; #define HEX 'h' #define LINENOS 'n' #define SHOW 's' int StartPage[MAXFILES]; int ResetPage[MAXFILES]; int PrintType[MAXFILES]; #define HAVE_FILE -1 #define HAVE_DIR 1 void main(argc, argv) int argc; char *argv[]; { int PRTBRK(); printf("PRINT v 1.2\n"); printf("Copyright (c) 1988 by John F. Zacharias, All Rights Reserved\n"); IntuitionBase = OpenLibrary("intuition.library",0); if (IntuitionBase == NULL) { printf("Can't open Intuition Library\n"); exit(1); } GetPrefs(&Prefs,sizeof(Prefs)); lmargn = Prefs.PrintLeftMargin; lnsz = Prefs.PrintRightMargin-Prefs.PrintLeftMargin+1; pgsz = Prefs.PaperLength; getargs(argc,argv); /* showargs(); /* TEMPORARY for testing */ if ((Prt = fopen("PRT:","w")) == NULL) { printf(">> Printer can't be opened <<\n"); exit(1); } if (init_prtr) fputs("\x1b#1",Prt); _ONBREAK = PRTBRK; /* Set up break processing routine */ for(nfiles=1; nfiles <= nmbrfiles; nfiles++){ Abort_Print = 0; if (PrintType[nfiles] == HAVE_FILE) print_files(nfiles); if (PrintType[nfiles] == HAVE_DIR) print_directory(nfiles); } fclose(Prt); rbrk(); exit(0); } getargs(argc,argv) int argc; char *argv[]; { int ftype; int argn = 0; int n = 1; char opt; if (argc < 2) printf("ERROR: no arguements given\n"); while(argc-- > 1) { argn++; if (stricmp(argv[argn],"-i") == 0) { init_prtr = 1; continue; } if (strnicmp(argv[argn],"rp=",3) == 0) { if (nmbrfiles == 0) { printf("ERROR: Starting page must follow filename\n"); exit(1); } if (sscanf(argv[argn],"rp=%d", &StartPage[nmbrfiles]) != 1) { printf("ERROR: Incorrect starting page number\n"); exit(1); } continue; } if (stricmp(argv[argn],"opt") == 0) { if (--argc < 1) { printf("ERROR: No option given\n"); exit(1); } if (strlen(argv[++argn]) > 1) { printf("ERROR: Option '%c' invalid combination\n", argv[argn]); exit(1); } strlwr(argv[argn]); opt = *argv[argn]; if (((opt == HEX) || (opt == LINENOS) || (opt == SHOW)) == 0) { printf("ERROR: '%c' is an invalid option\n", opt); exit(1); } for(;n <= nmbrfiles; n++) Option[n] = opt; continue; } ftype = getfa(argv[argn]); if (ftype != NULL) { nmbrfiles++; strcpy(FileName[nmbrfiles],argv[argn]); PrintType[nmbrfiles] = ftype; StartPage[nmbrfiles] = 0; } else printf("%s does not exist\n",argv[argn]); } return(0); } print_files(fileno) int fileno; { int lnend, newline, textsz, mode; /* * mode = 0 (text display), 1 (hex display) * newline = 0 (continuation line), 1 (start of line) * lnend = 0 (end of file) * + (size of line if line feed encountered) * -1 (EJECT encountered - TEXT only!) * -2 (line size reached, no line feed - TEXT only!) * */ char inbuf[182], date[50]; page_no = 1; set_header(heading_buf,fileno); lncnt = pgsz - FILHD_LINES; if (page_no >= StartPage[fileno]) { skip_lines(TOP_MARGIN); fprintf(Prt,heading_buf,page_no); ConvertDate(&FileDate,date,1); fprintf(Prt,"\nThe file was last updated on %s\n",date); fprintf(Prt,"The file size is %d bytes (%d blocks)\n",FileSize,FileBlocks); fprintf(Prt,"File protection status: "); Set_Protect(FileProtect); fputs(" allowed\n",Prt); fprintf(Prt,"File comments are: %s\n",FileComments); DateStamp(&SysDate); ConvertDate(&SysDate,date,1); fprintf(Prt,"\nThis file is being printed on %s\n",date); line_across(); skip_lines(2); } lncnt = lncnt - 8; if ((Inp = fopen(FileName[fileno],"r")) == NULL) { printf("Cannot open file %s\n",FileName[fileno]); fprintf(Prt,"CANNOT OPEN FILE TO PRINT\n\f"); return(0); } mode = 0; newline = 1; /* indicate start of new line */ SeqNo = 0; textsz = lnsz; if (Option[fileno] == LINENOS) textsz = lnsz-7; if (Option[fileno] == HEX) { textsz = 16; mode = 1; } while ((lnend = get_line(inbuf,textsz,mode,Option[fileno]))) { if (Abort_Print) { fprintf(Prt,"\n>>> PRINTOUT ABORTED WITH CONTROL C <<<\n"); break; } if ((lnend == EJECT) && (*inbuf == 0)) { newline = 1; lncnt = 0; continue; } if (newline || (lncnt < -3)) { if (lncnt <= 0) { if (page_no >= StartPage[fileno]) putc('\f',Prt); if (++page_no >= StartPage[fileno]) { skip_lines(TOP_MARGIN); fprintf(Prt,heading_buf,page_no); line_across(); skip_lines(2); } lncnt = pgsz - FILHD_LINES; } } if (mode) newline = lnend-1; print_line(inbuf,newline,fileno); lncnt--; newline = 1; /* indicate start of line for next line */ if (lnend == PARLINE) newline = 0; /* next not start */ if (lnend == EJECT) lncnt = 0; } putc('\f',Prt); fclose(Inp); return(0); } Set_Protect(fp) long fp; { if (fp & 128) putc('-',Prt); else putc('-',Prt); if (fp & 64) putc('s',Prt); else putc('-',Prt); if (fp & 32) putc('p',Prt); else putc('-',Prt); if (fp & 16) putc('a',Prt); else putc('-',Prt); if (fp & 8) putc('-',Prt); else putc('r',Prt); if (fp & 4) putc('-',Prt); else putc('w',Prt); if (fp & 2) putc('-',Prt); else putc('e',Prt); if (fp & 1) putc('-',Prt); else putc('d',Prt); return(0); } set_header(buf,fileno) char *buf; int fileno; { char l,*p; get_path(fileno); p = stpcpy(buf,"FILE: "); if (PrintType[fileno] == HAVE_DIR) { p = stpcpy(buf,"DIRECTORY: "); } l = strlen(FullPath); p = p + stccpy(p,FullPath,lnsz-15) - 1; while(p < buf+lnsz-8) *p++=' '; stpcpy(p,"Page %3d\n"); return(0); } get_path(fileno) int fileno; { long file_lock,new_lock; char *p; file_lock = Lock(FileName[fileno],ACCESS_READ); if (file_lock == NULL) { printf("Can't get File Lock for %s\n",FileName[fileno]); exit(1); } if (Info(file_lock,&DiskInfo) == NULL) { printf("Cannot get volume information for %s\n", FileName[fileno]); exit(1); } if (Examine(file_lock,&Fib) == NULL) { printf("Cannot get FIB for %s\n",FileName[fileno]); exit(1); } strcpy(FullPath,Fib.fib_FileName); FileProtect = Fib.fib_Protection; FileSize = Fib.fib_Size; FileBlocks = Fib.fib_NumBlocks; FileDate.ds_Days = Fib.fib_Date.ds_Days; FileDate.ds_Minute = Fib.fib_Date.ds_Minute; FileDate.ds_Tick = Fib.fib_Date.ds_Tick; strcpy(FileComments,Fib.fib_Comment); while(new_lock = ParentDir(file_lock)) { if (Examine(new_lock,&Fib) == NULL) { printf("Cannot get parent FIB for %s\n",FullPath); return(0); } strins(FullPath,"/"); strins(FullPath,Fib.fib_FileName); UnLock(file_lock); file_lock = new_lock; } p = strchr(FullPath,'/'); if (p) { *p = ':'; return(0); } strcat(FullPath,":"); return(0); } ConvertDate(Date,datebuf,mode) struct DateStamp *Date; int mode; char *datebuf; { long t; int i, weekday, day, month, year, dmode; int tmode = 6; static int month_day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; char date_table[3]; char time_table[4]; char *p; static char *day_week[] = { "Sunday, ", "Monday, ", "Tuesday, ", "Wednesday, ", "Thursday, ", "Friday, ", "Saturday, " }; i = 2; t = Date->ds_Days; year = 0; month_day[2] = 29; weekday = t % 7; while(1) { while (i<4) { if (t<365) { month_day[2] = 28; break; } t = t - 365; year++; i++; if (year == 2100) i = 0; } if (t<366) break; t = t - 366; year++; i = 1; } i = 0; month = 0; while (t >= 0) { day = t + 1; t = t - month_day[++month]; } date_table[0] = year; date_table[1] = month; date_table[2] = day; time_table[0] = Date->ds_Minute / 60; time_table[1] = Date->ds_Minute % 60; time_table[2] = Date->ds_Tick / TICKS_PER_SECOND; time_table[3] = 0; p = datebuf; /* dmode = 2; if (mode) dmode = 5; * this was required for stpdate */ dmode = mode; if (mode) p = stpcpy(p,day_week[weekday]); p = astpdate(p,dmode,date_table); /* replaces stpdate */ if (mode) p = stpcpy(p," at "); else p = stpcpy(p," "); stptime(p,tmode,time_table); return(0); } skip_lines(nolines) int nolines; { while (nolines--) putc('\n',Prt); return(0); } print_line(inbuf,lnstrt,fn) int fn, lnstrt; char *inbuf; { if (Option[fn] == LINENOS) { if (lnstrt) { SeqNo++; if (page_no >= StartPage[fn]) fprintf(Prt,"%5d: %s\n",SeqNo,inbuf); return(1); } else { if (page_no >= StartPage[fn]) fprintf(Prt," %s\n",inbuf); return(1); } } if (page_no < StartPage[fn]) return(1); if (Option[fn] == HEX) { print_hexline(inbuf,lnstrt); return(1); } fprintf(Prt,"%s\n",inbuf); return(1); } line_across() { int i; i = 10; while (i--) fputc(' ',Prt); i = lnsz - 20; while (i--) fputc('-',Prt); i = 10; while (i--) fputc(' ',Prt); fputc('\n',Prt); return(0); } get_line(buf,sz,mode,opt) char *buf; int sz, mode; char opt; /* Mode is 0 for text display and 1 for hex display. * * Normally, this routine returns the size of the text placed in * the buffer. On text displays this occurs only when a line * feed ($0A) is encountered. * * If the "end of file" occurs a zero is returned. * * The following applies to text displays only: * * This routine returns EJECT (-1) if a line form ($0C) appears * in the text even if the buffer has data in it. * * This routine returns PARLINE (-2) if the line size passed as * "sz" is reached before a line feed is encountered. * * Binary zeros in text are ignored. * * If a carriage return ($0D) is encountered it is ignored if a * line feed is in the same sequence, otherwise the carriage * return is treated as a line feed. * * All other control sequences (ASCII 0 through 31) are displayed * with a ^ followed with a capitol character representing the * ASCII position. * */ { int l = 0; int cr = 0; int c; while (l < sz) { if ((c = fgetc(Inp)) == EOF) { *buf = 0; if (l == 0) return(0); ungetc(c,Inp); return(l+1); } if (mode == 0) { if (c > 127) c = c-128; if (c == '\n') { *buf = 0; return(l+1); } if (opt == SHOW) { if (c < 32) { if (l > sz-3) break; *buf++ = '^'; l++; c = c + 64; } } if (c == '\f') { *buf = 0; if ((c = fgetc(Inp)) != '\n') ungetc(c,Inp); return(EJECT); } if (c == 13) { cr = 1; continue; } if (cr && l) { *buf = 0; ungetc(c,Inp); return(l+1); } cr = 0; if (c == 8) { if (l == 0) continue; l--; *buf-- = 0; continue; } if (c == 27) { if (byp_esc() == 0) { *buf = 0; if (l == 0) return(0); ungetc(c,Inp); return(l+1); } } if (c == '\t') { while (++l %8) *buf++ = ' '; *buf++ = ' '; continue; } if (c < 32) continue; } l++; *buf++ = c; } if (mode == 1) return(l+1); *buf = 0; if ((c = fgetc(Inp)) == '\n') return(l+1); ungetc(c,Inp); return(PARLINE); } print_hexline(inbuf,ln) int ln; unsigned char *inbuf; { unsigned int hexbuf[8], i; unsigned char c; for(i = 0; i < ln; i+=2) hexbuf[i/2] = (*(inbuf+i))*256 + (*(inbuf+i+1)); fprintf(Prt," %06X: ",SeqNo); for (i=0; i < ln/2; i++) fprintf(Prt,"%04X ",hexbuf[i]); if (ln%2) fprintf(Prt,"%02X ",hexbuf[ln/2]/256); for (i = (ln/2)+(ln%2); i < 8; i++) fprintf(Prt," "); fprintf(Prt, " "); for (i=0; i < ln; i++) { c = *inbuf++; c = toascii(c); /* removes 2-7 high zone */ if (c == '\x7f') c = '.'; if (c == '\n') c = '>'; if (c < 32) c = '.'; fputc(c,Prt); } fputc('\n',Prt); SeqNo = SeqNo + ln; return(0); } print_directory(fn) int fn; { struct Dir_Entry *root, *get_dir_base(); int dir_no = 0; int percent, free, fbytes; char date[50], vol_name[30]; root = NULL; root = get_dir_base(FileName[fn],root); page_no = 1; set_header(heading_buf,fn); lncnt = pgsz - DIRHD_LINES; if (page_no >= StartPage[fn]) { skip_lines(TOP_MARGIN); fprintf(Prt,heading_buf,page_no); ConvertDate(&FileDate,date,1); fprintf(Prt,"\nThis directory was last updated on %s\n",date); stptok(FullPath,vol_name,sizeof(vol_name),":"); fprintf(Prt,"The Volume containing the directory is: %s\n", vol_name); fprintf(Prt,"The Volume contains %d blocks of %d bytes each.\n", DiskInfo.id_NumBlocks, DiskInfo.id_BytesPerBlock); percent = 100 * DiskInfo.id_NumBlocksUsed / DiskInfo.id_NumBlocks; fprintf(Prt,"The number of blocks currently is use are %d (%d%%).\n", DiskInfo.id_NumBlocksUsed, percent); free = DiskInfo.id_NumBlocks - DiskInfo.id_NumBlocksUsed; fbytes = free * DiskInfo.id_BytesPerBlock; fprintf(Prt,"The number of blocks available are %d (%d bytes).\n", free, fbytes); fprintf(Prt,"The number of soft errors are %d.\n\n", DiskInfo.id_NumSoftErrors); DateStamp(&SysDate); ConvertDate(&SysDate,date,1); fprintf(Prt,"\nThis directory is being printed on %s\n",date); print_dir_head_1(); } lncnt = lncnt - 11; print_dir_line(root,dir_no,fn); putc('\f',Prt); return(0); } struct Dir_Entry *get_dir_base(name,root) char *name; struct Dir_Entry *root; { struct Dir_Entry *get_file_info(); struct FileInfoBlock *Dib; long dir_lock, old_lock; Dib = (struct FileInfoBlock *)malloc(sizeof(struct FileInfoBlock)); if (!Dib) { printf("ERROR: Out of Memory allocating directory FIB\n"); exit(1); } dir_lock = Lock(name,ACCESS_READ); if (dir_lock == NULL) { printf("Can't get file lock for directory %s\n",name); exit(1); } old_lock = CurrentDir(dir_lock); if (Examine(dir_lock,Dib) == NULL) { printf("Can't get FIB for directory %s\n",name); exit(1); } while(ExNext (dir_lock,Dib)) { root = get_file_info(root,Dib); if (Abort_Print) break; } UnLock(dir_lock); CurrentDir(old_lock); return(root); } struct Dir_Entry *get_file_info(p,fb) struct Dir_Entry *p; struct FileInfoBlock *fb; { struct Dir_Entry *get_dir_base(); if (p == NULL) { p = (struct Dir_Entry *)malloc(sizeof(struct Dir_Entry)); if (!p) { printf("ERROR: Out of Memory allocating Directories\n"); exit(1); } p->de_Type = fb->fib_DirEntryType; p->de_Protect = fb->fib_Protection; p->de_Size = fb->fib_Size; p->de_Blocks = fb->fib_NumBlocks; p->de_Date.ds_Days = fb->fib_Date.ds_Days; p->de_Date.ds_Minute = fb->fib_Date.ds_Minute; p->de_Date.ds_Tick = fb->fib_Date.ds_Tick; stccpy(p->de_Name,fb->fib_FileName,30); p->de_left = p->de_right = p->de_root = NULL; if (p->de_Type > 0) p->de_root = get_dir_base(p->de_Name,p->de_root); return(p); } if (p->de_Type == fb->fib_DirEntryType) { if (stricmp (fb->fib_FileName, p->de_Name) < 0) p->de_left = get_file_info(p->de_left,fb); else p->de_right = get_file_info(p->de_right,fb); return(p); } if (fb->fib_DirEntryType < 0) p->de_left = get_file_info(p->de_left,fb); else p->de_right = get_file_info(p->de_right,fb); return(p); } print_dir_line(p,n,fileno) struct Dir_Entry *p; int n; int fileno; { int n1; char date[30]; if (Abort_Print) { fprintf(Prt,"\n>>> PRINTOUT ABORTED WITH CONTROL C <<<\n"); return(1); } if (p != NULL) { if (print_dir_line(p->de_left, n, fileno)) return(1); if (lncnt <= 0) { if (page_no >= StartPage[fileno]) putc('\f',Prt); if (++page_no >= StartPage[fileno]) { skip_lines(TOP_MARGIN); fprintf(Prt,heading_buf,page_no); print_dir_head_1(); } lncnt = pgsz - 14; } else { if (p->de_Type > 0) { if (page_no >= StartPage[fileno]) line_across(); lncnt--; } } if (page_no >= StartPage[fileno]) { fprintf(Prt,"%2d> ", n); if (p->de_Type > 0) fprintf(Prt,""); else fprintf(Prt," "); fprintf(Prt,"%30.30s %6d %4d ", p->de_Name, p->de_Size, p->de_Blocks); Set_Protect(p->de_Protect); ConvertDate(&p->de_Date,date,0); } if (lnsz < DIRLNSZ+1) { if (page_no >= StartPage[fileno]) fprintf(Prt,"\n Last Updated On "); lncnt--; } if (page_no >= StartPage[fileno]) fprintf(Prt," %s\n",date); lncnt--; if (p->de_Type > 0) { if (page_no >= StartPage[fileno]) skip_lines(1); lncnt--; n1 = n + 1; if (print_dir_line(p->de_root, n1, fileno)) return(1); } if (print_dir_line(p->de_right, n, fileno)) return(1); } return(0); } print_dir_head_1() { line_across(); skip_lines(2); fprintf(Prt,"Lvl %35.35s Bytes Blks","NAME"); if (lnsz > DIRLNSZ) fprintf(Prt," Last Updated On"); skip_lines(2); return(0); } /* the following routine is used to replace the Lattice "stpdate" * routine because of the incompatibility of base years (Amiga uses * 1978 while Lattice uses 1980). Since "print" only uses two of * the stpdate modes, these are the only two that are programmed. */ astpdate(p,m,dt) char *p, *dt; int m; { int l, dy, yr, mo; static char *month[] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", }; mo = dt[1]; yr = dt[0]; dy = dt[2]; if (m) { p = stpcpy(p,month[mo]); yr = yr+1978; l = sprintf(p," %d, %4.4d",dy,yr); return (p+l); } else { yr = yr+78; l = sprintf(p,"%2.2d/%02.2d/%02.2d",mo,dy,yr); return (p+l); } } PRTBRK() { NameText.IText = _ProgramName; NameText.NextText = &Text1; if (AutoRequest (NULL, &NameText, &NoText, &YesText, 0, 0, 296, 60) == TRUE) return(0); Abort_Print = 1; if (nfiles >= nmbrfiles) return(0); NameText.NextText = &Text2; if (AutoRequest (NULL, &NameText, &NoText, &YesText, 0, 0, 254, 60) == TRUE) nfiles = nmbrfiles+1; return(0); } byp_esc() { int c; if ((c = fgetc(Inp)) == EOF) return(0); if ((c == '#') || (c == '(')) { if (fgetc(Inp) == EOF) return(0); return(1); } if (c != '[') return(1); while ((c = fgetc(Inp)) != EOF) { if (isalpha(c)) return(1); } return(0); } /* * The following routine is for testing purposes only. * * It is used to display the arguments as they are parsed by * by the 'getargs()' routine. * */ showargs() { int nfiles; printf("Initialize Printer = %d\n",init_prtr); for(nfiles=1; nfiles <= nmbrfiles; nfiles++) { printf("\nFile number %d:\n",nfiles); printf(" FILE NAME: %s\n",FileName[nfiles]); printf(" PRINT OPTION: %c\n",Option[nfiles]); printf(" STARTING PAGE: %d\n",StartPage[nfiles]); printf(" RESET PAGE: %d\n",ResetPage[nfiles]); printf(" PRINT TYPE: "); if (PrintType[nfiles] == HAVE_FILE) printf("HAVE_FILE\n"); if (PrintType[nfiles] == HAVE_DIR) printf("HAVE_DIR\n"); } return(1); }