view blobstat/readclass.c @ 406:1a852266ba74 default tip

tfo moved to gsm-net-reveng repository
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 May 2024 21:19:59 +0000
parents 23e5b940cb8b
children
line wrap: on
line source

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

extern struct category *category_list;
extern struct libentry *libentry_list;

static struct category *
find_or_create_cat(catname)
	char *catname;
{
	struct category *p, **pp;
	char *buf;

	for (pp = &category_list; p = *pp; pp = &p->next)
		if (!strcmp(p->name, catname))
			return(p);
	buf = malloc(sizeof(struct category) + strlen(catname) + 1);
	if (!buf) {
		perror("malloc");
		exit(1);
	}
	p = (struct category *) buf;
	p->name = buf + sizeof(struct category);
	strcpy(p->name, catname);
	p->accum = 0;
	p->next = 0;
	*pp = p;
	return(p);
}

static
add_whole_lib(libname, cat)
	char *libname;
	struct category *cat;
{
	struct libentry *p, **pp;
	char *buf;

	for (pp = &libentry_list; p = *pp; pp = &p->next)
		if (!strcmp(p->libname, libname))
			return(-1);
	buf = malloc(sizeof(struct libentry) + strlen(libname) + 1);
	if (!buf) {
		perror("malloc");
		exit(1);
	}
	p = (struct libentry *) buf;
	p->libname = buf + sizeof(struct libentry);
	strcpy(p->libname, libname);
	p->member = 0;
	p->cat = cat;
	p->next = 0;
	*pp = p;
	return(0);
}

static
add_lib_member(libname, member, cat)
	char *libname, *member;
	struct category *cat;
{
	struct libentry *p, **pp;
	char *buf;

	for (pp = &libentry_list; p = *pp; pp = &p->next) {
		if (strcmp(p->libname, libname))
			continue;
		if (!p->member || !strcmp(p->member, member))
			return(-1);
	}
	buf = malloc(sizeof(struct libentry) + strlen(libname) +
			strlen(member) + 2);
	if (!buf) {
		perror("malloc");
		exit(1);
	}
	p = (struct libentry *) buf;
	buf += sizeof(struct libentry);
	p->libname = buf;
	strcpy(p->libname, libname);
	buf += strlen(libname) + 1;
	p->member = buf;
	strcpy(p->member, member);
	p->cat = cat;
	p->next = 0;
	*pp = p;
	return(0);
}

static void
process_line(linebuf, lineno, filename_for_errs)
	char *linebuf, *filename_for_errs;
	int lineno;
{
	char *cp, *libname, *member, *catname;
	struct category *cat;
	int rc;

	for (cp = linebuf; isspace(*cp); cp++)
		;
	if (*cp == '\0' || *cp == '#')
		return;
	for (libname = cp; *cp && !isspace(*cp); cp++)
		;
	if (!*cp) {
inv:		fprintf(stderr, "%s line %d: invalid syntax\n",
			filename_for_errs, lineno);
		exit(1);
	}
	*cp++ = '\0';
	while (isspace(*cp))
		cp++;
	if (*cp == '\0' || *cp == '#')
		goto inv;
	for (catname = cp; *cp && !isspace(*cp); cp++)
		;
	if (*cp)
		*cp++ = '\0';
	while (isspace(*cp))
		cp++;
	if (*cp != '\0' && *cp != '#')
		goto inv;
	member = index(libname, ':');
	if (member)
		*member++ = '\0';
	cat = find_or_create_cat(catname);
	if (member)
		rc = add_lib_member(libname, member, cat);
	else
		rc = add_whole_lib(libname, cat);
	if (rc < 0) {
		fprintf(stderr,
			"%s line %d: conflict with earlier declaration\n",
			filename_for_errs, lineno);
		exit(1);
	}
}

read_class_file(filename)
	char *filename;
{
	FILE *inf;
	int lineno;
	char linebuf[512];

	inf = fopen(filename, "r");
	if (!inf) {
		perror(filename);
		exit(1);
	}
	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++)
		process_line(linebuf, lineno, filename);
	fclose(inf);
	return(0);
}