twitter
    Find out what I'm doing, Follow Me :)

List.C - The Program Lister

This program is actually composed of two files, list.c and listf.c that must be separately compiled and linked together with your linker. There is nothing new here and you should have no trouble compiling and linking this program by reading the documentation supplied with your compiler.

The way to compile them with HiTech C is:
relcc -v -W1 list.c listf.c
/* ******************************************************************* */
/* This program will read in any file and list it on the monitor with */
/* line numbers and with page numbers. */

/* ******************************************************************* */
#include "/sys/stdio.h" /* standard I/O header file */
#define MAXCHARS 255 /* maximum size of a line */
FILE *file_point; /* point to file to be read */
FILE *print_file_point; /* pointer to pronter */
extern top_of_page();
char oneline[256]; /* input string buffer area */
main(number,name)
int number; /* number of arguments on command line */
char *name[]; /* arguments on the command line */
{
char *c; /* variable to indicate end of file */
char *point;
point = name[1];
open_file(number,point); /* open the file to read and print */
open_print_file();
do {
c = fgets(oneline,MAXCHARS,file_point); /* read one line */
if (c != NULL)
print_a_line(); /* print a line */
} while (c !=NULL); /* continue until EOF */
top_of_page(); /* move paper to top of page */
close(file_point); /* close read file */
close(print_file_point); /* close printer file */
}


The only thing that is new in this program is the inclusion of three "extern" variables in the listf.c listing. The only purpose for this is to tie these global variables to the main program and tell the compiler that these are not new variables. The compiler will therefore not generate any new storage space for them but simply use their names during the compile process. At link time, the linker will get their actual storage locations from the LIST.OBJ file and use those locations for the variables in the LISTF part of the memory map also. The variables of those names in both files are therefore the same identical variables and can be used just as any otherglobal variables could be used if both parts of the program were in one file.
Enter


/* ******************************************************************** */
/* Module contains the functions called by the list.c program. If this */
/* were a program to be used for specific purpose,it would probably not*/
/* be wise to break it into two separately compiled modules.It is only */
/* done here for purposes of illustration. It is a useful program.
*/

/* ******************************************************************** */
#define MAXLINES 54 /* maximum number of lines per page */
#include "/sys/stdio.h" /* standard I/O header file */
extern FILE *file_point; /* point to the file to be read */
extern FILE *print_file_point; /* pointer to the printer */
extern char oneline[]; /* input string buffer area */
char filename[15]; /* filename from header or prompt */
int line_number = 0; /* line number initialized to one */
int page_number = 1; /* page number initialized to one */
int lines_this_page = 0; /* lines on this page so far */

/* ******************************************************* open_file */
/* This functions opens input file on the command line,if there was */
/* one defined. Otherwise, requests a file to open and opens the */
/* requested file. */

/* ***************************************************************** */
open_file(no,name)
int no; /* number of arguments on command line */
char *name; /* first argument from command line */
{
strcpy(filename,name); /* copy name for printing header */
file_point = NULL; /* if no name was given in command */
if (no == 2) { /* 2nd field in command is filename */
file_point = fopen(name,"r"); /* open requested file */
if (file_point == NULL) /* NULL if file doesn’t exist */
printf("File name on command line doesn’t exist!\n");
}
do {
if (file_point == NULL) { /* no filename yet */
printf("Enter filename -> ");
scanf("%s",filename);
file_point = fopen(filename,"r"); /* open file */
if (file_point == NULL) /* NULL if file no exist */
printf("Filename doesn’t exist,try again.\n");
}
} while (file_point == NULL); /* continue until good filename */
}
/* ****************************************************** open_print_file
*/
/* This function opens the printer file to the standard printer.
*/
/* **********************************************************************
*/
open_print_file()
{
print_file_point = fopen("PRN","w"); /* open printer file */
}

/* ********************************************************* print_a_line
*/
/* This routine prints a text line and checks to see if there is room for
*/
/* another on the page. If not,it starts a new page with a new header.
*/
/* This routine calls several other local routines.
*/

/* **********************************************************************
*/

print_a_line()
{
int index;
header();
printf("%5d %s",line_number,oneline);
/* This prints a line of less than 72 chars */
if (strlen(oneline) < 72)
fprintf(print_file_point,"%5d %s",line_number,oneline);
/* This prints a line of 72 to 143 chars */
else if (strlen(oneline) < 144) {
fprintf(print_file_point,"%5d ",line_number);
for (index = 0;index < 72;index++)
fprintf(print_file_point,"%c",oneline[index]);
fprintf(print_file_point,"<\n ");
for (index = 72;index < strlen(oneline);index++)
fprintf(print_file_point,"%c",oneline[index]);
lines_this_page++;
}
/* This prints a line of 144 to 235 chars */
else if (strlen(oneline) < 235) {
fprintf(print_file_point,"%5d ",line_number);
for (index = 0;index < 72;index++)
fprintf(print_file_point,"%c",oneline[index]);
fprintf(print_file_point,"<\n ");
for (index = 72;index < 144;index++)
fprintf(print_file_point,"%c",oneline[index]);
fprintf(print_file_point,"<\n ");
for (index = 144;index < strlen(oneline);index++)
fprintf(print_file_point,"%c",oneline[index]);
lines_this_page += 2;
}
/* the following line outputs a newline if there is none
at the end of the last line */
if (oneline[strlen(oneline)-1] != ’\n’)
fprintf(print_file_point,"%c",’\n’);
line_number++;
lines_this_page++;
}
/* ********************************************************* header */
/* This routine checks if a header needs to be printed.It also checks */
/* for the end of a page,and spaces the paper up. */
/* ****************************************************************** */
header()
{
int index;
/* first see if we are at the bottom of the page */
if (lines_this_page > MAXLINES) { /* space paper up from bottom */
for (index = lines_this_page;index < 61;index++)
fprintf(print_file_point,"\n");
lines_this_page = 0;
}
/* put a monitor header out only at the very beginning */
if (line_number == 0) { /* display monitor header */
printf(" Source file %s\n",filename);
line_number = 1;
}
/* check to see if we are at the top of the page either */
/* through starting a file,or following a bottom of page */
if (lines_this_page == 0) { /* top of every printer page */
fprintf(print_file_point,"\n\n\n ");
fprintf(print_file_point," Source file - %s ",filename);
fprintf(print_file_point," Page %d\n\n",page_number);

page_number++;
}
}
/* ******************************************************** top_of_page */
/* This function spaces the paper to the top of the next page so another */
/* call to this function will start correctly. Used only at the end */
/* of a complete printout. */
/* ********************************************************************* */
top_of_page()
{
int index;
for (index = lines_this_page;index < 61;index++)
fprintf(print_file_point,"\n");
}


There is no reason why the variables couldn’t have been defined in the listf.c part of the program and declared as "extern" in the list.c part. Some of the variables could have been defined in one and some in the other. It is merely a matter of personal taste. Carried to an extreme, all of the variables could have been defined in a third file and named "extern" in both of these files. The third file would then be compiled and included in the linking process. It would be to your advantage to compile, link, and run this program to prepare you for the next
program which is composed of 5 separate files which must all work together.