ofmt.c revision 25ec3e3dd27cc1038c10efa18ed08f064eab5fbe
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER START
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The contents of this file are subject to the terms of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Common Development and Distribution License (the "License").
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You may not use this file except in compliance with the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * See the License for the specific language governing permissions
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and limitations under the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * When distributing Covered Code, include this CDDL HEADER in each
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If applicable, add the following below this CDDL HEADER, with the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * fields enclosed by brackets "[]" replaced with your own identifying
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * information: Portions Copyright [yyyy] [name of copyright owner]
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER END
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Use is subject to license terms.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * functions and structures to internally process a comma-separated string
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * of fields selected for output.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppotypedef struct {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo const char **s_fields; /* array of pointers to the fields in s_buf */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo uint_t s_currfield; /* the current field being processed */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic split_t *split_fields(const ofmt_field_t *, uint_t, uint_t);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The state of the output is tracked in a ofmt_state_t structure.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Each os_fields[i] entry points at an ofmt_field_t array for
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * the sub-command whose contents are provided by the caller, with
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * os_nfields set to the number of requested fields.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppotypedef struct ofmt_state_s {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * A B_TRUE return value from the callback function will print out the contents
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * of the output buffer, except when the buffer is returned with the empty
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * string "", in which case the OFMT_VAL_UNDEF will be printed.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If the callback function returns B_FALSE, the "?" string will be emitted.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The maximum number of rows supported by the OFMT_WRAP option.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void ofmt_print_field(ofmt_state_t *, ofmt_field_t *, const char *,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Split `str' into at most `maxfields' fields, Return a pointer to a
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * split_t containing the split fields, or NULL on failure.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while ((field = strtok_r(token, ",", &lasts)) != NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Split `fields' into at most `maxfields' fields. Return a pointer to
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * a split_t containing the split fields, or NULL on failure. Invoked
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * when all fields are implicitly selected at handle creation by
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * passing in a NULL fields_str
1ae0874509b6811fdde1dfd46f0d93fd09867a3fhepposplit_fields(const ofmt_field_t *template, uint_t maxfields, uint_t maxcols)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < maxfields; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If all fields are implied without explicitly passing
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * in a fields_str, build a list of field names, stopping
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * when we run out of columns.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Free the split_t structure pointed to by `sp'.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Open a handle to be used for printing formatted output.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoofmt_open(const char *str, const ofmt_field_t *template, uint_t flags,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * For parsable output mode, the caller always needs
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * to specify precisely which fields are to be selected,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * since the set of fields may change over time.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * split str into the columns selected, or construct the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * full set of columns (equivalent to -o all).
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (parsable || (str != NULL && strcmp(str, "all") == 0))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * sp->s_nfields is the number of fields requested in fields_str.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * nfields is the number of fields in template.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (j = 0; j < nfields; j++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (j == nfields) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo sizeof (char *));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo os->os_nfields = of_index; /* actual number of fields printed */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * free resources associated with the ofmt_handle_t
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Print the value for the selected field by calling the callback-function
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * registered for the field.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoofmt_print_field(ofmt_state_t *os, ofmt_field_t *ofp, const char *value,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Parsable fields are separated by ':'. If such a field contains
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * a ':' or '\', this character is prefixed by a '\'.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Print enough to fit the field width.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoofmt_fit_width(split_t **spp, uint_t width, char *value, uint_t bufsize)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ptr += snprintf(ptr, lim - ptr, "%s,", sp->s_fields[i]);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Print one or more rows of output values for the selected columns.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((os->os_nrow++ % os->os_winsize.ws_row) == 0 && !os->os_parsable) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * 'value' will be split at comma boundaries
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and stored into sp[i].
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ofmt_print_field(os, &of[i], OFMT_VAL_UNKNOWN, escsep);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Print the field headers
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Update the current window size.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Return error diagnostics using the information in the ofmt_handle_t
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoofmt_strerror(ofmt_handle_t ofmt, ofmt_status_t err, char *buf, uint_t bufsize)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo const char *s;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * ebuf is intended for optional error-specific data to be appended
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * after the internationalized error string for an error code.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo switch (err) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "success";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Enumerate the singular/plural version of the warning
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and error to simplify and improve localization.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "ignoring unknown output fields:";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "ignoring unknown output field:";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "unknown output fields:";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "unknown output field:";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* set up the bad fields in ebuf */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "no valid output fields";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "output field `all' invalid in parsable mode";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "output fields must be specified in parsable mode";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "parsable mode is incompatible with wrap mode";
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo s = "no template provided for fields";