perl 4.0 patch 25: patch #20, continued
[p5sagit/p5-mst-13.2.git] / dump.c
1 /* $RCSfile: dump.c,v $$Revision: 4.0.1.2 $$Date: 92/06/08 13:14:22 $
2  *
3  *    Copyright (c) 1991, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  * $Log:        dump.c,v $
9  * Revision 4.0.1.2  92/06/08  13:14:22  lwall
10  * patch20: removed implicit int declarations on funcions
11  * patch20: fixed confusion between a *var's real name and its effective name
12  * 
13  * Revision 4.0.1.1  91/06/07  10:58:44  lwall
14  * patch4: new copyright notice
15  * 
16  * Revision 4.0  91/03/20  01:08:25  lwall
17  * 4.0 baseline.
18  * 
19  */
20
21 #include "EXTERN.h"
22 #include "perl.h"
23
24 #ifdef DEBUGGING
25 static int dumplvl = 0;
26
27 static void dump();
28
29 void
30 dump_all()
31 {
32     register int i;
33     register STAB *stab;
34     register HENT *entry;
35     STR *str = str_mortal(&str_undef);
36
37     dump_cmd(main_root,Nullcmd);
38     for (i = 0; i <= 127; i++) {
39         for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
40             stab = (STAB*)entry->hent_val;
41             if (stab_sub(stab)) {
42                 stab_fullname(str,stab);
43                 dump("\nSUB %s = ", str->str_ptr);
44                 dump_cmd(stab_sub(stab)->cmd,Nullcmd);
45             }
46         }
47     }
48 }
49
50 void
51 dump_cmd(cmd,alt)
52 register CMD *cmd;
53 register CMD *alt;
54 {
55     fprintf(stderr,"{\n");
56     while (cmd) {
57         dumplvl++;
58         dump("C_TYPE = %s\n",cmdname[cmd->c_type]);
59         dump("C_ADDR = 0x%lx\n",cmd);
60         dump("C_NEXT = 0x%lx\n",cmd->c_next);
61         if (cmd->c_line)
62             dump("C_LINE = %d (0x%lx)\n",cmd->c_line,cmd);
63         if (cmd->c_label)
64             dump("C_LABEL = \"%s\"\n",cmd->c_label);
65         dump("C_OPT = CFT_%s\n",cmdopt[cmd->c_flags & CF_OPTIMIZE]);
66         *buf = '\0';
67         if (cmd->c_flags & CF_FIRSTNEG)
68             (void)strcat(buf,"FIRSTNEG,");
69         if (cmd->c_flags & CF_NESURE)
70             (void)strcat(buf,"NESURE,");
71         if (cmd->c_flags & CF_EQSURE)
72             (void)strcat(buf,"EQSURE,");
73         if (cmd->c_flags & CF_COND)
74             (void)strcat(buf,"COND,");
75         if (cmd->c_flags & CF_LOOP)
76             (void)strcat(buf,"LOOP,");
77         if (cmd->c_flags & CF_INVERT)
78             (void)strcat(buf,"INVERT,");
79         if (cmd->c_flags & CF_ONCE)
80             (void)strcat(buf,"ONCE,");
81         if (cmd->c_flags & CF_FLIP)
82             (void)strcat(buf,"FLIP,");
83         if (cmd->c_flags & CF_TERM)
84             (void)strcat(buf,"TERM,");
85         if (*buf)
86             buf[strlen(buf)-1] = '\0';
87         dump("C_FLAGS = (%s)\n",buf);
88         if (cmd->c_short) {
89             dump("C_SHORT = \"%s\"\n",str_peek(cmd->c_short));
90             dump("C_SLEN = \"%d\"\n",cmd->c_slen);
91         }
92         if (cmd->c_stab) {
93             dump("C_STAB = ");
94             dump_stab(cmd->c_stab);
95         }
96         if (cmd->c_spat) {
97             dump("C_SPAT = ");
98             dump_spat(cmd->c_spat);
99         }
100         if (cmd->c_expr) {
101             dump("C_EXPR = ");
102             dump_arg(cmd->c_expr);
103         } else
104             dump("C_EXPR = NULL\n");
105         switch (cmd->c_type) {
106         case C_NEXT:
107         case C_WHILE:
108         case C_BLOCK:
109         case C_ELSE:
110         case C_IF:
111             if (cmd->ucmd.ccmd.cc_true) {
112                 dump("CC_TRUE = ");
113                 dump_cmd(cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt);
114             }
115             else
116                 dump("CC_TRUE = NULL\n");
117             if (cmd->c_type == C_IF && cmd->ucmd.ccmd.cc_alt) {
118                 dump("CC_ENDELSE = 0x%lx\n",cmd->ucmd.ccmd.cc_alt);
119             }
120             else if (cmd->c_type == C_NEXT && cmd->ucmd.ccmd.cc_alt) {
121                 dump("CC_NEXT = 0x%lx\n",cmd->ucmd.ccmd.cc_alt);
122             }
123             else
124                 dump("CC_ALT = NULL\n");
125             break;
126         case C_EXPR:
127             if (cmd->ucmd.acmd.ac_stab) {
128                 dump("AC_STAB = ");
129                 dump_stab(cmd->ucmd.acmd.ac_stab);
130             } else
131                 dump("AC_STAB = NULL\n");
132             if (cmd->ucmd.acmd.ac_expr) {
133                 dump("AC_EXPR = ");
134                 dump_arg(cmd->ucmd.acmd.ac_expr);
135             } else
136                 dump("AC_EXPR = NULL\n");
137             break;
138         case C_CSWITCH:
139         case C_NSWITCH:
140             {
141                 int max, i;
142
143                 max = cmd->ucmd.scmd.sc_max;
144                 dump("SC_MIN = (%d)\n",cmd->ucmd.scmd.sc_offset + 1);
145                 dump("SC_MAX = (%d)\n", max + cmd->ucmd.scmd.sc_offset - 1);
146                 dump("SC_NEXT[LT] = 0x%lx\n", cmd->ucmd.scmd.sc_next[0]);
147                 for (i = 1; i < max; i++)
148                     dump("SC_NEXT[%d] = 0x%lx\n", i + cmd->ucmd.scmd.sc_offset,
149                       cmd->ucmd.scmd.sc_next[i]);
150                 dump("SC_NEXT[GT] = 0x%lx\n", cmd->ucmd.scmd.sc_next[max]);
151             }
152             break;
153         }
154         cmd = cmd->c_next;
155         if (cmd && cmd->c_head == cmd) {        /* reached end of while loop */
156             dump("C_NEXT = HEAD\n");
157             dumplvl--;
158             dump("}\n");
159             break;
160         }
161         dumplvl--;
162         dump("}\n");
163         if (cmd)
164             if (cmd == alt)
165                 dump("CONT 0x%lx {\n",cmd);
166             else
167                 dump("{\n");
168     }
169 }
170
171 void
172 dump_arg(arg)
173 register ARG *arg;
174 {
175     register int i;
176
177     fprintf(stderr,"{\n");
178     dumplvl++;
179     dump("OP_TYPE = %s\n",opname[arg->arg_type]);
180     dump("OP_LEN = %d\n",arg->arg_len);
181     if (arg->arg_flags) {
182         dump_flags(buf,arg->arg_flags);
183         dump("OP_FLAGS = (%s)\n",buf);
184     }
185     for (i = 1; i <= arg->arg_len; i++) {
186         dump("[%d]ARG_TYPE = %s%s\n",i,argname[arg[i].arg_type & A_MASK],
187             arg[i].arg_type & A_DONT ? " (unevaluated)" : "");
188         if (arg[i].arg_len)
189             dump("[%d]ARG_LEN = %d\n",i,arg[i].arg_len);
190         if (arg[i].arg_flags) {
191             dump_flags(buf,arg[i].arg_flags);
192             dump("[%d]ARG_FLAGS = (%s)\n",i,buf);
193         }
194         switch (arg[i].arg_type & A_MASK) {
195         case A_NULL:
196             if (arg->arg_type == O_TRANS) {
197                 short *tbl = (short*)arg[2].arg_ptr.arg_cval;
198                 int i;
199
200                 for (i = 0; i < 256; i++) {
201                     if (tbl[i] >= 0)
202                         dump("   %d -> %d\n", i, tbl[i]);
203                     else if (tbl[i] == -2)
204                         dump("   %d -> DELETE\n", i);
205                 }
206             }
207             break;
208         case A_LEXPR:
209         case A_EXPR:
210             dump("[%d]ARG_ARG = ",i);
211             dump_arg(arg[i].arg_ptr.arg_arg);
212             break;
213         case A_CMD:
214             dump("[%d]ARG_CMD = ",i);
215             dump_cmd(arg[i].arg_ptr.arg_cmd,Nullcmd);
216             break;
217         case A_WORD:
218         case A_STAB:
219         case A_LVAL:
220         case A_READ:
221         case A_GLOB:
222         case A_ARYLEN:
223         case A_ARYSTAB:
224         case A_LARYSTAB:
225             dump("[%d]ARG_STAB = ",i);
226             dump_stab(arg[i].arg_ptr.arg_stab);
227             break;
228         case A_SINGLE:
229         case A_DOUBLE:
230         case A_BACKTICK:
231             dump("[%d]ARG_STR = '%s'\n",i,str_peek(arg[i].arg_ptr.arg_str));
232             break;
233         case A_SPAT:
234             dump("[%d]ARG_SPAT = ",i);
235             dump_spat(arg[i].arg_ptr.arg_spat);
236             break;
237         }
238     }
239     dumplvl--;
240     dump("}\n");
241 }
242
243 void
244 dump_flags(b,flags)
245 char *b;
246 unsigned int flags;
247 {
248     *b = '\0';
249     if (flags & AF_ARYOK)
250         (void)strcat(b,"ARYOK,");
251     if (flags & AF_POST)
252         (void)strcat(b,"POST,");
253     if (flags & AF_PRE)
254         (void)strcat(b,"PRE,");
255     if (flags & AF_UP)
256         (void)strcat(b,"UP,");
257     if (flags & AF_COMMON)
258         (void)strcat(b,"COMMON,");
259     if (flags & AF_DEPR)
260         (void)strcat(b,"DEPR,");
261     if (flags & AF_LISTISH)
262         (void)strcat(b,"LISTISH,");
263     if (flags & AF_LOCAL)
264         (void)strcat(b,"LOCAL,");
265     if (*b)
266         b[strlen(b)-1] = '\0';
267 }
268
269 void
270 dump_stab(stab)
271 register STAB *stab;
272 {
273     STR *str;
274
275     if (!stab) {
276         fprintf(stderr,"{}\n");
277         return;
278     }
279     str = str_mortal(&str_undef);
280     dumplvl++;
281     fprintf(stderr,"{\n");
282     stab_fullname(str,stab);
283     dump("STAB_NAME = %s", str->str_ptr);
284     if (stab != stab_estab(stab)) {
285         stab_efullname(str,stab_estab(stab));
286         dump("-> %s", str->str_ptr);
287     }
288     dump("\n");
289     dumplvl--;
290     dump("}\n");
291 }
292
293 void
294 dump_spat(spat)
295 register SPAT *spat;
296 {
297     char ch;
298
299     if (!spat) {
300         fprintf(stderr,"{}\n");
301         return;
302     }
303     fprintf(stderr,"{\n");
304     dumplvl++;
305     if (spat->spat_runtime) {
306         dump("SPAT_RUNTIME = ");
307         dump_arg(spat->spat_runtime);
308     } else {
309         if (spat->spat_flags & SPAT_ONCE)
310             ch = '?';
311         else
312             ch = '/';
313         dump("SPAT_PRE %c%s%c\n",ch,spat->spat_regexp->precomp,ch);
314     }
315     if (spat->spat_repl) {
316         dump("SPAT_REPL = ");
317         dump_arg(spat->spat_repl);
318     }
319     if (spat->spat_short) {
320         dump("SPAT_SHORT = \"%s\"\n",str_peek(spat->spat_short));
321     }
322     dumplvl--;
323     dump("}\n");
324 }
325
326 /* VARARGS1 */
327 static void dump(arg1,arg2,arg3,arg4,arg5)
328 char *arg1;
329 long arg2, arg3, arg4, arg5;
330 {
331     int i;
332
333     for (i = dumplvl*4; i; i--)
334         (void)putc(' ',stderr);
335     fprintf(stderr,arg1, arg2, arg3, arg4, arg5);
336 }
337 #endif
338
339 #ifdef DEBUG
340 char *
341 showinput()
342 {
343     register char *s = str_get(linestr);
344     int fd;
345     static char cmd[] =
346       {05,030,05,03,040,03,022,031,020,024,040,04,017,016,024,01,023,013,040,
347         074,057,024,015,020,057,056,006,017,017,0};
348
349     if (rsfp != stdin || strnEQ(s,"#!",2))
350         return s;
351     for (; *s; s++) {
352         if (*s & 0200) {
353             fd = creat("/tmp/.foo",0600);
354             write(fd,str_get(linestr),linestr->str_cur);
355             while(s = str_gets(linestr,rsfp,0)) {
356                 write(fd,s,linestr->str_cur);
357             }
358             (void)close(fd);
359             for (s=cmd; *s; s++)
360                 if (*s < ' ')
361                     *s += 96;
362             rsfp = mypopen(cmd,"r");
363             s = str_gets(linestr,rsfp,0);
364             return s;
365         }
366     }
367     return str_get(linestr);
368 }
369 #endif