GithubHelp home page GithubHelp logo

jacoblincool / cimple-lib Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 0.0 422 KB

A delightful library for C learners.

Home Page: https://jacoblincool.github.io/Cimple-Lib/

License: MIT License

Makefile 1.63% C 97.78% Dockerfile 0.43% Shell 0.16%
c computer-programming

cimple-lib's Introduction

Cimple Lib

A delightful helper library for C learners.

Good for someone who needs to do C programming homework.

Usage

All libraries are header files, so you can directly include them in your C code.

Since the libraries are all lightweight, we don't have to worry about the compilation time.

#include "src/all.h"

int main() {
    char* label = "print 1 to 1000";
    Timing.start(label);
    for (int i = 1; i <= 1000; i++) {
        Console.rainbow("%d", i);
    }
    Console.log("%s: %Lf ms", label, Timing.check(label));

    return 0;
}

I recommend you to use VS Code because of the great language server support.

language server

Features

all.h

Includes all the libraries below.

base.h

This header file includes:

  • Standard libraries that are useful in most cases.
  • Type alias for standard types.
    • i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, f128

bucket.h

Pointer manager. It can help you to elegantly code with function chaining.

$(), $clear(), ...

Example

for (int i = 0; i < 4096; i++) {
    char* str = $(calloc(1024, sizeof(char)));
    sprintf(str, "%d", i);
}

assert($size() == 4096);
assert($capacity() == 4096);
$free(); // free all pointers at once
// With $
char* str = String.upper($(String.trim($(String.format("%s %s!", "  Hello", "World")), " ")));
$free(); // free the intermediates
assert(strcmp(str, "HELLO WORLD!") == 0);
do_something(str);

// Without $
char* formatted = String.format("%s %s!", "  Hello", "World");
char* trimmed = String.trim(formatted, " ");
free(formatted);
char* str = String.upper(trimmed);
free(trimmed);
assert(strcmp(str, "HELLO WORLD!") == 0);
do_something(str);

buffer.h

Bit operations and endianness conversion.

/**
 * @brief Buffer utility functions.
 */
struct {
    /**
     * @brief Get bit from buffer
     * @param buffer The buffer
     * @param bit The bit to be get
     */
    bool (*get_bit)(const void* buffer, size_t bit);
    /**
     * @brief Set bit in buffer
     * @param buffer The buffer
     * @param bit The bit to be set
     * @param value The value to be set
     */
    void (*set_bit)(void* buffer, size_t bit, bool value);
    /**
     * @brief Stringify the buffer
     * @param buffer The buffer
     * @param size The size of the buffer, in bits
     * @param col_size The size of each column, in bits
     * @param row_size The size of each row, in columns
     */
    char* (*stringify)(const void* buffer, size_t size, size_t col_size, size_t row_size);
    /**
     * @brief Parse a stringified buffer into a buffer
     * @param buffer The buffer
     * @param str The string to be parsed
     * @param size The size of the buffer, in bits
     */
    void (*parse)(void* buffer, const char* str, size_t size);
    /**
     * @brief Get the endian of the system
     * @return true if the system is little endian, false otherwise
     */
    bool (*endian)();
    /**
     * @brief Reverse the buffer
     * @param buffer The buffer
     * @param size The size of the buffer, in bytes
     */
    uint8_t* (*reverse)(const void* buffer, size_t size);
    /**
     * @brief Convert a little endian buffer to big endian
     * @param buffer The buffer
     * @param size The size of the buffer, in bits
     */
    void* (*to_big)(const void* buffer, size_t size);
    /**
     * @brief Convert a big endian buffer to little endian
     * @param buffer The buffer
     * @param size The size of the buffer, in bits
     */
    void* (*to_little)(const void* buffer, size_t size);
} Buffer;

Example

uint8_t* buffer = calloc(16 / 8, sizeof(uint8_t));
for (int i = 0; i < 16; i++) {
    Buffer.set_bit(buffer, i, i % 2);
}
for (int i = 0; i < 16; i++) {
    assert(Buffer.get_bit(buffer, i) == i % 2);
}

char* str = Buffer.stringify(buffer, 16, 8, 8);
printf("%s\n", str); // "01010101 01010101"

console.h

Console utilities.

struct {
    size_t (*gray)(const char* str, ...);
    size_t (*red)(const char* str, ...);
    size_t (*green)(const char* str, ...);
    size_t (*blue)(const char* str, ...);
    size_t (*yellow)(const char* str, ...);
    size_t (*magenta)(const char* str, ...);
    size_t (*cyan)(const char* str, ...);

    size_t (*success)(const char* str, ...);
    size_t (*info)(const char* str, ...);
    size_t (*warn)(const char* str, ...);
    size_t (*error)(const char* str, ...);

    /** Logs a message to the console, with time prefix */
    void (*log)(const char* str, ...);

    /** Print in rainbow colors */
    size_t (*rainbow)(const char* str, ...);

    /** Color constants */
    struct {
        const char* GRAY;
        const char* RED;
        const char* GREEN;
        const char* BLUE;
        const char* YELLOW;
        const char* MAGENTA;
        const char* CYAN;
    } C;
} Console;

debug.h

Debug utilities.

THROW THROW_IF

options.h

Parse command line options.

struct {
    /**
     * @brief Parse command line arguments
     * @param argc number of arguments
     * @param argv array of arguments
     * @return parsed options
     */
    ParsedOptions* (*parse)(size_t argc, char* argv[]);
    /**
     * @brief Get an option from the parsed options
     * @param options parsed options
     * @param name name of the option
     * @return value of the option
     */
    char* (*get)(ParsedOptions* options, char* name);
    /**
     * @brief Check if an option is present
     * @param options parsed options
     * @param name name of the option
     * @return true if the option is present, false otherwise
     */
    bool (*has)(ParsedOptions* options, char* name);
    /**
     * @brief Free the parsed options
     * @param options parsed options
     */
    void (*free)(ParsedOptions* options);
} Options;

Example

ParsedOptions* options = Options.parse(argc, argv);

if (Options.has(options, "help") || Options.has(options, "h")) {
    printf("Usage: %s --name <something>\n", argv[0]);
    return 0;
}

printf("Hello, %s!\n", Options.get(options, "name") || "XYZ");
Options.free(options);

string.h

String utilities.

struct {
    /**
     * Construct a new string with IO formatting.
     */
    char* (*format)(const char* format, ...);
    /**
     * Trim the chars from the beginning and end of a string and returns the new string.
     * If charset is NULL, the default charset ( \\t\\n\\r\\f\\v ) is used.
     */
    char* (*trim)(const char* string, const char* charset);
    /**
     * Extract a substring from a string and returns the new string.
     */
    char* (*substring)(const char* string, size_t start, size_t end);
    /**
     * Search for a substring in a string and returns the index of occurrences, with size `count`.
     */
    size_t* (*search)(const char* string, const char* pattern, size_t* count);
    /**
     * Repeat a string with separator for a given number of times and returns the new string.
     */
    char* (*repeat)(const char* string, size_t times, const char* separator);
    /**
     * Replace a substring in a string with another substring and returns the new string.
     */
    char* (*replace)(const char* string, const char* old, const char* new);
    /**
     * Make a string uppercase and returns the new string.
     */
    char* (*upper)(const char* string);
    /**
     * Make a string lowercase and returns the new string.
     */
    char* (*lower)(const char* string);
    /**
     * Reverse a string and returns the new string.
     */
    char* (*reverse)(const char* string);
    /**
     * Pad a string with a given string and returns the new string.
     */
    char* (*pad)(const char* string, size_t length, const char* pad);
    /**
     * Split a string with a given separator and returns the new string array.
     */
    char** (*split)(const char* string, const char* delimiter, size_t* count);
} String;

Example

char* my_string = String.format("There are %d monkeys in the %s", 10, "tree");

size_t size;
char** words = String.split(my_string, " ", &size);

timing.h

Timing utilities.

struct {
    /**
     * @brief Start a timer with a label.
     * @param label The label of the timer.
     */
    bool (*start)(const char* label);
    /**
     * @brief Get the time elapsed since the last timing_start() call.
     * @param label The label of the timer.
     * @return long double The time elapsed since the last timing_start() call in milliseconds.
     */
    long double (*check)(const char* label);
    /**
     * @brief Remove a timer with a label.
     * @param label The label of the timer.
     * @return bool True if the timer is removed successfully.
     */
    bool (*remove)(const char* label);
    /**
     * @brief Clear all the timers.
     * @return size_t The number of timers cleared.
     */
    size_t (*clear)();
    /**
     * @brief Sleep for a certain amount of milliseconds.
     * @param ms The amount of milliseconds to sleep.
     */
    void (*sleep)(const uint64_t ms);
} Timing;

Example

Timing.start("test");
Timing.sleep(500);
Console.cyan("%Lf ms", Timing.check("test"));
Timing.sleep(500);
Console.yellow("%Lf ms", Timing.check("test"));

Run Tests

  1. Clone the repository and cd into the directory.
  2. Run make to compile the C code.

Or just open in Gitpod:

Open in Gitpod

Some Concepts

Why using String.lower instead of strlower?

Namespace is a good idea, although it is not exisiting in C, but we can still simulate it by using a global struct.

Benefits:

  • Avoid naming conflicts (pollution)
  • Provide library description through VS Code intellisense

The only downside is that dereferring a function pointer may have a small cost. (Maybe compiler will optimize it away?)

Development

  1. build the ubuntu environment image scripts/build.sh
  2. enter the container scripts/start.sh
  3. do anything you want

cimple-lib's People

Contributors

jacoblincool avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.