Commit 806224be authored by Geoff Simmons's avatar Geoff Simmons

varnishevent: add strfTIM

parent 604ab830
......@@ -22,6 +22,8 @@ varnishevent_SOURCES = \
monitor.c \
format.c \
handler.c \
strfTIM.h \
strfTIM.c \
$(top_builddir)/lib/libvarnish/assert.c \
$(top_builddir)/lib/libvarnish/flopen.c \
$(top_builddir)/lib/libvarnish/version.c \
......
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <time.h>
#include "strfTIM.h"
#include "vsb.h"
#include "libvarnish.h"
size_t
strfTIM(char *s, size_t max, const char *fmt, struct tm *tm, long nsec)
{
struct vsb *vsb = VSB_new(NULL, NULL, max, VSB_FIXEDLEN);
const char *p;
size_t n;
for (p = fmt; *p; p++) {
if (*p != '%') {
VSB_putc(vsb, *p);
continue;
}
p++;
if (*p == '%') {
VSB_cat(vsb, "%%");
continue;
}
if (*p != 'N') {
VSB_putc(vsb, '%');
VSB_putc(vsb, *p);
continue;
}
VSB_printf(vsb, "%09ld", nsec);
}
VSB_finish(vsb);
if (VSB_error(vsb)) {
VSB_delete(vsb);
return 0;
}
n = strftime(s, max, VSB_data(vsb), tm);
VSB_delete(vsb);
return n;
}
#define strfTIM_tz(tz) \
size_t \
strfTIM##tz(char *s, size_t max, const char *fmt, double t) \
{ \
struct timespec tim = TIM_timespec(t); \
struct tm tm; \
\
AN(tz##time_r((time_t *) &tim.tv_sec, &tm)); \
return(strfTIM(s, max, fmt, &tm, tim.tv_nsec)); \
}
strfTIM_tz(local)
strfTIM_tz(gm)
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <time.h>
#include <stddef.h>
size_t strfTIM(char *s, size_t max, const char *fmt, struct tm *tm, long nsec);
size_t strfTIMlocal(char *s, size_t max, const char *fmt, double t);
size_t strfTIMgm(char *s, size_t max, const char *fmt, double t);
TESTS = regress.sh ncsa.sh vslarg.sh
TESTS = test_strfTIM regress.sh ncsa.sh vslarg.sh
check_PROGRAMS = test_strfTIM
test_strfTIM_SOURCES = \
minunit.h \
../strfTIM.h \
test_strfTIM.c
test_strfTIM_LDADD = \
$(top_builddir)/lib/libvarnish/libvarnish.la \
../strfTIM.$(OBJEXT)
/*-
* Copyright (c) 2012 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2012 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <stdlib.h>
/*-
* Adapted from http://www.jera.com/techinfo/jtns/jtn002.html
* "MinUnit" - a minimal unit testing framework for C
*
* "You may use the code in this tech note for any purpose, with the
* understanding that it comes with NO WARRANTY."
*/
/* XXX: Format error message in mu_assert() */
#define mu_assert(msg, test) do { if (!(test)) return msg; } while (0)
#define mu_run_test(test) do { const char *msg = test(); tests_run++; \
if (msg) return msg; } while (0)
/* phk-ish mu_assert */
#define mu_assert_errno(c) \
do { \
if (!(c)) { \
sprintf(errmsg, "%s failed in %s at %s:%d: errno %d (%s)", \
#c, __func__, __FILE__, __LINE__, errno, strerror(errno)); \
mu_assert(errmsg, 0); \
} \
} while(0)
/* short for MU Assert Zero / Non-Zero */
#define MAZ(c) do { mu_assert_errno((c) == 0); } while(0)
#define MAN(c) do { mu_assert_errno((c) != 0); } while(0)
extern int tests_run;
#define TEST_RUNNER \
int \
main(int argc, char **argv) \
{ \
(void) argc; \
\
printf("\nTEST: %s\n", argv[0]); \
const char *result = all_tests(); \
printf("%s: %d tests run\n", argv[0], tests_run); \
if (result != NULL) { \
printf("%s\n", result); \
exit(EXIT_FAILURE); \
} \
exit(EXIT_SUCCESS); \
}
/*-
* Copyright (c) 2012 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2012 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "minunit.h"
#include "../strfTIM.h"
int tests_run = 0;
static char errmsg[BUFSIZ];
static char
*test_strfTIM_strftime(void)
{
time_t now;
struct tm *tm;
char strftime_s[BUFSIZ], strfTIM_s[BUFSIZ];
const char *fmt =
"%a %A %b %B %c %C %d %D %e %F %g %G %h %H %I %J %m %M %n %p %r %R %S "\
"%t %T %u %U %V %w %W %x %X %y %Y %z %Z %% %Ec %EC %Ex %EX %Ey %Ey "\
"%Od %Oe %OH %OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy";
size_t strftime_n, strfTIM_n;
printf("... testing strfTIM equivalence to strftime\n");
time(&now);
tm = localtime(&now);
assert(tm != NULL);
strftime_n = strftime(strftime_s, BUFSIZ, fmt, tm);
strfTIM_n = strfTIM(strfTIM_s, BUFSIZ, fmt, tm, 0);
sprintf(errmsg, "strfTIM incorrect return value %zu (expected %zu)",
strfTIM_n, strftime_n);
mu_assert(errmsg, strfTIM_n == strftime_n);
sprintf(errmsg, "strfTIM incorrect result '%s' (expected '%s')", strfTIM_s,
strftime_s);
mu_assert(errmsg, strcmp(strfTIM_s, strftime_s) == 0);
return NULL;
}
static char
*test_strfTIM_N(void)
{
size_t n;
time_t t = 1382804827;
long nsec = 112625579;
const char *exp = "2013-10-26-18:27:07.112625579";
char s[BUFSIZ];
struct tm *tm;
printf("... testing strfTIM %%N conversion specifier\n");
tm = localtime(&t);
assert(tm != NULL);
n = strfTIM(s, BUFSIZ, "%F-%T.%N", tm, nsec);
sprintf(errmsg, "strfTIM incorrect return value %zu (expected %zu)", n,
strlen(exp));
mu_assert(errmsg, n == strlen(exp));
sprintf(errmsg, "strfTIM incorrect result '%s' (expected '%s')", s, exp);
mu_assert(errmsg, strcmp(s, exp) == 0);
n = strfTIM(s, BUFSIZ, "%%N", tm, nsec);
sprintf(errmsg, "strfTIM incorrect return value %zu (expected %zu)", n,
strlen("%N"));
mu_assert(errmsg, n == strlen("%N"));
sprintf(errmsg, "strfTIM incorrect result '%s' (expected '%s')", s, "%N");
mu_assert(errmsg, strcmp(s, "%N") == 0);
n = strfTIM(s, BUFSIZ, "%%%N", tm, nsec);
sprintf(errmsg, "strfTIM incorrect return value %zu (expected %zu)", n,
strlen("%112625579"));
mu_assert(errmsg, n == strlen("%112625579"));
sprintf(errmsg, "strfTIM incorrect result '%s' (expected '%s')", s,
"%112625579");
mu_assert(errmsg, strcmp(s, "%112625579") == 0);
return NULL;
}
static char
*test_strfTIMlocal(void)
{
size_t n;
char s[BUFSIZ], exp[BUFSIZ];
printf("... testing strfTIMlocal\n");
n = strfTIMlocal(s, BUFSIZ, "%F-%T.%N", 1382804820.112625579);
sprintf(exp, "2013-10-26-18:27:0%.9f", 0.112625579);
sprintf(errmsg, "strfTIMlocal incorrect return value %zu (expected %zu)",
n, strlen(exp));
mu_assert(errmsg, n == strlen(exp));
/*
* Don't require equality into the nanosecond range, because that gets
* us into floating point precision issues. Just require equality in
* the µsec range, by terminating the result string after six decimal
* places.
*/
s[strlen(s) - 3] = '\0';
exp[strlen(exp) - 3] = '\0';
sprintf(errmsg, "strfTIMlocal incorrect result '%s' (expected '%s')", s,
exp);
mu_assert(errmsg, strcmp(s, exp) == 0);
return NULL;
}
static char
*test_strfTIMgm(void)
{
size_t n;
char s[BUFSIZ], exp[BUFSIZ];
printf("... testing strfTIMgm\n");
n = strfTIMgm(s, BUFSIZ, "%F-%T.%N", 1382804820.112625579);
sprintf(exp, "2013-10-26-16:27:0%.9f", 0.112625579);
sprintf(errmsg, "strfTIMgm incorrect return value %zu (expected %zu)",
n, strlen(exp));
mu_assert(errmsg, n == strlen(exp));
/* As above */
s[strlen(s) - 3] = '\0';
exp[strlen(exp) - 3] = '\0';
sprintf(errmsg, "strfTIMgm incorrect result '%s' (expected '%s')", s, exp);
mu_assert(errmsg, strcmp(s, exp) == 0);
return NULL;
}
static const char
*all_tests(void)
{
mu_run_test(test_strfTIM_strftime);
mu_run_test(test_strfTIM_N);
mu_run_test(test_strfTIMlocal);
mu_run_test(test_strfTIMgm);
return NULL;
}
TEST_RUNNER
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment