|
getbuf.c
Click here to get the file
Size
11.6 kB
-
File type
text/plain
File contents
/*ident "@(#)G2++:g2++lib/getbuf.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.
*
******************************************************************************/
#include <g2debug.h>
#include <g2ctype.h>
#include <g2io.h>
#include <g2manip.h>
#include <stdlib.h>
#include <iostream.h>
#ifdef __GNUG__
#define IOSTREAMH
#endif
static char sccs_id[] = "@(#)G2++ library, version 093096";
extern int seekflag_ATTLC; // should be in a header file
extern String seekname_ATTLC; // "
// Local functions
static int
discard(int c, istream& is);
static G2BUF*
getbody(G2BUF* bp, const String& name, istream& is);
static int
getchild(G2BUF* bp, int lvl, int peek, istream& is,
G2NODE *&parent_node, const String& name);
static int xindent; // for passing indent between levels
int getchar_G2_ATTLC(istream& is) {
int retval;
#ifdef IOSTREAMH
retval = is.get();
if(retval==BS_EOF)is.clear(is.rdstate() | ios::failbit);
#else
unsigned char c_char;
is.get(c_char);
if(is) retval = c_char;
else retval = BS_EOF;
#endif
return retval;
}
G2BUF*
getbuf_ATTLC(G2BUF* bp, istream& is){
DEBUG(cerr << "enter getbuf_ATTLC\n";)
g2init_ATTLC(bp);
// If seekflag is set, this should be a call
// to getbody
if (seekflag_ATTLC){
seekflag_ATTLC=0;
return(getbody(bp,seekname_ATTLC,is));
}
String name=getname_ATTLC(is);
if (name.is_empty()){
return NULL;
}
DEBUG(cerr
<< "in getbuf_ATTLC, get name="
<< name
<< "\n"
;)
return getbody(bp,name,is);
}
static G2BUF*
getbody(G2BUF* bp, const String& name, istream& is){
DEBUG(cerr
<< "enter getbody with name="
<< name
<< "\n"
;)
int cur;
G2NODE header_node;
header_node.child = 0;
header_node.next = 0;
// Clear seekflag in case it is set
seekflag_ATTLC=0;
// Local node buffer allocation pointer (incremented)
cur = getchar_G2_ATTLC(is);
if (cur == BS_EOF){
return NULL;
}
// Call getchild
DEBUG(cerr << "ready to call getchild\n";)
G2NODE *header_ptr = &header_node;
cur = getchild(
bp, // pointer to G2BUF
0, // level
cur, // current character
is, // input stream
header_ptr, // pointer to parent node
name // record name
);
// Fix up
bp->root = header_node.child;
DEBUG(cerr << "back in getbody, *bp=\n";)
DEBUG(showbuf_ATTLC(bp);)
// Process attributes
while (cur == '.'){
cur = _g2getdot_ATTLC(is);
}
DEBUG(cerr
<< "after getdot loop, cur = ASCII "
<< cur
<< " ("
<< char(cur)
<< ")"
<< "\n"
;)
if (cur == '\n' || cur == BS_EOF){
return bp;
}
if (isname1_ATTLC(cur)){
DEBUG(cerr << "isname1_ATTLC(cur) returns 1\n";)
is.putback(cur);
return bp;
}
_g2sync_ATTLC(cur,is);
DEBUG(cerr
<< "after sync, ready return with cur = ASCII "
<< cur
<< " ("
<< char(cur)
<< ")"
<< "\n"
;)
return bp;
}
static int
getchild(G2BUF* bp, int level, int c, istream& is,
G2NODE *&parent_node, const String& name){
DEBUG(cerr
<< "enter getchild with\n"
<< " level="
<< level
<< "\n"
<< " c = ASCII "
<< c
<< " ("
<< char(c)
<< ")"
<< "\n"
<< " parent_node = "
<< (void*)parent_node
<< "\n"
<< " name="
<< name
<< "\n"
;)
int indent = level;
int first = 1;
G2NODE* curr_node = 0;
int curr_offset = -1; // added to solve curr_node error - dmm 5/13/96
if (level >= G2MAXDEPTH_ATTLC){
g2error_ATTLC(G2TOODEEP);
return c;
}
top:
DEBUG(cerr << "at label top\n";)
// added to solve curr_node error - dmm 5/13/96
if (curr_offset != -1)
curr_node = (G2NODE*)((char*)(bp->base) + curr_offset);
else
curr_node = 0;
for(;;){
if (c == BS_EOF){
DEBUG(cerr << "hit eof -- break\n";)
indent = 0;
break;
}
// Linkage
if (bp->ptr >= bp->end){
// abort(); // jfi
// The following code is wrong. Changing the size of
// a block relocates the contents, invalidating
// pointers (jfi). For now, we prevent the code
// from executing by aborting (see above).
// bp->buf.size((unsigned int)(1.414*bp->buf.size()));
// bp->base = bp->ptr = bp->buf;
// DEBUG(cerr
// << "increase node buffer size to "
// << (G2NODE*)bp->buf.end()-(G2NODE*)bp->buf
// << "\n"
// ;)
// The following code should be right. Changing the
// size of a block will relocate the contents, so all
// of the pointers must be modified. The only pointers
// into this Block are:
//
// - the bp->base, bp->ptr, bp->buf, and bp->end pointers
// - the child and next pointers of the G2NODE objects
// within the Block
// - the parent_node pointer and its child and next fields (if level != 0)
// - the curr_node pointer
G2NODE *oldbase = bp->base;
G2NODE *oldpnchild = parent_node->child;
G2NODE *oldpnnext = parent_node->next;
DEBUG(cerr
<< "before:\n"
<< "bp->base=" << (void*)bp->base << "\n"
<< "bp->ptr=" << (void*)bp->ptr << "\n"
<< "bp->buf=" << (void*)(G2NODE*)bp->buf << "\n"
<< "bp->end=" << (void*)bp->end << "\n"
<< "parent_node->child=" << (void*)parent_node->child << "\n"
<< "parent_node->next=" << (void*)parent_node->next << "\n"
<< "curr_node=" << (void*)curr_node << "\n"
;)
int oldsize = bp->buf.size();
bp->buf.size((unsigned int)(1.414*bp->buf.size()));
bp->base = bp->ptr = bp->buf;
bp->end = bp->buf.end();
DEBUG(cerr
<< "increase node buffer size to "
<< (G2NODE*)bp->buf.end()-(G2NODE*)bp->buf
<< "\n"
;)
// this is the amount of the "fixup" that needs to
// be applied to all pointers
int diff = (char*)bp->base - (char*)oldbase;
DEBUG(cerr << "diff=" << diff << "\n" ;)
// fix up all of the pointers
if (oldsize != 0 && diff != 0) {
G2NODE *newbase = bp->base;
if (level != 0) {
parent_node = (G2NODE*)((char*)parent_node + diff);
//parent_node->child = (G2NODE*)((char*)oldpnchild + diff);
//parent_node->next = (G2NODE*)((char*)oldpnnext + diff);
}
if (curr_node != 0) // added to solve curr_node error - dmm 5/13/96
curr_node = (G2NODE*)((char*)curr_node + diff);
int i;
for (i = 0; i < oldsize; i++) {
if (newbase->child != 0)
newbase->child = (G2NODE*)((char*)newbase->child + diff);
else newbase->child = 0;
if (newbase->next != 0)
newbase->next = (G2NODE*)((char*)newbase->next + diff);
else newbase->next = 0;
newbase++;
}
bp->ptr = newbase;
}
DEBUG(cerr
<< "after:\n"
<< "bp->base=" << (void*)bp->base << "\n"
<< "bp->ptr=" << (void*)bp->ptr << "\n"
<< "bp->buf=" << (void*)(G2NODE*)bp->buf << "\n"
<< "bp->end=" << (void*)bp->end << "\n"
<< "parent_node->child=" << (void*)parent_node->child << "\n"
<< "parent_node->next=" << (void*)parent_node->next << "\n"
<< "curr_node=" << (void*)curr_node << "\n"
;)
////// end of new code for reallocating the Block
}
if (first){
DEBUG(cerr << "first pass through loop\n";)
first = 0;
curr_offset = (char*)(bp->ptr) - (char*)(bp->base);
curr_node = parent_node->child = bp->ptr++;
DEBUG(cerr
<< "set curr_node and parent_node->child to "
<< (void*)curr_node
<< "\n"
;)
}else{
DEBUG(cerr << "subsequent pass through loop\n";)
curr_offset = (char*)(bp->ptr) - (char*)(bp->base);
curr_node = curr_node->next = bp->ptr++;
DEBUG(cerr
<< "set curr_node and curr_node->next to "
<< (void*)curr_node
<< "\n"
;)
}
curr_node->next = NULL;
curr_node->child = NULL;
// Get name
if (!name.is_empty()){
DEBUG(cerr << "name is non-empty\n";)
// True when the 'name' parameter is non-null
// (when getchild is called from getbody)
DEBUG(cerr
<< "before assignment:\n"
<< " name = "
<< name
<< "\n"
<< " curr_node="
<< (void*)curr_node
<< "\n"
<< " curr_node->name="
<< curr_node->name
<< "\n"
;)
curr_node->name = name;
DEBUG(cerr
<< "curr_node->name = "
<< curr_node->name
<< "\n"
;)
}else{
// True when 'name' parameter is the empty string
// (when called recursively).
// Get the name from the input file.
DEBUG(cerr << "name is empty\n";)
curr_node->name="";
if (c == '.'){
curr_node->name=".";
c = getchar_G2_ATTLC(is);
}
DEBUG(cerr << "get into curr_node->name: ";)
while (isname2_ATTLC(c)){
DEBUG(cerr << char(c);)
curr_node->name += c;
c = getchar_G2_ATTLC(is);
}
DEBUG(cerr << "\n";)
DEBUG(cerr
<< "exit from loop with c = ASCII "
<< c
<< " ("
<< char(c)
<< ")"
<< "\n"
;)
}
curr_node->val=""; // dmm, 11/17/95
if (c == '\t'){
// Get value
DEBUG(cerr << "c is a tab -- append value: ";)
curr_node->val=""; // jfi
for( ;; ){
c = getchar_G2_ATTLC(is);
if (!is || !isprint_ATTLC(c)) break;
curr_node->val += c;
DEBUG(cerr << char(c);)
}
DEBUG(cerr << "\n";)
}
if (c != '\n' && (c=discard(c,is)) == BS_EOF){
indent = 0;
break;
}
for(;;){
// Get indent
DEBUG(cerr << "at top of inner for(;;), count tabs\n";)
indent = 0;
for( ;; ){
c = getchar_G2_ATTLC(is);
if( c!= '\t' )break;
indent++;
}
DEBUG(cerr
<< "indent, c = "
<< indent
<< ","
<< char(c)
<< "\n"
;)
if (isname2_ATTLC(c) || c == '.'){
// Decisions
DEBUG(cerr
<< "make decisions for indent, level="
<< indent
<< ","
<< level
<< "\n"
;)
if (indent == level+1){
// This is a child: recurse
DEBUG(cerr << "ready to call getchild recursively\n";)
c=getchild(
bp, // pointer to G2BUF
level+1, // level
c, // current character
is, // input file
curr_node, // pointer to parent
"" // no name
);
indent = xindent;
DEBUG(cerr
<< "back from call to getchild, set indent to "
<< xindent
<< "\n"
;)
}
if (indent <= 0){
// End of record (?)
DEBUG(cerr << "indent<=0 (end of record)\n";)
goto out;
}
if (indent == level){
// This is a sibling
DEBUG(cerr << "indent==level (a sibling)\n";)
goto top;
}
if (indent < level){
// End of siblings
DEBUG(cerr << "indent <level (end of siblings)\n";)
goto out;
}
// (indent > level+1) falls through
}
DEBUG(cerr << "indent>level+1 (fall thru)\n";)
if (indent == 0){
DEBUG(cerr << "indent==0\n";)
if (c == '\n'){
DEBUG(cerr << "c is a newline\n";)
goto out;
}
}
if ((c=discard(c,is)) == BS_EOF){
indent = 0;
goto out;
}
}
}
out:
if (level == 0)
parent_node->child = bp->base;
xindent = indent;
DEBUG(cerr
<< "at label out, return c = ASCII "
<< c
<< " ("
<< char(c)
<< ")"
<< "\n"
;)
return c;
}
static int
discard(int c, istream& is){
DEBUG(cerr << "discard characters\n";)
while (c != '\n' && c != BS_EOF){
c = getchar_G2_ATTLC(is);
DEBUG(
cerr
<< "is.get() returns c = ASCII "
<< c
<< " ("
<< char(c)
<< " )"
<< "\n"
;
)
}
DEBUG(cerr << "exit from discard loop\n";)
DEBUG(
void* test = (void*)is;
if(test){
cerr << "is tests non-null\n";
}else{
cerr << "is tests null\n";
}
)
return c;
}
|
«
|
April
2025
|
»
|
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 |
|
|
|
|