📄 skeleton.c
字号:
}
else
{
output_and_count(&p, control_char);
control_char = *control_string++;
}
}
return p.number_of_output_chars;
}
static int
lputc(void *fd, int c)
{
return VWRITE((int)fd, &c, 1);
}
static int
lprintf(char *fmt, ...)
{
return gprintf(lputc, (void*)1, fmt, (int*)(&fmt+1));
}
static int
lvprintf(char *fmt, void *args)
{
return gprintf(lputc, (void*)1, fmt, args);
}
static int lfilc(void *p, int c)
{
*(*(char **)p)++ = c;
return 0;
}
static int
lsprintf(char *buf, char *fmt, ...)
{
int n;
n = gprintf(lfilc, &buf, fmt, (int*)(&fmt+1));
*buf = 0;
return n;
}
#endif /* EARLY_PRINT == 1 */
void
_cleanup()
{/* SUPPRESS PULLIN OF STDIO STUFF */
}
/* ================== END OF INTERNAL SUPPORT FUNCTIONS ================= */
#include "oxlink.i"
/* ================ END OF THE DYNAMIC LINKER ======================= */
struct _linkups {
void *dst;
char *src;
};
static struct _linkups __linkups[] = {
{&VPUSH_VALUE, "_cfpush_value"},
{&VPUSH_DATA, "_cfpush_data"},
{&VGET, "_cfgetx"},
{&VFIND, "_cffindx"},
{&VCFOPEN, "_cfopen"},
{&VCFCLOSE, "_cfclose"},
{&VCFREAD, "_cfrdwr_object"},
{&VCFWRITE, "_cfrdwr_object"},
{&VCFLSEEK, "_cfseek"},
{&VSUBOPEN, "_cfsubopen"},
{&VOBTYPE, "_cfobtype"},
{&VPUT, "_cfputx"},
{&VFILESIZE, "_cffilesize"},
{&VOPEN_CHUNK, "_cfopen_chunk"},
{&VLOCALIZE, "_cflocalize"},
{&VRELEASE, "_cfrelease"},
{&VMEMTEMP, "_MEMTEMP"},
{&VVPRINTF, "_cfvprintf"},
{&VSPRINTF, "_cfsprintf"},
{&VPRINTF, "_cfprintf"},
{&VSTAT, "_cfstat"},
{&CFINIT, "_cfinit"},
{&CFEXIT, "_cfexit"},
{&COSINIT, "_InitCOS"},
{&THREADER, "__start_threader"},
{&THREAD, "__start_thread"},
{&VINHIBIT_THREADER, "__no_context_switch"},
{NULL}
};
static int badsyms;
static void
linkup()
{
struct _linkups *l = __linkups;
while(l->dst)
{
*((long *)l->dst) = (long)oxlink_find_bare_symb(l->src);
++l;
}
/* REDIRECT USER CALLS TO OUR PREFERRED SUBROUTINES */
SYMLINK(__filbuf, _cf_filbuf);
SYMLINK(__flsbuf, _cf_flsbuf);
SYMLINK(_fread, _cffread);
SYMLINK(_fputc, _cffputc);
SYMLINK(_fgetc, _cffgetc);
SYMLINK(_fputs, _cffputs);
SYMLINK(_fgets, _cffgets);
SYMLINK(_puts, _cfputs);
SYMLINK(_putw, _cfputw);
SYMLINK(_gets, _cfgets);
SYMLINK(_ftell, _cfftell);
SYMLINK(_printf, _cfprintf);
SYMLINK(_fprintf, _cffprintf);
SYMLINK(_sprintf, _cfsprintf);
SYMLINK(_vprintf, _cfvprintf);
SYMLINK(_vfprintf, _cfvfprintf);
SYMLINK(_fscanf, _cffscanf);
SYMLINK(_fopen, _cffopen);
SYMLINK(_freopen, _cffreopen);
SYMLINK(_fseek, _cffseek);
SYMLINK(_rewind, _cfrewind);
SYMLINK(_fflush, _cffflush);
SYMLINK(_fwrite, _cffwrite);
SYMLINK(_unlink, _cfunlink);
SYMLINK(_remove, _cfunlink);
SYMLINK(_ungetc, _cfungetc);
SYMLINK(_fclose, _cffclose);
SYMLINK(_fdopen, _cffdopen);
SYMLINK(_setmode, _cfsetmode);
SYMLINK(_setbuf, _cfsetbuf);
SYMLINK(_setvbuf, _cfsetvbuf);
SYMLINK(_setlinebuf, _cfsetlinebuf);
SYMLINK(_scanf, _cfscanf);
SYMLINK(_sscanf, _cfsscanf);
SYMLINK(_fscanf, _cffscanf);
SYMLINK(_vscanf, _cfvscanf);
SYMLINK(_vfscanf, _cfvfscanf);
SYMLINK(_vsscanf, _cfvsscanf);
SYMLINK(__iob, _cf_iob);
SYMLINK(_stat, _TRAPSTAT);
SYMLINK(_rename, _TRAPRENAME);
SYMLINK(_fgetpos, _cffgetpos);
SYMLINK(_fsetpos, _cffsetpos);
SYMLINK(_tmpfile, _cftmpfile);
SYMLINK(_tmpnam, _cftmpnam);
SYMLINK(_tempnam, _cftempnam);
SYMLINK(_itoa, _ltoa);
}
static char *
appnameof(char *path)
{
char *aname;
char *cp;
if(path == NULL)
return NULL;
cp = concat("_", fileof(path, 0), "");
aname = strdup(cp);
_oxlink_free(cp); /* was not allocated with malloc */
if((cp = strrchr(aname, '.')) != NULL)
*cp = 0;
cp = aname;
while(*cp)
{/* lower case app names only */
if(*cp >= 'A' && *cp <= 'Z')
*cp += 32;
++cp;
}
return aname;
}
static char *
appfileof(char *aname)
{
char *fname;
char *gname;
int fcnt;
if(aname == NULL)
return NULL;
fcnt = strlen(aname);
fname = malloc(fcnt+6);
if(aname[0] == '_')
fcnt = _strcpy(fname, &aname[1]);
else
strcpy(fname, aname);
strcpy(&fname[fcnt], ".o");
if(!(gname = cf_find_file(fname, 0)))
{
#if 0
strcpy(&fname[fcnt], ".byt");
if(!(gname = cf_find_file(fname, 0)))
#endif
strcpy(&fname[fcnt], ".cff");
gname = cf_find_file(fname, 0);
}
free(fname);
return gname;
}
static char *
cfffileof(char *aname)
{
char *fname;
char *gname;
int fcnt;
if(aname == NULL)
return NULL;
fcnt = strlen(aname);
fname = malloc(fcnt+6);
if(aname[0] == '_')
fcnt = _strcpy(fname, &aname[1]);
else
strcpy(fname, aname);
strcpy(&fname[fcnt], ".cff");
gname = cf_find_file(fname, 0);
free(fname);
return gname;
}
static void
Usage()
{
lprintstr("\
Usage: cfrun appname [-APP=][-LIB=][-PATH=][-TRACE=][-LBUFS=][appargs]\n\
Switch -------- Meaning\n\
-APP=filename Permanent object file/archive for the application.\n\
-LIB=filename A library file.\n\
-PATH=p1;p2;... Lookup path for files.\n\
-LBUFS=n Allocate n kilobytes of database buffering.\n\
-TRACE=n Set trace bits (hex,octal,decimal ok).\n\
appargs Application args.\n\
");
}
/* ====================== THE MAIN FUNCTION ======================= */
static int chainargc;
static char *chainargv[30];
static char *chainapp, *chainfile, *chaincff;
static int chainapp_hasextension, chainfile_iscff;
char **Envp;
static char newmain[10];
int
main(int argc, char **argv, char **envp)
{
char *appath, *appname, *appfile, *ap, *dp;
int lbufs, i;
int appfile_iscff = 0;
int appname_hasextension = 0;
char *appcff = 0;
char *
check_for_arg(char *arg)
{/* NESTED SUBROUTINE */
int i;
int arglen = strlen(arg);
for(i = 1; i < argc; ++i)
{
if(argv[i][0] == '-' && !strncmp(arg, &argv[i][1], arglen))
{
int j;
char *cp = &argv[i][arglen+1];
for(j = i; j < argc; ++j)
argv[j] = argv[j+1];
--argc;
return cp;
}
}
return NULL;
}
/* main */
path_sep = ';';
_oxlink_openmode = O_RDONLY|O_BINARY;
_oxlink_seekmode = 0;
oxlink_errno = 0;
Envp = envp;
cf_set_search_path(check_for_arg("PATH="));
if((ap = check_for_arg("TRACE=")) != NULL)
_oxlink_trace = strtol(ap, NULL, 0);
/* Get relevant info about this program name */
appath = cf_find_file(argv[0], 0);
appname = appnameof(appath);
if(!strcmp(appname, "_cfrun"))
{/* arg1 contains the real name of the application */
int j;
if(argc > 1)
{
appname = appnameof(argv[1]);
if((dp = strchr(argv[1], '.')))
{
appfile = cf_find_file(argv[1], 0);
appname_hasextension = 1;
}
else
appfile = appfileof(appname);
for(j = 1; j < argc; ++j)
argv[j] = argv[j+1];
--argc;
}
else
{
Usage();
VEXIT(0);
}
}
else appfile = appfileof(appname);
if(appfile)
{
if((dp = strrchr(appfile, '.')))
{
if(!strcmp(dp, ".cff"))
{
appfile_iscff = 1;
appcff = appfile;
}
else
{
appcff = cfffileof(appname);
}
}
}
/* Link in the base level code */
permanent_symbols = 1;
if(!oxlink_init(appath)) {
oxlink_use_library("oxbow.a");
if(!oxlink_load_object("dj12port.o")) {
if(!oxlink_load_object("cffsys.o")) {
if(!oxlink_load_object("cossys.o")) {
oxlink_nouse_library("oxbow.a");
linkup();
}
}
}
}
permanent_symbols = 0;
if(oxlink_errno) {
lprintstr(oxlink_errstr());
VEXIT(oxlink_errno);
}
/* CFF and COS are now linked */
linkup_complete = 1;
_oxlink_openmode = F_STAT;
_oxlink_seekmode = S_SET;
/* check for appfile override */
if((ap = check_for_arg("APP=")) != NULL)
appfile = strdup(ap);
if((ap = check_for_arg("LBUFS=")) != NULL)
lbufs = strtol(ap, NULL, 0);
else lbufs = 100;
/* Initialize CFF and COS */
CFINIT(&appname[1], lbufs, appfile);
COSINIT(&argc);
/* Get rid of the symbol `_main' so it doesn't clash */
strcpy(newmain, "_main$$$");
oxlink_rename_symb("_main", newmain);
/* Specify which libraries will provide code and data */
oxlink_use_library("oxlib.cff");
/* Pick up any additional libraries of interest */
while((ap = check_for_arg("LIB=")) != NULL)
oxlink_use_library(ap);
/* Enable demand loading */
oxlink_demand_load();
if(_oxlink_trace)
{/* Print the addresses of the early load modules */
struct file_entry *entry = _oxlink_latest_entry;
void print_file(struct file_entry *e)
{/* NESTED SUBROUTINE */
VPRINTF("%s\ntext:0x%x sz=%d data:0x%x sz=%d bss:0x%x sz=%d end=%x\n",
e->local_sym_name,
e->text_start_address, e->header.text_size,
e->data_start_address, e->header.data_size,
e->bss_start_address, e->header.bss_size,
e->text_start_address+e->header.image_size
);
}
while(entry)
{
if(entry->library_flag) {
struct file_entry *subentry = entry->subfiles;
while(subentry)
{
print_file(subentry);
subentry = subentry->chain;
}
}
entry = entry->chain;
}
}
/* Start threads */
THREADER(&argc);
if(setjmp(_t_start)) {
THREAD();
}
*VINHIBIT_THREADER += 1;
{
int ret;
int run_argc;
char **run_argv;
run_argc = argc;
run_argv = argv;
chain:
if(appcff)
{
oxlink_use_library(appcff); /* ignored if not a library */
}
run_argv[0] = &appname[1];
if(appfile)
{/* The file could be .o or .cff */
char *filename;
int (*funcptr)();
int loaded = 0;
if(appfile_iscff || !appname_hasextension)
{/* look for a file inside a .cff file */
/* FIRST TRY TO RUN THE APPNAME */
if((ret = oxfunc(appname, run_argc, run_argv)) != -1)
{
oxlink_unload_bare_symb(appname, 0);
loaded = -1;
}
else
{/* try loading object from any defined libraries */
dp = strrchr(appfile, '/')+1;
filename = calloc(1, strlen(dp)+5);
strcpy(filename, dp);
strcpy(strchr(filename,'.'), ".o");
if(!oxlink_load_object(filename))
{
loaded = 1;
}
}
}
if(!loaded)
{/* try loading the file directly */
filename = appfile;
if(oxlink_load_file(filename))
{
VPRINTF("Can't start application `%s'\n", &appname[1]);
VEXIT(1);
}
loaded = 1;
}
if(loaded > 0)
{
if((funcptr = oxlink_find_bare_func("_main")))
{/* Get rid of the symbol `_main' so it doesn't clash */
++newmain[8];
oxlink_rename_symb("_main", newmain);
}
else if(!(funcptr = oxlink_find_bare_func(appname)))
{
VPRINTF("Can't find `_main' or `%s' in file %s\n",
appname, filename);
VEXIT(1);
}
ret = funcptr(run_argc, run_argv);
oxlink_unload_file(filename, 0);
if(filename != appfile)
free(filename);
}
}
else
{/* Just try to run the name from a library */
if((ret = oxfunc(appname, run_argc, run_argv)) == -1)
VPRINTF("Can't start application `%s'\n", &appname[1]);
oxlink_unload_bare_symb(appname, 0);
}
free(appname);
if(appcff)
{
oxlink_nouse_library(appcff);
if(appcff != appfile)
free(appcff);
}
if(appfile)
free(appfile);
if(chainapp)
{/* The previous program chained to a new one */
appname = chainapp;
appfile = chainfile;
appcff = chaincff;
appfile_iscff = chainfile_iscff;
appname_hasextension = chainapp_hasextension;
chainapp = 0;
if(run_argv != argv)
{/* was chained previously, get rid of prev args */
for(i = 1; i < run_argc; ++i)
free(run_argv[i]);
}
run_argc = chainargc;
run_argv = (char**)chainargv;
goto chain;
}
CF_InitIO(-1, 0);
VEXIT(ret);
}
}
void
CF_ChainFile(char *newname, int argc, char **argv)
{/* CALLED FROM APPLICATION TO CHAIN TO ANOTHER PROGRAM */
int i;
char *dp;
chaincff = 0;
chainfile_iscff = 0;
chainapp_hasextension = 0;
chainapp = appnameof(newname);
if((dp = strchr(newname, '.')))
{
chainfile = cf_find_file(newname, 0);
chainapp_hasextension = 1;
}
else chainfile = appfileof(chainapp);
if(chainfile)
{
if((dp = strrchr(chainfile, '.')))
{
if(!strcmp(dp, ".cff"))
{
chainfile_iscff = 1;
chaincff = chainfile;
}
else
{
chaincff = cfffileof(chainapp);
}
}
}
chainargc = argc+1;
for(i = 0; i < argc; ++i)
chainargv[i+1] = copy_of(argv[i]);
}
void
CF_InitIO(long arg, long long (*msgproc)())
{/* THIS FUNCTION IS CALLED FROM THE APPLICATION */
static void (*initio)() = NULL;
if(arg >= 0)
{
AppArg = arg;
initio = oxload(CF_Interactive_IO);
initio(0, msgproc, &VAPPMSG);
}
else if(arg == -1)
{/* deinit */
if(initio)
initio(-1, 0, 0);
}
else
{/* re-init */
if(initio)
initio(arg, 0, 0);
}
}
long long
AppMsg(void *self, void *wnd, long long it)
{
return VAPPMSG(self, wnd, it);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -