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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _OFMT_H 28 #define _OFMT_H 29 30 /* 31 * Data structures and routines for printing output. 32 * 33 * All output is assumed to be in a columnar format, where each column 34 * represents a field to be printed out. Multiple fields in parsable output 35 * are separated by ':', with the ':' character itself escaped by a \ 36 * (e.g., IPv6 addresses may be printed as "fe80\:\:1"); single field output 37 * is printed as-is. 38 * 39 * The caller must open a handle for each set of fields to be printed by 40 * invoking ofmt_open(). The invocation to ofmt_open must provide the list of 41 * supported fields, along with formatting information (e.g., field width), and 42 * a pointer to a callback function that can provide a string representation of 43 * the value to be printed out. The set of supported fields must be a NULL 44 * terminated array of type ofmt_field_t *ofields[]. The contents of the 45 * ofmt_field_t structure are used to construct the string that is emitted by 46 * ofmt_print(), and the interpretation of these contents is described with the 47 * semantics of ofmt_print() below. 48 * 49 * In addition, the call to ofmt_open() should provide a comma-separated 50 * list of the fields, char *fields_str, that have been selected for output 51 * (typically the string passed to -o in the command-line). The caller may 52 * also specify machine-parsable mode by specifying OFMT_PARSABLE in the oflags 53 * argument. Specifying a null or empty fields_str in the machine-parsable mode 54 * will result in a returned error value of OFMT_EPARSENONE. An attempt to 55 * create a handle in machine-parsable mode with the fields_str set to "all" 56 * will result in a returned error value of OFMT_EPARSEALL. In human-friendly 57 * (non machine-parsable) mode, a NULL fields_str, or a value of "all" for 58 * fields_str, is treated as a request to print all allowable fields that fit 59 * other applicable constraints. 60 * 61 * Thus a typical invocation to open the ofmt_handle would be: 62 * 63 * ofmt_handle_t ofmt; 64 * ofmt_status_t ofmt_err; 65 * 66 * ofmt_err = ofmt_open(fields_str, ofields, oflags, maxcols, &ofmt); 67 * 68 * where ofields is an array of the form: 69 * 70 * static ofmt_field_t ofields[] = { 71 * {<name>, <field width>, <id>, <callback> }, 72 * : 73 * {<name>, <field width>, <id>, <callback> }, 74 * {NULL, 0, 0, NULL}} 75 * 76 * <callback> is the application-specified function that provides a string 77 * representation of the value to be printed for the field. The calling 78 * application may provide unique values of <id> that will be passed back to 79 * <callback>, allowing a single <callback> to be shared between multiple 80 * fields in ofields[] with the value of <id> identifying the field that 81 * triggers the callback. 82 * 83 * If successful, ofmt_open() will return OFMT_SUCCESS, with a non-null 84 * ofmt_handle. The function returns a failure code otherwise, and more 85 * information about the type of failure can be obtained by calling 86 * ofmt_strerror() 87 * 88 * In order to print a row of output, the calling application should invoke 89 * 90 * ofmt_print(ofmt_handle, cbarg); 91 * 92 * where 'cbarg' points at the arguments to be passed to the <callback> 93 * function for each column in the row. The call to ofmt_print() will then 94 * result in the <callback> function of each selected field from ofields[] 95 * invoked with cbarg embedded in the ofmt_arg as 96 * 97 * (*callback)(ofmt_arg_t *ofmt_arg, char *buf, uint_t bufsize) 98 * 99 * Columns selected for output are identified by a match between the of_name 100 * value in the ofmt_field_t and the fields_str requested. For each selected 101 * column, the callback function (*of_cb)() is invoked, and is passed the of_id 102 * value from the ofmt_field_t structure for the field. 103 * 104 * The interpretation of the of_id field is completely private to the caller, 105 * and can be optionally used by the callback function as a cookie 106 * to identify the field being printed when a single callback function is 107 * shared between multiple ofmt_field_t entries. 108 * 109 * The callback function should fill `buf' with the string to be printed for 110 * the field using the data in cbarg. 111 * 112 * The calling application should invoke ofmt_close(ofmt_handle) to free up any 113 * resources allocated for the handle after all printing is completed. 114 * 115 * The printing library computes the current size of the output window when the 116 * handle is first created. If the caller wishes to adjust the window size 117 * after the handle has been created (e.g., on the reception of SIGWINCH by the 118 * caller), the function ofmt_update_winsize(handle) may be called. 119 */ 120 121 #ifdef __cplusplus 122 extern "C" { 123 #endif 124 125 /* 126 * Recommended buffer size for buffers passed, for example, to ofmt_strerror(). 127 */ 128 #define OFMT_BUFSIZE 256 129 130 typedef enum { 131 OFMT_SUCCESS = 0, 132 OFMT_ENOMEM, /* out of memory */ 133 OFMT_EBADFIELDS, /* one or more bad fields with good fields */ 134 OFMT_ENOFIELDS, /* no valid output fields */ 135 OFMT_EPARSEALL, /* 'all' invalid in parsable mode */ 136 OFMT_EPARSENONE, /* output fields missing in parsable mode */ 137 OFMT_EPARSEWRAP, /* parsable mode incompatible with wrap mode */ 138 OFMT_ENOTEMPLATE /* no template provided for fields */ 139 } ofmt_status_t; 140 141 /* 142 * The callback function for each field is invoked with a pointer to the 143 * ofmt_arg_t structure that contains the <id> registered by the application 144 * for that field, and the cbarg used by the application when invoking 145 * ofmt_output(). 146 */ 147 typedef struct ofmt_arg_s { 148 uint_t ofmt_id; 149 void *ofmt_cbarg; 150 } ofmt_arg_t; 151 152 /* 153 * ofmt callback function that provides a string representation of the value to 154 * be printed for the field. 155 */ 156 typedef boolean_t ofmt_cb_t(ofmt_arg_t *, char *, uint_t); 157 typedef struct ofmt_field_s { 158 char *of_name; /* column name */ 159 uint_t of_width; /* output column width */ 160 uint_t of_id; /* implementation specific cookie */ 161 ofmt_cb_t *of_cb; /* callback function defined by caller */ 162 } ofmt_field_t; 163 164 /* 165 * ofmt_open() must be called to create the ofmt_handle_t; Resources allocated 166 * for the handle are freed by ofmt_close(); 167 */ 168 typedef struct ofmt_state_s *ofmt_handle_t; 169 extern ofmt_status_t ofmt_open(const char *, const ofmt_field_t *, uint_t, 170 uint_t, ofmt_handle_t *); 171 172 #define OFMT_PARSABLE 0x00000001 /* machine parsable mode */ 173 #define OFMT_WRAP 0x00000002 /* wrap output if field width is exceeded */ 174 175 /* 176 * ofmt_close() must be called to free resources associated 177 * with the ofmt_handle_t 178 */ 179 extern void ofmt_close(ofmt_handle_t); 180 181 /* 182 * ofmt_print() emits one row of output 183 */ 184 extern void ofmt_print(ofmt_handle_t, void *); 185 186 /* 187 * ofmt_update_winsize() updates the window size information for ofmt_handle_t 188 */ 189 extern void ofmt_update_winsize(ofmt_handle_t); 190 191 /* 192 * ofmt_strerror() provides error diagnostics in the buffer that it is passed. 193 */ 194 extern char *ofmt_strerror(ofmt_handle_t, ofmt_status_t, char *, uint_t); 195 196 #ifdef __cplusplus 197 } 198 #endif 199 200 #endif /* _OFMT_H */ 201