|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 7168 (0x1c00) Types: TextFile Names: »USQ.C«
└─⟦1275f6521⟧ Bits:30005823 BD Software C Compiler v1.50a └─ ⟦this⟧ »USQ.C«
/* Program to unsqueeze files formed by sq.com * * Useage: * USQ item ... * where ... represents more (optional) items and * "item" is either: * drive: to change the output drive * file input file * drive:file input file * -count Previewing feature: redirects output * files to standard output with parity stripped * and unprintables except CR, LF, TAB and FF * converted to periods. Limits each file * to first count lines. * Defaults to console, but see below how * to capture all in one file for further * processing, such as by PIP. * Count defaults to a very high value. * No CRC check is performed when previewing. * Use drive: to cancel this. * * -fcount Same as -count except formfeed * appended to preview of each file. * Example: -f10. * * If no such items are given on the command line you will be * prompted for commands (one at a time). An empty command * terminates the program. * * USQ uses the dio package, so input and output can be redirected * by special items on the command line such as: * <file reads console input from file * >file sends console output to file * +file sends console output to console and file * Also console output of another program using dio can be piped * to the input of USQ or vice-versa. Example: * A>fls parameters øusq * where fls might be a program that expands patterns like *.asm * to a list of specific file names for usq to unsqueeze. * * The unsqueezed file name is recorded in the squeezed file. * * Examples: * A>USQ GRUMP.QQQ writes on a: * A>USQ D:CRAP.XQZ writes on A: * A>USQ B: D:CRAP.CQM writes on B: * B>USQ X.AQ C: Y.BQ writes X.?? on B: and Y.?? on C: */ /* CHANGE HISTORY: * 1.3 Close inbuff to avoid exceeding maximum number of * open files. Includes rearranging error exits. * 1.4 Add -count option to allow quick inspection of files. * 1.5 Break up long lines of introductory text * 1.5 -count no longer appends formfeed to preview of each file. * -fcount (-f10, -F10) does append formfeed. */ \f #include <bdscio.h> #include <dio.h> #include "sqcom.h" #include "usq.h" #define VERSION "1.5 08/02/81" #define STDERR 4 /*Error output stream (always cxonsole) */ /* This must follow all include files */ unsigned dispcnt; /* How much of each file to preview */ char ffflag; /* should formfeed separate preview from different files */ main(argc, argv) int argc; char *argvÆÅ; æ int i,c; int getchar(); /* Directed io version */ char inpargÆ16Å; /* parameter from input */ dioinit(&argc, argv); /* obey directed to args */ dispcnt = 0; /* Not in preview mode */ fprintf(STDERR, "File unsqueezer version %s byØnØtRichard GreenlawØnØt251 Colony Ct.ØnØtGahanna, Ohio 43230Øn", VERSION); fprintf(STDERR, "Accepts redirection and pipes.ØnOmit other parameters for help and promptØn"); /* Initialize output drive to default drive */ outdrvÆ0Å = 'Ø0'; /* But prepare for a specific drive */ outdrvÆ1Å = ':'; outdrvÆ2Å = 'Ø0'; /* string terminator */ /* Process the parameters in order */ for(i = 1; i < argc; ++i) obey(argvÆiÅ); if(argc < 2) æ fprintf(STDERR, "Parameters are from command line or one-at-a-time from standardØninput and are output drives and input file names. Empty to quit.Øn"); do æ fprintf(STDERR, "Øn*"); for(i = 0; i < 16; ++i) æ if((c = getchar()) == EOF) c = 'Øn'; /* force empty (exit) command */ if((inpargÆiÅ = c) == 'Øn') æ inpargÆiÅ = 'Ø0'; break; å å if(inpargÆ0Å != 'Ø0') obey(inparg); å while(inpargÆ0Å != 'Ø0'); å dioflush(); /* clean up any directed io */ å \f obey(p) char *p; æ char *q; if(*p == '-') æ if(ffflag = (toupper(*(p+1)) == 'F')) ++p; /* Set number of lines of each file to view */ dispcnt = 65535; /* default */ if(*(p+1)) if((dispcnt = atoi(p + 1)) == 0) fprintf(STDERR, "ØnBAD COUNT %s", p + 1); return; å if(*(p + 1) == ':') æ /* Got a drive */ if(isalpha(*p)) æ if(*(p+2) == 'Ø0') æ /* Change output drive */ dispcnt = 0; /* cancel previewing */ printf("ØnOutput drive =%s",p); outdrvÆ0Å = *p; return; å å else æ fprintf(STDERR, "ØnERROR - Ignoring %s", p); return; å å /* Check for ambiguous (wild-card) name */ for(q = p; *q != 'Ø0'; ++q) if(*q == '*' øø *q == '?') æ fprintf(STDERR, "ØnCan't accept ambiguous name %s", p); return; å unsqueeze(p); å \f unsqueeze(infile) char *infile; æ struct _buf inbuff, outbuff; /* file buffers */ int i, c; char cc; char *p; unsigned filecrc; /* checksum */ int numnodes; /* size of decoding tree */ char outfileÆ16Å; /* output file name */ unsigned linect; /* count of number of lines previewed */ if(fopen(infile, &inbuff) == ERROR) æ fprintf(STDERR, "Can't open %sØn", infile); return; å /* Initialization */ linect = 0; crc = 0; init_huff(); /* Process header */ if(getw(&inbuff) != RECOGNIZE) æ fprintf(STDERR, "%s is not a squeezed fileØn", infile); goto closein; å filecrc = getw(&inbuff); /* Get original file name */ p = origname; /* send it to array */ do æ *p = getc(&inbuff); å while(*p++ != 'Ø0'); /* Combine with output drive */ outfileÆ0Å = 'Ø0'; /* empty */ strcat(outfile, outdrv); /* drive */ strcat(outfile, origname); /* name */ printf("Øn%s -> %s: ", infile, outfile); numnodes = getw(&inbuff); if(numnodes < 0 øø numnodes >= NUMVALS) æ fprintf(STDERR, "%s has invalid decode tree sizeØn", infile); goto closein; å /* Initialize for possible empty tree (SPEOF only) */ dnodeÆ0Å.childrenÆ0Å = -(SPEOF + 1); dnodeÆ0Å.childrenÆ1Å = -(SPEOF + 1); /* Get decoding tree from file */ for(i = 0; i < numnodes; ++i) æ dnodeÆiÅ.childrenÆ0Å = getw(&inbuff); dnodeÆiÅ.childrenÆ1Å = getw(&inbuff); å if(dispcnt) æ /* Use standard output for previewing */ putchar('Øn'); while(((c = getuhuff(&inbuff)) != EOF) && (linect < dispcnt)) æ cc = 0x7f & c; /* strip parity */ if((cc < ' ') øø (cc > 'ü')) /* Unprintable */ switch(cc) æ case 'Ør': /* return */ /* newline will generate CR-LF */ goto next; case 'Øn': /* newline */ ++linect; case 'Øf': /* formfeed */ case 'Øt': /* tab */ break; default: cc = '.'; å putchar(cc); next: ; å if(ffflag) putchar('Øf'); /* formfeed */ å else æ /* Create output file */ if(fcreat(outfile, &outbuff) == ERROR) æ fprintf(STDERR, "Can't create %sØn", outfile); goto closeall; å /* Get translated output bytes and write file */ while((c = getuhuff(&inbuff)) != EOF) æ crc += c; if((putc(c, &outbuff)) == ERROR) æ fprintf(STDERR, "Write error in %sØn", outfile); goto closeall; å å if(filecrc != crc) fprintf(STDERR, "ERROR - checksum error in %sØn", outfile); closeall: fflush(&outbuff); fclose(&outbuff); å closein: fclose(&inbuff); å «eof»