Commit c39a77b1 authored by Lubomir Bulej's avatar Lubomir Bulej
Browse files

Move string utils out of "common" into "strutil"

parent 0047be2f
......@@ -131,7 +131,7 @@ AGENT_GENSRCS := bytecode.c codeflags.h
AGENT_SOURCES := \
bytecode.c common.c jvmtiutil.c connection.c \
connpool.c msgchannel.c network.c classparser.c \
dislagent.c sessions.c
dislagent.c sessions.c strutil.c
AGENT_OBJECTS = $(addprefix $(BUILD_DIR)/,$(AGENT_SOURCES:%.c=%.o))
AGENT_SRCDEPS = $(addprefix $(BUILD_DIR)/,$(AGENT_SOURCES:%.c=%.d))
......
......@@ -9,23 +9,6 @@
//
/**
* Returns the index of the given value in the given array of values.
* Returns -1 if the value could not be found among the allowed values.
*/
int
find_value_index (const char * restrict strval, const char * restrict values [], int nvals) {
for (int i = 0; i < nvals; i++) {
if (strcasecmp (values [i], strval) == 0) {
return i;
}
}
return -1;
}
//
/**
* Reports an error and terminates the program. This function implements the
* slow path of check_error(). It prints the given error message and exits with
......@@ -59,37 +42,7 @@ die_with_std_error (int errnum, const char * restrict format, va_list args) {
exit (ERROR_STD);
}
// ****************************************************************************
// STRING UTILS SECTION
// ****************************************************************************
size_t
substr_count (const char * string, const char * restrict substr) {
size_t count = 0;
for (const char * token = string; (token = strstr (token, substr)) != NULL; ++token) {
++count;
}
return count;
}
char **
split_string (char * string, const char * restrict separator, size_t * tkns) {
size_t tokens = substr_count (string, separator) + 1;
assert (tokens > 0);
char ** arr = malloc (tokens * sizeof (char *));
arr [0] = strtok (string, separator);
for (size_t i = 1; i < tokens; ++i) {
arr [i] = strtok (NULL, separator);
}
*tkns = tokens;
return arr;
}
//
#ifdef MINGW
......
......@@ -67,10 +67,6 @@
//
int find_value_index (const char * restrict strval, const char * restrict values [], int nvals);
//
#define ERROR_GENERIC 10000
#define ERROR_SERVER 10003
#define ERROR_STD 10002
......@@ -129,28 +125,6 @@ warn_std_error (bool error, const char * message) {
}
}
// ****************************************************************************
// STRING UTILS SECTION
// ****************************************************************************
/**
* Counts the occurrences of a substring in the given string.
*/
size_t substr_count (const char * string, const char * restrict substr);
/**
* Split the string into tokens
* Remember to free the result.
*
* @param string The string to split
* @param separator
* @param tokens Pointer to the size_t variable to store the number of tokens
* @return
*/
char ** split_string (char * string, const char * restrict separator, size_t * token_count);
//
#ifdef MINGW
......
......@@ -52,7 +52,7 @@ struct config {
// Instrumentation jars.
size_t jar_count;
char ** jar_paths;
const char ** jar_paths;
// Code generation.
enum bypass_mode bypass_mode;
......
#include "common.h"
#include "config.h"
#include "strutil.h"
#include "jvmtiutil.h"
#include "connection.h"
......@@ -660,7 +661,7 @@ jvmti_callback_vm_death (jvmtiEnv * jvmti, JNIEnv * jni) {
static void
__parse_instrumentations (char * list, struct config * config) {
size_t jar_count;
char ** jar_paths = split_string (list, LIST_SEPARATOR, &jar_count);
const char ** jar_paths = strsplit (list, LIST_SEPARATOR, &jar_count);
config->jar_count = jar_count;
config->jar_paths = jar_paths;
......@@ -676,7 +677,7 @@ __configure_from_properties (jvmtiEnv * jvmti, struct config * config) {
);
static const char * values [] = { "disabled", "bootstrap", "dynamic" };
int bypass_index = find_value_index (bypass, values, sizeof_array (values));
int bypass_index = strarray_index (values, sizeof_array (values), bypass);
check_error (bypass_index < 0, "invalid bypass mode, check " DISL_BYPASS);
config->bypass_mode = bypass_index;
......
// Required for strdup
#define _POSIX_C_SOURCE 200809L
#include "jvmtiutil.h"
#include <assert.h>
......@@ -9,6 +12,7 @@
#include <jvmti.h>
#include "common.h"
#include "strutil.h"
//
......@@ -110,7 +114,7 @@ __get_system_property (jvmtiEnv * jvmti, const char * name) {
static bool
__parse_bool (const char * strval) {
static const char * trues [] = { "true", "yes", "on", "1" };
return find_value_index (strval, trues, sizeof_array (trues)) >= 0;
return strarray_index (trues, sizeof_array (trues), strval) >= 0;
}
......
......@@ -78,7 +78,7 @@ __load_file (const char * name, void * restrict buffer, const size_t size) {
* for jar sizes and jar data.
*/
static InstrumentationDelivery
InstrumentationDelivery_create (const size_t jar_count, char ** jar_names) {
InstrumentationDelivery_create (const size_t jar_count, const char ** jar_names) {
// First load all the jar files into a contiguous buffer.
int32_t * jar_sizes = malloc (jar_count * sizeof (int32_t));
check_std_error (jar_sizes == NULL, "failed to allocate memory for instrumentation sizes");
......@@ -166,7 +166,7 @@ session_start (bool require_disl, bool require_shvm) {
void
session_send_instrumentation (const int32_t session_id, const size_t jar_count, char ** jar_paths) {
session_send_instrumentation (const int32_t session_id, const size_t jar_count, const char ** jar_paths) {
// Create message with instrumentation.
InstrumentationDelivery delivery = InstrumentationDelivery_create (jar_count, jar_paths);
......@@ -199,7 +199,7 @@ session_send_instrumentation (const int32_t session_id, const size_t jar_count,
* Send a session-closing message to the server.
*/
void
session_end(int32_t session_id) {
session_end (int32_t session_id) {
// Create session close request.
CloseConnection cc = CLOSE_CONNECTION__INIT;
cc.reason = CLOSE_CONNECTION__CLOSE_REASON__FINISHED;
......
......@@ -35,6 +35,6 @@ void session_end (const int32_t session_id);
/**
* Sends instrumentation jars to the server.
*/
void session_send_instrumentation (const int32_t session_id, const size_t jar_count, char ** jar_paths);
void session_send_instrumentation (const int32_t session_id, const size_t jar_count, const char ** jar_paths);
#endif // _SESSIONS_H
#include "strutil.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "common.h"
//
size_t
strstr_count (const char * haystack, const char * restrict needle) {
size_t needle_len = strlen (needle);
size_t count = 0;
const char * token = strstr (haystack, needle);
while (token != NULL) {
token = strstr (token + needle_len, needle);
count++;
}
return count;
}
const char **
strsplit (
const char * string, const char * restrict separator, size_t * count
) {
const size_t token_count = strstr_count (string, separator) + 1;
const char ** tokens = malloc (token_count * sizeof (char *));
check_error (tokens == NULL, "failed to allocate token array");
//
const char * token_end = strstr (string, separator);
if (token_end != NULL) {
const size_t separator_len = strlen (separator);
size_t token_nr = 0;
while (token_nr < token_count && token_end != NULL) {
const size_t token_len = token_end - string;
const char * token = strndup (string, token_len);
check_error (token == NULL, "failed to duplicate token");
tokens [token_nr] = token;
token_end = strstr (token_end + separator_len, separator);
token_nr++;
}
assert (token_nr == token_count);
} else {
assert (token_count == 1);
tokens [0] = strdup (string);
}
//
*count = token_count;
return tokens;
}
int
strarray_index (
const char * restrict strings [], int nstrings, const char * restrict needle
) {
for (int i = 0; i < nstrings; i++) {
if (strcasecmp (strings [i], needle) == 0) {
return i;
}
}
return -1;
}
#ifndef _STRUTIL_H
#define _STRUTIL_H
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
//
/**
* Counts the number of occurrences of a substring in the given string.
*/
size_t strstr_count (const char * haystack, const char * restrict needle);
/**
* Splits a string into tokens. The values in the returned arrays are
* duplicates and the caller is responsible for freeing the result.
*
* @param string The string to split
* @param separator The separator at which to split
* @param tokens Pointer to size_t where to store the number of tokens
* @return An array of strings representing individual tokens
*/
const char ** strsplit (
const char * string, const char * restrict separator, size_t * count
);
/**
* Returns the index of a given string in an array of values.
* Returns -1 if the given string cannot be found among the allowed values.
*/
int strarray_index (
const char * restrict strings [], int nstrings, const char * restrict needle
);
#endif // _STRUTIL_H
......@@ -136,7 +136,7 @@ AGENT_SOURCES := \
tagger.c network/sender.c dislreagent.c pbmanager.c redispatcher.c netref.c \
globalbuffer.c tlocalbuffer.c freehandler.c \
network/connection.c network/msgchannel.c network/network_task.c \
disl/disl.c disl/bytecode.c disl/classparser.c sessions.c
disl/disl.c disl/bytecode.c disl/classparser.c sessions.c strutil.c
AGENT_OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(AGENT_SOURCES:%.c=%.o)))
AGENT_SRCDEPS = $(addprefix $(BUILD_DIR)/,$(notdir $(AGENT_SOURCES:%.c=%.d)))
......
......@@ -7,23 +7,6 @@
//
/**
* Returns the index of the given value in the given array of values.
* Returns -1 if the value could not be found among the allowed values.
*/
int
find_value_index (const char * restrict strval, const char * restrict values [], int nvals) {
for (int i = 0; i < nvals; i++) {
if (strcasecmp (values [i], strval) == 0) {
return i;
}
}
return -1;
}
//
/**
* Reports an error and terminates the program. This function implements the
* slow path of check_error(). It prints the given error message and exits with
......@@ -58,37 +41,6 @@ die_with_std_error (int errnum, const char * restrict format, va_list args) {
}
// ****************************************************************************
// STRING UTILS SECTION
// ****************************************************************************
size_t
substr_count (const char * string, const char * restrict substr) {
size_t count = 0;
for (const char * token = string; (token = strstr (token, substr)) != NULL; ++token) {
++count;
}
return count;
}
char **
split_string (char * string, const char * restrict separator, size_t * tkns) {
size_t tokens = substr_count (string, separator) + 1;
assert (tokens > 0);
char ** arr = malloc (tokens * sizeof (char *));
arr [0] = strtok (string, separator);
for (size_t i = 1; i < tokens; ++i) {
arr [i] = strtok (NULL, separator);
}
*tkns = tokens;
return arr;
}
#ifdef MINGW
/**
......
......@@ -79,10 +79,6 @@
//
int find_value_index (const char * restrict strval, const char * restrict values [], int nvals);
//
#define ERROR_GENERIC 10000
#define ERROR_SERVER 10003
#define ERROR_STD 10002
......@@ -129,28 +125,6 @@ check_std_error (bool error, const char * format, ...) {
}
}
// ****************************************************************************
// STRING UTILS SECTION
// ****************************************************************************
/**
* Counts the occurrences of a substring in the given string.
*/
size_t substr_count (const char * string, const char * restrict substr);
/**
* Split the string into tokens
* Remember to free the result.
*
* @param string The string to split
* @param separator
* @param tokens Pointer to the size_t variable to store the number of tokens
* @return
*/
char ** split_string (char * string, const char * restrict separator, size_t * token_count);
//
#ifdef MINGW
......
......@@ -6,6 +6,7 @@
#include "debug.h"
#include "jvmtiutil.h"
#include "strutil.h"
/*
......@@ -23,7 +24,7 @@ static struct config agent_config;
static void
__parse_instrumentations (char * list, struct config * config) {
size_t jar_count;
char ** jar_paths = split_string (list, LIST_SEPARATOR, &jar_count);
const char ** jar_paths = strsplit (list, LIST_SEPARATOR, &jar_count);
config->jar_count = jar_count;
config->jar_paths = jar_paths;
......@@ -82,7 +83,7 @@ __configure_from_properties (jvmtiEnv * jvmti, struct config * config) {
);
static const char * values [] = { "disabled", "bootstrap", "dynamic" };
int bypass_index = find_value_index (bypass, values, sizeof_array (values));
int bypass_index = strarray_index (values, sizeof_array (values), bypass);
check_error (bypass_index < 0, "invalid bypass mode, check " DISL_BYPASS);
config->bypass_mode = bypass_index;
......
......@@ -120,7 +120,7 @@ struct config {
// Instrumentation jars.
size_t jar_count;
char ** jar_paths;
const char ** jar_paths;
// Code generation.
enum bypass_mode bypass_mode;
......
......@@ -130,7 +130,7 @@ __load_file (const char * name, void * restrict buffer, const size_t size) {
* for jar sizes and jar data.
*/
static InstrumentationDelivery
InstrumentationDelivery_create (const size_t jar_count, char ** jar_names) {
InstrumentationDelivery_create (const size_t jar_count, const char ** jar_names) {
// First load all the jar files into a contiguous buffer.
int32_t * jar_sizes = malloc (jar_count * sizeof (int32_t));
check_std_error (jar_sizes == NULL, "failed to allocate memory for instrumentation sizes");
......@@ -180,7 +180,7 @@ InstrumentationDelivery_destroy (InstrumentationDelivery * delivery) {
static void
send_instrumentation (const int32_t session_id, const size_t jar_count, char ** jar_paths) {
send_instrumentation (const int32_t session_id, const size_t jar_count, const char ** jar_paths) {
// Create message with instrumentation.
InstrumentationDelivery delivery = InstrumentationDelivery_create (jar_count, jar_paths);
......
......@@ -9,6 +9,7 @@
#include <string.h>
#include "common.h"
#include "strutil.h"
//
......@@ -110,7 +111,7 @@ __get_system_property (jvmtiEnv * jvmti, const char * name) {
static bool
__parse_bool (const char * strval) {
static const char * trues [] = { "true", "yes", "on", "1" };
return find_value_index (strval, trues, sizeof_array (trues)) >= 0;
return strarray_index (trues, sizeof_array (trues), strval) >= 0;
}
......
#include "strutil.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "common.h"
//
size_t
strstr_count (const char * haystack, const char * restrict needle) {
size_t needle_len = strlen (needle);
size_t count = 0;
const char * token = strstr (haystack, needle);
while (token != NULL) {
token = strstr (token + needle_len, needle);
count++;
}
return count;
}
const char **
strsplit (
const char * string, const char * restrict separator, size_t * count
) {
const size_t token_count = strstr_count (string, separator) + 1;
const char ** tokens = malloc (token_count * sizeof (char *));
check_error (tokens == NULL, "failed to allocate token array");
//
const char * token_end = strstr (string, separator);
if (token_end != NULL) {
const size_t separator_len = strlen (separator);
size_t token_nr = 0;
while (token_nr < token_count && token_end != NULL) {
const size_t token_len = token_end - string;
const char * token = strndup (string, token_len);
check_error (token == NULL, "failed to duplicate token");
tokens [token_nr] = token;
token_end = strstr (token_end + separator_len, separator);
token_nr++;
}
assert (token_nr == token_count);
} else {
assert (token_count == 1);
tokens [0] = strdup (string);
}
//
*count = token_count;
return tokens;
}
int
strarray_index (
const char * restrict strings [], int nstrings, const char * restrict needle
) {
for (int i = 0; i < nstrings; i++) {
if (strcasecmp (strings [i], needle) == 0) {
return i;
}
}
return -1;
}
#ifndef _STRUTIL_H
#define _STRUTIL_H
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
//
/**
* Counts the number of occurrences of a substring in the given string.
*/
size_t strstr_count (const char * haystack, const char * restrict needle);
/**
* Splits a string into tokens. The values in the returned arrays are
* duplicates and the caller is responsible for freeing the result.
*
* @param string The string to split
* @param separator The separator at which to split
* @param tokens Pointer to size_t where to store the number of tokens
* @return An array of strings representing individual tokens
*/
const char ** strsplit (
const char * string, const char * restrict separator, size_t * count
);
/**
* Returns the index of a given string in an array of values.
* Returns -1 if the given string cannot be found among the allowed values.
*/
int strarray_index (