From: Michael Tremer Date: Wed, 8 Oct 2025 09:35:40 +0000 (+0000) Subject: parse: Add custom functions to parse token and integers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=46b7cbbc7eec302502c240853323fda8edbc32f6;p=telemetry.git parse: Add custom functions to parse token and integers Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 07a9660..f3b17e3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -124,6 +124,8 @@ dist_collectyd_SOURCES = \ src/daemon/logging.c \ src/daemon/logging.h \ src/daemon/main.c \ + src/daemon/parse.c \ + src/daemon/parse.h \ src/daemon/proc.c \ src/daemon/proc.h \ src/daemon/proto.c \ diff --git a/src/daemon/parse.c b/src/daemon/parse.c new file mode 100644 index 0000000..be18f39 --- /dev/null +++ b/src/daemon/parse.c @@ -0,0 +1,82 @@ +/*############################################################################# +# # +# collecty - A system statistics collection daemon for IPFire # +# Copyright (C) 2025 IPFire Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include + +#include "parse.h" +#include "string.h" + +static void collecty_skip_whitespace(char** s) { + char* p = *s; + + // Consume any whitespace + while (*p && isspace(*p)) + p++; + + // Reset s + *s = p; +} + +int __collecty_parse_token(char** line, char* token, size_t length) { + char* p = *line; + int r; + + // Skip any leading whitespace + collecty_skip_whitespace(&p); + + // End of line + if (!*p) + return __collecty_string_set(token, length, ""); + + // Pointer that points to the end of the token + char* e = p; + + // Advance the end pointer until we hit some whitespace + while (*e && !isspace(*e)) + e++; + + // Copy the token + r = __collecty_string_setn(token, length, p, e - p); + if (r < 0) + return r; + + // Reset line + *line = e; + return 0; +} + +int collecty_parse_uint64(char** line, uint64_t* value) { + char* p = *line; + char* e = NULL; + + // Skip any leading whitespace + collecty_skip_whitespace(&p); + + // Parse the value + *value = strtoul(p, &e, 10); + + // Assume that parsing failed if the next character is not whitespace + if (*e && !isspace(*e)) + return -EINVAL; + + // Reset line + *line = e; + return 0; +} diff --git a/src/daemon/parse.h b/src/daemon/parse.h new file mode 100644 index 0000000..a1601a0 --- /dev/null +++ b/src/daemon/parse.h @@ -0,0 +1,34 @@ +/*############################################################################# +# # +# collecty - A system statistics collection daemon for IPFire # +# Copyright (C) 2025 IPFire Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef COLLECTY_PARSE_H +#define COLLECTY_PARSE_H + +#include +#include + +#define collecty_parse_token(line, token) \ + __collecty_parse_token(line, token, sizeof(token)) + +int __collecty_parse_token(char** line, char* token, size_t length); + +int collecty_parse_uint64(char** line, uint64_t* value); + +#endif /* COLLECTY_PARSE_H */ diff --git a/src/daemon/proc.c b/src/daemon/proc.c index 5de82ab..a91c64b 100644 --- a/src/daemon/proc.c +++ b/src/daemon/proc.c @@ -26,6 +26,7 @@ #include #include "file.h" +#include "parse.h" #include "proc.h" #include "string.h" @@ -267,9 +268,7 @@ typedef struct collecty_proc_softirq_state { static int collecty_proc_softirq_line(collecty_ctx* ctx, unsigned long lineno, char* line, size_t length, void* data) { collecty_proc_softirq_state* state = data; - char* e = NULL; - char* p = NULL; - char* t = NULL; + uint64_t n = 0; uint64_t v = 0; char key[16]; int r; @@ -278,42 +277,26 @@ static int collecty_proc_softirq_line(collecty_ctx* ctx, if (!lineno++) return 0; - // Fetch the key - t = strtok_r(line, ":", &p); - if (!t) - return -errno; - - // Store the key - r = collecty_string_set(key, t); + // Parse the key + r = collecty_parse_token(&line, key); if (r < 0) - return -errno; + return r; - // Strip any whitespace - collecty_string_strip(key); + // Remove the trailing : + collecty_string_rstrip2(key, ':'); // Add up all values - for (;;) { - // Fetch the next token - t = strtok_r(NULL, " ", &p); - if (!t) - break; - - // Parse the token - v += strtoul(t, &e, 10); - - // Check if could parse the value - switch (*e) { - case '\0': - case '\n': - break; + while (*line) { + r = collecty_parse_uint64(&line, &v); + if (r < 0) + return r; - default: - return -EINVAL; - } + // Sum up all values + n += v; } // Call the callback - return state->callback(ctx, key, v, state->data); + return state->callback(ctx, key, n, state->data); } int collecty_proc_read_softirq(collecty_ctx* ctx,