|
|
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 - metrics - 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»