Print this page
7085 add support for "if" and "else" statements in dtrace

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libdtrace/common/dt_parser.c
          +++ new/usr/src/lib/libdtrace/common/dt_parser.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  24   25   * Copyright (c) 2013, Joyent Inc. All rights reserved.
  25      - * Copyright (c) 2013 by Delphix. All rights reserved.
  26   26   */
  27   27  
  28   28  /*
  29   29   * DTrace D Language Parser
  30   30   *
  31   31   * The D Parser is a lex/yacc parser consisting of the lexer dt_lex.l, the
  32   32   * parsing grammar dt_grammar.y, and this file, dt_parser.c, which handles
  33   33   * the construction of the parse tree nodes and their syntactic validation.
  34   34   * The parse tree is constructed of dt_node_t structures (see <dt_parser.h>)
  35   35   * that are built in two passes: (1) the "create" pass, where the parse tree
↓ open down ↓ 2094 lines elided ↑ open up ↑
2130 2130              expr->dn_ident->di_kind == DT_IDENT_ACTFUNC)
2131 2131                  dnp = dt_node_alloc(DT_NODE_DFUNC);
2132 2132          else
2133 2133                  dnp = dt_node_alloc(DT_NODE_DEXPR);
2134 2134  
2135 2135          dnp->dn_expr = expr;
2136 2136          return (dnp);
2137 2137  }
2138 2138  
2139 2139  dt_node_t *
     2140 +dt_node_if(dt_node_t *pred, dt_node_t *acts, dt_node_t *else_acts)
     2141 +{
     2142 +        dt_node_t *dnp = dt_node_alloc(DT_NODE_IF);
     2143 +        dnp->dn_conditional = pred;
     2144 +        dnp->dn_body = acts;
     2145 +        dnp->dn_alternate_body = else_acts;
     2146 +
     2147 +        return (dnp);
     2148 +}
     2149 +
     2150 +dt_node_t *
2140 2151  dt_node_pdesc_by_name(char *spec)
2141 2152  {
2142 2153          dtrace_hdl_t *dtp = yypcb->pcb_hdl;
2143 2154          dt_node_t *dnp;
2144 2155  
2145 2156          if (spec == NULL)
2146 2157                  longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
2147 2158  
2148 2159          dnp = dt_node_alloc(DT_NODE_PDESC);
2149 2160          dnp->dn_spec = spec;
↓ open down ↓ 48 lines elided ↑ open up ↑
2198 2209  
2199 2210  dt_node_t *
2200 2211  dt_node_clause(dt_node_t *pdescs, dt_node_t *pred, dt_node_t *acts)
2201 2212  {
2202 2213          dt_node_t *dnp = dt_node_alloc(DT_NODE_CLAUSE);
2203 2214  
2204 2215          dnp->dn_pdescs = pdescs;
2205 2216          dnp->dn_pred = pred;
2206 2217          dnp->dn_acts = acts;
2207 2218  
2208      -        yybegin(YYS_CLAUSE);
2209 2219          return (dnp);
2210 2220  }
2211 2221  
2212 2222  dt_node_t *
2213 2223  dt_node_inline(dt_node_t *expr)
2214 2224  {
2215 2225          dtrace_hdl_t *dtp = yypcb->pcb_hdl;
2216 2226          dt_scope_t *dsp = &yypcb->pcb_dstack;
2217 2227          dt_decl_t *ddp = dt_decl_top();
2218 2228  
↓ open down ↓ 971 lines elided ↑ open up ↑
3190 3200                                  dhp = dtp->dt_globals;
3191 3201                                  idp = dt_idstack_lookup(
3192 3202                                      &yypcb->pcb_globals, lp->dn_string);
3193 3203                                  idkind = DT_IDENT_ARRAY;
3194 3204                          }
3195 3205  
3196 3206                          if (idp == NULL || dt_ident_unref(idp))
3197 3207                                  dt_xcook_ident(lp, dhp, idkind, B_TRUE);
3198 3208                          else
3199 3209                                  dt_xcook_ident(lp, dhp, idp->di_kind, B_FALSE);
3200      -                } else
     3210 +                } else {
3201 3211                          lp = dnp->dn_left = dt_node_cook(lp, 0);
     3212 +                }
3202 3213  
3203 3214                  /*
3204 3215                   * Switch op to '+' for *(E1 + E2) array mode in these cases:
3205 3216                   * (a) lp is a DT_IDENT_ARRAY variable that has already been
3206 3217                   *      referenced using [] notation (dn_args != NULL).
3207 3218                   * (b) lp is a non-ARRAY variable that has already been given
3208 3219                   *      a type by assignment or declaration (!dt_ident_unref())
3209 3220                   * (c) lp is neither a variable nor an aggregation
3210 3221                   */
3211 3222                  if (lp->dn_kind == DT_NODE_VAR) {
3212 3223                          if (lp->dn_ident->di_kind == DT_IDENT_ARRAY) {
3213 3224                                  if (lp->dn_args != NULL)
3214 3225                                          op = DT_TOK_ADD;
3215      -                        } else if (!dt_ident_unref(lp->dn_ident))
     3226 +                        } else if (!dt_ident_unref(lp->dn_ident)) {
3216 3227                                  op = DT_TOK_ADD;
3217      -                } else if (lp->dn_kind != DT_NODE_AGG)
     3228 +                        }
     3229 +                } else if (lp->dn_kind != DT_NODE_AGG) {
3218 3230                          op = DT_TOK_ADD;
     3231 +                }
3219 3232          }
3220 3233  
3221 3234          switch (op) {
3222 3235          case DT_TOK_BAND:
3223 3236          case DT_TOK_XOR:
3224 3237          case DT_TOK_BOR:
3225 3238                  lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
3226 3239                  rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
3227 3240  
3228 3241                  if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) {
↓ open down ↓ 403 lines elided ↑ open up ↑
3632 3645                                      opstr(op),
3633 3646                                      dt_node_type_name(rp, n2, sizeof (n2)));
3634 3647                          }
3635 3648                  }
3636 3649  asgn_common:
3637 3650                  dt_assign_common(dnp);
3638 3651                  break;
3639 3652  
3640 3653          case DT_TOK_PTR:
3641 3654                  /*
3642      -                 * If the left-hand side of operator -> is the name "self",
3643      -                 * then we permit a TLS variable to be created or referenced.
     3655 +                 * If the left-hand side of operator -> is one of the
     3656 +                 * scoping keywords, permit a local or thread
     3657 +                 * variable to be created or referenced.
3644 3658                   */
3645      -                if (lp->dn_kind == DT_NODE_IDENT &&
3646      -                    strcmp(lp->dn_string, "self") == 0) {
3647      -                        if (rp->dn_kind != DT_NODE_VAR) {
3648      -                                dt_xcook_ident(rp, dtp->dt_tls,
3649      -                                    DT_IDENT_SCALAR, B_TRUE);
3650      -                        }
     3659 +                if (lp->dn_kind == DT_NODE_IDENT) {
     3660 +                        dt_idhash_t *dhp = NULL;
3651 3661  
3652      -                        if (idflags != 0)
3653      -                                rp = dt_node_cook(rp, idflags);
3654      -
3655      -                        dnp->dn_right = dnp->dn_left; /* avoid freeing rp */
3656      -                        dt_node_free(dnp);
3657      -                        return (rp);
3658      -                }
3659      -
3660      -                /*
3661      -                 * If the left-hand side of operator -> is the name "this",
3662      -                 * then we permit a local variable to be created or referenced.
3663      -                 */
3664      -                if (lp->dn_kind == DT_NODE_IDENT &&
3665      -                    strcmp(lp->dn_string, "this") == 0) {
3666      -                        if (rp->dn_kind != DT_NODE_VAR) {
3667      -                                dt_xcook_ident(rp, yypcb->pcb_locals,
3668      -                                    DT_IDENT_SCALAR, B_TRUE);
     3662 +                        if (strcmp(lp->dn_string, "self") == 0) {
     3663 +                                dhp = dtp->dt_tls;
     3664 +                        } else if (strcmp(lp->dn_string, "this") == 0) {
     3665 +                                dhp = yypcb->pcb_locals;
3669 3666                          }
     3667 +                        if (dhp != NULL) {
     3668 +                                if (rp->dn_kind != DT_NODE_VAR) {
     3669 +                                        dt_xcook_ident(rp, dhp,
     3670 +                                            DT_IDENT_SCALAR, B_TRUE);
     3671 +                                }
3670 3672  
3671      -                        if (idflags != 0)
3672      -                                rp = dt_node_cook(rp, idflags);
     3673 +                                if (idflags != 0)
     3674 +                                        rp = dt_node_cook(rp, idflags);
3673 3675  
3674      -                        dnp->dn_right = dnp->dn_left; /* avoid freeing rp */
3675      -                        dt_node_free(dnp);
3676      -                        return (rp);
     3676 +                                /* avoid freeing rp */
     3677 +                                dnp->dn_right = dnp->dn_left;
     3678 +                                dt_node_free(dnp);
     3679 +                                return (rp);
     3680 +                        }
3677 3681                  }
3678      -
3679 3682                  /*FALLTHRU*/
3680      -
3681 3683          case DT_TOK_DOT:
3682 3684                  lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
3683 3685  
3684 3686                  if (rp->dn_kind != DT_NODE_IDENT) {
3685 3687                          xyerror(D_OP_IDENT, "operator %s must be followed by "
3686 3688                              "an identifier\n", opstr(op));
3687 3689                  }
3688 3690  
3689 3691                  if ((idp = dt_node_resolve(lp, DT_IDENT_XLSOU)) != NULL ||
3690 3692                      (idp = dt_node_resolve(lp, DT_IDENT_XLPTR)) != NULL) {
↓ open down ↓ 798 lines elided ↑ open up ↑
4489 4491          dt_cook_statement,      /* DT_NODE_DEXPR */
4490 4492          dt_cook_statement,      /* DT_NODE_DFUNC */
4491 4493          dt_cook_aggregation,    /* DT_NODE_AGG */
4492 4494          dt_cook_none,           /* DT_NODE_PDESC */
4493 4495          dt_cook_clause,         /* DT_NODE_CLAUSE */
4494 4496          dt_cook_inline,         /* DT_NODE_INLINE */
4495 4497          dt_cook_member,         /* DT_NODE_MEMBER */
4496 4498          dt_cook_xlator,         /* DT_NODE_XLATOR */
4497 4499          dt_cook_none,           /* DT_NODE_PROBE */
4498 4500          dt_cook_provider,       /* DT_NODE_PROVIDER */
4499      -        dt_cook_none            /* DT_NODE_PROG */
     4501 +        dt_cook_none,           /* DT_NODE_PROG */
     4502 +        dt_cook_none,           /* DT_NODE_IF */
4500 4503  };
4501 4504  
4502 4505  /*
4503 4506   * Recursively cook the parse tree starting at the specified node.  The idflags
4504 4507   * parameter is used to indicate the type of reference (r/w) and is applied to
4505 4508   * the resulting identifier if it is a D variable or D aggregation.
4506 4509   */
4507 4510  dt_node_t *
4508 4511  dt_node_cook(dt_node_t *dnp, uint_t idflags)
4509 4512  {
4510 4513          int oldlineno = yylineno;
4511 4514  
4512 4515          yylineno = dnp->dn_line;
4513 4516  
     4517 +        assert(dnp->dn_kind <
     4518 +            sizeof (dt_cook_funcs) / sizeof (dt_cook_funcs[0]));
4514 4519          dnp = dt_cook_funcs[dnp->dn_kind](dnp, idflags);
4515 4520          dnp->dn_flags |= DT_NF_COOKED;
4516 4521  
4517 4522          if (dnp->dn_kind == DT_NODE_VAR || dnp->dn_kind == DT_NODE_AGG)
4518 4523                  dnp->dn_ident->di_flags |= idflags;
4519 4524  
4520 4525          yylineno = oldlineno;
4521 4526          return (dnp);
4522 4527  }
4523 4528  
↓ open down ↓ 82 lines elided ↑ open up ↑
4606 4611                      ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type));
4607 4612          }
4608 4613  
4609 4614          tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ?
4610 4615              (dnp->dn_flags & DT_NF_USERLAND) ? DIF_TF_BYUREF :
4611 4616              DIF_TF_BYREF : 0;
4612 4617          tp->dtdt_pad = 0;
4613 4618          tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type);
4614 4619  }
4615 4620  
     4621 +/*
     4622 + * Output the parse tree as D.  The "-xtree=8" argument will call this
     4623 + * function to print out the program after any syntactic sugar
     4624 + * transformations have been applied (e.g. to implement "if").  The
     4625 + * resulting output can be used to understand the transformations
     4626 + * applied by these features, or to run such a script on a system that
     4627 + * does not support these features
     4628 + *
     4629 + * Note that the output does not express precisely the same program as
     4630 + * the input.  In particular:
     4631 + *  - Only the clauses are output.  #pragma options, variable
     4632 + *    declarations, etc. are excluded.
     4633 + *  - Command argument substitution has already been done, so the output
     4634 + *    will not contain e.g. $$1, but rather the substituted string.
     4635 + */
4616 4636  void
     4637 +dt_printd(dt_node_t *dnp, FILE *fp, int depth)
     4638 +{
     4639 +        dt_node_t *arg;
     4640 +
     4641 +        switch (dnp->dn_kind) {
     4642 +        case DT_NODE_INT:
     4643 +                (void) fprintf(fp, "0x%llx", (u_longlong_t)dnp->dn_value);
     4644 +                if (!(dnp->dn_flags & DT_NF_SIGNED))
     4645 +                        (void) fprintf(fp, "u");
     4646 +                break;
     4647 +
     4648 +        case DT_NODE_STRING: {
     4649 +                char *escd = strchr2esc(dnp->dn_string, strlen(dnp->dn_string));
     4650 +                (void) fprintf(fp, "\"%s\"", escd);
     4651 +                free(escd);
     4652 +                break;
     4653 +        }
     4654 +
     4655 +        case DT_NODE_IDENT:
     4656 +                (void) fprintf(fp, "%s", dnp->dn_string);
     4657 +                break;
     4658 +
     4659 +        case DT_NODE_VAR:
     4660 +                (void) fprintf(fp, "%s%s",
     4661 +                    (dnp->dn_ident->di_flags & DT_IDFLG_LOCAL) ? "this->" :
     4662 +                    (dnp->dn_ident->di_flags & DT_IDFLG_TLS) ? "self->" : "",
     4663 +                    dnp->dn_ident->di_name);
     4664 +
     4665 +                if (dnp->dn_args != NULL) {
     4666 +                        (void) fprintf(fp, "[");
     4667 +
     4668 +                        for (arg = dnp->dn_args; arg != NULL;
     4669 +                            arg = arg->dn_list) {
     4670 +                                dt_printd(arg, fp, 0);
     4671 +                                if (arg->dn_list != NULL)
     4672 +                                        (void) fprintf(fp, ", ");
     4673 +                        }
     4674 +
     4675 +                        (void) fprintf(fp, "]");
     4676 +                }
     4677 +                break;
     4678 +
     4679 +        case DT_NODE_SYM: {
     4680 +                const dtrace_syminfo_t *dts = dnp->dn_ident->di_data;
     4681 +                (void) fprintf(fp, "%s`%s", dts->dts_object, dts->dts_name);
     4682 +                break;
     4683 +        }
     4684 +        case DT_NODE_FUNC:
     4685 +                (void) fprintf(fp, "%s(", dnp->dn_ident->di_name);
     4686 +
     4687 +                for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list) {
     4688 +                        dt_printd(arg, fp, 0);
     4689 +                        if (arg->dn_list != NULL)
     4690 +                                (void) fprintf(fp, ", ");
     4691 +                }
     4692 +                (void) fprintf(fp, ")");
     4693 +                break;
     4694 +
     4695 +        case DT_NODE_OP1:
     4696 +                (void) fprintf(fp, "%s(", opstr(dnp->dn_op));
     4697 +                dt_printd(dnp->dn_child, fp, 0);
     4698 +                (void) fprintf(fp, ")");
     4699 +                break;
     4700 +
     4701 +        case DT_NODE_OP2:
     4702 +                (void) fprintf(fp, "(");
     4703 +                dt_printd(dnp->dn_left, fp, 0);
     4704 +                if (dnp->dn_op == DT_TOK_LPAR) {
     4705 +                        (void) fprintf(fp, ")");
     4706 +                        dt_printd(dnp->dn_right, fp, 0);
     4707 +                        break;
     4708 +                }
     4709 +                if (dnp->dn_op == DT_TOK_PTR || dnp->dn_op == DT_TOK_DOT ||
     4710 +                    dnp->dn_op == DT_TOK_LBRAC)
     4711 +                        (void) fprintf(fp, "%s", opstr(dnp->dn_op));
     4712 +                else
     4713 +                        (void) fprintf(fp, " %s ", opstr(dnp->dn_op));
     4714 +                dt_printd(dnp->dn_right, fp, 0);
     4715 +                if (dnp->dn_op == DT_TOK_LBRAC) {
     4716 +                        dt_node_t *ln = dnp->dn_right;
     4717 +                        while (ln->dn_list != NULL) {
     4718 +                                (void) fprintf(fp, ", ");
     4719 +                                dt_printd(ln->dn_list, fp, depth);
     4720 +                                ln = ln->dn_list;
     4721 +                        }
     4722 +                        (void) fprintf(fp, "]");
     4723 +                }
     4724 +                (void) fprintf(fp, ")");
     4725 +                break;
     4726 +
     4727 +        case DT_NODE_OP3:
     4728 +                (void) fprintf(fp, "(");
     4729 +                dt_printd(dnp->dn_expr, fp, 0);
     4730 +                (void) fprintf(fp, " ? ");
     4731 +                dt_printd(dnp->dn_left, fp, 0);
     4732 +                (void) fprintf(fp, " : ");
     4733 +                dt_printd(dnp->dn_right, fp, 0);
     4734 +                (void) fprintf(fp, ")");
     4735 +                break;
     4736 +
     4737 +        case DT_NODE_DEXPR:
     4738 +        case DT_NODE_DFUNC:
     4739 +                (void) fprintf(fp, "%*s", depth * 8, "");
     4740 +                dt_printd(dnp->dn_expr, fp, depth + 1);
     4741 +                (void) fprintf(fp, ";\n");
     4742 +                break;
     4743 +
     4744 +        case DT_NODE_PDESC:
     4745 +                (void) fprintf(fp, "%s:%s:%s:%s",
     4746 +                    dnp->dn_desc->dtpd_provider, dnp->dn_desc->dtpd_mod,
     4747 +                    dnp->dn_desc->dtpd_func, dnp->dn_desc->dtpd_name);
     4748 +                break;
     4749 +
     4750 +        case DT_NODE_CLAUSE:
     4751 +                for (arg = dnp->dn_pdescs; arg != NULL; arg = arg->dn_list) {
     4752 +                        dt_printd(arg, fp, 0);
     4753 +                        if (arg->dn_list != NULL)
     4754 +                                (void) fprintf(fp, ",");
     4755 +                        (void) fprintf(fp, "\n");
     4756 +                }
     4757 +
     4758 +                if (dnp->dn_pred != NULL) {
     4759 +                        (void) fprintf(fp, "/");
     4760 +                        dt_printd(dnp->dn_pred, fp, 0);
     4761 +                        (void) fprintf(fp, "/\n");
     4762 +                }
     4763 +                        (void) fprintf(fp, "{\n");
     4764 +
     4765 +                for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
     4766 +                        dt_printd(arg, fp, depth + 1);
     4767 +                (void) fprintf(fp, "}\n");
     4768 +                (void) fprintf(fp, "\n");
     4769 +                break;
     4770 +
     4771 +        case DT_NODE_IF:
     4772 +                (void) fprintf(fp, "%*sif (", depth * 8, "");
     4773 +                dt_printd(dnp->dn_conditional, fp, 0);
     4774 +                (void) fprintf(fp, ") {\n");
     4775 +
     4776 +                for (arg = dnp->dn_body; arg != NULL; arg = arg->dn_list)
     4777 +                        dt_printd(arg, fp, depth + 1);
     4778 +                if (dnp->dn_alternate_body == NULL) {
     4779 +                        (void) fprintf(fp, "%*s}\n", depth * 8, "");
     4780 +                } else {
     4781 +                        (void) fprintf(fp, "%*s} else {\n", depth * 8, "");
     4782 +                        for (arg = dnp->dn_alternate_body; arg != NULL;
     4783 +                            arg = arg->dn_list)
     4784 +                                dt_printd(arg, fp, depth + 1);
     4785 +                        (void) fprintf(fp, "%*s}\n", depth * 8, "");
     4786 +                }
     4787 +
     4788 +                break;
     4789 +
     4790 +        default:
     4791 +                (void) fprintf(fp, "/* bad node %p, kind %d */\n",
     4792 +                    (void *)dnp, dnp->dn_kind);
     4793 +        }
     4794 +}
     4795 +
     4796 +void
4617 4797  dt_node_printr(dt_node_t *dnp, FILE *fp, int depth)
4618 4798  {
4619 4799          char n[DT_TYPE_NAMELEN], buf[BUFSIZ], a[8];
4620 4800          const dtrace_syminfo_t *dts;
4621 4801          const dt_idnode_t *inp;
4622 4802          dt_node_t *arg;
4623 4803  
4624 4804          (void) fprintf(fp, "%*s", depth * 2, "");
4625 4805          (void) dt_attr_str(dnp->dn_attr, a, sizeof (a));
4626 4806  
↓ open down ↓ 89 lines elided ↑ open up ↑
4716 4896  
4717 4897          case DT_NODE_OP1:
4718 4898                  (void) fprintf(fp, "OP1 %s (%s)\n", opstr(dnp->dn_op), buf);
4719 4899                  dt_node_printr(dnp->dn_child, fp, depth + 1);
4720 4900                  break;
4721 4901  
4722 4902          case DT_NODE_OP2:
4723 4903                  (void) fprintf(fp, "OP2 %s (%s)\n", opstr(dnp->dn_op), buf);
4724 4904                  dt_node_printr(dnp->dn_left, fp, depth + 1);
4725 4905                  dt_node_printr(dnp->dn_right, fp, depth + 1);
     4906 +                if (dnp->dn_op == DT_TOK_LBRAC) {
     4907 +                        dt_node_t *ln = dnp->dn_right;
     4908 +                        while (ln->dn_list != NULL) {
     4909 +                                dt_node_printr(ln->dn_list, fp, depth + 1);
     4910 +                                ln = ln->dn_list;
     4911 +                        }
     4912 +                }
4726 4913                  break;
4727 4914  
4728 4915          case DT_NODE_OP3:
4729 4916                  (void) fprintf(fp, "OP3 (%s)\n", buf);
4730 4917                  dt_node_printr(dnp->dn_expr, fp, depth + 1);
4731 4918                  (void) fprintf(fp, "%*s?\n", depth * 2, "");
4732 4919                  dt_node_printr(dnp->dn_left, fp, depth + 1);
4733 4920                  (void) fprintf(fp, "%*s:\n", depth * 2, "");
4734 4921                  dt_node_printr(dnp->dn_right, fp, depth + 1);
4735 4922                  break;
↓ open down ↓ 41 lines elided ↑ open up ↑
4777 4964                      dt_attr_str(dnp->dn_ctxattr, a, sizeof (a)));
4778 4965  
4779 4966                  if (dnp->dn_pred != NULL) {
4780 4967                          (void) fprintf(fp, "%*sPREDICATE /\n", depth * 2, "");
4781 4968                          dt_node_printr(dnp->dn_pred, fp, depth + 1);
4782 4969                          (void) fprintf(fp, "%*s/\n", depth * 2, "");
4783 4970                  }
4784 4971  
4785 4972                  for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
4786 4973                          dt_node_printr(arg, fp, depth + 1);
     4974 +                (void) fprintf(fp, "\n");
4787 4975                  break;
4788 4976  
4789 4977          case DT_NODE_INLINE:
4790 4978                  inp = dnp->dn_ident->di_iarg;
4791 4979  
4792 4980                  (void) fprintf(fp, "INLINE %s (%s)\n",
4793 4981                      dnp->dn_ident->di_name, buf);
4794 4982                  dt_node_printr(inp->din_root, fp, depth + 1);
4795 4983                  break;
4796 4984  
↓ open down ↓ 30 lines elided ↑ open up ↑
4827 5015                  for (arg = dnp->dn_probes; arg != NULL; arg = arg->dn_list)
4828 5016                          dt_node_printr(arg, fp, depth + 1);
4829 5017                  break;
4830 5018  
4831 5019          case DT_NODE_PROG:
4832 5020                  (void) fprintf(fp, "PROGRAM attr=%s\n", a);
4833 5021                  for (arg = dnp->dn_list; arg != NULL; arg = arg->dn_list)
4834 5022                          dt_node_printr(arg, fp, depth + 1);
4835 5023                  break;
4836 5024  
     5025 +        case DT_NODE_IF:
     5026 +                (void) fprintf(fp, "IF attr=%s CONDITION:\n", a);
     5027 +
     5028 +                dt_node_printr(dnp->dn_conditional, fp, depth + 1);
     5029 +
     5030 +                (void) fprintf(fp, "%*sIF BODY: \n", depth * 2, "");
     5031 +                for (arg = dnp->dn_body; arg != NULL; arg = arg->dn_list)
     5032 +                        dt_node_printr(arg, fp, depth + 1);
     5033 +
     5034 +                if (dnp->dn_alternate_body != NULL) {
     5035 +                        (void) fprintf(fp, "%*sIF ELSE: \n", depth * 2, "");
     5036 +                        for (arg = dnp->dn_alternate_body; arg != NULL;
     5037 +                            arg = arg->dn_list)
     5038 +                                dt_node_printr(arg, fp, depth + 1);
     5039 +                }
     5040 +
     5041 +                break;
     5042 +
4837 5043          default:
4838 5044                  (void) fprintf(fp, "<bad node %p, kind %d>\n",
4839 5045                      (void *)dnp, dnp->dn_kind);
4840 5046          }
4841 5047  }
4842 5048  
4843 5049  int
4844 5050  dt_node_root(dt_node_t *dnp)
4845 5051  {
4846 5052          yypcb->pcb_root = dnp;
↓ open down ↓ 133 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX