Personal tools
You are here: Home Projects C++ Cfront releases Release 3.0.3 source libSC aoutdem parse.c
Document Actions

parse.c

by Michael L Powell last modified 2007-01-26 03:23

Click here to get the file

Size 5.4 kB - File type text/plain

File contents

/*ident	"@(#)aoutdem:parse.c	3.1" */
/******************************************************************************
*
* C++ Standard Components, Release 3.0.
*
* Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc.
* Copyright (c) 1988, 1989, 1990 AT&T.  All Rights Reserved.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System
* Laboratories, Inc.  The copyright notice above does not evidence
* any actual or intended publication of such source code.
*
******************************************************************************/

/* This is a brute force predictive parser for subgrammar of dbx -g strings 
*  that we care about.  For the whole grammar, see dbx(5).
*/

/* Please excuse anything in this file that strikes you as disgusting -- 
*  I assure you, it's all in the name of speed.
*/

#if defined(BSD) || defined(SUNOS)

#include "aoutdem.h"
#include <setjmp.h>


// not consts since we might have to realloc
static int newDbxStringLen = 100;
static char *newDbxString = new char[newDbxStringLen];
static int available;	// space still open in newDbxString
static char *newi;  	// current location in newDbxString 
			// (i.e., always points to the null at the end of the current string)

static char *oldDbxString;
static char *oldi;  // current location in oldDbxString
static char LA;	    // == *oldi

// not consts since we might have to realloc
static int thenameLen = 50;
static char *thename = new char[thenameLen];


static void doTheRealloc()
{
	available += newDbxStringLen;
	newDbxStringLen <<= 1;
	char *tmp = new char[newDbxStringLen];
	strcpy(tmp, newDbxString);
	delete newDbxString;
	newDbxString = tmp;
	newi = newDbxString + strlen(newDbxString);
}

static inline void checkForRealloc(int len)
{
	if (len >= available)  // i think just ">" would be ok, but i don't trust myself.
	{
		doTheRealloc();
	}
}

static void appendToNewDbxString(const char *s, int slen)
{
	checkForRealloc(slen);
	strcpy(newi, s);
	newi += slen;
	available -= slen;
}

static void appendToNewDbxString(char c)
{
	checkForRealloc(1);
	*newi++ = c;
	available--;
	*newi = NULL;
}

static void initParser(char *oldString)
{
	newi = newDbxString;
	*newi = NULL;
	available = newDbxStringLen - 1;

	oldi = oldDbxString = oldString;
	LA = *oldi;
}

inline static void advance()
{
	if (*oldi != NULL)
	{
		oldi++;
		LA = *oldi;
	}
}

inline static void appendToNewDbxStringThenAdvance()
{
	appendToNewDbxString(LA);
	advance();
}

static jmp_buf beginning;

/* the string is not in our subgrammar, so just collect the rest 
*  of it into newDbxString, then longjmp back to the beginning.
*/
static void fail()
{
	while (LA != NULL)
	{
		appendToNewDbxStringThenAdvance();
	}
	longjmp(beginning, 1);
}

inline static void match(char c)
{
	if (LA == c)
		appendToNewDbxStringThenAdvance();
	else
		fail();
}

/*
static void match(char *s)
{
	while (*s)
		match(*s++);
}
*/

/* match one of the chars in s
*/
/*
static void matchone(char *s)
{
	while (*s)
	{
		if (LA == *s++)
		{
			appendToNewDbxStringThenAdvance();
			return;
		}
	}
	fail();
}
*/

static void matchthru(char c)
{
	while (LA != c && LA != NULL)
		appendToNewDbxStringThenAdvance();
	match(c);
}

static void integer()
{
	if (LA == '-')
		appendToNewDbxStringThenAdvance();

	if (isdigit(LA))
	{
		appendToNewDbxStringThenAdvance();
		while (isdigit(LA))
			appendToNewDbxStringThenAdvance();
	}
	else
		fail();
}

static void aggregateHeader()
{
	match('T');
#ifdef SUNOS
	match('(');
#endif
	integer();
#ifdef SUNOS
	match(',');
	integer();
	match(')');
#endif
	match('=');
	if (LA == 's')
		match('s');
	else
		match('u');
	integer();
}

/* puts name in thename, and returns length of name
*/
static int name()
{
	if (!isalpha(LA) && LA != '_')
	{
		fail();
		return 0;
	}
	else 
	{
		char *from = oldi;
		MARK(nameLoop);
		for (advance(); isalnum(LA) || LA == '_'; advance())
			;
		int len = oldi-from;
		if (len+1 > thenameLen)
		{
			delete thename;
			thename = new char[thenameLen = len+1];
		}
 		strncpy(thename, from, len);
		thename[len] = NULL;
		return len;
	}
}

static int lastEntryWasContinued = 0;

static void aggregateMembers(int stetype)
{
	while (LA != NULL)
	{
		if (isalpha(LA) || LA == '_')
		{
			int namelen = name();
			String s = demangleAndSimplify(String(thename, namelen), 1, stetype);
			appendToNewDbxString(s, s.length());
			match(':');
		}
		else if (LA == '\\')
		{
			lastEntryWasContinued = 1;
			fail();
		}
		matchthru(';');
	}
}

static void parseTheString(int stetype)
{
	if (lastEntryWasContinued)
	{
		lastEntryWasContinued = 0;
		aggregateMembers(stetype);
	}
	else
	{
		int namelen = name();
		if (LA == NULL)  // then it's probably text or data.
		{
			String s = demangleAndSimplify(String(thename, namelen), 0, stetype);
			appendToNewDbxString(s, s.length());
		}
		else if (LA != ':') // heaven only knows what this entry is.  probably a file name.
		{
			appendToNewDbxString(thename, namelen);
			fail();
		}
		else
		{
			String s = demangleAndSimplify(String(thename, namelen), 0, stetype);
			appendToNewDbxString(s, s.length());
			match(':');
			aggregateHeader();
			aggregateMembers(stetype);
		}
	}
}

String parseDbxString(char *s, int stetype)
{
	initParser(s);
	if (setjmp(beginning)) 
	{
		/* parsing returns here on fail()ure */
	}
	else
	{
		parseTheString(stetype);
	}
	if (verboseDbx)
	{
		cerr << "\n\t" << oldDbxString << " =>\n\n\t" << newDbxString << endl;
	}
	return String(newDbxString, newi-newDbxString);
}


#endif
« April 2014 »
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: