TEST_F(TestIBUtilLogformat, test_parse_default)
{
    ib_status_t rc;
    ib_logformat_t *lf = NULL;
    const ib_list_node_t *node;
    const ib_logformat_item_t *item;
    static char linebuf[buflen + 1];
    static const char *formatted = \
                                   TIME_STAMP " " HOST_NAME " " REMOTE_IP " " SENSOR_ID " " SITE_ID " " \
                                   TX_ID " " LOG_FILE;
    size_t len;

    rc = ib_logformat_create(MM(), &lf);
    ASSERT_EQ(IB_OK, rc);

    rc = ib_logformat_parse(lf, IB_LOGFORMAT_DEFAULT);
    ASSERT_EQ(IB_OK, rc);

    ASSERT_STREQ(IB_LOGFORMAT_DEFAULT, lf->format);

    ASSERT_EQ(13U, ib_list_elements(lf->items));

    node = ib_list_first_const(lf->items);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_format, item->itype);
    ASSERT_EQ('T', item->item.field.fchar);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_literal, item->itype);
    ASSERT_STREQ(" ", item->item.literal.buf.short_str);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_format, item->itype);
    ASSERT_EQ('h', item->item.field.fchar);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_literal, item->itype);
    ASSERT_STREQ(" ", item->item.literal.buf.short_str);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_format, item->itype);
    ASSERT_EQ('a', item->item.field.fchar);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_literal, item->itype);
    ASSERT_STREQ(" ", item->item.literal.buf.short_str);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_format, item->itype);
    ASSERT_EQ('S', item->item.field.fchar);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_literal, item->itype);
    ASSERT_STREQ(" ", item->item.literal.buf.short_str);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_format, item->itype);
    ASSERT_EQ('s', item->item.field.fchar);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_literal, item->itype);
    ASSERT_STREQ(" ", item->item.literal.buf.short_str);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_format, item->itype);
    ASSERT_EQ('t', item->item.field.fchar);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_literal, item->itype);
    ASSERT_STREQ(" ", item->item.literal.buf.short_str);

    node = ib_list_node_next_const(node);
    ASSERT_TRUE(node);
    item = (const ib_logformat_item_t *)node->data;
    ASSERT_EQ(item_type_format, item->itype);
    ASSERT_EQ('f', item->item.field.fchar);

    rc = ib_logformat_format(lf, linebuf, buflen, &len, format_field, NULL);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_STREQ(formatted, linebuf);

    /* Verify that truncation is handled correctly */
    rc = ib_logformat_format(lf, linebuf, trunclen, &len, format_field, NULL);
    ASSERT_EQ(IB_ETRUNC, rc);
    ASSERT_EQ(len, trunclen-1);
    char trunc_buf[trunclen];
    strncpy(trunc_buf, formatted, trunclen-1);
    trunc_buf[trunclen-1] = '\0';
    ASSERT_STREQ(trunc_buf, linebuf);
}
Esempio n. 2
0
ib_status_t ib_string_join(
    const char  *join_string,
    ib_list_t   *list,
    ib_mm_t      mm,
    const char **pout,
    size_t      *pout_len
)
{
    assert(join_string != NULL);
    assert(list != NULL);
    assert(pout != NULL);
    assert(pout_len != NULL);

    const ib_list_node_t *node;
    char                 *end;         /* Points to the \0 in out. */
    const char           *out;
    size_t                out_len = 1; /* Size to hold an empty string, '\0' */
    size_t               *str_len;     /* Array of lengths of char*s in list. */
    size_t                str_idx;     /* Index into str_len. */
    size_t                join_string_len;

    join_string_len = strlen(join_string);

    /* Handle the base-case and avoid asking for size 0 memory segments. */
    if (ib_list_elements(list) == 0) {
        *pout     = "";
        *pout_len = 0;
        return IB_OK;
    }

    /* First, build a place to cache string lengths. */
    str_len = ib_mm_alloc(mm, sizeof(*str_len) * ib_list_elements(list));
    if (str_len == NULL) {
        return IB_EALLOC;
    }

    /* Record each string length and sum those lengths into out_len.
     * Recall that out_len starts equal to 1 for the '\0'. */
    str_idx = 0;
    IB_LIST_LOOP_CONST(list, node) {
        const size_t len = strlen((const char *)ib_list_node_data_const(node));

        out_len += len;
        str_len[str_idx] = len;
        ++str_idx;
    }

    /* Increase out_len by the join string length * (n-1) elements. */
    out_len += (ib_list_elements(list) - 1)* join_string_len;

    /* Allocate the final string. */
    end = ib_mm_alloc(mm, out_len);
    if (end == NULL) {
        return IB_EALLOC;
    }

    /* Setup vars for joining the strings into out. */
    out     = end;
    str_idx = 0;
    node    = ib_list_first(list);

    /* Copy the first string. We know the list is > 0 elements long. */
    strcpy(end, (const char *)ib_list_node_data_const(node));
    end += str_len[str_idx];
    ++str_idx;
    /* Having copied the first string, now copy the join string, then the
     * the next string until the end of the list. */
    for (
        node = ib_list_node_next_const(node);
        node != NULL;
        node = ib_list_node_next_const(node)
    )
    {
        /* Copy the join string first. */
        strcpy(end, join_string);
        end += join_string_len;

        /* Copy the lagging string. */
        strcpy(end, (const char *)ib_list_node_data_const(node));
        end += str_len[str_idx];

        ++str_idx;
    }

    /* Commit work back to the caller. */
    *pout     = out;
    *pout_len = out_len-1;
    return IB_OK;
}