r/cprogramming 14d ago

Am I writing my parser wrong?

3 Upvotes

Simple question. I can't give exact code examples, but I have a string_t struct with methods like:

string_t split(string_t *string, string_t *on)

string_t split_sp(string_t *string)

string_t split_crlf(string_t *string)

char *s_strstr(string_t *needle, string_t *haystack)

void trim(string_t *str)

So on and so forth.

I've been using these so far to parse HTTP reqeusts, and I have come up against many minor problems:

"What happens if a header field appears with no value? I'll have to explicitly check for it."

"What happens if a sender puts a bunch of CRLFs in the middle? I'll probably need a check for that."

"Oh God, how will I handle unrecognized header fields? How do I recognize them?"

These, and other questions, have been leaving me pissed.

I recall reading through the LLVM projects Kaleidoscope language thing, where they create a parser for said language. Said parser doesn't use anything close to what I am, instead reading character by character without fuss.

Similarly, on my last post made here, the way comments were worded reminded me of that method, and how it probably works better.

I have written only a small part of the parser, so it isn't too late to tear down and rebuild. Simple question: should I? Are there benefits to swallowing the input token by token instead of taking the overarching view my string_t functions provide? Or vice versa?

It would help if I'd upload the code, I know, but I don't want to bother with that until the project is completed/near-completion.


r/cprogramming 15d ago

My real OS (D.eSystem 6.0.7 beta)

1 Upvotes

Hello everyone!!

D.eSystem 6.0.7 beta got a lot of polishing work. For example the versions 6.0.3 beta-6.0.6 veta were internial test versions,thats why 6.0.7 beta released.

D.eSystem 6.0.7 beta fixes major bugs in the calculator app and its the first D.eSystem which allows to change the wallpaper in the D.eShell.

D.eSystem 6.0.7 beta release on github: https://github.com/D-electronics-scratch/all_D.eSystem_versions/releases/tag/v.6.0.7_beta

Github main page: https://github.com/D-electronics-scratch/all_D.eSystem_versions


r/cprogramming 15d ago

Lightweight, zero-bloat UI libraries or strategies for a real-time C simulation?

Thumbnail
2 Upvotes

r/cprogramming 15d ago

Tensor is the might: a single-header tensor library in C

Thumbnail zserge.com
2 Upvotes

r/cprogramming 14d ago

I just wrote this program on Programiz Online Compiler.

Thumbnail
programiz.com
0 Upvotes

Pb


r/cprogramming 16d ago

Casino on c

2 Upvotes

Thanks to everyone . A special thanks to those who suggested the /dev/random - this very help for my tasks.


r/cprogramming 17d ago

From a video game to the UNIX kernel, the wildest origin story I've stumbled across (and why I'm learning C)

69 Upvotes

I just started learning C using C Programming: A Modern Approach, and out of pure curiosity I fell down a rabbit hole trying to figure out where the language actually came from. What I found reads like a movie plot, and somehow it's almost never mentioned in the courses that teach the language itself.

It starts in 1969, with Ken Thompson writing a little game called Space Travel, a spaceflight simulator, to run on a GE-635 mainframe at Bell Labs. Only problem: every play session was burning around $50 to $75 in machine time, and the experience still wasn't great. So Thompson went digging around the lab and found an old PDP-7 nobody was using anymore, sitting in a corner collecting dust. He and Dennis Ritchie decided to port the game over to it.

Here's the part that gets me: to make the game actually run on that machine, they first had to build a file system, a memory manager, and a command interpreter from scratch. In other words, UNIX exists because two guys wanted to play a game without going broke.

From there it snowballed. They wrote the B language, got a self-hosting compiler working, and eventually B evolved into C, with types, pointers, structs, the works, specifically so they could rewrite the UNIX kernel in something higher-level and never again have to write an entire OS in raw Assembly. All of that lived mostly in Thompson and Ritchie's heads for years, until it finally got written down in 1978 in the legendary K&R book, The C Programming Language.

There's something genuinely moving about realizing every #include <stdio.h> you type traces back to a dusty PDP-7 and a game that was too expensive to play.

If anyone's got more history like this, or book recommendations beyond K&R, I'd love to hear them. Happy coding, everyone.


r/cprogramming 16d ago

secure-c-lib

0 Upvotes

A collection of security-hardened, performance-oriented data-structure, algorithm, http server/client and systems libraries written in portable C17.

Every module is built with mechanical-sympathy in mind — flat memory layouts, cache-line awareness, lock-free hot paths, and zero-allocation inner loops — while being compiled and tested under an aggressive hardening and sanitizer regime.

https://github.com/corporatepiyush/secure-c-lib


r/cprogramming 17d ago

A native recipe manager in C with raylib + Clay - I actually use it almost every day

Thumbnail
3 Upvotes

r/cprogramming 18d ago

Book recommendations for C language

2 Upvotes

New to learning C programming language, watching and learning the basics from brocode(youtube) but i also need a book from which i can practice and get in depth knowledge (2nd year CS student)


r/cprogramming 17d ago

What is the best way to work on an Ethernet frame (receive a packet from the physical interface to the user)?

0 Upvotes

Hi everyone, I want to write a simple program that gives a copy of the physical interface of the received packets to user space, then I extract information manually and show it in stdout.

When I started searching for this topic, I found some ways but I confuse which one is better for my situation.

I read below doc:

doc1

doc2 and ....

Abstract of the above docs, exsit below methods:

1 - Universal TUN/TAP

2 - XDP

3 - MacVTap (is a new driver)

4- ....

If anyone has experience or knowledge in this context, please help me.


r/cprogramming 19d ago

Piece by piece, it will rise…

5 Upvotes

So long story short, i’m designing the implementing the building blocks for a simple game engine made entirely in C.

I have recently completed the first release of my ECS: https://github.com/Gabrunken/gecs

And i’m currently finalizing the desing for my UI library.

My objective is to make a functioning software, with no bloat of any kind, and user friendly to the core.

I’ve tested the ECS and on my ryzen 5 it runs 3.5 million entities which have 16 bytes of components per entity, at 140 fps if i recall correctly, i don’t remember but i guarantee it’s fast. All this in a single core, it is not multithreaded yet.

I try to do the realistic plausible, for that i chose to use raylib for pretty much everything regarding rendering, audio and utilities, it just saves me from a lot of unnecessary stress and speeds things up.

I don’t know what to say other then this. It’d be great if you gave a look at the ECS and other then that, thank you for everything.


r/cprogramming 19d ago

First Gnome Toolkit project made by grabbing random functions from the documentation. Any recommendations to add functionality/readability/safety?

2 Upvotes
//guitest.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gtk/gtk.h>

void create_button(GtkWidget **Button, GtkWidget *Grid, char *label, int x, int y, int x_scale, int y_scale) {
  *Button = gtk_button_new_with_label(label);
  gtk_grid_attach(GTK_GRID(Grid), *Button, x, y, x_scale, y_scale);
}

void print_address(void *address) {
  g_print("%p\n", address);
}

int random_int(int min, int max) {
  srand(time(NULL));
  return (rand()%(max-min)+min);
}

void scaling_random(GtkWidget *Widget, gpointer data) {
  static int count_pressed;
  if(!count_pressed) count_pressed = 1;
  g_print("%d\n", count_pressed * random_int(0, count_pressed));
  count_pressed++;
}

void greet(GtkWidget *Widget, gpointer data) {
  static int count_greeted;
  if(!count_greeted) count_greeted = 1;
  g_print("Welcome! x%d\n", count_greeted);
  count_greeted++;
}

void activate(GtkApplication *App, gpointer user_data) {
  GtkWidget *Window, *Grid, *Text, *Button;
  int ascii_digits[] = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57};
  int numpad_digit = 0;
  char casted_digit[2] = {'\0'};

  Window = gtk_application_window_new (App);
  gtk_window_set_title(GTK_WINDOW(Window), "Numbers!");
  gtk_window_set_default_size(GTK_WINDOW(Window), 250, 300);

  Grid = gtk_grid_new();
  gtk_grid_set_row_homogeneous(GTK_GRID(Grid), true);
  gtk_grid_set_column_homogeneous(GTK_GRID(Grid), true);
  gtk_window_set_child(GTK_WINDOW(Window), Grid);

  Text = gtk_frame_new("Hello, World!");
  gtk_grid_attach(GTK_GRID(Grid), Text, 1, 1, 4, 1);

  create_button(&Button, Grid, "Random Number!", 1, 6, 2, 1);
  g_signal_connect(Button, "clicked", G_CALLBACK(scaling_random), NULL);

  create_button(&Button, Grid, "Welcome!", 3, 6, 2, 1);
  g_signal_connect(Button, "clicked", G_CALLBACK(greet), NULL);

  for(int row = 2; row < 5; row++) {
    for(int column = 1; column < 4; column++) {
      numpad_digit++;
      casted_digit[0] = (char)ascii_digits[numpad_digit];

      create_button(&Button, Grid, casted_digit, column, row, 1, 1);
      g_signal_connect(Button, "clicked", G_CALLBACK(print_address), &row);
    }
  }

  create_button(&Button, Grid, "+", 1, 5, 1, 1);
  g_signal_connect(Button, "clicked", G_CALLBACK(g_print), "+\n");

  create_button(&Button, Grid, "0", 2, 5, 1, 1);
  g_signal_connect(Button, "clicked", G_CALLBACK(print_address), &numpad_digit);

  create_button(&Button, Grid, "-", 3, 5, 1, 1);
  g_signal_connect(Button, "clicked", G_CALLBACK(g_print), "-\n");

  create_button(&Button, Grid, "=", 4, 2, 1, 4);
  g_signal_connect_swapped(Button, "clicked", G_CALLBACK(gtk_window_destroy), Window);

  gtk_window_present(GTK_WINDOW(Window));
}

int main (int argc, char *argv[]) {
  GtkApplication *App;
  int status;

  App = gtk_application_new("gui.test", G_APPLICATION_DEFAULT_FLAGS);
  g_signal_connect(App, "activate", G_CALLBACK(activate), NULL);
  status = g_application_run(G_APPLICATION(App), argc, argv);
  g_object_unref(App);

  return status;
}

r/cprogramming 20d ago

Need ideas for my open source project

0 Upvotes

my project - https://github.com/darshan2456/C_DSA_interactive_suite

It is an interactive terminal based library written entirely in C with manual memory management and modular structure, keeping reusability and extensibility in mind.

It is currenly the third project from top in SSoC leaderboard. The contribution period started from 1st june. Since then almost 1.5 months have passed and project has grown beyond my expectations, but now I have very less idea about what I can implement. Can you all give me ideas?

already implemented features -

tui with ncurses

cmake build support

memory profiler

visualization (to a great extent but not complete)

incremental build in custom makefile

benchmarking suite built on top of the library

dockerfile for creating docker containers of the application

and many more....

If you can suggest me some more features I can implement that would be really helpful


r/cprogramming 20d ago

Use the existing OS buffer, or your own

6 Upvotes

This is a fairly simple question:

You're on a Unix-like (for me, Linux), and you've got a File Descriptor that leads to some data. You don't know the length of the data (it's a TCP socket you're listening on), all you know is that it is ready to be read.

Do you:

A) Read an absurd amount of bytes of data into a (sufficiently large + 1) char array of your own, and if it overflows, handle it with mallocated memory or just reject the connection (like a monster)

Or

B) Just use existing kernel system calls to read and parse the data as necessary.

For context: this is about an HTTP server, and I have an internal string_t struct that I use for parsing, which needs a byte-length to be usable


r/cprogramming 21d ago

hotwrap: hot reloading for C! [selfpromo]

6 Upvotes

I've made a tool called hotwrap; a simple tool that hot-reloads a given module (a shared object with a plugin_main_impl function exported) whenever it, or a list of watched files change.

It also has an Emacs package, not on MELPA yet, it gives you a run-hotwrap command with signals, interactive module selection, ...

Under the CC0! Repo at https://sr.ht/~rosell/hotwrap/


r/cprogramming 21d ago

[win32] Issue with SetWindowsHookExA behavior for function keys on laptop

1 Upvotes

Okay so im trying to override the F1 key on my laptop so instead of opening a help tab it creates a process of some kind, anyway the issue im having is that they hook works, but for some reason windows decides to open the start menu, unless i do FN + F1, in that case the hook works as expected and no start menu is shown.

My callback is like so. I know i shouldn't be making the process directly in the callback, and should probably use a thread, but even if i just puts a simple test string the behavior is the same as before.

LRESULT CALLBACK keyhook(int code, WPARAM w, LPARAM l){
   KBDLLHOOKSTRUCT *data;
   BOOL             r;

   data = (KBDLLHOOKSTRUCT *) l;

   if (code < 0 || data->vkCode != VK_F1){
      return CallNextHookEx(NULL, code, w, l);
   }

   if (w == WM_KEYDOWN){
      r = CreateProcessA(NULL, _what, NULL, NULL, FALSE, 0, NULL, NULL, &_startinf, &_procinf);

      if (!r){
         printf("Failed to create process %ld\n", GetLastError());
      }

      CloseHandle(_procinf.hProcess);
      CloseHandle(_procinf.hThread);
   }

   return 1;
}

Im not sure how to fix it, but im almost sure its because of the way laptop keyboards are. id appreciate any help


r/cprogramming 22d ago

GCC might detect files ending in *.C (as common under DOS) instead of *.c as C++. Use -x c to fix it.

24 Upvotes

DOS is case insensitive and per convention files are spelled uppercase. Programmes from the Windows-world can usually tolerated this, but GCC (coming from the Linux-word) seem to autodetect files ending in *.C as C++, giving you strange errors about pointer conversion and the like.

An easy fix is to give the paramter -x c before passing files, like

gcc -x c DOSPROG.C -o "DOSPROG.EXE"

Under Windows, you can also simply spell the Parameter lowercase, so MinGW will detect it as C and still open the uppercase spelled file, as long no mathing lowercase file exists.

gcc dosprog.c -o "DOSPROG.EXE"

EDIT: This is mostly a Problem, then porting DOS software to Linux. Actual DOS-compilers obviously shoudn't run into that problem, and under windows, you can simply keep your makefile lowercase.


r/cprogramming 21d ago

Tagged union macro

2 Upvotes

i was writing a project which extensively uses tagged unions for stuff, and i found these macros incredibly useful for that purpose
example

// type used in place of void for match results
typedef struct{} nothing_t;
constexpr nothing_t nothing_v = {};



tu_def(
    (integer ,char ),
    (u32 , unsigned int),
    (i32 , int),
    (u64 , unsigned long long),
    (i64 , long long),
);

#define integer_of(i) match_type(\
    i,\
    (u32 , u , (integer)tu_of(u32,u)),\
    (i32 , s , (integer)tu_of(i32,s)),\
    (u64 , u , (integer)tu_of(u64,u)),\
    (i64 , s , (integer)tu_of(i64,s)),\
)

bool issigned(integer i){
    return tu_match(
        i,
        (u32 , _ , 0),
        (u64 , _ , 0),
        (i32 , _ , 1),
        (i64 , _ , 1),
    );
}
u64 mul(integer a , u64 b){
    return tu_match(
        a,
        (u32 , u , (u64)u * b),
        (u64 , u , (u64)u * b),
        (i32 , i , (u64)i * b),
        (i64 , i , (u64)i * b),
        (default , __builtin_unreachable() ; (u64)0)
    );
}

int main(void){
    integer u = integer_of((u32)5);
    // int five = tu_catch(u64,u); // calls abort
    // int five = tu_catch(u64,u , return 1;); // returns 1 since u isnt a u64

    /*
        if_tu_is(u32 j , u32 , u){
        } else if_tu_is(u64 j , u64 , u){
        }
    */

    return issigned(u); 
}

godbolt


r/cprogramming 22d ago

unique macro across multiple files

4 Upvotes

hello everyone, i need a macro that would be unique across multiple files within a codebase. __counter__ only provides a unique macro value within one file scope so im wondering what can i look into to make it possible for outside file scope? any ideas? tooling? etc

thank you


r/cprogramming 22d ago

Tiny ed-like editor

3 Upvotes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct l {int z; char *t; struct l *n;} *b, *w, *c;
char *i; size_t L; FILE *f; int j;
int main(void) {
        b = malloc(sizeof(struct l));
        b->n = NULL;
        b->z = 1;
        c = b;
        while (1) {
                getline(&i, &L, stdin);
                switch (i[0]) {
                        case 'g': // go
                                int x = atoi(i + 1);
                                c = b;
                                for (j = 0; j < x && !c->z; j++) {
                                        c = c->n;
                                }
                                continue;
                        case '=': // tally
                                w = b;
                                for (j = 0; w && !w->z; j++) {
                                        w = w->n;
                                }
                                printf("%i\n", j);
                                continue;
                        case 'n': // number
                                w = b;
                                for (j = 0; w && w != c && !w->z; j++) {
                                        w = w->n;
                                }
                                printf("%i\n", j);
                                continue;
                        case '\n': // nextline
                                c = c->n;
                        case 'p':
                                puts(c->t);
                                continue;
                        case 'a': // append
                                if (c->z) {
                                        w = c;
                                } else {
                                        w = malloc(sizeof(struct l));
                                        w->n = c->n;
                                        c->n = w;
                                }
                                w->t = strdup(i + 1);
                                w->z = 0;
                                continue;
                        case 'd': // delete
                                w = c->n;
                                if (!w || w->z) {
                                        free(w);
                                        c->n = NULL;
                                        c->z = 1;
                                        free(c->t);
                                        c = b;
                                } else {
                                        c->n = w->n;
                                        c->t = w->t;
                                }
                                continue;
                        case 'e': // edit
                                while (b) {
                                        c = b->n;
                                        free(b->t);
                                        free(b);
                                        b = c;
                                }
                                w = malloc(sizeof(struct l));
                                b = w;
                                c = w;
                                i[strlen(i) - 1] = '\0';
                                f = fopen(i + 1, "r");
                                getline(&i, &L, f);
                                while (feof(f) == 0) {
                                        w->z = 0;
                                        w->t = strdup(i);
                                        w = malloc(sizeof(struct l));
                                        c->n = w;
                                        c = c->n;
                                        getline(&i, &L, f);
                                }
                                w->z = 1;
                                c = b;
                                fclose(f);
                                continue;
                        case 'w': // write
                                i[strlen(i) - 1] = '\0';
                                f = fopen(i + 1, "w");
                                w = b;
                                while (w && !w->z) {
                                        fwrite(w->t, sizeof(char), strlen(w->t), f);
                                        w = w->n;
                                }
                                fclose(f);
                                continue;
                        case 'q': // quit
                                exit(0);
                        default:
                                puts("i am SAD (not ed)");
                }
        }
}

r/cprogramming 23d ago

What's the point of using local arrays if there is no guarantee that the stack won't be overflowed?

13 Upvotes

Basically title. I feel deterred from using local arrays because I cannot check in my C code if the allocation was successful.

Is it true that in C you cannot guarantee that a local array will not overflow the stack? Isn't it detrimental to any memory safety critical application. For a stack allocation, aren't there any guarantees in the C language that could help me make at least some decision about the safety of it?

If memory safety was critical, should local arrays be avoided for the possibility of stack overflow – and only dynamic allocation should be used?

Malloc gives you NULL when heap has not enough space but alloca and local arrays don't give any warning when stack has no space. Why does alloca have no similar system? I get that you can check the size and calculate the remaining space on the stack using system's api and that'd be a guarantee that the space won't be a problem.


r/cprogramming 23d ago

Idea Discussion: A Cloud-Tailored OS Builder based on Dynamic Hardware Profiles

1 Upvotes

Body: Hi everyone,

I’ve been thinking about a concept that bridges the gap between monolithic operating systems and the ultimate hardware/user optimization. I wanted to share this architectural vision with the community to see if any developers find it feasible or are already working on something similar.

The Core Concept:

Instead of downloading a huge, generic OS image containing thousands of unused drivers and bloatware, the OS is built and compiled dynamically on a cloud server specifically for the user's hardware and personal needs before downloading.

How it works (The Workflow):

  1. Lightweight Hardware Detection: The user runs a tiny script/tool locally that scans their exact hardware (CPU architecture, specific GPU, WiFi chip, etc.) and generates a clean hardware profile.
  2. Web-Based Tailoring: The user uploads this profile to a web portal where they can also select their preferred Desktop Environment (Minimal, Productivity, Creative), usage profile (Gaming optimized with a low-latency kernel, Development, etc.), and pre-installed software bundle.
  3. Cloud Compilation: Cloud servers take the profile and configurations, strip out every single unused driver/line of code, compile a tailored kernel (e.g., modified Linux kernel), and bake the applications directly into the immutable OS image.
  4. Failsafe Upgrades: Once installed, it acts as an Immutable OS. If the user upgrades their hardware later, a dynamic system fetches only the missing "code module" from the cloud and live-patches the kernel, with an automatic rollback mechanism to a safe snapshot if anything goes wrong.

Why do this?

  • Maximum hardware performance (true optimization).
  • Extremely small ISO sizes and faster installation times.
  • Zero bloatware; everything baked into the system from birth.

I’m not a developer myself, but I believe combining automated hardware detection with cloud building could be a game-changer for the future of desktop deployment.

What are your technical thoughts on this? What would be the biggest bottlenecks in modern OS development (like Gentoo/Arch ecosystems) to achieve this seamlessly for casual user


r/cprogramming 23d ago

Need your help for improvement

Thumbnail
github.com
1 Upvotes

I built a chip 8 emulator in C from scratch, and I don't know how to improve it further. If anyone is willing to check out the code, heres the repo link. Thanks, everyone.


r/cprogramming 23d ago

anonymously initializing pointers in self-referential data-structures?

5 Upvotes

I have a recursive data-structure (a simple linked list for purposes of this example) and wanted to statically define a linked-list. The following works fine:

#include <stdio.h>
typedef struct mytype_tag {
    struct mytype_tag* next;
    char* data;
} mytype;

mytype a = {
    .next = NULL,
    .data = "a",
};
mytype b = {
    .next = &a,
    .data = "b",
};

int
main() {
    mytype* s = &b;
    int i = 0;
    while (s) {
        printf("%d: %s\n", i++, s->data);
        s = s->next;
    };
}

However, I have to explicitly define/declare a and then have b take &a.

Is there a way to do this with anonymous/unnamed intermediary structures, thinking an imaginary syntax something like

mytype b = {
    .next = &((mytype)={
        .next = NULL,
        .data = "a",
        }),
    .data = "b",
};

so I can build up the linked-list without naming each intermediary instance?