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