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 2004 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_PROP: 80 case T_MASK: 81 case T_ASRU: 82 case T_FRU: 83 case T_CONFIG: 84 return (1); 85 /*NOTREACHED*/ 86 break; 87 default: 88 break; 89 } 90 91 return (0); 92 } 93 94 void 95 ptree(int flags, struct node *np, int no_iterators, int fileline) 96 { 97 if (np == NULL) 98 return; 99 100 switch (np->t) { 101 case T_NOTHING: 102 break; 103 case T_NAME: 104 out(flags|O_NONL, "%s", np->u.name.s); 105 if (!no_iterators) { 106 if (np->u.name.cp != NULL) { 107 int num; 108 cp2num(np->u.name.cp, &num); 109 out(flags|O_NONL, "%d", num); 110 } else if (np->u.name.it == IT_HORIZONTAL) { 111 if (np->u.name.child == NULL || 112 (np->u.name.childgen && !Pchildgen)) 113 out(flags|O_NONL, "<>"); 114 else { 115 out(flags|O_NONL, "<"); 116 ptree(flags, np->u.name.child, 117 no_iterators, fileline); 118 out(flags|O_NONL, ">"); 119 } 120 } else if (np->u.name.child && 121 (!np->u.name.childgen || Pchildgen)) { 122 if (np->u.name.it != IT_NONE) 123 out(flags|O_NONL, "["); 124 ptree(flags, np->u.name.child, no_iterators, 125 fileline); 126 if (np->u.name.it != IT_NONE) 127 out(flags|O_NONL, "]"); 128 } 129 } 130 if (np->u.name.next) { 131 ASSERT(np->u.name.next->t == T_NAME); 132 if (np->u.name.it == IT_ENAME) 133 out(flags|O_NONL, "."); 134 else 135 out(flags|O_NONL, "/"); 136 ptree(flags, np->u.name.next, no_iterators, fileline); 137 } 138 break; 139 case T_TIMEVAL: 140 ptree_timeval(flags, &np->u.ull); 141 break; 142 case T_NUM: 143 out(flags|O_NONL, "%llu", np->u.ull); 144 break; 145 case T_QUOTE: 146 out(flags|O_NONL, "\"%s\"", np->u.quote.s); 147 break; 148 case T_GLOBID: 149 out(flags|O_NONL, "$%s", np->u.globid.s); 150 break; 151 case T_FUNC: 152 out(flags|O_NONL, "%s(", np->u.func.s); 153 ptree(flags, np->u.func.arglist, no_iterators, fileline); 154 out(flags|O_NONL, ")"); 155 break; 156 case T_NVPAIR: 157 ptree(flags, np->u.expr.left, no_iterators, fileline); 158 out(flags|O_NONL, "="); 159 ptree(flags, np->u.expr.right, no_iterators, fileline); 160 break; 161 case T_EVENT: 162 ptree(flags, np->u.event.ename, no_iterators, fileline); 163 if (np->u.event.epname) { 164 out(flags|O_NONL, "@"); 165 ptree(flags, np->u.event.epname, 166 no_iterators, fileline); 167 } 168 if (np->u.event.eexprlist) { 169 out(flags|O_NONL, "{"); 170 ptree(flags, np->u.event.eexprlist, 171 no_iterators, fileline); 172 out(flags|O_NONL, "}"); 173 } 174 break; 175 case T_ASSIGN: 176 out(flags|O_NONL, "("); 177 ptree(flags, np->u.expr.left, no_iterators, fileline); 178 out(flags|O_NONL, "="); 179 ptree(flags, np->u.expr.right, no_iterators, fileline); 180 out(flags|O_NONL, ")"); 181 break; 182 case T_NOT: 183 out(flags|O_NONL, "("); 184 out(flags|O_NONL, "!"); 185 ptree(flags, np->u.expr.left, no_iterators, fileline); 186 out(flags|O_NONL, ")"); 187 break; 188 case T_AND: 189 out(flags|O_NONL, "("); 190 ptree(flags, np->u.expr.left, no_iterators, fileline); 191 out(flags|O_NONL, "&&"); 192 ptree(flags, np->u.expr.right, no_iterators, fileline); 193 out(flags|O_NONL, ")"); 194 break; 195 case T_OR: 196 out(flags|O_NONL, "("); 197 ptree(flags, np->u.expr.left, no_iterators, fileline); 198 out(flags|O_NONL, "||"); 199 ptree(flags, np->u.expr.right, no_iterators, fileline); 200 out(flags|O_NONL, ")"); 201 break; 202 case T_EQ: 203 out(flags|O_NONL, "("); 204 ptree(flags, np->u.expr.left, no_iterators, fileline); 205 out(flags|O_NONL, "=="); 206 ptree(flags, np->u.expr.right, no_iterators, fileline); 207 out(flags|O_NONL, ")"); 208 break; 209 case T_NE: 210 out(flags|O_NONL, "("); 211 ptree(flags, np->u.expr.left, no_iterators, fileline); 212 out(flags|O_NONL, "!="); 213 ptree(flags, np->u.expr.right, no_iterators, fileline); 214 out(flags|O_NONL, ")"); 215 break; 216 case T_SUB: 217 out(flags|O_NONL, "("); 218 ptree(flags, np->u.expr.left, no_iterators, fileline); 219 out(flags|O_NONL, "-"); 220 ptree(flags, np->u.expr.right, no_iterators, fileline); 221 out(flags|O_NONL, ")"); 222 break; 223 case T_ADD: 224 out(flags|O_NONL, "("); 225 ptree(flags, np->u.expr.left, no_iterators, fileline); 226 out(flags|O_NONL, "+"); 227 ptree(flags, np->u.expr.right, no_iterators, fileline); 228 out(flags|O_NONL, ")"); 229 break; 230 case T_MUL: 231 out(flags|O_NONL, "("); 232 ptree(flags, np->u.expr.left, no_iterators, fileline); 233 out(flags|O_NONL, "*"); 234 ptree(flags, np->u.expr.right, no_iterators, fileline); 235 out(flags|O_NONL, ")"); 236 break; 237 case T_DIV: 238 out(flags|O_NONL, "("); 239 ptree(flags, np->u.expr.left, no_iterators, fileline); 240 out(flags|O_NONL, "/"); 241 ptree(flags, np->u.expr.right, no_iterators, fileline); 242 out(flags|O_NONL, ")"); 243 break; 244 case T_MOD: 245 out(flags|O_NONL, "("); 246 ptree(flags, np->u.expr.left, no_iterators, fileline); 247 out(flags|O_NONL, "%%"); 248 ptree(flags, np->u.expr.right, no_iterators, fileline); 249 out(flags|O_NONL, ")"); 250 break; 251 case T_LT: 252 out(flags|O_NONL, "("); 253 ptree(flags, np->u.expr.left, no_iterators, fileline); 254 out(flags|O_NONL, "<"); 255 ptree(flags, np->u.expr.right, no_iterators, fileline); 256 out(flags|O_NONL, ")"); 257 break; 258 case T_LE: 259 out(flags|O_NONL, "("); 260 ptree(flags, np->u.expr.left, no_iterators, fileline); 261 out(flags|O_NONL, "<="); 262 ptree(flags, np->u.expr.right, no_iterators, fileline); 263 out(flags|O_NONL, ")"); 264 break; 265 case T_GT: 266 out(flags|O_NONL, "("); 267 ptree(flags, np->u.expr.left, no_iterators, fileline); 268 out(flags|O_NONL, ">"); 269 ptree(flags, np->u.expr.right, no_iterators, fileline); 270 out(flags|O_NONL, ")"); 271 break; 272 case T_GE: 273 out(flags|O_NONL, "("); 274 ptree(flags, np->u.expr.left, no_iterators, fileline); 275 out(flags|O_NONL, ">="); 276 ptree(flags, np->u.expr.right, no_iterators, fileline); 277 out(flags|O_NONL, ")"); 278 break; 279 case T_BITNOT: 280 out(flags|O_NONL, "("); 281 out(flags|O_NONL, "~"); 282 ptree(flags, np->u.expr.left, no_iterators, fileline); 283 out(flags|O_NONL, ")"); 284 break; 285 case T_BITAND: 286 out(flags|O_NONL, "("); 287 ptree(flags, np->u.expr.left, no_iterators, fileline); 288 out(flags|O_NONL, "&"); 289 ptree(flags, np->u.expr.right, no_iterators, fileline); 290 out(flags|O_NONL, ")"); 291 break; 292 case T_BITOR: 293 out(flags|O_NONL, "("); 294 ptree(flags, np->u.expr.left, no_iterators, fileline); 295 out(flags|O_NONL, "|"); 296 ptree(flags, np->u.expr.right, no_iterators, fileline); 297 out(flags|O_NONL, ")"); 298 break; 299 case T_BITXOR: 300 out(flags|O_NONL, "("); 301 ptree(flags, np->u.expr.left, no_iterators, fileline); 302 out(flags|O_NONL, "^"); 303 ptree(flags, np->u.expr.right, no_iterators, fileline); 304 out(flags|O_NONL, ")"); 305 break; 306 case T_LSHIFT: 307 out(flags|O_NONL, "("); 308 ptree(flags, np->u.expr.left, no_iterators, fileline); 309 out(flags|O_NONL, "<<"); 310 ptree(flags, np->u.expr.right, no_iterators, fileline); 311 out(flags|O_NONL, ")"); 312 break; 313 case T_RSHIFT: 314 out(flags|O_NONL, "("); 315 ptree(flags, np->u.expr.left, no_iterators, fileline); 316 out(flags|O_NONL, ">>"); 317 ptree(flags, np->u.expr.right, no_iterators, fileline); 318 out(flags|O_NONL, ")"); 319 break; 320 case T_CONDIF: 321 out(flags|O_NONL, "("); 322 ptree(flags, np->u.expr.left, no_iterators, fileline); 323 out(flags|O_NONL, "?"); 324 ptree(flags, np->u.expr.right, no_iterators, fileline); 325 out(flags|O_NONL, ")"); 326 break; 327 case T_CONDELSE: 328 out(flags|O_NONL, "("); 329 ptree(flags, np->u.expr.left, no_iterators, fileline); 330 out(flags|O_NONL, ":"); 331 ptree(flags, np->u.expr.right, no_iterators, fileline); 332 out(flags|O_NONL, ")"); 333 break; 334 case T_ARROW: 335 ptree(flags, np->u.arrow.lhs, no_iterators, fileline); 336 if (np->u.arrow.nnp) { 337 out(flags|O_NONL, "("); 338 ptree(flags, np->u.arrow.nnp, no_iterators, fileline); 339 out(flags|O_NONL, ")"); 340 } 341 out(flags|O_NONL, "->"); 342 if (np->u.arrow.knp) { 343 out(flags|O_NONL, "("); 344 ptree(flags, np->u.arrow.knp, no_iterators, fileline); 345 out(flags|O_NONL, ")"); 346 } 347 ptree(flags, np->u.arrow.rhs, no_iterators, fileline); 348 break; 349 case T_LIST: 350 ptree(flags, np->u.expr.left, no_iterators, fileline); 351 if (np->u.expr.left && np->u.expr.right && 352 (np->u.expr.left->t != T_LIST || 353 ! is_stmt(np->u.expr.right))) 354 out(flags|O_NONL, ","); 355 ptree(flags, np->u.expr.right, no_iterators, fileline); 356 break; 357 case T_FAULT: 358 case T_UPSET: 359 case T_DEFECT: 360 case T_ERROR: 361 case T_EREPORT: 362 if (fileline) 363 out(flags, "# %d \"%s\"", np->line, np->file); 364 out(flags|O_NONL, "event "); 365 ptree(flags, np->u.stmt.np, no_iterators, fileline); 366 if (np->u.stmt.nvpairs) { 367 out(flags|O_NONL, " "); 368 ptree(flags, np->u.stmt.nvpairs, no_iterators, 369 fileline); 370 } 371 out(flags, ";"); 372 break; 373 case T_SERD: 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_PROP: return L_prop; 536 case T_MASK: return L_mask; 537 default: 538 (void) sprintf(buf, "[unexpected nodetype: %d]", t); 539 return (buf); 540 } 541 } 542 543 const char * 544 ptree_nametype2str(enum nametype t) 545 { 546 static char buf[100]; 547 548 switch (t) { 549 case N_UNSPEC: return L_N_UNSPEC; 550 case N_FAULT: return L_fault; 551 case N_DEFECT: return L_defect; 552 case N_UPSET: return L_upset; 553 case N_ERROR: return L_error; 554 case N_EREPORT: return L_ereport; 555 case N_SERD: return L_serd; 556 default: 557 (void) sprintf(buf, "[unexpected nametype: %d]", t); 558 return (buf); 559 } 560 } 561 562 struct printer_info { 563 enum nodetype t; 564 const char *pat; 565 int flags; 566 }; 567 568 static int 569 name_pattern_match(struct node *np, const char *pat) 570 { 571 const char *cend; /* first character not in component in pat */ 572 573 if (pat == NULL || *pat == '\0') 574 return (1); /* either no pattern or we've matched it all */ 575 576 if (np == NULL) 577 return (0); /* there's more pattern and nothing to match */ 578 579 ASSERTeq(np->t, T_NAME, ptree_nodetype2str); 580 581 cend = strchr(pat, '/'); 582 if (cend == NULL) 583 cend = strchr(pat, '.'); 584 if (cend == NULL) 585 cend = &pat[strlen(pat)]; 586 587 while (np) { 588 const char *s = np->u.name.s; 589 590 while (*s) { 591 const char *cstart = pat; 592 593 while (*s && tolower(*s) == tolower(*cstart)) { 594 cstart++; 595 if (cstart == cend) { 596 /* component matched */ 597 while (*cend == '/') 598 cend++; 599 return 600 name_pattern_match(np->u.name.next, 601 cend); 602 } 603 s++; 604 } 605 if (*s) 606 s++; 607 } 608 np = np->u.name.next; 609 } 610 return (0); 611 } 612 613 static int 614 name_pattern_match_in_subtree(struct node *np, const char *pat) 615 { 616 if (pat == NULL || *pat == '\0') 617 return (1); 618 619 if (np == NULL) 620 return (0); 621 622 if (np->t == T_NAME) 623 return (name_pattern_match(np, pat)); 624 else if (np->t == T_EVENT) 625 return (name_pattern_match_in_subtree(np->u.event.ename, pat) || 626 name_pattern_match_in_subtree(np->u.event.epname, pat) || 627 name_pattern_match_in_subtree(np->u.event.eexprlist, pat)); 628 else if (np->t == T_ARROW) 629 return (name_pattern_match_in_subtree(np->u.arrow.lhs, pat) || 630 name_pattern_match_in_subtree(np->u.arrow.rhs, pat)); 631 else if (np->t == T_ASSIGN || 632 np->t == T_CONDIF || 633 np->t == T_CONDELSE || 634 np->t == T_NOT || 635 np->t == T_AND || 636 np->t == T_OR || 637 np->t == T_EQ || 638 np->t == T_NE || 639 np->t == T_SUB || 640 np->t == T_ADD || 641 np->t == T_MUL || 642 np->t == T_DIV || 643 np->t == T_MOD || 644 np->t == T_LT || 645 np->t == T_LE || 646 np->t == T_GT || 647 np->t == T_GE || 648 np->t == T_BITAND || 649 np->t == T_BITOR || 650 np->t == T_BITXOR || 651 np->t == T_BITNOT || 652 np->t == T_LSHIFT || 653 np->t == T_RSHIFT || 654 np->t == T_LIST) { 655 return (name_pattern_match_in_subtree(np->u.expr.left, pat) || 656 name_pattern_match_in_subtree(np->u.expr.right, pat)); 657 } else if (np->t == T_FUNC) { 658 return (name_pattern_match_in_subtree(np->u.func.arglist, pat)); 659 } 660 return (0); 661 } 662 663 static void 664 byname_printer(struct node *lhs, struct node *rhs, void *arg) 665 { 666 struct printer_info *infop = (struct printer_info *)arg; 667 668 if (infop->t != T_NOTHING && rhs->t != infop->t) 669 return; 670 if (!name_pattern_match(lhs, infop->pat)) 671 return; 672 ptree(infop->flags, rhs, 0, 0); 673 } 674 675 static void 676 ptree_type_pattern(int flags, enum nodetype t, const char *pat) 677 { 678 struct printer_info info; 679 struct node *np; 680 681 info.flags = flags; 682 info.pat = pat; 683 info.t = t; 684 685 switch (t) { 686 case T_FAULT: 687 lut_walk(Faults, (lut_cb)byname_printer, (void *)&info); 688 return; 689 case T_UPSET: 690 lut_walk(Upsets, (lut_cb)byname_printer, (void *)&info); 691 return; 692 case T_DEFECT: 693 lut_walk(Defects, (lut_cb)byname_printer, (void *)&info); 694 return; 695 case T_ERROR: 696 lut_walk(Errors, (lut_cb)byname_printer, (void *)&info); 697 return; 698 case T_EREPORT: 699 lut_walk(Ereports, (lut_cb)byname_printer, (void *)&info); 700 return; 701 case T_SERD: 702 lut_walk(SERDs, (lut_cb)byname_printer, (void *)&info); 703 return; 704 case T_ASRU: 705 lut_walk(ASRUs, (lut_cb)byname_printer, (void *)&info); 706 return; 707 case T_FRU: 708 lut_walk(FRUs, (lut_cb)byname_printer, (void *)&info); 709 return; 710 case T_CONFIG: 711 lut_walk(Configs, (lut_cb)byname_printer, (void *)&info); 712 return; 713 case T_PROP: 714 for (np = Props; np; np = np->u.stmt.next) 715 if (name_pattern_match_in_subtree(np->u.stmt.np, pat)) 716 ptree(flags, np, 0, 0); 717 return; 718 case T_MASK: 719 for (np = Masks; 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 default: 724 ptree(flags, tree_root(NULL), 0, 0); 725 } 726 } 727 728 void 729 ptree_all(int flags, const char *pat) 730 { 731 ptree_type_pattern(flags, T_NOTHING, pat); 732 } 733 734 void 735 ptree_fault(int flags, const char *pat) 736 { 737 ptree_type_pattern(flags, T_FAULT, pat); 738 } 739 740 void 741 ptree_upset(int flags, const char *pat) 742 { 743 ptree_type_pattern(flags, T_UPSET, pat); 744 } 745 746 void 747 ptree_defect(int flags, const char *pat) 748 { 749 ptree_type_pattern(flags, T_DEFECT, pat); 750 } 751 752 void 753 ptree_error(int flags, const char *pat) 754 { 755 ptree_type_pattern(flags, T_ERROR, pat); 756 } 757 758 void 759 ptree_ereport(int flags, const char *pat) 760 { 761 ptree_type_pattern(flags, T_EREPORT, pat); 762 } 763 764 void 765 ptree_serd(int flags, const char *pat) 766 { 767 ptree_type_pattern(flags, T_SERD, pat); 768 } 769 770 void 771 ptree_asru(int flags, const char *pat) 772 { 773 ptree_type_pattern(flags, T_ASRU, pat); 774 } 775 776 void 777 ptree_fru(int flags, const char *pat) 778 { 779 ptree_type_pattern(flags, T_FRU, pat); 780 } 781 782 void 783 ptree_prop(int flags, const char *pat) 784 { 785 ptree_type_pattern(flags, T_PROP, pat); 786 } 787 788 void 789 ptree_mask(int flags, const char *pat) 790 { 791 ptree_type_pattern(flags, T_MASK, pat); 792 } 793 794 void 795 ptree_timeval(int flags, unsigned long long *ullp) 796 { 797 unsigned long long val; 798 799 #define NOREMAINDER(den, num, val) (((val) = ((den) / (num))) * (num) == (den)) 800 if (*ullp == 0) 801 out(flags|O_NONL, "0us"); 802 else if (*ullp >= TIMEVAL_EVENTUALLY) 803 out(flags|O_NONL, "infinity"); 804 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24*365, val)) 805 out(flags|O_NONL, "%lluyear%s", val, (val == 1) ? "" : "s"); 806 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24*30, val)) 807 out(flags|O_NONL, "%llumonth%s", val, (val == 1) ? "" : "s"); 808 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24*7, val)) 809 out(flags|O_NONL, "%lluweek%s", val, (val == 1) ? "" : "s"); 810 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60*24, val)) 811 out(flags|O_NONL, "%lluday%s", val, (val == 1) ? "" : "s"); 812 else if (NOREMAINDER(*ullp, 1000000000ULL*60*60, val)) 813 out(flags|O_NONL, "%lluhour%s", val, (val == 1) ? "" : "s"); 814 else if (NOREMAINDER(*ullp, 1000000000ULL*60, val)) 815 out(flags|O_NONL, "%lluminute%s", val, (val == 1) ? "" : "s"); 816 else if (NOREMAINDER(*ullp, 1000000000ULL, val)) 817 out(flags|O_NONL, "%llusecond%s", val, (val == 1) ? "" : "s"); 818 else if (NOREMAINDER(*ullp, 1000000ULL, val)) 819 out(flags|O_NONL, "%llums", val); 820 else if (NOREMAINDER(*ullp, 1000ULL, val)) 821 out(flags|O_NONL, "%lluus", val); 822 else 823 out(flags|O_NONL, "%lluns", *ullp); 824 } 825