* 29-Oct-97 JLH pass ";!" comments to output file
*/
+#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
* references the usage text strings printed by usage().
*/
+static const char *search_path[100];
+static int search_path_length;
+
+/**
+ * The search_path_append is used to append another directory to the end
+ * of the include file search path.
+ *
+ * @param dir
+ * The directory to be added to the path.
+ */
+void
+search_path_append(const char *dir)
+{
+ if (search_path_length < sizeof(search_path)/sizeof(char*))
+ {
+ search_path[search_path_length++] = dir;
+ }
+}
+
+/**
+ * The search_path_fopen function is used to open the named file. If
+ * the file isn't in the current directory, the search path is then used
+ * to build a series of possible file names, and attempts to open them.
+ * The first found is used.
+ *
+ * @param filename
+ * The name of the file to be opened.
+ * @param mode
+ * The mode of the file to be opened.
+ * @returns
+ * what the fopen function would return on success, or NULL if the
+ * file is not anywhere in the search path.
+ */
+static FILE *
+search_path_fopen(const char *filename, const char *mode)
+{
+ FILE *fp;
+ int j;
+
+ fp = fopen(filename, mode);
+ if (fp != NULL || filename[0] == '/' || filename[0] == '\\')
+ return fp;
+ for (j = 0; j < search_path_length; ++j)
+ {
+ char path[2000];
+
+ strncpy(path, search_path[j], sizeof(path));
+ if ((path[strlen(path) - 1] != '/') &&
+ (path[strlen(path) - 1] != DIR_SEPARATOR_CHAR))
+ {
+ strncat(path, DIR_SEPARATOR_STRING, sizeof(path));
+ }
+ strncat(path, filename, sizeof(path));
+ fp = fopen(path, mode);
+ if (fp != NULL)
+ return fp;
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
/*)Function VOID main(argc, argv)
*
* int argc argument count
char relFile[128];
int
-main(argc, argv)
-char *argv[];
+main(int argc, char *argv[])
{
register char *p;
register int c, i;
case 'c':
case 'C':
- ++cflag;
- break;
+ ++cflag;
+ break;
case 'g':
case 'G':
++gflag;
break;
+ case 'i':
+ case 'I':
+ search_path_append(p);
+ while (*p)
+ ++p;
+ break;
+
case 'j': /* JLH: debug info */
case 'J':
++jflag;
if (lflag)
lfp = afile(p, "lst", 1);
if (oflag) {
- ofp = afile(p, "rel", 1);
- // save the file name if we have to delete it on error
- strcpy(relFile,afn);
+ ofp = afile(p, "rel", 1);
+ // save the file name if we have to delete it on error
+ strcpy(relFile,afn);
}
if (sflag)
tfp = afile(p, "sym", 1);
radix = 10;
srcline[0] = 0;
page = 0;
+ org_cnt = 0;
stb[0] = 0;
lop = NLPP;
cfile = 0;
*/
VOID
-asexit(i)
-int i;
+asexit(int i)
{
int j;
*/
VOID
-asmbl()
+asmbl(void)
{
register struct mne *mp;
register struct sym *sp;
char fn[PATH_MAX];
char *p;
int d, n, uaf, uf;
+ static struct area *abs_ap; /* pointer to current absolute area structure */
laddr = dot.s_addr;
lmode = SLIST;
lmode = SLIST;
break;
- case S_OPTSDCC:
+ case S_OPTSDCC:
p = optsdcc;
if ((c = getnb()) != 0) {
do {
*p = 0;
unget(c);
lmode = SLIST;
- /*if (pass == 0) printf("optsdcc=%s\n", optsdcc);*/
- break;
+ /*if (pass == 0) printf("optsdcc=%s\n", optsdcc);*/
+ break;
case S_GLOBL:
do {
}
newdot(ap);
lmode = SLIST;
+ if (dot.s_area->a_flag & A_ABS)
+ abs_ap = ap;
break;
case S_ORG:
if (dot.s_area->a_flag & A_ABS) {
- outall();
- laddr = dot.s_addr = dot.s_org = absexpr();
+ char buf[NCPS];
+
+ laddr = absexpr();
+ sprintf(buf, "%s%x", abs_ap->a_id, org_cnt++);
+ if ((ap = alookup(buf)) == NULL) {
+ ap = (struct area *) new (sizeof(struct area));
+ *ap = *areap;
+ ap->a_ap = areap;
+ strncpy(ap->a_id, buf, NCPS);
+ ap->a_ref = areap->a_ref + 1;
+ ap->a_size = 0;
+ ap->a_fuzz = 0;
+ areap = ap;
+ }
+ newdot(ap);
+ lmode = ALIST;
+ dot.s_addr = dot.s_org = laddr;
} else {
err('o');
}
- outall();
- lmode = ALIST;
break;
case S_RADIX:
}
*p = 0;
if ((++incfil == MAXINC) ||
- (ifp[incfil] = fopen(fn, "r")) == NULL) {
+ (ifp[incfil] = search_path_fopen(fn, "r")) == NULL) {
--incfil;
err('i');
} else {
*/
FILE *
-afile(fn, ft, wf)
-char *fn;
-char *ft;
-int wf;
+afile(char *fn, char *ft, int wf)
{
register char *p2, *p3;
register int c;
*/
VOID
-newdot(nap)
-register struct area *nap;
+newdot(register struct area *nap)
{
register struct area *oap;
}
} else if (oap->a_flag & A_ABS) {
oap->a_addr = dot.s_org;
- oap->a_size = dot.s_addr - dot.s_org;
+ oap->a_size += dot.s_addr - dot.s_org;
+ dot.s_addr = dot.s_org = 0;
} else {
oap->a_addr = 0;
oap->a_size = dot.s_addr;
// a new overlay starts at 0, no fuzz
dot.s_addr = 0;
fuzz = 0;
+ } else if (nap->a_flag & A_ABS) {
+ // a new absolute starts at org, no fuzz
+ dot.s_addr = dot.s_org;
+ fuzz = 0;
} else {
dot.s_addr = nap->a_size;
fuzz = nap->a_fuzz;
*/
VOID
-phase(ap, a)
-struct area *ap;
-Addr_T a;
+phase(struct area *ap, Addr_T a)
{
if (ap != dot.s_area || a != dot.s_addr)
err('p');
}
char *usetxt[] = {
- "Usage: [-dqxjgalopsf] file1 [file2 file3 ...]",
+ "Usage: [-dqxjgalopsf][ -I<dir> ] file1 [file2 file3 ...]",
" d decimal listing",
" q octal listing",
" x hex listing (default)",
" p disable listing pagination",
" f flag relocatable references by ` in listing file",
" ff flag relocatable references by mode in listing file",
+ "-I<dir> Add the named directory to the include file",
+ " search path. This option may be used more than once.",
+ " Directories are searched in the order given.",
"",
0
};
*/
VOID
-usage()
+usage(void)
{
register char **dp;