1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * ptree.c -- routines for printing the prop tree 27 * 28 * this module contains routines to print portions of the parse tree. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <ctype.h> 37 #include "out.h" 38 #include "stable.h" 39 #include "literals.h" 40 #include "lut.h" 41 #include "tree.h" 42 #include "ptree.h" 43 44 int Pchildgen; 45 46 #ifdef FMAPLUGIN 47 48 #include "itree.h" 49 #include "eval.h" 50 #include "config.h" 51 52 static void 53 cp2num(struct config *cp, int *num) 54 { 55 config_getcompname(cp, NULL, num); 56 } 57 58 #else 59 60 /*ARGSUSED*/ 61 static void 62 cp2num(struct config *cp, int *num) 63 { 64 out(O_DIE, "ptree: non-NULL cp"); 65 } 66 67 #endif /* FMAPLUGIN */ 68 69 static int 70 is_stmt(struct node *np) 71 { 72 switch (np->t) { 73 case T_FAULT: 74 case T_UPSET: 75 case T_DEFECT: 76 case T_ERROR: 77 case T_EREPORT: 78 case T_SERD: 79 case T_STAT: 80 case T_PROP: 81 case T_MASK: 82 case T_ASRU: 83 case T_FRU: 84 case T_CONFIG: 85 return (1); 86 /*NOTREACHED*/ 87 break; 88 default: 89 break; 90 } 91 92 return (0); 93 } 94 95 void 96 ptree(int flags, struct node *np, int no_iterators, int fileline) 97 { 98 if (np == NULL) 99 return; 100 101 switch (np->t) { 102 case T_NOTHING: 103 break; 104 case T_NAME: 105 out(flags|O_NONL, "%s", np->u.name.s); 106 if (!no_iterators) { 107 if (np->u.name.cp != NULL) { 108 int num; 109 cp2num(np->u.name.cp, &num); 110 out(flags|O_NONL, "%d", num); 111 } else if (np->u.name.it == IT_HORIZONTAL) { 112 if (np->u.name.child == NULL || 113 (np->u.name.childgen && !Pchildgen)) 114 out(flags|O_NONL, "<>"); 115 else { 116 out(flags|O_NONL, "<"); 117 ptree(flags, np->u.name.child, 118 no_iterators, fileline); 119 out(flags|O_NONL, ">"); 120 } 121 } else if (np->u.name.child && 122 (!np->u.name.childgen || Pchildgen)) { 123 if (np->u.name.it != IT_NONE) 124 out(flags|O_NONL, "["); 125 ptree(flags, np->u.name.child, no_iterators, 126 fileline); 127 if (np->u.name.it != IT_NONE) 128 out(flags|O_NONL, "]"); 129 } 130 } 131 if (np->u.name.next) { 132 ASSERT(np->u.name.next->t == T_NAME); 133 if (np->u.name.it == IT_ENAME) 134 out(flags|O_NONL, "."); 135 else 136 out(flags|O_NONL, "/"); 137 ptree(flags, np->u.name.next, no_iterators, fileline); 138 } 139 break; 140 case T_TIMEVAL: 141 ptree_timeval(flags, &np->u.ull); 142 break; 143 case T_NUM: 144 out(flags|O_NONL, "%llu", np->u.ull); 145 break; 146 case T_QUOTE: 147 out(flags|O_NONL, "\"%s\"", np->u.quote.s); 148 break; 149 case T_GLOBID: 150 out(flags|O_NONL, "$%s", np->u.globid.s); 151 break; 152 case T_FUNC: 153 out(flags|O_NONL, "%s(", np->u.func.s); 154 ptree(flags, np->u.func.arglist, no_iterators, fileline); 155 out(flags|O_NONL, ")"); 156 break; 157 case T_NVPAIR: 158 ptree(flags, np->u.expr.left, no_iterators, fileline); 159 out(flags|O_NONL, "="); 160 ptree(flags, np->u.expr.right, no_iterators, fileline); 161 break; 162 case T_EVENT: 163 ptree(flags, np->u.event.ename, no_iterators, fileline); 164 if (np->u.event.epname) { 165 out(flags|O_NONL, "@"); 166 ptree(flags, np->u.event.epname, 167 no_iterators, fileline); 168 } 169 if (np->u.event.eexprlist) { 170 out(flags|O_NONL, "{"); 171 ptree(flags, np->u.event.eexprlist, 172 no_iterators, fileline); 173 out(flags|O_NONL, "}"); 174 } 175 break; 176 case T_ASSIGN: 177 out(flags|O_NONL, "("); 178 ptree(flags, np->u.expr.left, no_iterators, fileline); 179 out(flags|O_NONL, "="); 180 ptree(flags, np->u.expr.right, no_iterators, fileline); 181 out(flags|O_NONL, ")"); 182 break; 183 case T_NOT: 184 out(flags|O_NONL, "("); 185 out(flags|O_NONL, "!"); 186 ptree(flags, np->u.expr.left, no_iterators, fileline); 187 out(flags|O_NONL, ")"); 188 break; 189 case T_AND: 190 out(flags|O_NONL, "("); 191 ptree(flags, np->u.expr.left, no_iterators, fileline); 192 out(flags|O_NONL, "&&"); 193 ptree(flags, np->u.expr.right, no_iterators, fileline); 194 out(flags|O_NONL, ")"); 195 break; 196 case T_OR: 197 out(flags|O_NONL, "("); 198 ptree(flags, np->u.expr.left, no_iterators, fileline); 199 out(flags|O_NONL, "||"); 200 ptree(flags, np->u.expr.right, no_iterators, fileline); 201 out(flags|O_NONL, ")"); 202 break; 203 case T_EQ: 204 out(flags|O_NONL, "("); 205 ptree(flags, np->u.expr.left, no_iterators, fileline); 206 out(flags|O_NONL, "=="); 207 ptree(flags, np->u.expr.right, no_iterators, fileline); 208 out(flags|O_NONL, ")"); 209 break; 210 case T_NE: 211 out(flags|O_NONL, "("); 212 ptree(flags, np->u.expr.left, no_iterators, fileline); 213 out(flags|O_NONL, "!="); 214 ptree(flags, np->u.expr.right, no_iterators, fileline); 215 out(flags|O_NONL, ")"); 216 break; 217 case T_SUB: 218 out(flags|O_NONL, "("); 219 ptree(flags, np->u.expr.left, no_iterators, fileline); 220 out(flags|O_NONL, "-"); 221 ptree(flags, np->u.expr.right, no_iterators, fileline); 222 out(flags|O_NONL, ")"); 223 break; 224 case T_ADD: 225 out(flags|O_NONL, "("); 226 ptree(flags, np->u.expr.left, no_iterators, fileline); 227 out(flags|O_NONL, "+"); 228 ptree(flags, np->u.expr.right, no_iterators, fileline); 229 out(flags|O_NONL, ")"); 230 break; 231 case T_MUL: 232 out(flags|O_NONL, "("); 233 ptree(flags, np->u.expr.left, no_iterators, fileline); 234 out(flags|O_NONL, "*"); 235 ptree(flags, np->u.expr.right, no_iterators, fileline); 236 out(flags|O_NONL, ")"); 237 break; 238 case T_DIV: 239 out(flags|O_NONL, "("); 240 ptree(flags, np->u.expr.left, no_iterators, fileline); 241 out(flags|O_NONL, "/"); 242 ptree(flags, np->u.expr.right, no_iterators, fileline); 243 out(flags|O_NONL, ")"); 244 break; 245 case T_MOD: 246 out(flags|O_NONL, "("); 247 ptree(flags, np->u.expr.left, no_iterators, fileline); 248 out(flags|O_NONL, "%%"); 249 ptree(flags, np->u.expr.right, no_iterators, fileline); 250 out(flags|O_NONL, ")"); 251 break; 252 case T_LT: 253 out(flags|O_NONL, "("); 254 ptree(flags, np->u.expr.left, no_iterators, fileline); 255 out(flags|O_NONL, "<"); 256 ptree(flags, np->u.expr.right, no_iterators, fileline); 257 out(flags|O_NONL, ")"); 258 break; 259 case T_LE: 260 out(flags|O_NONL, "("); 261 ptree(flags, np->u.expr.left, no_iterators, fileline); 262 out(flags|O_NONL, "<="); 263 ptree(flags, np->u.expr.right, no_iterators, fileline); 264 out(flags|O_NONL, ")"); 265 break; 266 case T_GT: 267 out(flags|O_NONL, "("); 268 ptree(flags, np->u.expr.left, no_iterators, fileline); 269 out(flags|O_NONL, ">"); 270 ptree(flags, np->u.expr.right, no_iterators, fileline); 271 out(flags|O_NONL, ")"); 272 break; 273 case T_GE: 274 out(flags|O_NONL, "("); 275 ptree(flags, np->u.expr.left, no_iterators, fileline); 276 out(flags|O_NONL, ">="); 277 ptree(flags, np->u.expr.right, no_iterators, fileline); 278 out(flags|O_NONL, ")"); 279 break; 280 case T_BITNOT: 281 out(flags|O_NONL, "("); 282 out(flags|O_NONL, "~"); 283 ptree(flags, np->u.expr.left, no_iterators, fileline); 284 out(flags|O_NONL, ")"); 285 break; 286 case T_BITAND: 287 out(flags|O_NONL, "("); 288 ptree(flags, np->u.expr.left, no_iterators, fileline); 289 out(flags|O_NONL, "&"); 290 ptree(flags, np->u.expr.right, no_iterators, fileline); 291 out(flags|O_NONL, ")"); 292 break; 293 case T_BITOR: 294 out(flags|O_NONL, "("); 295 ptree(flags, np->u.expr.left, no_iterators, fileline); 296 out(flags|O_NONL, "|"); 297 ptree(flags, np->u.expr.right, no_iterators, fileline); 298 out(flags|O_NONL, ")"); 299 break; 300 case T_BITXOR: 301 out(flags|O_NONL, "("); 302 ptree(flags, np->u.expr.left, no_iterators, fileline); 303 out(flags|O_NONL, "^"); 304 ptree(flags, np->u.expr.right, no_iterators, fileline); 305 out(flags|O_NONL, ")"); 306 break; 307 case T_LSHIFT: 308 out(flags|O_NONL, "("); 309 ptree(flags, np->u.expr.left, no_iterators, fileline); 310 out(flags|O_NONL, "<<"); 311 ptree(flags, np->u.expr.right, no_iterators, fileline); 312 out(flags|O_NONL, ")"); 313 break; 314 case T_RSHIFT: 315 out(flags|O_NONL, "("); 316 ptree(flags, np->u.expr.left, no_iterators, fileline); 317 out(flags|O_NONL, ">>"); 318 ptree(flags, np->u.expr.right, no_iterators, fileline); 319 out(flags|O_NONL, ")"); 320 break; 321 case T_CONDIF: 322 out(flags|O_NONL, "("); 323 ptree(flags, np->u.expr.left, no_iterators, fileline); 324 out(flags|O_NONL, "?"); 325 ptree(flags, np->u.expr.right, no_iterators, fileline); 326 out(flags|O_NONL, ")"); 327 break; 328 case T_CONDELSE: 329 out(flags|O_NONL, "("); 330 ptree(flags, np->u.expr.left, no_iterators, fileline); 331 out(flags|O_NONL, ":"); 332 ptree(flags, np->u.expr.right, no_iterators, fileline); 333 out(flags|O_NONL, ")"); 334 break; 335 case T_ARROW: 336 ptree(flags, np->u.arrow.lhs, no_iterators, fileline); 337 if (np->u.arrow.nnp) { 338 out(flags|O_NONL, "("); 339 ptree(flags, np->u.arrow.nnp, no_iterators, fileline); 340 out(flags|O_NONL, ")"); 341 } 342 out(flags|O_NONL, "->"); 343 if (np->u.arrow.knp) { 344 out(flags|O_NONL, "("); 345 ptree(flags, np->u.arrow.knp, no_iterators, fileline); 346 out(flags|O_NONL, ")"); 347 } 348 ptree(flags, np->u.arrow.rhs, no_iterators, fileline); 349 break; 350 case T_LIST: 351 ptree(flags, np->u.expr.left, no_iterators, fileline); 352 if (np->u.expr.left && np->u.expr.right && 353 (np->u.expr.left->t != T_LIST || 354 ! is_stmt(np->u.expr.right))) 355 out(flags|O_NONL, ","); 356 ptree(flags, np->u.expr.right, no_iterators, fileline); 357 break; 358 case T_FAULT: 359 case T_UPSET: 360 case T_DEFECT: 361 case T_ERROR: 362 case T_EREPORT: 363 if (fileline) 364 out(flags, "# %d \"%s\"", np->line, np->file); 365 out(flags|O_NONL, "event "); 366 ptree(flags, np->u.stmt.np, no_iterators, fileline); 367 if (np->u.stmt.nvpairs) { 368 out(flags|O_NONL, " "); 369 ptree(flags, np->u.stmt.nvpairs, no_iterators, 370 fileline); 371 } 372 out(flags, ";"); 373 break; 374 case T_SERD: 375 case T_STAT: 376 if (fileline) 377 out(flags, "# %d \"%s\"", np->line, np->file); 378 out(flags|O_NONL, "engine "); 379 ptree(flags, np->u.stmt.np, no_iterators, fileline); 380 if (np->u.stmt.nvpairs) { 381 out(flags|O_NONL, " "); 382 ptree(flags, np->u.stmt.nvpairs, no_iterators, 383 fileline); 384 } else if (np->u.stmt.lutp) { 385 struct plut_wlk_data pd; 386 387 pd.flags = flags; 388 pd.first = 0; 389 390 lut_walk(np->u.stmt.lutp, ptree_plut, &pd); 391 } 392 out(flags, ";"); 393 break; 394 case T_ASRU: 395 if (fileline) 396 out(flags, "# %d \"%s\"", np->line, np->file); 397 out(flags|O_NONL, "asru "); 398 ptree(flags, np->u.stmt.np, no_iterators, fileline); 399 if (np->u.stmt.nvpairs) { 400 out(flags|O_NONL, " "); 401 ptree(flags, np->u.stmt.nvpairs, no_iterators, 402 fileline); 403 } 404 out(flags, ";"); 405 break; 406 case T_FRU: 407 if (fileline) 408 out(flags, "# %d \"%s\"", np->line, np->file); 409 out(flags|O_NONL, "fru "); 410 ptree(flags, np->u.stmt.np, no_iterators, fileline); 411 if (np->u.stmt.nvpairs) { 412 out(flags|O_NONL, " "); 413 ptree(flags, np->u.stmt.nvpairs, no_iterators, 414 fileline); 415 } 416 out(flags, ";"); 417 break; 418 case T_CONFIG: 419 if (fileline) 420 out(flags, "# %d \"%s\"", np->line, np->file); 421 out(flags|O_NONL, "config "); 422 ptree(flags, np->u.stmt.np, no_iterators, fileline); 423 if (np->u.stmt.nvpairs) { 424 out(flags|O_NONL, " "); 425 ptree(flags, np->u.stmt.nvpairs, no_iterators, 426 fileline); 427 } 428 out(flags, ";"); 429 break; 430 case T_PROP: 431 if (fileline) 432 out(flags, "# %d \"%s\"", np->line, np->file); 433 out(flags|O_NONL, "prop "); 434 ptree(flags, np->u.stmt.np, no_iterators, fileline); 435 out(flags, ";"); 436 break; 437 case T_MASK: 438 if (fileline) 439 out(flags, "# %d \"%s\"", np->line, np->file); 440 out(flags|O_NONL, "mask "); 441 ptree(flags, np->u.stmt.np, no_iterators, fileline); 442 out(flags, ";"); 443 break; 444 default: 445 out(O_DIE, 446 "internal error: ptree unexpected nodetype: %d", np->t); 447 /*NOTREACHED*/ 448 } 449 } 450 451 void 452 ptree_plut(void *name, void *val, void *arg) 453 { 454 struct plut_wlk_data *pd = (struct plut_wlk_data *)arg; 455 int c; 456 static int indent; 457 458 indent++; 459 460 if (pd->first == 0) 461 out(pd->flags, ","); 462 else 463 pd->first = 0; 464 465 for (c = indent; c > 0; c--) 466 out(pd->flags|O_NONL, "\t"); 467 out(pd->flags|O_NONL, "%s", (char *)name); 468 469 out(pd->flags|O_NONL, "="); 470 ptree(pd->flags, val, 0, 0); 471 472 indent--; 473 } 474 475 void 476 ptree_name(int flags, struct node *np) 477 { 478 ptree(flags, np, 1, 0); 479 } 480 481 void 482 ptree_name_iter(int flags, struct node *np) 483 { 484 ptree(flags, np, 0, 0); 485 } 486 487 const char * 488 ptree_nodetype2str(enum nodetype t) 489 { 490 static char buf[100]; 491 492 switch (t) { 493 case T_NOTHING: return L_T_NOTHING; 494 case T_NAME: return L_T_NAME; 495 case T_GLOBID: return L_T_GLOBID; 496 case T_EVENT: return L_T_EVENT; 497 case T_ENGINE: return L_T_ENGINE; 498 case T_ASRU: return L_asru; 499 case T_FRU: return L_fru; 500 case T_CONFIG: return L_config; 501 case T_TIMEVAL: return L_T_TIMEVAL; 502 case T_NUM: return L_T_NUM; 503 case T_QUOTE: return L_T_QUOTE; 504 case T_FUNC: return L_T_FUNC; 505 case T_NVPAIR: return L_T_NVPAIR; 506 case T_ASSIGN: return L_T_ASSIGN; 507 case T_CONDIF: return L_T_CONDIF; 508 case T_CONDELSE: return L_T_CONDELSE; 509 case T_NOT: return L_T_NOT; 510 case T_AND: return L_T_AND; 511 case T_OR: return L_T_OR; 512 case T_EQ: return L_T_EQ; 513 case T_NE: return L_T_NE; 514 case T_SUB: return L_T_SUB; 515 case T_ADD: return L_T_ADD; 516 case T_MUL: return L_T_MUL; 517 case T_DIV: return L_T_DIV; 518 case T_MOD: return L_T_MOD; 519 case T_LT: return L_T_LT; 520 case T_LE: return L_T_LE; 521 case T_GT: return L_T_GT; 522 case T_GE: return L_T_GE; 523 case T_BITAND: return L_T_BITAND; 524 case T_BITOR: return L_T_BITOR; 525 case T_BITXOR: return L_T_BITXOR; 526 case T_BITNOT: return L_T_BITNOT; 527 case T_LSHIFT: return L_T_LSHIFT; 528 case T_RSHIFT: return L_T_RSHIFT; 529 case T_ARROW: return L_T_ARROW; 530 case T_LIST: return L_T_LIST; 531 case T_FAULT: return L_fault; 532 case T_UPSET: return L_upset; 533 case T_DEFECT: return L_defect; 534 case T_ERROR: return L_error; 535 case T_EREPORT: return L_ereport; 536 case T_SERD: return L_serd; 537 case T_STAT: return L_stat; 538 case T_PROP: return L_prop; 539 case T_MASK: return L_mask; 540 default: 541 (void) sprintf(buf, "[unexpected nodetype: %d]", t); 542 return (buf); 543 } 544 } 545 546 const char * 547 ptree_nametype2str(enum nametype t) 548 { 549 static char buf[100]; 550 551 switch (t) { 552 case N_UNSPEC: return L_N_UNSPEC; 553 case N_FAULT: return L_fault; 554 case N_DEFECT: return L_defect; 555 case N_UPSET: return L_upset; 556 case N_ERROR: return L_error; 557 case N_EREPORT: return L_ereport; 558 case N_SERD: return L_serd; 559 case N_STAT: return L_stat; 560 default: 561 (void) sprintf(buf, "[unexpected nametype: %d]", t); 562 return (buf); 563 } 564 } 565 566 struct printer_info { 567 enum nodetype t; 568 const char *pat; 569 int flags; 570 }; 571 572 static int 573 name_pattern_match(struct node *np, const char *pat) 574 { 575 const char *cend; /* first character not in component in pat */ 576 577 if (pat == NULL || *pat == '\0') 578 return (1); /* either no pattern or we've matched it all */ 579 580 if (np == NULL) 581 return (0); /* there's more pattern and nothing to match */ 582 583 ASSERTeq(np->t, T_NAME, ptree_nodetype2str); 584 585 cend = strchr(pat, '/'); 586 if (cend == NULL) 587 cend = strchr(pat, '.'); 588 if (cend == NULL) 589 cend = &pat[strlen(pat)]; 590 591 while (np) { 592 const char *s = np->u.name.s; 593 594 while (*s) { 595 const char *cstart = pat; 596 597 while (*s && tolower(*s) == tolower(*cstart)) { 598 cstart++; 599 if (cstart == cend) { 600 /* component matched */ 601 while (*cend == '/') 602 cend++; 603 return 604 name_pattern_match(np->u.name.next, 605 cend); 606 } 607 s++; 608 } 609 if (*s) 610 s++; 611 } 612 np = np->u.name.next; 613 } 614 return (0); 615 } 616 617 static int 618 name_pattern_match_in_subtree(struct node *np, const char *pat) 619 { 620 if (pat == NULL || *pat == '\0') 621 return (1); 622 623 if (np == NULL) 624 return (0); 625 626 if (np->t == T_NAME) 627 return (name_pattern_match(np, pat)); 628 else if (np->t == T_EVENT) 629 return (name_pattern_match_in_subtree(np->u.event.ename, pat) || 630 name_pattern_match_in_subtree(np->u.event.epname, pat) || 631 name_pattern_match_in_subtree(np->u.event.eexprlist, pat)); 632 else if (np->t == T_ARROW) 633 return (name_pattern_match_in_subtree(np->u.arrow.lhs, pat) || 634 name_pattern_match_in_subtree(np->u.arrow.rhs, pat)); 635 else if (np->t == T_ASSIGN || 636 np->t == T_CONDIF || 637 np->t == T_CONDELSE || 638 np->t == T_NOT || 639 np->t == T_AND || 640 np->t == T_OR || 641 np->t == T_EQ || 642 np->t == T_NE || 643 np->t == T_SUB || 644 np->t == T_ADD || 645 np->t == T_MUL || 646 np->t == T_DIV || 647 np->t == T_MOD || 648 np->t == T_LT || 649 np->t == T_LE || 650 np->t == T_GT || 651 np->t == T_GE || 652 np->t == T_BITAND || 653 np->t == T_BITOR || 654 np->t == T_BITXOR || 655 np->t == T_BITNOT || 656 np->t == T_LSHIFT || 657 np->t == T_RSHIFT || 658 np->t == T_LIST) { 659 return (name_pattern_match_in_subtree(np->u.expr.left, pat) || 660 name_pattern_match_in_subtree(np->u.expr.right, pat)); 661 } else if (np->t == T_FUNC) { 662 return (name_pattern_match_in_subtree(np->u.func.arglist, pat)); 663 } 664 return (0); 665 } 666 667 static void 668 byname_printer(struct node *lhs, struct node *rhs, void *arg) 669 { 670 struct printer_info *infop = (struct printer_info *)arg; 671 672 if (infop->t != T_NOTHING && rhs->t != infop->t) 673 return; 674 if (!name_pattern_match(lhs, infop->pat)) 675 return; 676 ptree(infop->flags, rhs, 0, 0); 677 } 678 679 static void 680 ptree_type_pattern(int flags, enum nodetype t, const char *pat) 681 { 682 struct printer_info info; 683 struct node *np; 684 685 info.flags = flags; 686 info.pat = pat; 687 info.t = t; 688 689 switch (t) { 690 case T_FAULT: 691 lut_walk(Faults, (lut_cb)byname_printer, (void *)&info); 692 return; 693 case T_UPSET: 694 lut_walk(Upsets, (lut_cb)byname_printer, (void *)&info); 695 return; 696 case T_DEFECT: 697 lut_walk(Defects, (lut_cb)byname_printer, (void *)&info); 698 return; 699 case T_ERROR: 700 lut_walk(Errors, (lut_cb)byname_printer, (void *)&info); 701 return; 702 case T_EREPORT: 703 lut_walk(Ereports, (lut_cb)byname_printer, (void *)&info); 704 return; 705 case T_SERD: 706 lut_walk(SERDs, (lut_cb)byname_printer, (void *)&info); 707 return; 708 case T_STAT: 709 lut_walk(STATs, (lut_cb)byname_printer, (void *)&info); 710 return; 711 case T_ASRU: 712 lut_walk(ASRUs, (lut_cb)byname_printer, (void *)&info); 713 return; 714 case T_FRU: 715 lut_walk(FRUs, (lut_cb)byname_printer, (void *)&info); 716 return; 717 case T_CONFIG: 718 lut_walk(Configs, (lut_cb)byname_printer, (void *)&info); 719 return; 720 case T_PROP: 721 for (np = Props; np; np = np->u.stmt.next) 722 if (name_pattern_match_in_subtree(np->u.stmt.np, pat)) 723 ptree(flags, np, 0, 0); 724 return; 725 case T_MASK: 726 for (np = Masks; np; np = np->u.stmt.next) 727 if (name_pattern_match_in_subtree(np->u.stmt.np, pat)) 728 ptree(flags, np, 0, 0); 729 return; 730 default: 731 ptree(flags, tree_root(NULL), 0, 0); 732 } 733 } 734 735 void 736 ptree_all(int flags, const char *pat) 737 { 738 ptree_type_pattern(flags, T_NOTHING, pat); 739 } 740 741 void 742 ptree_fault(int flags, const char *pat) 743 { 744 ptree_type_pattern(flags, T_FAULT, pat); 745 } 746 747 void 748 ptree_upset(int flags, const char *pat) 749 { 750 ptree_type_pattern(flags, T_UPSET, pat); 751 } 752 753 void 754 ptree_defect(int flags, const char *pat) 755 { 756 ptree_type_pattern(flags, T_DEFECT, pat); 757 } 758 759 void 760 ptree_error(int flags, const char *pat) 761 { 762 ptree_type_pattern(flags, T_ERROR, pat); 763 } 764 765 void 766 ptree_ereport(int flags, const char *pat) 767 { 768 ptree_type_pattern(flags, T_EREPORT, pat); 769 } 770 771 void 772 ptree_serd(int flags, const char *pat) 773 { 774 ptree_type_pattern(flags, T_SERD, pat); 775 } 776 777 void 778 ptree_stat(int flags, const char *pat) 779 { 780 ptree_type_pattern(flags, T_STAT, pat); 781 } 782 783 void 784 ptree_asru(int flags, const char *pat) 785 { 786 ptree_type_pattern(flags, T_ASRU, pat); 787 } 788 789 void 790 ptree_fru(int flags, const char *pat) 791 { 792 ptree_type_pattern(flags, T_FRU, pat); 793 } 794 795 void 796 ptree_prop(int flags, const char *pat) 797 { 798 ptree_type_pattern(flags, T_PROP, pat); 799 } 800 801 void 802 ptree_mask(int flags, const char *pat) 803 { 804 ptree_type_pattern(flags, T_MASK, pat); 805 } 806 807 void 808 ptree_timeval(int flags, unsigned long long *ullp) 809 { 810 unsigned long long val; 811 812 #define NOREMAINDER(den, num, val) (((val) = ((den) / (num))) * (num) == (den)) 813 if (*ullp == 0) 814 out(flags|O_NONL, "0us"); 815 else if (*ullp >= TIMEVAL_EVENTUALLY) 816 out(flags|O_NONL, "infinity"); 817 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24*365, val)) 818 out(flags|O_NONL, "%lluyear%s", val, (val == 1) ? "" : "s"); 819 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24*30, val)) 820 out(flags|O_NONL, "%llumonth%s", val, (val == 1) ? "" : "s"); 821 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24*7, val)) 822 out(flags|O_NONL, "%lluweek%s", val, (val == 1) ? "" : "s"); 823 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24, val)) 824 out(flags|O_NONL, "%lluday%s", val, (val == 1) ? "" : "s"); 825 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60, val)) 826 out(flags|O_NONL, "%lluhour%s", val, (val == 1) ? "" : "s"); 827 else if (NOREMAINDER(*ullp, 1000000000ULL*60, val)) 828 out(flags|O_NONL, "%lluminute%s", val, (val == 1) ? "" : "s"); 829 else if (NOREMAINDER(*ullp, 1000000000ULL, val)) 830 out(flags|O_NONL, "%llusecond%s", val, (val == 1) ? "" : "s"); 831 else if (NOREMAINDER(*ullp, 1000000ULL, val)) 832 out(flags|O_NONL, "%llums", val); 833 else if (NOREMAINDER(*ullp, 1000ULL, val)) 834 out(flags|O_NONL, "%lluus", val); 835 else 836 out(flags|O_NONL, "%lluns", *ullp); 837 } 838