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