view ticoff/hints.c @ 126:2c6b1319383b

tiobjd: first preparations for adding disasm hints mechanism
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sat, 05 Apr 2014 19:14:43 +0000
parents
children a314d6aa9bf1
line wrap: on
line source

/*
 * Parsing of the disassembly hints file
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include "intstruct.h"
#include "globals.h"

static char *filename_for_err;
static int lineno;
static struct internal_scnhdr *section;
static struct hint **hint_link;

static void
set_section(name)
	char *name;
{
	unsigned n;
	struct internal_scnhdr *sec = 0;

	for (n = 0; n < nsections; n++)
		if (!strcmp(sections[n].name, name)) {
			sec = sections + n;
			break;
		}
	if (!sec) {
		fprintf(stderr, "%s line %d: no section named \"%s\" in %s\n",
			filename_for_err, lineno, name, objfilename);
		exit(1);
	}
	if (sec->sectype_hint || sec->hints) {
		fprintf(stderr, "%s line %d: [%s] given more than once\n",
			filename_for_err, lineno, name);
		exit(1);
	}
	section = sec;
	hint_link = &sec->hints;
}

static void
set_mode(arg)
	char *arg;
{
	char *cp;

	if (!section) {
		fprintf(stderr,
			"%s line %d: error: mode line outside of section\n",
			filename_for_err, lineno);
		exit(1);
	}
	if (section->sectype_hint) {
		fprintf(stderr,
			"%s line %d: mode given more than once for [%s]\n",
			filename_for_err, lineno, section->name);
		exit(1);
	}
	while (isspace(*arg))
		arg++;
	if (!*arg) {
		fprintf(stderr, "%s line %d: mode line: missing argument\n",
			filename_for_err, lineno);
		exit(1);
	}
	for (cp = arg; *cp && !isspace(*cp); cp++)
		;
	if (*cp)
		*cp++ = '\0';
	if (!strcmp(arg, "code"))
		section->sectype_hint = SECTYPE_CODE;
	else if (!strcmp(arg, "data"))
		section->sectype_hint = SECTYPE_DATA;
	else if (!strcmp(arg, "bss"))
		section->sectype_hint = SECTYPE_BSS;
	else {
		fprintf(stderr, "%s line %d: unknown mode \"%s\"\n",
			filename_for_err, lineno, arg);
		exit(1);
	}
}

static void
regular_hint(arg1, arg2)
	char *arg1, *arg2;
{
	fprintf(stderr, "error: regular hints not implemented yet\n");
	exit(1);
}

read_hints_file(filename)
	char *filename;
{
	FILE *f;
	char linebuf[128], *cp, *np;

	f = fopen(filename, "r");
	if (!f) {
		perror(filename);
		exit(1);
	}
	filename_for_err = filename;
	for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) {
		for (cp = linebuf; isspace(*cp); cp++)
			;
		if (!*cp || *cp == '#')
			continue;
		if (*cp == '[') {
			np = ++cp;
			cp = index(cp, ']');
			if (!cp) {
				fprintf(stderr,
					"%s line %d: invalid section syntax\n",
					filename, lineno);
				exit(1);
			}
			*cp = '\0';
			set_section(np);
			continue;
		}
		for (np = cp; *cp && !isspace(*cp); cp++)
			;
		if (*cp)
			*cp++ = '\0';
		if (!strcmp(np, "mode")) {
			set_mode(cp);
			continue;
		}
		regular_hint(np, cp);
	}
	fclose(f);
	return(0);
}