feat: strings and config modules
This commit is contained in:
commit
b9c9b21612
10 changed files with 576 additions and 0 deletions
79
.clang-format
Normal file
79
.clang-format
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: false
|
||||||
|
AlignTrailingComments: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterEnum: true
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros: ['ILIST_FOREACH', 'ILIST_FOREACH_ENTRY']
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '<.*>'
|
||||||
|
Priority: 1
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 2
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
Language: Cpp
|
||||||
|
NamespaceIndentation: All
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
7
httpd/.gitignore
vendored
Normal file
7
httpd/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.log
|
||||||
|
*.core
|
||||||
31
httpd/Makefile
Normal file
31
httpd/Makefile
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -std=c99 -Werror -Wall -Wextra -Wvla -pedantic
|
||||||
|
LDFLAGS =
|
||||||
|
LDLIBS =
|
||||||
|
|
||||||
|
LDFLAGS_DBG = -g
|
||||||
|
ASAN_DBG_FLAGS = -fsanitize=address
|
||||||
|
|
||||||
|
UTILS_SRCS = src/utils/string/string.c
|
||||||
|
CONFIG_SRCS = src/config/config.c
|
||||||
|
SRCS = $(UTILS_SRCS) $(CONFIG_SRCS) src/main.c
|
||||||
|
|
||||||
|
UTILS_OBJS = ${UTILS_SRCS:.c=.o}
|
||||||
|
CONFIG_OBJS = ${CONFIG_SRCS:.c=.o}
|
||||||
|
OBJS = ${SRCS:.c=.o}
|
||||||
|
|
||||||
|
TARGET=httpd
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CC) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS)
|
||||||
|
|
||||||
|
check:
|
||||||
|
dash tests/run.sh
|
||||||
|
|
||||||
|
debug: LDFLAGS += LDFLAGS_DBG
|
||||||
|
debug:
|
||||||
|
$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LDLIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(TARGET)
|
||||||
|
$(RM) $(OBJS)
|
||||||
9
httpd/config.txt
Normal file
9
httpd/config.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[global]
|
||||||
|
log = true
|
||||||
|
pid_file = /tmp/HTTPd.pid
|
||||||
|
|
||||||
|
[[vhosts]]
|
||||||
|
server_name = my_server
|
||||||
|
ip = 127.0.0.1
|
||||||
|
port = 6996
|
||||||
|
root_dir = .
|
||||||
86
httpd/config_reader.sh
Executable file
86
httpd/config_reader.sh
Executable file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 --path-config <file> [--path-bin <bin>] [--daemon <options>]"
|
||||||
|
echo
|
||||||
|
echo "Options:"
|
||||||
|
echo " --path-config <fichier> (mandatory) path to the config file"
|
||||||
|
echo " --path-bin <chemin-binaire> (optional) path to the httpd binary, default is ./httpd"
|
||||||
|
echo " --daemon <options> (optional) option passed to httpd"
|
||||||
|
echo " -h, --help prints this help page"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
OPTIONS=$(getopt -o h --long path-config:,path-bin:,daemon:,help -- "$@")
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
eval set -- "$OPTIONS"
|
||||||
|
|
||||||
|
PATH_CONFIG=""
|
||||||
|
PATH_BIN="./httpd"
|
||||||
|
DAEMON_OPTS=""
|
||||||
|
|
||||||
|
# Lecture des arguments
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
--path-config)
|
||||||
|
PATH_CONFIG="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--path-bin)
|
||||||
|
PATH_BIN="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--daemon)
|
||||||
|
DAEMON_OPTS="--daemon $2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# verify mandatory option
|
||||||
|
if [ -z "$PATH_CONFIG" ]; then
|
||||||
|
echo "error : --path-config is mandatory"
|
||||||
|
echo
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
! [ -f "$PATH_CONFIG" ] && (echo "config file: $PATH_CONFIG is not a file"; exit 1;)
|
||||||
|
PATH_BIN_TO_RUN="$PATH_BIN"
|
||||||
|
|
||||||
|
if [[ "$PATH_BIN_TO_RUN" != */* ]]; then
|
||||||
|
PATH_BIN_TO_RUN="./$PATH_BIN_TO_RUN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -x "$PATH_BIN_TO_RUN" ] || (echo "error: binary file: '$PATH_BIN_TO_RUN' is not executable or does not exist."; exit 1;)
|
||||||
|
|
||||||
|
PATH_BIN="$PATH_BIN_TO_RUN"
|
||||||
|
|
||||||
|
# main
|
||||||
|
ARGS=""
|
||||||
|
regex="([^ ]+) ?= ?([^ ]+)"
|
||||||
|
|
||||||
|
while IFS= read -r line || [[ -n "$line" ]];
|
||||||
|
do
|
||||||
|
[ "$line" = "[global]" ] || [ "$line" = "[[vhosts]]" ] && continue;
|
||||||
|
|
||||||
|
if [[ $line =~ $regex ]]; then
|
||||||
|
ARGS="$ARGS --${BASH_REMATCH[1]} ${BASH_REMATCH[2]}"
|
||||||
|
fi
|
||||||
|
done < "$PATH_CONFIG"
|
||||||
|
|
||||||
|
# launch binary with correct args
|
||||||
|
echo "command run is: $PATH_BIN $DAEMON_OPTS ${ARGS:1}"
|
||||||
|
$PATH_BIN $DAEMON_OPTS ${ARGS:1}
|
||||||
170
httpd/src/config/config.c
Normal file
170
httpd/src/config/config.c
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../utils/string/string.h"
|
||||||
|
|
||||||
|
#define ARG_VALID 0
|
||||||
|
#define ARG_INVALID 1
|
||||||
|
#define ARG_HELP 2
|
||||||
|
#define ARG_NOT_IMPLEMENTED 2
|
||||||
|
|
||||||
|
// == Static functions
|
||||||
|
|
||||||
|
// Returns 0 if the servers array is valid 1 otherwise
|
||||||
|
// static int check_server_config(struct server_config *server)
|
||||||
|
// {
|
||||||
|
// if (server->server_name == NULL || server->port == NULL
|
||||||
|
// || server->ip == NULL || server->root_dir == NULL)
|
||||||
|
// {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
static void print_help(char *program_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [OPTION]\n", program_name);
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns 0 if argument is valid, otherwise
|
||||||
|
static int handle_opt(char **argv, char opt, struct config *cfg)
|
||||||
|
{
|
||||||
|
// Options without value
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
// Help
|
||||||
|
case 'h':
|
||||||
|
print_help(argv[0]);
|
||||||
|
return ARG_HELP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optarg == NULL)
|
||||||
|
return ARG_INVALID;
|
||||||
|
|
||||||
|
// Options with value
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
// Daemon
|
||||||
|
case 'd':
|
||||||
|
if (strcmp(optarg, "start") == 0)
|
||||||
|
cfg->daemon = START;
|
||||||
|
else if (strcmp(optarg, "stop") == 0)
|
||||||
|
cfg->daemon = STOP;
|
||||||
|
else if (strcmp(optarg, "restart") == 0)
|
||||||
|
cfg->daemon = RESTART;
|
||||||
|
else
|
||||||
|
return ARG_INVALID;
|
||||||
|
return ARG_VALID;
|
||||||
|
|
||||||
|
// Server name
|
||||||
|
case 's':
|
||||||
|
cfg->servers->server_name = string_create(optarg, strlen(optarg));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Port
|
||||||
|
case 'p':
|
||||||
|
cfg->servers->port = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// IP
|
||||||
|
case 'i':
|
||||||
|
cfg->servers->ip = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Root dir
|
||||||
|
case 'r':
|
||||||
|
cfg->servers->root_dir = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Default file
|
||||||
|
case 'D':
|
||||||
|
cfg->servers->ip = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// PID file
|
||||||
|
case 'P':
|
||||||
|
cfg->pid_file = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Log file
|
||||||
|
case 'L':
|
||||||
|
cfg->log_file = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Logs
|
||||||
|
case 'l':
|
||||||
|
return ARG_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// TODO print full flags
|
||||||
|
// printf("Unrecognized option '%s'", optstring);
|
||||||
|
return ARG_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ARG_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// == Main functions
|
||||||
|
|
||||||
|
struct config *parse_configuration(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct option options[] = { // Global
|
||||||
|
{ "daemon", optional_argument, NULL, 'd' },
|
||||||
|
{ "help", optional_argument, NULL, 'h' },
|
||||||
|
// Vhosts
|
||||||
|
{ "server_name", required_argument, NULL, 's' },
|
||||||
|
{ "port", required_argument, NULL, 'p' },
|
||||||
|
{ "ip", required_argument, NULL, 'i' },
|
||||||
|
{ "root_dir", required_argument, NULL, 'r' },
|
||||||
|
{ "defaut_file", optional_argument, NULL, 'D' },
|
||||||
|
// Logging
|
||||||
|
{ "pid_file", required_argument, NULL, 'P' },
|
||||||
|
{ "log_file", optional_argument, NULL, 'L' },
|
||||||
|
{ "log", optional_argument, NULL, 'l' },
|
||||||
|
// End
|
||||||
|
{ NULL, 0, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct config *config = calloc(1, sizeof(struct config));
|
||||||
|
if (config == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
config->servers = calloc(1, sizeof(struct server_config));
|
||||||
|
if (config->servers == NULL)
|
||||||
|
{
|
||||||
|
free(config);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char opt;
|
||||||
|
int optindex;
|
||||||
|
while ((opt = getopt_long(argc, argv, "*", options, &optindex)) != -1)
|
||||||
|
{
|
||||||
|
int err = handle_opt(argv, opt, config);
|
||||||
|
if (err != ARG_VALID)
|
||||||
|
{
|
||||||
|
if (err == ARG_INVALID)
|
||||||
|
printf("%s: Invalid argument '%s'", argv[0], argv[optindex]);
|
||||||
|
if (err == ARG_NOT_IMPLEMENTED)
|
||||||
|
printf("%s: This function is not implemented", argv[0]);
|
||||||
|
|
||||||
|
free(config->servers);
|
||||||
|
free(config);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_destroy(struct config *config)
|
||||||
|
{
|
||||||
|
free(config->servers);
|
||||||
|
free(config);
|
||||||
|
}
|
||||||
73
httpd/src/config/config.h
Normal file
73
httpd/src/config/config.h
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Enum daemon
|
||||||
|
** NO_OPTION if the '--daemon' option is not given
|
||||||
|
** START, STOP, RESTART if option is "start", "stop" and "restart"
|
||||||
|
*/
|
||||||
|
enum daemon
|
||||||
|
{
|
||||||
|
NO_OPTION = 0,
|
||||||
|
START,
|
||||||
|
STOP,
|
||||||
|
RESTART
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Configuration structure
|
||||||
|
**
|
||||||
|
** @param pid_file Path to the pid file
|
||||||
|
** @param log_file Path to the log file
|
||||||
|
** @param log Enable or disable logging
|
||||||
|
** @param servers Array of vhosts
|
||||||
|
** @daemon option for the daemon (START, STOP, RESTART)
|
||||||
|
*/
|
||||||
|
struct config
|
||||||
|
{
|
||||||
|
char *pid_file;
|
||||||
|
char *log_file;
|
||||||
|
bool log;
|
||||||
|
|
||||||
|
struct server_config *servers;
|
||||||
|
enum daemon daemon;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Vhost configuration structure
|
||||||
|
**
|
||||||
|
** @param server_name Server name
|
||||||
|
** @param port Port to listen on
|
||||||
|
** @param ip IP address
|
||||||
|
** @param root_dir Root directory to serve
|
||||||
|
** @param default_file Default file to serve
|
||||||
|
*/
|
||||||
|
struct server_config
|
||||||
|
{
|
||||||
|
struct string *server_name;
|
||||||
|
char *port;
|
||||||
|
char *ip;
|
||||||
|
char *root_dir;
|
||||||
|
char *default_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Parse the given argv argument and returns a filled struct
|
||||||
|
**
|
||||||
|
** @param argc Number of arguments
|
||||||
|
** @param argv A list of char * containing all the arguments
|
||||||
|
*/
|
||||||
|
struct config *parse_configuration(int argc, char *argv[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Free the config struct
|
||||||
|
**
|
||||||
|
** @param config The config struct to free
|
||||||
|
*/
|
||||||
|
void config_destroy(struct config *config);
|
||||||
|
|
||||||
|
#endif /* !CONFIG_H */
|
||||||
4
httpd/src/main.c
Normal file
4
httpd/src/main.c
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
70
httpd/src/utils/string/string.c
Normal file
70
httpd/src/utils/string/string.c
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct string *string_create(const char *str, size_t size)
|
||||||
|
{
|
||||||
|
struct string *res = malloc(sizeof(struct string));
|
||||||
|
if (res == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
res->data = malloc(size * sizeof(char));
|
||||||
|
if (res->data == NULL)
|
||||||
|
{
|
||||||
|
free(res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(res->data, str, size);
|
||||||
|
res->size = size;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int string_compare_n_str(const struct string *str1, const char *str2, size_t n)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
int res = 0;
|
||||||
|
char reached_str2_end = 0;
|
||||||
|
while (i < n)
|
||||||
|
{
|
||||||
|
if (i < str1->size)
|
||||||
|
res += str1->data[i];
|
||||||
|
|
||||||
|
if (!reached_str2_end)
|
||||||
|
{
|
||||||
|
if (str2[i] == '\0')
|
||||||
|
reached_str2_end = 1;
|
||||||
|
else
|
||||||
|
res -= str2[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_concat_str(struct string *str, const char *to_concat, size_t size)
|
||||||
|
{
|
||||||
|
size_t new_size = str->size + size;
|
||||||
|
size_t str_size = str->size;
|
||||||
|
|
||||||
|
if (new_size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
str->data = realloc(str->data, new_size);
|
||||||
|
if (str->data == NULL)
|
||||||
|
return; // Handle ?
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
str->data[str_size + i] = to_concat[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_destroy(struct string *str)
|
||||||
|
{
|
||||||
|
free(str->data);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
47
httpd/src/utils/string/string.h
Normal file
47
httpd/src/utils/string/string.h
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef STRING_H
|
||||||
|
#define STRING_H
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct string
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
char *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Create new string struct from char * and size
|
||||||
|
** Be careful, the argument str will not be deallocated and thus you
|
||||||
|
** can call this function with a static char *
|
||||||
|
**
|
||||||
|
** @param str
|
||||||
|
** @param size
|
||||||
|
**
|
||||||
|
** @return the newly allocated string
|
||||||
|
*/
|
||||||
|
struct string *string_create(const char *str, size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Act like memcmp(3) but for struct string and char *
|
||||||
|
**
|
||||||
|
** @param str1
|
||||||
|
** @param str2
|
||||||
|
** @param n
|
||||||
|
**
|
||||||
|
** @return
|
||||||
|
*/
|
||||||
|
int string_compare_n_str(const struct string *str1, const char *str2, size_t n);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Concat a char * with its size in a struct string
|
||||||
|
**
|
||||||
|
** @param str
|
||||||
|
** @param to_concat
|
||||||
|
** @param size
|
||||||
|
*/
|
||||||
|
void string_concat_str(struct string *str, const char *to_concat, size_t size);
|
||||||
|
|
||||||
|
void string_destroy(struct string *str);
|
||||||
|
|
||||||
|
#endif /* ! STRING_H */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue