Ejemplo n.º 1
0
/*
 *    Parse the user's string argument that represents the list of key
 *    fields or the counter fields to use in the AggBag.  Parse the
 *    string against the specified string map.  The final parameter is
 *    the argument type.  On success, set the keys or counters on the
 *    AggBag and return 0.  Return non-zero on error.
 */
static int
parseFields(
    const sk_stringmap_t   *string_map,
    const char             *name_list_arg,
    appOptionsEnum          key_or_counter)
{
    sk_stringmap_iter_t *sm_iter = NULL;
    sk_stringmap_entry_t *sm_entry = NULL;
    sk_aggbag_type_t *fields = NULL;
    unsigned int i;
    /* error message generated when parsing fields */
    char *errmsg;
    ssize_t err;
    /* return value; assume failure */
    int rv = -1;

    assert(string_map);
    assert(name_list_arg);
    assert(OPT_KEYS == key_or_counter
           || OPT_COUNTERS == key_or_counter);

    /* parse the argument */
    if (skStringMapParse(string_map, name_list_arg, SKSTRINGMAP_DUPES_ERROR,
                         &sm_iter, &errmsg))
    {
        skAppPrintErr("Invalid %s: %s",
                      appOptions[key_or_counter].name, errmsg);
        goto END;
    }

    /* create array to hold field IDs */
    fields = (sk_aggbag_type_t *)calloc(skStringMapIterCountMatches(sm_iter),
                                        sizeof(sk_aggbag_type_t));
    if (NULL == fields) {
        goto END;
    }

    /* add the field IDs to the array */
    i = 0;
    while (skStringMapIterNext(sm_iter, &sm_entry, NULL) == SK_ITERATOR_OK) {
        assert(i < skStringMapIterCountMatches(sm_iter));
        fields[i] = (sk_aggbag_type_t)sm_entry->id;
        ++i;
    }
    assert(skStringMapIterCountMatches(sm_iter) == i);

    if (OPT_KEYS == key_or_counter) {
        err = skAggBagSetKeyFields(ab, i, fields);
    } else {
        err = skAggBagSetCounterFields(ab, i, fields);
    }
    if (err) {
        skAppPrintErr("Unable to set %s %" SK_PRIdZ,
                      appOptions[key_or_counter].name, err);
        goto END;
    }

    /* successful */
    rv = 0;

  END:
    skStringMapIterDestroy(sm_iter);
    free(fields);
    return rv;
}
Ejemplo n.º 2
0
/*
 *  status = timestampFormatParse(format_string, out_flags);
 *
 *    Parse the comma-separated list of timestamp format strings
 *    contained in 'format_string' and set 'out_flags' to the result
 *    of parsing the string.  Return 0 on success, or -1 if parsing of
 *    the values fails or conflicting values are given.
 */
static int
timestampFormatParse(
    const char         *format,
    uint32_t           *out_flags)
{
    char buf[256];
    char *errmsg;
    sk_stringmap_t *str_map = NULL;
    sk_stringmap_iter_t *iter = NULL;
    sk_stringmap_entry_t *found_entry;
    const sk_stringmap_entry_t *entry;
    int name_seen = 0;
    int zone_seen = 0;
    int rv = -1;

    /* create a stringmap of the available timestamp formats */
    if (SKSTRINGMAP_OK != skStringMapCreate(&str_map)) {
        skAppPrintOutOfMemory(NULL);
        goto END;
    }
    if (skStringMapAddEntries(str_map, -1, timestamp_names) != SKSTRINGMAP_OK){
        skAppPrintOutOfMemory(NULL);
        goto END;
    }
    if (skStringMapAddEntries(str_map, -1, timestamp_zones) != SKSTRINGMAP_OK){
        skAppPrintOutOfMemory(NULL);
        goto END;
    }

    /* attempt to match */
    if (skStringMapParse(str_map, format, SKSTRINGMAP_DUPES_ERROR,
                         &iter, &errmsg))
    {
        skAppPrintErr("Invalid %s: %s",
                      appOptions[OPT_TIMESTAMP_FORMAT].name, errmsg);
        goto END;
    }

    *out_flags = 0;

    while (skStringMapIterNext(iter, &found_entry, NULL) == SK_ITERATOR_OK) {
        *out_flags |= found_entry->id;
        switch (found_entry->id) {
#if 0
          case SKTIMESTAMP_NOMSEC:
            break;
#endif
          case 0:
          case SKTIMESTAMP_EPOCH:
          case SKTIMESTAMP_ISO:
          case SKTIMESTAMP_MMDDYYYY:
            if (name_seen) {
                entry = timestamp_names;
                strncpy(buf, entry->name, sizeof(buf));
                for (++entry; entry->name; ++entry) {
                    strncat(buf, ",", sizeof(buf)-strlen(buf)-1);
                    strncat(buf, entry->name, sizeof(buf)-strlen(buf)-1);
                }
                skAppPrintErr("Invalid %s: May only specify one of %s",
                              appOptions[OPT_TIMESTAMP_FORMAT].name, buf);
                goto END;
            }
            name_seen = 1;
            break;

          case SKTIMESTAMP_UTC:
          case SKTIMESTAMP_LOCAL:
            if (zone_seen) {
                entry = timestamp_zones;
                strncpy(buf, entry->name, sizeof(buf));
                for (++entry; entry->name; ++entry) {
                    strncat(buf, ",", sizeof(buf)-strlen(buf)-1);
                    strncat(buf, entry->name, sizeof(buf)-strlen(buf)-1);
                }
                skAppPrintErr("Invalid %s: May only specify one of %s",
                              appOptions[OPT_TIMESTAMP_FORMAT].name, buf);
                goto END;
            }
            zone_seen = 1;
            break;

          default:
            skAbortBadCase(found_entry->id);
        }
    }

    rv = 0;

  END:
    if (str_map) {
        skStringMapDestroy(str_map);
    }
    if (iter) {
        skStringMapIterDestroy(iter);
    }
    return rv;
}