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
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.
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]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 * ptree.c -- routines for printing the prop tree
28 * this module contains routines to print portions of the parse tree.
31 #pragma ident "%Z%%M% %I% %E% SMI"
53 cp2num(struct config
*cp
, int *num
)
55 config_getcompname(cp
, NULL
, num
);
62 cp2num(struct config
*cp
, int *num
)
64 out(O_DIE
, "ptree: non-NULL cp");
67 #endif /* FMAPLUGIN */
70 is_stmt(struct node
*np
)
96 ptree(int flags
, struct node
*np
, int no_iterators
, int fileline
)
105 out(flags
|O_NONL
, "%s", np
->u
.name
.s
);
107 if (np
->u
.name
.cp
!= NULL
) {
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
, "<>");
116 out(flags
|O_NONL
, "<");
117 ptree(flags
, np
->u
.name
.child
,
118 no_iterators
, fileline
);
119 out(flags
|O_NONL
, ">");
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
,
127 if (np
->u
.name
.it
!= IT_NONE
)
128 out(flags
|O_NONL
, "]");
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
, ".");
136 out(flags
|O_NONL
, "/");
137 ptree(flags
, np
->u
.name
.next
, no_iterators
, fileline
);
141 ptree_timeval(flags
, &np
->u
.ull
);
144 out(flags
|O_NONL
, "%llu", np
->u
.ull
);
147 out(flags
|O_NONL
, "\"%s\"", np
->u
.quote
.s
);
150 out(flags
|O_NONL
, "$%s", np
->u
.globid
.s
);
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
, ")");
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
);
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
);
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
, "}");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
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
, ")");
348 ptree(flags
, np
->u
.arrow
.rhs
, no_iterators
, fileline
);
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
);
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
,
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
,
384 } else if (np
->u
.stmt
.lutp
) {
385 struct plut_wlk_data pd
;
390 lut_walk(np
->u
.stmt
.lutp
, ptree_plut
, &pd
);
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
,
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
,
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
,
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
);
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
);
446 "internal error: ptree unexpected nodetype: %d", np
->t
);
452 ptree_plut(void *name
, void *val
, void *arg
)
454 struct plut_wlk_data
*pd
= (struct plut_wlk_data
*)arg
;
465 for (c
= indent
; c
> 0; c
--)
466 out(pd
->flags
|O_NONL
, "\t");
467 out(pd
->flags
|O_NONL
, "%s", (char *)name
);
469 out(pd
->flags
|O_NONL
, "=");
470 ptree(pd
->flags
, val
, 0, 0);
476 ptree_name(int flags
, struct node
*np
)
478 ptree(flags
, np
, 1, 0);
482 ptree_name_iter(int flags
, struct node
*np
)
484 ptree(flags
, np
, 0, 0);
488 ptree_nodetype2str(enum nodetype t
)
490 static char buf
[100];
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
;
541 (void) sprintf(buf
, "[unexpected nodetype: %d]", t
);
547 ptree_nametype2str(enum nametype t
)
549 static char buf
[100];
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
;
561 (void) sprintf(buf
, "[unexpected nametype: %d]", t
);
566 struct printer_info
{
573 name_pattern_match(struct node
*np
, const char *pat
)
575 const char *cend
; /* first character not in component in pat */
577 if (pat
== NULL
|| *pat
== '\0')
578 return (1); /* either no pattern or we've matched it all */
581 return (0); /* there's more pattern and nothing to match */
583 ASSERTeq(np
->t
, T_NAME
, ptree_nodetype2str
);
585 cend
= strchr(pat
, '/');
587 cend
= strchr(pat
, '.');
589 cend
= &pat
[strlen(pat
)];
592 const char *s
= np
->u
.name
.s
;
595 const char *cstart
= pat
;
597 while (*s
&& tolower(*s
) == tolower(*cstart
)) {
599 if (cstart
== cend
) {
600 /* component matched */
604 name_pattern_match(np
->u
.name
.next
,
612 np
= np
->u
.name
.next
;
618 name_pattern_match_in_subtree(struct node
*np
, const char *pat
)
620 if (pat
== NULL
|| *pat
== '\0')
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
||
637 np
->t
== T_CONDELSE
||
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
));
668 byname_printer(struct node
*lhs
, struct node
*rhs
, void *arg
)
670 struct printer_info
*infop
= (struct printer_info
*)arg
;
672 if (infop
->t
!= T_NOTHING
&& rhs
->t
!= infop
->t
)
674 if (!name_pattern_match(lhs
, infop
->pat
))
676 ptree(infop
->flags
, rhs
, 0, 0);
680 ptree_type_pattern(int flags
, enum nodetype t
, const char *pat
)
682 struct printer_info info
;
691 lut_walk(Faults
, (lut_cb
)byname_printer
, (void *)&info
);
694 lut_walk(Upsets
, (lut_cb
)byname_printer
, (void *)&info
);
697 lut_walk(Defects
, (lut_cb
)byname_printer
, (void *)&info
);
700 lut_walk(Errors
, (lut_cb
)byname_printer
, (void *)&info
);
703 lut_walk(Ereports
, (lut_cb
)byname_printer
, (void *)&info
);
706 lut_walk(SERDs
, (lut_cb
)byname_printer
, (void *)&info
);
709 lut_walk(STATs
, (lut_cb
)byname_printer
, (void *)&info
);
712 lut_walk(ASRUs
, (lut_cb
)byname_printer
, (void *)&info
);
715 lut_walk(FRUs
, (lut_cb
)byname_printer
, (void *)&info
);
718 lut_walk(Configs
, (lut_cb
)byname_printer
, (void *)&info
);
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);
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);
731 ptree(flags
, tree_root(NULL
), 0, 0);
736 ptree_all(int flags
, const char *pat
)
738 ptree_type_pattern(flags
, T_NOTHING
, pat
);
742 ptree_fault(int flags
, const char *pat
)
744 ptree_type_pattern(flags
, T_FAULT
, pat
);
748 ptree_upset(int flags
, const char *pat
)
750 ptree_type_pattern(flags
, T_UPSET
, pat
);
754 ptree_defect(int flags
, const char *pat
)
756 ptree_type_pattern(flags
, T_DEFECT
, pat
);
760 ptree_error(int flags
, const char *pat
)
762 ptree_type_pattern(flags
, T_ERROR
, pat
);
766 ptree_ereport(int flags
, const char *pat
)
768 ptree_type_pattern(flags
, T_EREPORT
, pat
);
772 ptree_serd(int flags
, const char *pat
)
774 ptree_type_pattern(flags
, T_SERD
, pat
);
778 ptree_stat(int flags
, const char *pat
)
780 ptree_type_pattern(flags
, T_STAT
, pat
);
784 ptree_asru(int flags
, const char *pat
)
786 ptree_type_pattern(flags
, T_ASRU
, pat
);
790 ptree_fru(int flags
, const char *pat
)
792 ptree_type_pattern(flags
, T_FRU
, pat
);
796 ptree_prop(int flags
, const char *pat
)
798 ptree_type_pattern(flags
, T_PROP
, pat
);
802 ptree_mask(int flags
, const char *pat
)
804 ptree_type_pattern(flags
, T_MASK
, pat
);
808 ptree_timeval(int flags
, unsigned long long *ullp
)
810 unsigned long long val
;
812 #define NOREMAINDER(den, num, val) (((val) = ((den) / (num))) * (num) == (den))
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
);
836 out(flags
|O_NONL
, "%lluns", *ullp
);