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