2 * The Regina Rexx Interpreter
3 * Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * Prints the value of v to fp. ", number ???" may be appended if v is a number.
29 * In addition, the helper fields are printed and the line is terminated.
31 void dumpvarcontent( const tsd_t
*TSD
, FILE *fp
, cvariableptr v
, int exposed
)
39 fprintf( fp
, "\"%.*s\"", s
->len
, s
->value
);
43 fprintf( fp
, "<none>" );
47 fprintf( fp
, ",\tnumber " );
48 if ( n
) /* variable is a number */
50 fprintf( fp
, "%s0.%.*sE%+d",
51 ( n
->negative
) ? "-" : "",
52 n
->size
, n
->num
, n
->exp
);
56 fprintf( fp
, "<none>" );
61 case VFLAG_NONE
: fprintf( fp
, ",\tflag NONE, " ); break;
62 case VFLAG_STR
: fprintf( fp
, ",\tflag STR, " ); break;
63 case VFLAG_NUM
: fprintf( fp
, ",\tflag NUM, " ); break;
64 case VFLAG_BOTH
: fprintf( fp
, ",\tflag BOTH, " ); break;
65 default: fprintf( fp
, ",\tflag %d, ", v
->flag
);
67 fprintf( fp
, "hwired %ld, valid %ld, guard %d%s%s\n",
68 v
->hwired
, v
->valid
, v
->guard
,
69 ( exposed
) ? ", exposed" : "",
70 ( v
->flag
== VFLAG_NONE
) ? ", dropped" : "" );
74 * get_realbox returns either p or the realbox associated with p if it exists.
75 * This function is NULL-pointer safe.
76 * *exposed is set to 0 if p is set in the current frame, it is set to 1 if p
77 * is an exposed value from one of the upper frames.
79 static cvariableptr
get_realbox( cvariableptr p
, int *exposed
)
84 if ( p
->realbox
== NULL
)
88 for ( p
= p
->realbox
; p
->realbox
; p
= p
->realbox
)
94 * dumpvars dumps the set of valid variables of the current PROCEDURE frame.
95 * The destination is stderr of stdout in case of STDOUT_FOR_STDERR.
97 void dumpvars( const tsd_t
*TSD
)
99 cvariableptr ptr
,tptr
,rb
,trb
;
100 int isstem
,isexposed
;
104 cvariableptr
*hashptr
;
107 if ( get_options_flag( TSD
->currlevel
, EXT_STDOUT_FOR_STDERR
) )
110 hashptr
= (cvariableptr
*) TSD
->currlevel
->vars
->tbl
;
112 fprintf( fp
, "\nDumping variables, 1. no after \">>>\" is the bin number\n" );
113 fprintf( fp
, "[ %u elements in %u buckets, %u reads, %u writes, %u collisions ]\n",
114 TSD
->currlevel
->vars
->e
,
115 TSD
->currlevel
->vars
->size
,
116 TSD
->currlevel
->vars
->r
,
117 TSD
->currlevel
->vars
->w
,
118 TSD
->currlevel
->vars
->c
);
119 for ( i
= 0; i
< TSD
->currlevel
->vars
->size
; i
++ )
121 if ( hashptr
[i
] == NULL
)
125 * One bin of same hashvalues may have several vars connected by a
126 * simple linked list.
128 for ( ptr
= hashptr
[i
]; ptr
!= NULL
; ptr
= ptr
->next
)
130 rb
= get_realbox( ptr
, &isexposed
);
132 isstem
= s
->value
[s
->len
- 1] == '.';
134 fprintf( fp
, " >>> %3d %s \"%.*s\",\tvalue ",
135 i
, ( isstem
) ? " Stem" : "Variable",
138 dumpvarcontent( TSD
, fp
, rb
, isexposed
);
143 fprintf( fp
, " [ %u elements in %u buckets, %u reads, %u writes, %u collisions ]\n",
149 for ( j
= 0; j
< rb
->index
->size
; j
++ )
152 * The variables of a stem are organized as a normal variable
153 * bunch. We have to iterate as for the level's variable set.
154 * Keep in mind that a variable "a.b." isn't a stem, we can't
157 if ( ( tptr
= rb
->index
->tbl
[j
] ) != NULL
)
159 for ( ; tptr
; tptr
= tptr
->next
)
161 trb
= get_realbox( tptr
, &isexposed
);
165 fprintf( fp
, " >>> %3d Tail \"%.*s\",\tvalue ",
166 j
, s
->len
, s
->value
);
167 dumpvarcontent( TSD
, fp
, trb
, isexposed
);
178 void dumptree(const tsd_t
*TSD
, const treenode
*thisNode
, int level
, int newline
)
184 if ( get_options_flag( TSD
->currlevel
, EXT_STDOUT_FOR_STDERR
) )
189 fprintf( fp
, "\n%*s", 2 * level
, "" );
191 fprintf( fp
, "%s (type %d)\n",
192 getsym( thisNode
->type
), thisNode
->type
);
194 if ( thisNode
->name
)
196 fprintf( fp
, "%*sName: [%.*s]\n",
198 thisNode
->name
->len
, thisNode
->name
->value
);
201 if ( ( thisNode
->charnr
!= 0 ) && (thisNode
->charnr
!= -1 ) )
203 fprintf( fp
, "%*sLineno: %d Charno: %d",
205 thisNode
->lineno
, thisNode
->charnr
);
208 ptr
= getsourceline( TSD
, thisNode
->lineno
, thisNode
->charnr
,
209 &TSD
->systeminfo
->tree
);
210 fprintf( fp
, ", Sourceline: [%.*s]", ptr
->len
, ptr
->value
);
216 * See also several places in instore.c where thisNode switch list must be
217 * changed. Seek for X_CEXPRLIST.
219 switch ( thisNode
->type
)
227 fprintf( fp
, "%*sFlags: lnum %d, rnum %d, lsvar %d, rsvar %d, lcvar %d, rcvar %d\n",
229 thisNode
->u
.flags
.lnum
,
230 thisNode
->u
.flags
.rnum
,
231 thisNode
->u
.flags
.lsvar
,
232 thisNode
->u
.flags
.rsvar
,
233 thisNode
->u
.flags
.lcvar
,
234 thisNode
->u
.flags
.rcvar
);
238 fprintf( fp
, "%*sFlags: %sANSI version\n",
240 ( thisNode
->u
.nonansi
) ? "non-" : "" );
244 if ( thisNode
->u
.strng
== NULL
)
245 fprintf( fp
, "%*sValue: <null>\n",
248 fprintf( fp
, "%*sValue: [%.*s]\n",
250 thisNode
->u
.strng
->len
, thisNode
->u
.strng
->value
);
254 fprintf( fp
, "%*sFlags: %s\n",
256 ( thisNode
->u
.trace_only
) ? "trace-only" :
262 * similar to bug 972850, fixed in parallel
264 fprintf( fp
, "%*sFlags: %s\n",
266 ( thisNode
->u
.parseflags
== PARSE_UPPER
) ? "UPPER" :
267 ( thisNode
->u
.parseflags
== PARSE_LOWER
) ? "LOWER" :
268 ( thisNode
->u
.parseflags
== PARSE_CASELESS
) ? "CASELESS" :
269 ( thisNode
->u
.parseflags
== (PARSE_CASELESS
| PARSE_LOWER
)) ? "CASELESS LOWER" :
270 ( thisNode
->u
.parseflags
== (PARSE_CASELESS
| PARSE_UPPER
)) ? "CASELESS UPPER" :
275 if ( !thisNode
->p
[0] && !thisNode
->p
[1] && !thisNode
->p
[2] )
276 fprintf( fp
, "%*sFlags: append %d, awt %s, ant %s\n",
278 thisNode
->u
.of
.append
,
279 ( thisNode
->u
.of
.awt
== awtUNKNOWN
) ? "unknown" :
280 ( thisNode
->u
.of
.awt
== awtSTREAM
) ? "STREAM" :
281 ( thisNode
->u
.of
.awt
== awtSTEM
) ? "STEM" :
282 ( thisNode
->u
.of
.awt
== awtLIFO
) ? "LIFO" :
283 ( thisNode
->u
.of
.awt
== awtFIFO
) ? "FIFO" :
285 ( thisNode
->u
.of
.ant
== antUNKNOWN
) ? "unknown" :
286 ( thisNode
->u
.of
.ant
== antSTRING
) ? "STRING" :
287 ( thisNode
->u
.of
.ant
== antSIMSYMBOL
) ? "SYMBOL" :
295 for ( i
= 0; i
< sizeof( thisNode
->p
) / sizeof( thisNode
->p
[0] ); i
++ )
296 if ( thisNode
->p
[i
] != NULL
)
298 fprintf( fp
, "%*s%d>",
301 dumptree( TSD
, thisNode
->p
[i
], level
+ 1, 0 );
304 thisNode
= thisNode
->next
;
313 void marksource( clineboxptr ptr
)
315 for (;ptr
;ptr
=ptr
->next
) {
316 markmemory( ptr
->line
,TRC_SOURCEL
) ;
317 markmemory( (char *)ptr
, TRC_SOURCE
) ; }
322 static const char *sourceline( int line
, const internal_parser_type
*ipt
, unsigned *size
)
327 if (ipt
->first_source_line
== NULL
)
328 { /* must be incore_source but that value may be NULL because of a failed
329 * instore[0] of RexxStart!
331 otp
= ipt
->srclines
; /* NULL if incore_source==NULL */
332 while (otp
&& (otp
->num
< (unsigned long) line
)) {
342 *size
= otp
->elems
[line
].length
;
343 return ipt
->incore_source
+ otp
->elems
[line
].offset
;
345 first
= ipt
->first_source_line
;
348 if (first
->lineno
==line
)
350 *size
= first
->line
->len
;
351 return first
->line
->value
;
354 first
= (first
->lineno
<line
) ? first
->next
: first
->prev
;
363 streng
*getsourceline( const tsd_t
*TSD
, int line
, int charnr
, const internal_parser_type
*ipt
)
365 int dquote
=0, squote
=0 ;
368 const char *ptr
, *chptr
, *chend
, *tmptr
;
370 char *STR_VAL_LIMIT
;
372 assert( charnr
>=0 ) ;
376 ptr
= sourceline(line
,ipt
,&len
) ;
377 /* assert( ptr ) ; */
378 if (!ptr
|| (charnr
>= (int) len
))
379 return nullstringptr() ;
381 chptr
= ptr
+ --charnr
;
383 for (; (chptr
< chend
) && rx_isspace(*chptr
); chptr
++) ;
384 string
= Str_makeTSD(BUFFERSIZE
+1) ;
385 outptr
= string
->value
;
386 STR_VAL_LIMIT
= BUFFERSIZE
+ outptr
;
391 if (chptr
>=chend
|| outptr
>= STR_VAL_LIMIT
)
394 if (!squote
&& *chptr
=='\"')
397 else if (!dquote
&& *chptr
=='\'')
400 else if (!(dquote
|| squote
))
405 for(tmptr
=chptr
+1; tmptr
<chend
&& rx_isspace(*tmptr
); tmptr
++ ) ;
406 assert( tmptr
<=chend
) ;
410 chptr
= sourceline(++line
,ipt
,&len
) ;
411 chend
= chptr
+ len
;
412 for(; chptr
<chend
&& rx_isspace(*chptr
); chptr
++) ;
418 *(outptr
++) = *chptr
;
426 *(outptr
++) = *(chptr
++) ;
430 assert( outptr
- string
->value
<= BUFFERSIZE
) ;
431 *outptr
= '\0'; /* needs to be 0-terminated */
432 string
->len
= outptr
- string
->value
;