Skip to content

Commit

Permalink
Some more changes, added some readme stuff etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
JayLCypher committed Nov 15, 2023
1 parent 207200f commit ffa7f61
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 44 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ DEBUG = -ggdb
COMPILER_FLAGS = -Wall -Wextra -Wpedantic -Wdouble-promotion -Wextra -Wswitch-default -Wswitch-enum -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn
COMPILER_IGNORE = -Wno-unused-function


all:
gcc $(FILES) -o $(OUT) $(DEBUG) $(COMPILER_FLAGS) $(COMPILER_IGNORE)

ARGS =
run:
./main
./main $(ARGS)

18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# jclibc
# jclibc - Opinionated C STL

Just a re-implementation of some C standard library functions for fun. Bits and bobs written or found from places, comments will denote from where if applicable.
No license yet.

## I swear I'm right
Because if I'm not right, I'm wrong. And I don't like that.




## Components

* String_View (Which is just a fat pointer, sue me.)
* Argc and Argv stack manipulation
* C String manipulation
* Memory block manipulation


Binary file added main
Binary file not shown.
13 changes: 6 additions & 7 deletions main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// LINT_C_FILE
#include <limits.h>
#include <stdio.h>
#include <assert.h>

Expand All @@ -11,7 +10,7 @@

#ifdef TEST_ALL
#define TEST_ARGS
#define TEST_ASCII
#define TEST_ATO
#define TEST_STRING
#define TEST_STRING_VIEW
#endif
Expand All @@ -25,12 +24,12 @@ static int test_args(int *const argc, char **argv[*argc]) {
return 0;
}

static int test_ascii(void) {
static int test_ato(void) {
printf("Testing atoi: ");
do {
int k = atoi("420kekw");
int k = atoi("9420kekw");
printf("%d\n", k);
if (k != 420) { return -1; }
if (k != 9420) { return -1; }
} while (0);
printf("Testing atou: ");
do {
Expand Down Expand Up @@ -88,8 +87,8 @@ int main(int argc, char *argv[argc]) {
assert(test_args(&argc, &argv) == 0);
#endif
// Tests all of the functions in the standard library using their test suites.
#ifdef TEST_ASCII
assert(test_ascii() == 0);
#ifdef TEST_ATO
assert(test_ato() == 0);
#endif

// String
Expand Down
File renamed without changes.
11 changes: 11 additions & 0 deletions src/jcmemc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// LINT_C_FILE
#pragma once
#ifndef _JCMEMC_H_
#define _JCMEMC_H_

const void *mem_chr(const void *const, const char, const size_t);
const void *mem_rchr(const void *const, const char, const size_t);
const void *mem_rchrr(const void *const, const void *const, const char);
const void *mem_rawchr(const void *const, const char);

#endif /* end of include guard: _JCMEMC_H_ */
12 changes: 12 additions & 0 deletions src/jcstddef.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

#include <assert.h>

/*
* * * * * * * * * * * *
* DECLARATION SECTION *
* * * * * * * * * * * *
*/

#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0

Expand Down Expand Up @@ -39,6 +45,12 @@ typedef signed intptr_t;
typedef signed ptrdiff_t;
#endif

/*
* * * * * * * * * * * * * *
* IMPLEMENTATION SECTIONS *
* * * * * * * * * * * * * *
*/

#endif // _JCSTDDEF_H_

/* LICENSE INFORMATION */
Expand Down
85 changes: 52 additions & 33 deletions src/jcstrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ static inline const char *skip_whitespace(const char s[static 1]) {
}

// Assume that most likely the next ascii character is a normal character and not control to short-stroke.
static inline bool is_ascii_digit(const char c) { return (c < '9' && c > '0'); }
static inline bool is_ascii_binary(const char c) { return !(c > '1' || c < '0'); }
static inline bool is_ascii_ternary(const char c) { return !(c > '2' || c < '0'); }
static inline bool is_ascii_quaternary(const char c) { return !(c > '3' || c < '0'); }
static inline bool is_ascii_quinary(const char c) { return !(c > '4' || c < '0'); }
static inline bool is_ascii_senary(const char c) { return !(c > '5' || c < '0'); }
static inline bool is_ascii_septenary(const char c) { return !(c > '6' || c < '0'); }
static inline bool is_ascii_octal(const char c) { return !(c > '7' || c < '0'); }
static inline bool is_ascii_nonary(const char c) { return !(c > '8' || c < '0'); }
static inline bool is_ascii_dec(const char c) { return !(c > '9' || c < '0'); }
static inline bool is_ascii_hex(const char c) { return !(is_ascii_dec(c) || (c > 'F' || c < 'A') || (c > 'f' || c < 'a')); }
static inline bool is_ascii_vig(const char c) { return !(is_ascii_dec(c) || (c > 'K' || c < 'A') || (c > 'k' || c < 'a')); }

typedef struct _string string;
struct _string {
Expand Down Expand Up @@ -81,12 +91,17 @@ static string string_copy(const string *const s) {
return string_new(s->len, s->s);
}

// STRING_VIEW STUFF
static string_view *sv_init(string_view *sv) {
if (sv) { *sv = (string_view){0}; }
return sv;
}

static string_view sv_new(void) {
static string_view sv_new(const size_t count, const char *s) {
return (string_view) {.count = count, .s = s};
}

static string_view sv_new_empty(void) {
string_view sv = {0};
return sv;
}
Expand All @@ -97,28 +112,26 @@ string_view *sv_trim_whitespace_left(string_view *const sv) {
}

string_view *sv_trim_whitespace_right(string_view *const sv) {
for (char *c = sv->s+sv->count; sv->count > 0; sv->count--) { if (*c != ' ') { break; } }
for (const char *c = sv->s+sv->count; sv->count > 0; sv->count--) { if (*c != ' ') { break; } }
return sv;
}

string_view *sv_trim_whitespace(string_view *const sv) {
return sv_trim_whitespace_right(sv_trim_whitespace_left(sv));
}

bool sv_eq(const string_view *sv_a, const string_view *sv_b) {
if (sv_a->count != sv_b->count) { return false; }
const char *a = sv_a->s, *b = sv_b->s;
while (*a++ && *b++) { if (*a != *b) { return false; } }
return true;
}

void sv_print(string_view *const sv) {
printf("%.*s\n", (int)sv->count, sv->s);
}

static inline int ato_inner(const char s[static 1]) {
s = skip_whitespace(s);
bool has_minus = is_negative(s[0]);
size_t i = has_minus || s[0] == '+';
size_t res = 0;
for (const char *c = &s[i]; (c = &s[i]) && is_ascii_digit(*c); ++i) {
res = (res * 10) + (*c & 0xF);
}
return has_minus ? -res : res;
}
#define ato_resolve(base) result = (result * base) + (c & 0xF)

int atoi(const char s[static 1]) {
int result = 0;
Expand All @@ -127,8 +140,8 @@ int atoi(const char s[static 1]) {
bool is_negative = (s[i] == '-');
for (i += is_negative || s[i] == '+';; ++i) {
const char c = s[i];
if (c > '9' || c < '0') { break; } // Check > 9 to short-stroke because statistically that's more likely.
result = (result * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; } // Check > 9 to short-stroke because statistically that's more likely.
result = (result * 10) + (c & 0xF);
}
return is_negative ? -result : result;
}
Expand All @@ -139,8 +152,8 @@ unsigned int atou(const char s[static 1]) {
for (; s[i] == ' '; ++i) {}
for (i += (s[i] == '+');; ++i) {
const char c = s[i];
if (c > '9' || c < '0') { break; }
result = (result * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; } // Check > 9 to short-stroke because statistically that's more likely.
result = (result * 10) + (c & 0xF);
}
return result;
}
Expand All @@ -152,8 +165,8 @@ long int atol(const char s[static 1]) {
bool is_negative = (s[i] == '-');
for (i += is_negative || s[i] == '+';; ++i) {
const char c = s[i];
if (c > '9' || c < '0') { break; }
result = (result * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; } // Check > 9 to short-stroke because statistically that's more likely.
result = (result * 10) + (c & 0xF);
}
return is_negative ? -result : result;
}
Expand All @@ -165,8 +178,8 @@ long long int atoll(const char s[static 1]) {
bool is_negative = (s[i] == '-');
for (i += is_negative || s[i] == '+';; ++i) {
const char c = s[i];
if (c > '9' || c < '0') { break; }
result = (result * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; } // Check > 9 to short-stroke because statistically that's more likely.
result = (result * 10) + (c & 0xF);
}
return is_negative ? -result : result;
}
Expand All @@ -179,15 +192,15 @@ float atof(const char s[static 1]) {
unsigned int pre_dot = 0;
for (i += is_negative || s[i] == '+';; ++i) {
const char c = s[i];
if (c > '9' || c < '0') { break; }
pre_dot = (pre_dot * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; }
pre_dot = (pre_dot * 10) + (c & 0xF);
}
if (s[i] == '.') {
unsigned int n = 0, post_dot = 0;
for (i += 1;; ++n, ++i) {
const char c = s[i];
if (c > '9' || c < '0') { break; }
post_dot = (post_dot * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; }
post_dot = (post_dot * 10) + (c & 0xF);
}
result = post_dot;
for (; n > 0; --n) { result /= 10; }
Expand All @@ -204,15 +217,15 @@ double atod(const char s[static 1]) {
unsigned int pre_dot = 0;
for (i += is_negative || s[i] == '+';; ++i) {
const char c = s[i];
if (c < '0' || c > '9') { break; }
pre_dot = (pre_dot * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; }
pre_dot = (pre_dot * 10) + (c & 0xF);
}
if (s[i] == '.') {
unsigned int n = 0, post_dot = 0;
for (i += 1;; ++n, ++i) {
const char c = s[i];
if (c < '0' || c > '9') { break; }
post_dot = (post_dot * 10) + (c & 0xf);
if (!is_ascii_dec(c)) { break; }
post_dot = (post_dot * 10) + (c & 0xF);
}
result = post_dot;
for (; n > 0; --n) { result /= 10; }
Expand Down Expand Up @@ -241,15 +254,15 @@ double cstr_to_d(const char *const s, const char *const *const end_ptr, const en
return 0.0;
}

int cstr_to_i(const char *const s, const char *const *const end_ptr, const enum NUMBER_BASE base) {
int cstr_to_i(const char *const s, const char *const *const end_ptr, const unsigned base) {
const char *p = s; // Local pointer to string s
p = skip_space(p); // Skip whitespace
bool is_negative = (*p == '-');
p += is_negative || (*p == '+'); // Add 1 if we're negative to bypass the '-' or '+' symbol.
int result = 0;
while (p++ < *end_ptr) {
if (!is_ascii_digit(*p)) { break; }
result = (result * 10) + (*p & 0xf);
if (!is_ascii_dec(*p)) { break; }
result = (result * base) + (*p & 0xF);
}
return is_negative ? -result : result;
}
Expand All @@ -260,6 +273,12 @@ size_t cstr_len(const char *const restrict s) {
return (p - s - 1);
}

// Get an end pointer to NULL-terminated c style string.
const char *cstr_end(const char s[static 1]) {
while (*s++) {}
return s;
}

// Copy no more than N characters from s to buf. Make sure buf can hold len.
const char *cstr_ncpy(const size_t n, const char s_in[static n], char buf_out[static n]) {
assert(s_in && buf_out);
Expand All @@ -278,7 +297,7 @@ int cstr_ncmp(const size_t n, const char s1[static n], const char s2[static n])

const char *cstr_chr(const char s[static 1], const char c) {
while (*s++ != '\0') { if (*s == c) { return s; } }
return nullptr;
return s; // Returns the end of the string, in case that's useful.
}

const char *cstr_rchr(const char s[static 1], const char c) {
Expand Down
21 changes: 19 additions & 2 deletions src/jcstrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
#ifndef _JCSTRC_H_
#define _JCSTRC_H_

//#define JCLIBC
#include "./jcstddef.h"

#define JCLIBC
/*
* * * * * * * * * * * *
* DECLARATION SECTION *
* * * * * * * * * * * *
*/

enum NUMBER_BASE {
BASE_2,
Expand All @@ -21,7 +26,7 @@ constexpr size_t whitespace_sz = sizeof (whitespace) / sizeof (whitespace[0]);
typedef struct _string_view string_view;
struct _string_view {
size_t count;
char *s;
const char *s;
};

void sv_print(string_view *const);
Expand All @@ -30,6 +35,8 @@ string_view *sv_trim_whitespace_left(string_view *const);
string_view *sv_trim_whitespace_right(string_view *const);
string_view *sv_trim_whitespace(string_view *const);

bool sv_eq(const string_view *, const string_view *);

int atoi(const char[static 1]);
unsigned int atou(const char[static 1]);
long int atol(const char[static 1]);
Expand All @@ -42,10 +49,20 @@ double cstr_to_d(const char *const, const char *const *const, const enum NUMBER_
int cstr_to_i(const char *const, const char *const *const, const enum NUMBER_BASE);

size_t cstr_len(const char *const restrict);
const char *cstr_end(const char[static 1]);
const char *cstr_ncpy(const size_t n, const char[static n], char[static n]);
int cstr_ncmp(const size_t n, const char[static n], const char[static n]);
const char *cstr_chr(const char[static 1], const char);
const char *cstr_rchr(const char[static 1], const char);
const char *cstr_rchrr(const char[static 1], const char *, const char);

/*
* * * * * * * * * * * * * *
* IMPLEMENTATION SECTIONS *
* * * * * * * * * * * * * *
*/
#ifdef JC_STRING_VIEW_IMPLEMENTATION

#endif

#endif // _JCSTRC_H_

0 comments on commit ffa7f61

Please sign in to comment.