home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
norge.freeshell.org (192.94.73.8)
/
192.94.73.8.tar
/
192.94.73.8
/
pub
/
computers
/
cpm
/
alphatronic
/
TINY_C.ZIP
/
LIST.C
< prev
next >
Wrap
Text File
|
1999-03-05
|
4KB
|
161 lines
/*
This program accepts a list of filenames, which
should represent ascii files on the disk, and
prints them out on the CP/M list device.
There is nothing particularly fascinating about
this program; it is included mainly as an example
of file I/O handling in C.
Note the use of ARGC and ARGV in main; the names
themselves mean "arg count" and "arg vector", and
point out that upon entry to the "main" program,
your command line arguments are available for
processing. ARGC is equal to the number of arguments
given on the command line PLUS ONE, and ARGV tells you
the address of the beginning of each argument. Thus,
the expression
argv[1]
represents the address of the first character of the
first argument string;
argv[2]
would be the address of the second argument string,
etc. By convention, argv[0] is not used, since 0
arguments is a special case. On UNIX C, the original
C, argv[0] would point to the command itself
(i.e., the string 'foo' in
A> foo arg1 arg2 arg3 )
But, unfortunately, CP/M doesn't bother to save that
part of the command line, so the C COM file can never
see what its name really is.
Note that ARGV can NEVER equal zero; the case of zero
arguments causes ARGV to be equal to 1. Again, this
is to maintain compatibility with UNIX C.
Alternatively (and, in fact, how it is done here), it
is possible to use the variable argv as a pointer, so
that the value of
*++argv
upon entry to main would point to the first
argument string; after incrementing argv again
it would point to the second argument string, etc.
Note how the increment operation specified by
argv++
or
++argv
knows to add 2 to argv, since argv was declared as
a pointer to pointers, and pointers take 2 bytes!
Thus, should argv have been (incorrectly) declared
char *argv;
then the
argv++
operation would add only 1 to argv, instead of 2.
Oh well, enough tutorial. Here's the program...
*/
#define BUFSIZ 8192
int lpos;
int lines;
main(argc,argv)
int argc;
char **argv;
{
outp(0,8); /* set 3P+S to 1200 baud */
while (--argc) {
printf("\nPrinting %s...\n",*++argv);
putlist(*argv);
}
}
putlist(file)
char *file;
{
char buffer[BUFSIZ];
int fd,i,j;
int nsects;
lpos=1; /* keep track of print head position */
nsects = BUFSIZ/128;
bdos(5,0x0d);
for(i=0; i<8; i++) bdos(5,0x0a);
lines=1;
fd=open(file,0);
if ( fd == -1) return;
while ((j= read(fd,buffer,nsects))==nsects)
putchunk(buffer);
if (j) putchunk(buffer);
close(fd);
}
/*
This routine puts BUFSIZ characters (or until EOF)
out on the list device.
*/
putchunk(buffer)
char *buffer;
{
char c;
int i,j,k;
for (k=0; k<BUFSIZ; k++)
switch (c= *buffer++) {
case '\r':
bdos(5,'\r');
putchar('\r');
lpos = 0;
break;
case '\t':
while(lpos%8) { lpos++;
bdos(5,' ');
putchar(' ');
}
bdos(5,' '); putchar(' ');
lpos++;
break;
case 0x1a:
return;
case 0x0a:
lines++;
if(lines==6) {
printf("\nTear off page...\n");
wait(300); /* give him 30 seconds */
}
if(lines==60) {
for(i=0; i<10; i++)
bdos(5,0x0a);
lines=1;
for(i=0; i<5000; i++);
}
default:
bdos(5,c);
putchar(c);
lpos++;
}
}
/* routine to wait for a specified number of
tenths of a second and return the number of tenths
of a second it took the user to type something */
wait(n)
int n;
{
int i;
int j;
for (i=1; i<n+1; i++)
for (j=0; j<165; j++)
if (bdos(11)&1) return i;
return n;
}