-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: add sml_error function pointer, allow user to intercept error messages #93
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,9 +17,29 @@ | |
// along with libSML. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
#include <sml/sml_shared.h> | ||
#include <stdarg.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
void (*sml_error)(const char *format, ...); | ||
|
||
void sml_error_default(const char *format, ...) { | ||
va_list args; | ||
va_start(args, format); | ||
|
||
char *format2 = malloc(9 + strlen(format) + 1 + 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you might check whether format is !=0? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems somewhat esoteric, as format will usually be static anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw: why 9? the terminating zero is already at the end, or? So I'd expect There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, i miscounted. |
||
strcpy(format2, "libsml: "); | ||
strcat(format2, format); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. strncpy/strncat? (some compilers/static code checker might sooner or later complain otherwise) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems needless as it's all static strings, i'd leave that to whoever adds that code-checker. |
||
strcat(format2, "\n"); | ||
|
||
vfprintf(stderr, format2, args); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. va_end(args) missing? |
||
free(format2); | ||
} | ||
|
||
// http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html#INIT-AND-CLEANUP | ||
void __attribute__((constructor)) sml_init() { sml_error = *sml_error_default; } | ||
|
||
int sml_buf_get_next_length(sml_buffer *buf) { | ||
int length = 0; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright 2020 volkszaehler.org | ||
// | ||
// This file is part of libSML. | ||
// | ||
// libSML 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. | ||
// | ||
// libSML 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 libSML. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
#include "../unity/unity_fixture.h" | ||
#include "test_helper.h" | ||
#include <sml/sml_shared.h> | ||
|
||
#include <unistd.h> | ||
|
||
TEST_GROUP(sml_error); | ||
|
||
TEST_SETUP(sml_error) { } | ||
|
||
TEST_TEAR_DOWN(sml_error) { } | ||
|
||
TEST(sml_error, default) { | ||
char *tmpfile="./test_sml_error.tmp"; // FIXME: should not be hardcoded | ||
char *test_string="this is a test"; | ||
char *expected_output="libsml: this is a test\n"; | ||
|
||
FILE *capture = fopen(tmpfile, "w"); | ||
TEST_ASSERT_NOT_NULL(capture); | ||
int stderr_backup=dup(2); // duplicate old stderr so it won't be closed | ||
dup2(fileno(capture),2); // assign capture-file to stderr | ||
|
||
sml_error(test_string); | ||
|
||
fclose(capture); | ||
dup2(stderr_backup,2); // restore stderr | ||
close(stderr_backup); // discard backup | ||
|
||
size_t len=strlen(expected_output)+1; | ||
char *buf=malloc(len); | ||
|
||
capture = fopen(tmpfile, "r"); | ||
size_t got=fread(buf,1,len-1,capture); | ||
*(buf+got)=0; // add zero termination | ||
//fprintf(stderr,"got: `%s`\n\n",buf); | ||
fclose(capture); | ||
unlink(tmpfile); | ||
|
||
TEST_ASSERT_EQUAL(0, strcmp(expected_output,buf)); | ||
|
||
free(buf); | ||
} | ||
|
||
const char *msg=NULL; | ||
void my_sml_error(const char *format, ... ){ | ||
msg=format; | ||
} | ||
|
||
TEST(sml_error, custom) { | ||
char *test_string="this is a test"; | ||
sml_error = my_sml_error; | ||
sml_error(test_string,1,2,3); | ||
sml_error = sml_error_default; | ||
TEST_ASSERT_NOT_NULL(msg); | ||
TEST_ASSERT_EQUAL(0, strcmp(msg,test_string)); | ||
} | ||
|
||
TEST_GROUP_RUNNER(sml_error) { | ||
RUN_TEST_CASE(sml_error, default); | ||
RUN_TEST_CASE(sml_error, custom); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this forces anybody using this to call va_* and vaprintf himself. (see the example in
sml_error_default()
below)i wonder if this is any good,
or if we should maybe rather have an intermediate function and pass out the completely formatted string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mbehr1:any idea on this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might also pass more details, like a loglevel (warning/error).