Print this page
11545 Want configurable output field separator for libofmt
Portions contributed by: Cody Peter Mello <cody.mello@joyent.com>
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libofmt/common/ofmt.h
+++ new/usr/src/lib/libofmt/common/ofmt.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
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]
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 + * Copyright (c) 2015 by Delphix. All rights reserved.
28 29 * Copyright 2017 Joyent, Inc.
29 30 */
30 31
31 32 #ifndef _OFMT_H
32 33 #define _OFMT_H
33 34
34 35 /*
35 36 * Data structures and routines for printing output.
36 37 *
37 38 * All output is assumed to be in a columnar format, where each column
38 39 * represents a field to be printed out. Multiple fields in parsable output
39 40 * are separated by ':', with the ':' character itself escaped by a \
40 41 * (e.g., IPv6 addresses may be printed as "fe80\:\:1"); single field output
41 42 * is printed as-is.
42 43 * In multiline mode, every [field,value] pair is printed in a line of
43 44 * its own, thus: "field: value".
44 45 *
45 46 * The caller must open a handle for each set of fields to be printed by
46 47 * invoking ofmt_open(). The invocation to ofmt_open must provide the list of
47 48 * supported fields, along with formatting information (e.g., field width), and
48 49 * a pointer to a callback function that can provide a string representation of
49 50 * the value to be printed out. The set of supported fields must be a NULL
50 51 * terminated array of type ofmt_field_t *ofields[]. The contents of the
51 52 * ofmt_field_t structure are used to construct the string that is emitted by
52 53 * ofmt_print(), and the interpretation of these contents is described with the
53 54 * semantics of ofmt_print() below.
54 55 *
55 56 * In addition, the call to ofmt_open() should provide a comma-separated
56 57 * list of the fields, char *fields_str, that have been selected for output
57 58 * (typically the string passed to -o in the command-line). The caller may
58 59 * also specify machine-parsable mode by specifying OFMT_PARSABLE in the oflags
59 60 * argument. Specifying a null or empty fields_str in the machine-parsable mode
60 61 * will result in a returned error value of OFMT_EPARSENONE. An attempt to
61 62 * create a handle in machine-parsable mode with the fields_str set to "all"
62 63 * will result in a returned error value of OFMT_EPARSEALL. In human-friendly
63 64 * (non machine-parsable) mode, a NULL fields_str, or a value of "all" for
64 65 * fields_str, is treated as a request to print all allowable fields that fit
65 66 * other applicable constraints.
66 67 * To achieve multiline mode, OFMT_MULTILINE needs to be specified in oflags.
67 68 * Specifying both OFMT_MULTILINE and OFMT_PARSABLE will result in
68 69 * OFMT_EPARSEMULTI.
69 70 *
70 71 * Thus a typical invocation to open the ofmt_handle would be:
71 72 *
72 73 * ofmt_handle_t ofmt;
73 74 * ofmt_status_t ofmt_err;
74 75 *
75 76 * ofmt_err = ofmt_open(fields_str, ofields, oflags, maxcols, &ofmt);
76 77 *
77 78 * where ofields is an array of the form:
78 79 *
79 80 * static ofmt_field_t ofields[] = {
80 81 * {<name>, <field width>, <id>, <callback> },
81 82 * :
82 83 * {<name>, <field width>, <id>, <callback> },
83 84 * {NULL, 0, 0, NULL}}
84 85 *
85 86 * <callback> is the application-specified function that provides a string
86 87 * representation of the value to be printed for the field. The calling
87 88 * application may provide unique values of <id> that will be passed back to
88 89 * <callback>, allowing a single <callback> to be shared between multiple
89 90 * fields in ofields[] with the value of <id> identifying the field that
90 91 * triggers the callback.
91 92 *
92 93 * If successful, ofmt_open() will return OFMT_SUCCESS, with a non-null
93 94 * ofmt_handle. The function returns a failure code otherwise, and more
94 95 * information about the type of failure can be obtained by calling
95 96 * ofmt_strerror()
96 97 *
97 98 * In order to print a row of output, the calling application should invoke
98 99 *
99 100 * ofmt_print(ofmt_handle, cbarg);
100 101 *
101 102 * where 'cbarg' points at the arguments to be passed to the <callback>
102 103 * function for each column in the row. The call to ofmt_print() will then
103 104 * result in the <callback> function of each selected field from ofields[]
104 105 * invoked with cbarg embedded in the ofmt_arg as
105 106 *
106 107 * (*callback)(ofmt_arg_t *ofmt_arg, char *buf, uint_t bufsize)
107 108 *
108 109 * Columns selected for output are identified by a match between the of_name
109 110 * value in the ofmt_field_t and the fields_str requested. For each selected
110 111 * column, the callback function (*of_cb)() is invoked, and is passed the of_id
111 112 * value from the ofmt_field_t structure for the field.
112 113 *
113 114 * The interpretation of the of_id field is completely private to the caller,
114 115 * and can be optionally used by the callback function as a cookie
115 116 * to identify the field being printed when a single callback function is
116 117 * shared between multiple ofmt_field_t entries.
117 118 *
118 119 * The callback function should fill `buf' with the string to be printed for
119 120 * the field using the data in cbarg.
↓ open down ↓ |
82 lines elided |
↑ open up ↑ |
120 121 *
121 122 * The calling application should invoke ofmt_close(ofmt_handle) to free up any
122 123 * resources allocated for the handle after all printing is completed.
123 124 *
124 125 * The printing library computes the current size of the output window when the
125 126 * handle is first created. If the caller wishes to adjust the window size
126 127 * after the handle has been created (e.g., on the reception of SIGWINCH by the
127 128 * caller), the function ofmt_update_winsize(handle) may be called.
128 129 */
129 130
130 -#include <sys/types.h>
131 -
132 131 #ifdef __cplusplus
133 132 extern "C" {
134 133 #endif
135 134
135 +#include <sys/types.h>
136 +
136 137 /*
137 138 * Recommended buffer size for buffers passed, for example, to ofmt_strerror().
138 139 */
139 140 #define OFMT_BUFSIZE 256
140 141
141 142 typedef enum {
142 143 OFMT_SUCCESS = 0,
143 144 OFMT_ENOMEM, /* out of memory */
144 145 OFMT_EBADFIELDS, /* one or more bad fields with good fields */
145 146 OFMT_ENOFIELDS, /* no valid output fields */
146 147 OFMT_EPARSEALL, /* 'all' invalid in parsable mode */
147 148 OFMT_EPARSENONE, /* output fields missing in parsable mode */
148 149 OFMT_EPARSEWRAP, /* parsable mode incompatible with wrap mode */
149 150 OFMT_ENOTEMPLATE, /* no template provided for fields */
150 151 OFMT_EPARSEMULTI /* parsable and multiline don't mix */
151 152 } ofmt_status_t;
152 153
153 154 /*
154 155 * The callback function for each field is invoked with a pointer to the
155 156 * ofmt_arg_t structure that contains the <id> registered by the application
156 157 * for that field, and the cbarg used by the application when invoking
157 158 * ofmt_output().
158 159 */
159 160 typedef struct ofmt_arg_s {
160 161 uint_t ofmt_id;
161 162 uint_t ofmt_width;
162 163 uint_t ofmt_index;
163 164 void *ofmt_cbarg;
164 165 } ofmt_arg_t;
165 166
166 167 /*
167 168 * ofmt callback function that provides a string representation of the value to
168 169 * be printed for the field.
169 170 */
170 171 typedef boolean_t ofmt_cb_t(ofmt_arg_t *, char *, uint_t);
171 172 typedef struct ofmt_field_s {
172 173 char *of_name; /* column name */
173 174 uint_t of_width; /* output column width */
174 175 uint_t of_id; /* implementation specific cookie */
175 176 ofmt_cb_t *of_cb; /* callback function defined by caller */
176 177 } ofmt_field_t;
177 178
178 179 /*
179 180 * ofmt_open() must be called to create the ofmt_handle_t; Resources allocated
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
180 181 * for the handle are freed by ofmt_close();
181 182 */
182 183 typedef struct ofmt_state_s *ofmt_handle_t;
183 184 extern ofmt_status_t ofmt_open(const char *, const ofmt_field_t *, uint_t,
184 185 uint_t, ofmt_handle_t *);
185 186
186 187 #define OFMT_PARSABLE 0x00000001 /* machine parsable mode */
187 188 #define OFMT_WRAP 0x00000002 /* wrap output if field width is exceeded */
188 189 #define OFMT_MULTILINE 0x00000004 /* "long" output: "name: value" lines */
189 190 #define OFMT_RIGHTJUST 0x00000008 /* right justified output */
191 +#define OFMT_NOHEADER 0x00000010 /* do not automatically print header lines */
190 192
191 193 /*
192 194 * ofmt_close() must be called to free resources associated
193 195 * with the ofmt_handle_t
194 196 */
195 197 extern void ofmt_close(ofmt_handle_t);
196 198
197 199 /*
200 + * Set the field separator used in parsable output (default is ':').
201 + */
202 +extern void ofmt_set_fs(ofmt_handle_t, char);
203 +
204 +/*
198 205 * ofmt_print() emits one row of output
199 206 */
200 207 extern void ofmt_print(ofmt_handle_t, void *);
201 208
202 209 /*
210 + * ofmt_print_header() prints the header line. It can be used with
211 + * OFMT_NOHEADER to control exactly when the header gets printed.
212 + */
213 +extern void ofmt_print_header(ofmt_handle_t);
214 +
215 +/*
203 216 * ofmt_update_winsize() updates the window size information for ofmt_handle_t
204 217 */
205 218 extern void ofmt_update_winsize(ofmt_handle_t);
206 219
207 220 /*
208 221 * ofmt_strerror() provides error diagnostics in the buffer that it is passed.
209 222 */
210 223 extern char *ofmt_strerror(ofmt_handle_t, ofmt_status_t, char *, uint_t);
211 224
212 225 extern void ofmt_check(ofmt_status_t oferr, boolean_t parsable,
213 226 ofmt_handle_t ofmt,
214 227 void (*die)(const char *, ...), void (*warn)(const char *, ...));
215 228
216 229 #ifdef __cplusplus
217 230 }
218 231 #endif
219 232
220 233 #endif /* _OFMT_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX