Basicly this is a shell or wrapper if you will that can be used for just about any piece oc C code that you would write. It keeps the allocation and deallocation of strings, arrays, or whatever dynamic code you need to have availabe between (not contained within) various functions. This is a lot like the way a C++ object is created. All of the 'global (if I can use that dirty word)' allocation is done in SysInit, and deallocation in SysFree. By passing the structure 'SysInfo' to subroutines (functions), you automatically pass access to everything within the sysinfo structure. This is not limited, you can build arrays, linked lists or whatever in the SysInfo structure, and all functions immediately have access to this information.
For example, let's say all you want to do is open a text file and print the contents. All you
need is a simple DoStuff.c file as follows, (also comment out the out file in SysInit as you don't
need an output file here).
#include "mainincl.h"
void DoStuff(sysinfo *SysInfo)
{
while(TRUE)
{
fgets(SysInfo->InBuff, SysInfo->BuffSz, SysInfo->In);
if(feof(SysInfo->In))
break;
fprintf(stdout, SysInfo->InBuff);
}
}
That's it! to execute, you would type:
WhaterTheNameIs.exe -i InputTextFileName
, and away you go. No worry about allocation of the input buffer, it's already done in SysInit.
Here's the working and tested code (6 files total)
----------------------------------------------------------
mainincl.h
----------------------------------------------------------
#ifndef main__h__
#define main__h__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
// etc. etc. etc
#ifndef bool
#define bool int
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define BuffSz1 512
#define BuffSz2 1024
typedef struct
{
char *InBuff;
int BuffSz;
char *OutBuff;
FILE *In;
char *InFileName;
FILE *Out;
char *OutFileName;
int argc;
char **argv;
} sysinfo;
// Function prototypes
int main(int argc, char **argv);
bool SysInit(sysinfo *SysInfo);
void SysAbort(sysinfo *SysInfo, char *String, int
NumArgs, ...);
void SysFree(sysinfo *SysInfo);
void DoStuff(sysinfo *SysInfo);
#endif
----------------------------------------------------------
Main.c
----------------------------------------------------------
#include "mainincl.h"
int main(int argc, char **argv)
{
sysinfo *SysInfo = NULL;
SysInfo = (sysinfo *)calloc(1, sizeof(sysinfo));
SysInfo->argc = argc;
SysInfo->argv = argv;
if(SysInit(SysInfo))
SysAbort(SysInfo, "Unable to initialize", 0);
DoStuff(SysInfo);
SysFree(SysInfo);
free(SysInfo);
}
----------------------------------------------------------
SysInit.c
----------------------------------------------------------
#include "mainincl.h"
bool SysInit(sysinfo *SysInfo)
{
char *ArgPtr = NULL;
char Argid = 0;
int i = 0;
bool RetVal = FALSE;
for(i = 1; i < SysInfo->argc; i++)
{
if(SysInfo->argv[0] == '-')
{
Argid = SysInfo->argv[1];
if(!SysInfo->argv[2])
{
i++;
ArgPtr = SysInfo->argv;
}
else
ArgPtr = (char *)&SysInfo->argv[2];
switch (Argid)
{
case 'i':
SysInfo->InFileName = ArgPtr;
break;
case 'o':
SysInfo->OutFileName = ArgPtr;
break;
default:
SysAbort(SysInfo, "Invalid parameters", 0);
break;
}
}
}
SysInfo->InBuff = (char *)calloc(1, SysInfo->BuffSz);
if(SysInfo->InBuff == NULL)
SysAbort(SysInfo,
"Unable to allocate space for InBuff", 0);
/* Don't need an output file for this instance
SysInfo->OutBuff = (char *)calloc(1, SysInfo->BuffSz);
if(SysInfo->OutBuff == NULL)
SysAbort(SysInfo,
"Unable to allocate space for OutBuff", 0);
*/
SysInfo->In = fopen(SysInfo->InFileName, "r");
if(SysInfo->In == NULL)
SysAbort(SysInfo, "Unable to open input file %s", 1,
SysInfo->InFileName);
SysInfo->BuffSz = BuffSz1;
// any other initialization stuff here.
}
----------------------------------------------------------
SysAbort.c
----------------------------------------------------------
#include "mainincl.h"
void SysAbort(sysinfo *SysInfo, char *String, int
NumArgs, ...)
{
va_list ap;
va_start(ap, NumArgs);
vfprintf(stderr, String, ap);
va_end(ap);
// Check if n\memory needs to be cleaned up
SysFree(SysInfo);
free(SysInfo);
exit(1);
}
----------------------------------------------------------
SysFree.c
----------------------------------------------------------
#include "mainincl.h"
void SysFree(sysinfo *SysInfo)
{
if(SysInfo->Out != NULL)
fclose(SysInfo->Out);
if(SysInfo->In != NULL)
fclose(SysInfo->In);
if(SysInfo->OutBuff != NULL)
free(SysInfo->OutBuff);
if(SysInfo->InBuff != NULL)
free(SysInfo->InBuff);
}
----------------------------------------------------------
DoStuff.c
----------------------------------------------------------
#include "mainincl.h"
void DoStuff(sysinfo *SysInfo)
{
while(TRUE)
{
fgets(SysInfo->InBuff, SysInfo->BuffSz, SysInfo->In);
if(feof(SysInfo->In))
break;
fprintf(stdout, SysInfo->InBuff);
}
}
----------------------------------------------------------
As you can see, in order to create a file list program, all that was needed was the code in DoStuff.c. If you wanted to create a copy program, where you added line numbers to the beginning of the file, all you need is:
1. Since you do need an output file, uncomment the stuff for SysInfo->Out in SysInit.c
2. Create a DoStuff.c as follows:
----------------------------------------------------------
DoStuff.c
----------------------------------------------------------
#include "mainincl.h"
void DoStuff(sysinfo *SysInfo)
{
long linect = 1;
while(TRUE)
{
memset(SysInfo->InBuff, 0, SysInfo->BuffSz);
memset(SysInfo->OutBuff, 0, SysInfo->BuffSz);
fgets(SysInfo->InBuff, SysInfo->BuffSz, SysInfo->In);
if(feof(SysInfo->In))
break;
sprintf(SysInfo->OutBuff, "%d %s", linect++, SysInfo->InBuff);
fputs(SysInfo->OutBuff, SysInfo->Out;
}
}
----------------------------------------------------------
And it's done
To execute this one:
WhaterTheNameIs.exe -i InputTextFileName -o OutputFileName
Hope this makes it a little clearer.