📄 module.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <ctype.h>
#include "cmdline.h"
#include "umem.h"
#include "module.h"
#include "register.h"
#include "maker.h"
#include "interp.h"
#include "phash.h"
#define OBJECT_BUFFER_SIZE 256
extern HASHREC **hashtable;
extern short xpath[];
BOOL prm_case_sensitive = TRUE;
extern BOOL prm_autodepends;
static short xspace[] =
{
0x20, 0
};
static BYTE objectbuffer[OBJECT_BUFFER_SIZE]; /* Record buffer */
static long offset; /* Current offset in file */
static int left = 0;
static BYTE *bptr;
static FILE *curfile;
static char *curname;
static short *curbuf;
static BOOL endofmodule;
static BYTE putbackbuf;
void ReadHeader(void);
void CheckSum(void);
void ModEnd(void);
void SetMAUs(void);
void Assign(void);
void DateTime(void);
void Comment(void);
void EnumeratedData(void);
void ReadFixup(void);
void PublicDefinitions(void);
void ExternDefinitions(void);
void SectionAlignment(void);
void SectionStart(void);
void SectionDefinitions(void);
void PublicSetAttribs(void);
/* List of defined MUFOM records. Bit defs:
* TE_REPORT: Generate a warning message for this record
* TE_IGNORE: Ignore the record
*/
static TYPEXEC main_exec_list[] =
{
{
"AD", TE_REPORT - TE_REPORT, SetMAUs
}
,
{
"AS", TE_REPORT - TE_REPORT, Assign
}
,
{
"AT", TE_REPORT - TE_REPORT, PublicSetAttribs
}
,
{
"CO", TE_REPORT - TE_REPORT, Comment
}
,
{
"CS", TE_REPORT - TE_REPORT, CheckSum
}
,
{
"DT", TE_REPORT - TE_REPORT, DateTime
}
,
{
"LD", TE_REPORT - TE_REPORT, EnumeratedData
}
,
{
"LR", TE_REPORT - TE_REPORT, ReadFixup
}
,
{
"MB", TE_REPORT - TE_REPORT, ReadHeader
}
,
{
"ME", TE_REPORT - TE_REPORT, ModEnd
}
,
{
"NI", TE_REPORT - TE_REPORT, PublicDefinitions
}
,
{
"NN", TE_REPORT - TE_REPORT, ExternDefinitions
}
,
{
"NX", TE_REPORT - TE_REPORT, ExternDefinitions
}
,
{
"SA", TE_REPORT - TE_REPORT, SectionAlignment
}
,
{
"SB", TE_REPORT - TE_REPORT, SectionStart
}
,
{
"ST", TE_REPORT - TE_REPORT, SectionDefinitions
}
,
{
"\0\0", 0, 0
}
};
long theoffset(void)
{
return (offset - left);
}
/*
* Quit with a message if a bad record is encountered
*/
void BadObjectFile(void)
{
fatal("Bad object module %s near file offset 0x%x", curname, theoffset());
}
//-------------------------------------------------------------------------
void CheckForPeriod(void)
{
if (ReadChar() != '.')
BadObjectFile();
}
//-------------------------------------------------------------------------
BOOL CheckForComma(BOOL musthave)
{
BYTE rv = ReadChar();
if (rv == ',')
return (TRUE);
if (musthave || rv != '.')
BadObjectFile();
return (FALSE);
}
//-------------------------------------------------------------------------
void WadeToPeriod(void)
{
while (ReadChar() != '.')
;
}
/*
* Perform function
*/
static void ReadHeader(void)
{
BYTE rv;
char buffer[100];
short buf2[100];
rv = ReadChar();
while ((rv) != '.' && rv != ',')
rv = ReadChar();
if (rv == ',')
{
int i;
ReadString(buffer, 60);
CheckForPeriod();
for (i = 0; i < strlen(buffer); i++)
buffer[i] = tolower(buffer[i]);
ExpandFile(buf2, buffer);
pstrcat(curbuf, buf2);
pstrcat(curbuf, xspace);
}
}
//-------------------------------------------------------------------------
static void ModEnd(void)
{
WadeToPeriod();
endofmodule = TRUE;
}
//-------------------------------------------------------------------------
static void Comment(void)
{
char buffer[100];
short buf2[100];
int val = ReadNumber(0);
CheckForComma(TRUE);
ReadString(buffer, 100);
CheckForPeriod();
if (val == 0x102)
{
int i;
for (i = 0; i < strlen(buffer); i++)
buffer[i] = tolower(buffer[i]);
ExpandFile(buf2, buffer);
pstrcat(curbuf, buf2);
pstrcat(curbuf, xspace);
}
else if (val == 0x101)
endofmodule = TRUE;
}
//-------------------------------------------------------------------------
static void CheckSum(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
static void SetMAUs(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
static void Assign(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
static void DateTime(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void EnumeratedData(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void ReadFixup(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void PublicDefinitions(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void ExternDefinitions(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void SectionAlignment(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void SectionStart(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void SectionDefinitions(void)
{
WadeToPeriod();
}
//-------------------------------------------------------------------------
void PublicSetAttribs(void)
{
WadeToPeriod();
}
/*
* Read data into the objectbuffer
*/
void ReadFile(void)
{
if (!feof(curfile))
{
left = fread(objectbuffer, 1, OBJECT_BUFFER_SIZE, curfile);
offset += left;
if (left < 0)
fatal("File read error in module %s", curname);
bptr = objectbuffer;
}
}
/*
* Read a char & do checksumming
*/
BYTE ReadCharNOCS(void)
{
BYTE rv;
if (putbackbuf)
{
rv = putbackbuf;
putbackbuf = 0;
return (rv);
}
while (TRUE)
{
if (!left)
{
ReadFile();
if (!left)
fatal("missing modend statement in module %s", curname);
}
left--;
rv = *bptr++;
if (rv > 31)
break;
}
return (rv);
}
//-------------------------------------------------------------------------
BYTE ReadChar(void)
{
BYTE rv = ReadCharNOCS();
return (rv);
}
//-------------------------------------------------------------------------
void putback(BYTE ch)
{
putbackbuf = ch;
}
//-------------------------------------------------------------------------
long ReadNumber(uint digits)
{
int i;
long rv = 0;
if (!digits)
digits = 200;
for (i = 0; i < digits; i++)
{
BYTE ch = ReadChar();
if (!isxdigit(ch))
{
putback(ch);
break;
}
rv *= 16;
ch -= '0';
if (ch > 9)
ch -= 7;
rv += ch;
}
return (rv);
}
//-------------------------------------------------------------------------
void ReadString(char *buf, int len)
{
int slen = (int)(ReadNumber(2)), i;
int rlen = slen > len - 1 ? len - 1: slen;
for (i = 0; i < rlen; i++)
if (prm_case_sensitive)
buf[i] = ReadChar();
else
buf[i] = toupper(ReadChar());
if (rlen >= 0)
buf[rlen] = 0;
else
rlen = 0;
for (i = rlen; i < slen; i++)
ReadChar();
}
/*
* Read and execute an object record
*/
static uint ReadObjectRecord(void)
{
uint command;
TYPEXEC *p = main_exec_list;
command = ReadChar() + (ReadChar() << 8);
/* Search the dispatch table */
while (p->select[0])
{
if (*((uint*)p->select) == command)
{
uint temp = p->flags;
if (temp &TE_REPORT)
printf(
"Record type %c%c ignored at offset 0x%lx in module %s\n",
p->select[0], p->select[1], theoffset() - 2, curname);
if (temp &TE_ERROR)
return (MODERR);
if ((temp &TE_IGNORE) || !p->run)
/* Undefined functions are ignored, better have the TE_REPORT bit
set!!! */
return (MODIGNORE);
/* Dispatch the function */
p->run();
break;
}
p++;
}
/* Return an error if not found */
if (p->select[0] == 0)
return (MODERR);
/* Return the record type if was found */
return (command);
}
//-------------------------------------------------------------------------
void SetForRead(FILE *infile)
{
offset = 0;
curfile = infile;
endofmodule = FALSE;
}
//-------------------------------------------------------------------------
void UnsetForRead(void)
{
left -= 2;
bptr += 2;
}
/*
* Read in a module
*/
uint ReadModule(FILE *infile, BOOL sof)
{
uint temp;
offset = 0;
if (sof)
left = 0;
curfile = infile;
endofmodule = FALSE;
while (!endofmodule)
{
switch (temp = ReadObjectRecord())
{
case MODERR:
BadObjectFile();
case MODQUIT:
endofmodule = TRUE;
break;
}
}
return (temp);
}
//-------------------------------------------------------------------------
short *GetAutoDepends(short *name)
{
FILE *file = 0;
char cbuf[11];
char namebuf[100], namepath[200];
short extpath[100], lbuf[4096], *adptr;
short *p = pstrrchr(name, '.');
if (!prm_autodepends)
return 0;
CompressFile(namebuf, name);
if (p && *(p - 1) != '.')
{
REGISTRY **r;
pstrcpy(extpath, xpath);
pstrcat(extpath, p);
r = LookupPhiHash(hashtable, extpath);
if (r && (*r)->type == R_PATH)
{
CompressFile(namepath, (*r)->x.path);
file = SearchPath(namebuf, namepath, "rb");
}
}
if (!file)
if (!(file = fopen(namebuf, "rb")))
return 0;
fgets(cbuf, 10, file);
if (cbuf[0] != 'M' || cbuf[1] != 'B')
{
fclose(file);
return 0;
}
rewind(file);
curname = namebuf;
curbuf = lbuf;
lbuf[0] = 0;
ReadModule(file, TRUE);
fclose(file);
if (lbuf[0])
{
adptr = AllocateMemory(pstrlen(lbuf) *2+2);
pstrcpy(adptr, lbuf);
}
else
adptr = 0;
return adptr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -