Skip to content

Commit

Permalink
add prival from string (#377)
Browse files Browse the repository at this point in the history
Adds stumpless_prival_from_string to convert a provided string into
an integer prival value. This is intended to support CLI and other
string-based applications.

This fixes #357, which can be referenced for more information.

Signed-off-by: Jaroslaw Gawin <jaroslaw.gawin@mobica.com>
  • Loading branch information
jagw-mobica authored Oct 3, 2023
1 parent 117ee5d commit c54a498
Show file tree
Hide file tree
Showing 10 changed files with 355 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ set(STUMPLESS_SOURCES
${PROJECT_SOURCE_DIR}/src/target/stream.c
${PROJECT_SOURCE_DIR}/src/version.c
${PROJECT_SOURCE_DIR}/src/validate.c
${PROJECT_SOURCE_DIR}/src/priority.c
)


Expand Down Expand Up @@ -645,6 +646,7 @@ install(FILES
${PROJECT_SOURCE_DIR}/include/stumpless/severity.h
${PROJECT_SOURCE_DIR}/include/stumpless/target.h
${PROJECT_SOURCE_DIR}/include/stumpless/version.h
${PROJECT_SOURCE_DIR}/include/stumpless/priority.h
DESTINATION "include/stumpless"
)

Expand Down Expand Up @@ -957,6 +959,10 @@ add_function_test(version
SOURCES test/function/version.cpp
)

add_function_test(priority
SOURCES test/function/priority.cpp
)

add_custom_target(build-test
DEPENDS ${STUMPLESS_FUNCTION_TESTS}
)
Expand Down
1 change: 1 addition & 0 deletions include/stumpless.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
#include <stumpless/target/function.h>
#include <stumpless/target/stream.h>
#include <stumpless/version.h>
#include <stumpless/priority.h>

#ifdef STUMPLESS_JOURNALD_TARGETS_SUPPORTED
/** @example journald_example.c
Expand Down
66 changes: 66 additions & 0 deletions include/stumpless/priority.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: Apache-2.0 */

/*
* Copyright 2022 Joel E. Anderson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @file
* Priority value (PRIVAL) represents both the Facility and Severity values.
*
* @since release v2.2.0
*/

#ifndef __STUMPLESS_PRIORITY_H
# define __STUMPLESS_PRIORITY_H

# include <stumpless.h>

# ifdef __cplusplus
extern "C" {
# endif

/**
* Extract PRIVAL number (Facility and Severity) from the given string with
* the direct number or with two names divided with a period in the order:
* facility first, then severity ("<facility_descr>.<severity_descr>").
*
* **Thread Safety: MT-Safe**
* This function is thread safe. A mutex is used to coordinate changes to the
* target while it is being read.
*
* **Async Signal Safety: AS-Unsafe lock**
* This function is not safe to call from signal handlers due to the use of a
* non-reentrant lock to coordinate the read of the target.
*
* **Async Cancel Safety: AC-Unsafe lock**
* This function is not safe to call from threads that may be asynchronously
* cancelled, due to the use of a lock that could be left locked..
*
* @since release v2.2.0
*
* @param string The string to extract the prival from.
*
* @return the PRIVAL number used for the severity and facility values of
* the logged entry, in the event of an error it returns -1.
*/
STUMPLESS_PUBLIC_FUNCTION
int
stumpless_prival_from_string( const char *string );

# ifdef __cplusplus
} /* extern "C" */
# endif

#endif /* __STUMPLESS_PRIORITY_H */
118 changes: 118 additions & 0 deletions src/priority.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: Apache-2.0

/*
* Copyright 2022 Joel E. Anderson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stumpless.h>
#include "private/memory.h"
#include "private/entry.h"
#include "private/validate.h"
#include "private/config.h"

static void toUpperCase( char *str ) {
for( int i = 0; str[i]; i++) {
str[i] = toupper( str[i] );
}
}

int
stumpless_prival_from_string( const char *string ) {
int prival;
int severity;
int facility;
char *param;
char *period;
char *sec_period;
size_t len;
size_t slen;
size_t pre_len;
const char pre_facility[] = "STUMPLESS_FACILITY_";
const char pre_severity[] = "STUMPLESS_SEVERITY_";

VALIDATE_ARG_NOT_NULL_INT_RETURN( string );

if( unlikely( !string[0] ) ) {
return -1;
}

slen = strlen( string );

if( isdigit( string[0] ) ) {
prival = atoi( string );
if( prival >= 0 && prival <= 191 && slen < 4 ) {
return prival;
}
}

// find the first period character
period = strchr( string, '.' );
if( !period )
return -1;

// check there is no another period character
sec_period = strchr( period + 1, '.' );
if( sec_period != NULL ) {
return -1;
}

// Calculate the facility length, up to the first period character
len = period - string;
pre_len = sizeof(pre_facility) - 1;
param = alloc_mem( len + 1 + pre_len );
if( !param ) {
return -1;
}
// Copy the facility substring to the param buffer
memcpy( param, pre_facility, pre_len );
memcpy( param + pre_len, string, len );
param[pre_len + len] = '\0';

toUpperCase(param);
facility = stumpless_get_facility_enum( param );

free_mem( param );

if( facility < 0 )
return -1;

// Calculate the severity length
len = slen - ++len;
pre_len = sizeof(pre_severity) - 1;

param = alloc_mem( len + 1 + pre_len );
if( !param ) {
return -1;
}
// Copy the severity substring to the param buffer
memcpy( param, pre_severity, pre_len );
memcpy( param + pre_len, ++period, len);
param[pre_len + len] = '\0';

toUpperCase(param);
severity = stumpless_get_severity_enum( param );

free_mem( param );

if( severity < 0 )
return -1;

return get_prival( facility, severity );
}

1 change: 1 addition & 0 deletions src/windows/stumpless.def
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,4 @@ EXPORTS
stumpless_unload_entry_only @206
stumpless_unload_param @207
vstumpless_load_entry @208
stumpless_prival_from_string @209
4 changes: 4 additions & 0 deletions test/function/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@ Tests for general target functionality.

## `version.cpp`
Tests for versioning of the library.


## `priority.cpp`
Tests for functions that deal with priority values (PRIVAL).
123 changes: 123 additions & 0 deletions test/function/priority.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: Apache-2.0

/*
* Copyright 2019-2021 Joel E. Anderson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <gtest/gtest.h>
#include <stddef.h>
#include <stdlib.h>
#include <stumpless.h>
#include "test/helper/assert.hpp"
#include "test/helper/memory_allocation.hpp"

namespace {

class PriorityTest : public::testing::Test {
};

TEST( GetPriorityValue, NumValidPriority ) {
int result;

result = stumpless_prival_from_string( "119" );
EXPECT_EQ( result, 119 );
}

TEST( GetPriorityValue, UpperValidPriority ) {
int result;

result = stumpless_prival_from_string( "USER.INFO" );
EXPECT_EQ( result, 14 );
}

TEST( GetPriorityValue, LowerValidPriority ) {
int result;

result = stumpless_prival_from_string( "user.info" );
EXPECT_EQ( result, 14 );
}

TEST( GetPriorityValue, EmptyPriority ) {
int result;

result = stumpless_prival_from_string( "" );
EXPECT_EQ( result, -1 );
}

TEST( GetPriorityValue, NullPriority ) {
int result;

result = stumpless_prival_from_string( NULL );
EXPECT_EQ( result, -1 );
}

TEST( GetPriorityValue, InvalidFacilityPriority ) {
int result;

result = stumpless_prival_from_string( "umer.info" );
EXPECT_EQ( result, -1 );
}

TEST( GetPriorityValue, InvalidSeverityPriority ) {
int result;

result = stumpless_prival_from_string( "user.imfo" );
EXPECT_EQ( result, -1 );
}

TEST( GetPriorityValue, InvalidNoPeriodPriority ) {
int result;

result = stumpless_prival_from_string( "userinfo" );
EXPECT_EQ( result, -1 );
}

TEST( GetPriorityValue, InvalidMorePeriodPriority ) {
int result;

result = stumpless_prival_from_string( "user.info." );
EXPECT_EQ( result, -1 );
}

TEST( GetPriorityValue, InvalidMemFacilityPriority ) {
int result;
void * (*set_malloc_result)(size_t);
set_malloc_result = stumpless_set_malloc( MALLOC_FAIL );
ASSERT_NOT_NULL( set_malloc_result );

result = stumpless_prival_from_string( "user.err" );
EXPECT_EQ( result, -1 );

set_malloc_result = stumpless_set_malloc( malloc );
EXPECT_TRUE( set_malloc_result == malloc );
}

TEST( GetPriorityValue, InvalidMemSeverityPriority ) {
int result;
void * (*set_malloc_result)(size_t);
const struct stumpless_error *error;
set_malloc_result = stumpless_set_malloc( MALLOC_FAIL_ON_SIZE( 23 ) );
ASSERT_NOT_NULL( set_malloc_result );

result = stumpless_prival_from_string( "syslog.err" );
EXPECT_EQ( result, -1 );

EXPECT_ERROR_ID_EQ( STUMPLESS_MEMORY_ALLOCATION_FAILURE );

set_malloc_result = stumpless_set_malloc( malloc );
EXPECT_TRUE( set_malloc_result == malloc );
}

}
2 changes: 2 additions & 0 deletions tools/check_headers/standard_library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,5 @@
"WSACleanup":
- "winsock2.h"
- "private/windows_wrapper.h"
"isdigit": "ctype.h"
"toupper": "ctype.h"
1 change: 1 addition & 0 deletions tools/check_headers/stumpless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,4 @@
"stumpless_get_target_type_string" : "stumpless/target.h"
"STUMPLESS_FOREACH_TARGET_TYPE" : "stumpless/target.h"
"STUMPLESS_FOREACH_SEVERITY" : "stumpless/severity.h"
"stumpless_prival_from_string" : "stumpless/priority.h"
Loading

0 comments on commit c54a498

Please sign in to comment.