home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / perl / Perl / dump.c < prev    next >
C/C++ Source or Header  |  1995-01-19  |  9KB  |  391 lines

  1. /*    dump.c
  2.  *
  3.  *    Copyright (c) 1991-1994, 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.  */
  9.  
  10. /*
  11.  * "'You have talked long in your sleep, Frodo,' said Gandalf gently, 'and
  12.  * it has not been hard for me to read your mind and memory.'"
  13.  */
  14.  
  15. #include "EXTERN.h"
  16. #include "perl.h"
  17.  
  18. #ifndef DEBUGGING
  19. void
  20. dump_all()
  21. {
  22. }
  23. #else  /* Rest of file is for DEBUGGING */
  24.  
  25. static void dump();
  26.  
  27. void
  28. dump_all()
  29. {
  30. #ifdef HAS_SETLINEBUF
  31.     setlinebuf(stderr);
  32. #else
  33.     setvbuf(stderr, Nullch, _IOLBF, 0);
  34. #endif
  35.     if (main_root)
  36.     dump_op(main_root);
  37.     dump_packsubs(defstash);
  38. }
  39.  
  40. void
  41. dump_packsubs(stash)
  42. HV* stash;
  43. {
  44.     I32    i;
  45.     HE    *entry;
  46.  
  47.     if (!HvARRAY(stash))
  48.     return;
  49.     for (i = 0; i <= (I32) HvMAX(stash); i++) {
  50.     for (entry = HvARRAY(stash)[i]; entry; entry = entry->hent_next) {
  51.         GV *gv = (GV*)entry->hent_val;
  52.         HV *hv;
  53.         if (GvCV(gv))
  54.         dump_sub(gv);
  55.         if (GvFORM(gv))
  56.         dump_form(gv);
  57.         if (entry->hent_key[entry->hent_klen-1] == ':' &&
  58.           (hv = GvHV(gv)) && HvNAME(hv) && hv != defstash)
  59.         dump_packsubs(hv);        /* nested package */
  60.     }
  61.     }
  62. }
  63.  
  64. void
  65. dump_sub(gv)
  66. GV* gv;
  67. {
  68.     SV *sv = sv_newmortal();
  69.  
  70.     gv_fullname(sv,gv);
  71.     dump("\nSUB %s = ", SvPVX(sv));
  72.     if (CvXSUB(GvCV(gv)))
  73.     dump("(xsub 0x%x %d)\n",
  74.         (long)CvXSUB(GvCV(gv)),
  75.         CvXSUBANY(GvCV(gv)).any_i32);
  76.     else if (CvROOT(GvCV(gv)))
  77.     dump_op(CvROOT(GvCV(gv)));
  78.     else
  79.     dump("<undef>\n");
  80. }
  81.  
  82. void
  83. dump_form(gv)
  84. GV* gv;
  85. {
  86.     SV *sv = sv_newmortal();
  87.  
  88.     gv_fullname(sv,gv);
  89.     dump("\nFORMAT %s = ", SvPVX(sv));
  90.     if (CvROOT(GvFORM(gv)))
  91.     dump_op(CvROOT(GvFORM(gv)));
  92.     else
  93.     dump("<undef>\n");
  94. }
  95.  
  96. void
  97. dump_eval()
  98. {
  99.     dump_op(eval_root);
  100. }
  101.  
  102. void
  103. dump_op(op)
  104. register OP *op;
  105. {
  106.     SV *tmpsv;
  107.  
  108.     dump("{\n");
  109.     if (op->op_seq)
  110.     fprintf(stderr, "%-4d", op->op_seq);
  111.     else
  112.     fprintf(stderr, "    ");
  113.     dump("TYPE = %s  ===> ", op_name[op->op_type]);
  114.     if (op->op_next) {
  115.     if (op->op_seq)
  116.         fprintf(stderr, "%d\n", op->op_next->op_seq);
  117.     else
  118.         fprintf(stderr, "(%d)\n", op->op_next->op_seq);
  119.     }
  120.     else
  121.     fprintf(stderr, "DONE\n");
  122.     dumplvl++;
  123.     if (op->op_targ) {
  124.     if (op->op_type == OP_NULL)
  125.         dump("  (was %s)\n", op_name[op->op_targ]);
  126.     else
  127.         dump("TARG = %d\n", op->op_targ);
  128.     }
  129. #ifdef DUMPADDR
  130.     dump("ADDR = 0x%lx => 0x%lx\n",op, op->op_next);
  131. #endif
  132.     if (op->op_flags) {
  133.     *buf = '\0';
  134.     if (op->op_flags & OPf_KNOW) {
  135.         if (op->op_flags & OPf_LIST)
  136.         (void)strcat(buf,"LIST,");
  137.         else
  138.         (void)strcat(buf,"SCALAR,");
  139.     }
  140.     else
  141.         (void)strcat(buf,"UNKNOWN,");
  142.     if (op->op_flags & OPf_KIDS)
  143.         (void)strcat(buf,"KIDS,");
  144.     if (op->op_flags & OPf_PARENS)
  145.         (void)strcat(buf,"PARENS,");
  146.     if (op->op_flags & OPf_STACKED)
  147.         (void)strcat(buf,"STACKED,");
  148.     if (op->op_flags & OPf_REF)
  149.         (void)strcat(buf,"REF,");
  150.     if (op->op_flags & OPf_MOD)
  151.         (void)strcat(buf,"MOD,");
  152.     if (op->op_flags & OPf_SPECIAL)
  153.         (void)strcat(buf,"SPECIAL,");
  154.     if (*buf)
  155.         buf[strlen(buf)-1] = '\0';
  156.     dump("FLAGS = (%s)\n",buf);
  157.     }
  158.     if (op->op_private) {
  159.     *buf = '\0';
  160.     if (op->op_type == OP_AASSIGN) {
  161.         if (op->op_private & OPpASSIGN_COMMON)
  162.         (void)strcat(buf,"COMMON,");
  163.     }
  164.     else if (op->op_type == OP_SASSIGN) {
  165.         if (op->op_private & OPpASSIGN_BACKWARDS)
  166.         (void)strcat(buf,"BACKWARDS,");
  167.     }
  168.     else if (op->op_type == OP_TRANS) {
  169.         if (op->op_private & OPpTRANS_SQUASH)
  170.         (void)strcat(buf,"SQUASH,");
  171.         if (op->op_private & OPpTRANS_DELETE)
  172.         (void)strcat(buf,"DELETE,");
  173.         if (op->op_private & OPpTRANS_COMPLEMENT)
  174.         (void)strcat(buf,"COMPLEMENT,");
  175.     }
  176.     else if (op->op_type == OP_REPEAT) {
  177.         if (op->op_private & OPpREPEAT_DOLIST)
  178.         (void)strcat(buf,"DOLIST,");
  179.     }
  180.     else if (op->op_type == OP_ENTERSUB ||
  181.          op->op_type == OP_RV2SV ||
  182.          op->op_type == OP_RV2AV ||
  183.          op->op_type == OP_RV2HV ||
  184.          op->op_type == OP_RV2GV ||
  185.          op->op_type == OP_AELEM ||
  186.          op->op_type == OP_HELEM )
  187.     {
  188.         if (op->op_private & OPpDEREF_DB)
  189.         (void)strcat(buf,"DB,");
  190.         if (op->op_private & OPpDEREF_AV)
  191.         (void)strcat(buf,"AV,");
  192.         if (op->op_private & OPpDEREF_HV)
  193.         (void)strcat(buf,"HV,");
  194.         if (op->op_private & HINT_STRICT_REFS)
  195.         (void)strcat(buf,"STRICT_REFS,");
  196.     }
  197.     else if (op->op_type == OP_CONST) {
  198.         if (op->op_private & OPpCONST_BARE)
  199.         (void)strcat(buf,"BARE,");
  200.     }
  201.     else if (op->op_type == OP_FLIP) {
  202.         if (op->op_private & OPpFLIP_LINENUM)
  203.         (void)strcat(buf,"LINENUM,");
  204.     }
  205.     else if (op->op_type == OP_FLOP) {
  206.         if (op->op_private & OPpFLIP_LINENUM)
  207.         (void)strcat(buf,"LINENUM,");
  208.     }
  209.     if (op->op_flags & OPf_MOD && op->op_private & OPpLVAL_INTRO)
  210.         (void)strcat(buf,"INTRO,");
  211.     if (*buf) {
  212.         buf[strlen(buf)-1] = '\0';
  213.         dump("PRIVATE = (%s)\n",buf);
  214.     }
  215.     }
  216.  
  217.     switch (op->op_type) {
  218.     case OP_GVSV:
  219.     case OP_GV:
  220.     if (cGVOP->op_gv) {
  221.         ENTER;
  222.         tmpsv = NEWSV(0,0);
  223.         SAVEFREESV(tmpsv);
  224.         gv_fullname(tmpsv,cGVOP->op_gv);
  225.         dump("GV = %s\n", SvPV(tmpsv, na));
  226.         LEAVE;
  227.     }
  228.     else
  229.         dump("GV = NULL\n");
  230.     break;
  231.     case OP_CONST:
  232.     dump("SV = %s\n", SvPEEK(cSVOP->op_sv));
  233.     break;
  234.     case OP_NEXTSTATE:
  235.     case OP_DBSTATE:
  236.     if (cCOP->cop_line)
  237.         dump("LINE = %d\n",cCOP->cop_line);
  238.     if (cCOP->cop_label)
  239.         dump("LABEL = \"%s\"\n",cCOP->cop_label);
  240.     break;
  241.     case OP_ENTERLOOP:
  242.     dump("REDO ===> ");
  243.     if (cLOOP->op_redoop)
  244.         fprintf(stderr, "%d\n", cLOOP->op_redoop->op_seq);
  245.     else
  246.         fprintf(stderr, "DONE\n");
  247.     dump("NEXT ===> ");
  248.     if (cLOOP->op_nextop)
  249.         fprintf(stderr, "%d\n", cLOOP->op_nextop->op_seq);
  250.     else
  251.         fprintf(stderr, "DONE\n");
  252.     dump("LAST ===> ");
  253.     if (cLOOP->op_lastop)
  254.         fprintf(stderr, "%d\n", cLOOP->op_lastop->op_seq);
  255.     else
  256.         fprintf(stderr, "DONE\n");
  257.     break;
  258.     case OP_COND_EXPR:
  259.     dump("TRUE ===> ");
  260.     if (cCONDOP->op_true)
  261.         fprintf(stderr, "%d\n", cCONDOP->op_true->op_seq);
  262.     else
  263.         fprintf(stderr, "DONE\n");
  264.     dump("FALSE ===> ");
  265.     if (cCONDOP->op_false)
  266.         fprintf(stderr, "%d\n", cCONDOP->op_false->op_seq);
  267.     else
  268.         fprintf(stderr, "DONE\n");
  269.     break;
  270.     case OP_MAPWHILE:
  271.     case OP_GREPWHILE:
  272.     case OP_OR:
  273.     case OP_AND:
  274.     dump("OTHER ===> ");
  275.     if (cLOGOP->op_other)
  276.         fprintf(stderr, "%d\n", cLOGOP->op_other->op_seq);
  277.     else
  278.         fprintf(stderr, "DONE\n");
  279.     break;
  280.     case OP_PUSHRE:
  281.     case OP_MATCH:
  282.     case OP_SUBST:
  283.     dump_pm((PMOP*)op);
  284.     break;
  285.     default:
  286.     break;
  287.     }
  288.     if (op->op_flags & OPf_KIDS) {
  289.     OP *kid;
  290.     for (kid = cUNOP->op_first; kid; kid = kid->op_sibling)
  291.         dump_op(kid);
  292.     }
  293.     dumplvl--;
  294.     dump("}\n");
  295. }
  296.  
  297. void
  298. dump_gv(gv)
  299. register GV *gv;
  300. {
  301.     SV *sv;
  302.  
  303.     if (!gv) {
  304.     fprintf(stderr,"{}\n");
  305.     return;
  306.     }
  307.     sv = sv_newmortal();
  308.     dumplvl++;
  309.     fprintf(stderr,"{\n");
  310.     gv_fullname(sv,gv);
  311.     dump("GV_NAME = %s", SvPVX(sv));
  312.     if (gv != GvEGV(gv)) {
  313.     gv_efullname(sv,GvEGV(gv));
  314.     dump("-> %s", SvPVX(sv));
  315.     }
  316.     dump("\n");
  317.     dumplvl--;
  318.     dump("}\n");
  319. }
  320.  
  321. void
  322. dump_pm(pm)
  323. register PMOP *pm;
  324. {
  325.     char ch;
  326.  
  327.     if (!pm) {
  328.     dump("{}\n");
  329.     return;
  330.     }
  331.     dump("{\n");
  332.     dumplvl++;
  333.     if (pm->op_pmflags & PMf_ONCE)
  334.     ch = '?';
  335.     else
  336.     ch = '/';
  337.     if (pm->op_pmregexp)
  338.     dump("PMf_PRE %c%s%c\n",ch,pm->op_pmregexp->precomp,ch);
  339.     if (pm->op_type != OP_PUSHRE && pm->op_pmreplroot) {
  340.     dump("PMf_REPL = ");
  341.     dump_op(pm->op_pmreplroot);
  342.     }
  343.     if (pm->op_pmshort) {
  344.     dump("PMf_SHORT = %s\n",SvPEEK(pm->op_pmshort));
  345.     }
  346.     if (pm->op_pmflags) {
  347.     *buf = '\0';
  348.     if (pm->op_pmflags & PMf_USED)
  349.         (void)strcat(buf,"USED,");
  350.     if (pm->op_pmflags & PMf_ONCE)
  351.         (void)strcat(buf,"ONCE,");
  352.     if (pm->op_pmflags & PMf_SCANFIRST)
  353.         (void)strcat(buf,"SCANFIRST,");
  354.     if (pm->op_pmflags & PMf_ALL)
  355.         (void)strcat(buf,"ALL,");
  356.     if (pm->op_pmflags & PMf_SKIPWHITE)
  357.         (void)strcat(buf,"SKIPWHITE,");
  358.     if (pm->op_pmflags & PMf_FOLD)
  359.         (void)strcat(buf,"FOLD,");
  360.     if (pm->op_pmflags & PMf_CONST)
  361.         (void)strcat(buf,"CONST,");
  362.     if (pm->op_pmflags & PMf_KEEP)
  363.         (void)strcat(buf,"KEEP,");
  364.     if (pm->op_pmflags & PMf_GLOBAL)
  365.         (void)strcat(buf,"GLOBAL,");
  366.     if (pm->op_pmflags & PMf_RUNTIME)
  367.         (void)strcat(buf,"RUNTIME,");
  368.     if (pm->op_pmflags & PMf_EVAL)
  369.         (void)strcat(buf,"EVAL,");
  370.     if (*buf)
  371.         buf[strlen(buf)-1] = '\0';
  372.     dump("PMFLAGS = (%s)\n",buf);
  373.     }
  374.  
  375.     dumplvl--;
  376.     dump("}\n");
  377. }
  378.  
  379. /* VARARGS1 */
  380. static void dump(arg1,arg2,arg3,arg4,arg5)
  381. char *arg1;
  382. long arg2, arg3, arg4, arg5;
  383. {
  384.     I32 i;
  385.  
  386.     for (i = dumplvl*4; i; i--)
  387.     (void)putc(' ',stderr);
  388.     fprintf(stderr,arg1, arg2, arg3, arg4, arg5);
  389. }
  390. #endif
  391.