Sunday, March 09, 2025

Minimal implementations of grep and sed

 I had been thinking about it from quite some time...

Why do I always do a "shell-out" to `grep` and `sed` to edit Linux configuration files, knowing full well that its not good from security standpoint, and not a clean/efficient code! 🤔

Maybe its time, last week while sitting at a Dental clinic, I quickly wrote a minimal version of `grep`, just supporting the most basic operations, the equivalent of:

grep -e or egrep (extended POSIX regex match)

grep -q (quiet 🤫)

grep -F (fixed string match), and

grep -c (count the number of matches)

All I needed was a quick file read (getline) plus POSIX regex match - a.k.a `regcomp()`, `regexec()` and this was it:


(later I decided to throw in "show line number" and "stop on first match" also 😀 why not!? not a big change)

Emboldened by this, I attempted a minimal `sed` to do "inline-replace" (my most common use !)

The only additional checks I needed, was to find the match offsets, and of course captures and replace:


I am saving only 2 set of captures, one for the entire match (implicit, in `pmatch[0]`) and one if the user specifies a capture (`pmatch[1]`)

Note: I know `&` means  "all that matched" and not same as `\1` but since I am not going to add support for multiple captures and replace, this is it!

Thursday, February 27, 2025

 Switch case on strings!


Interesting solution:    https://stackoverflow.com/a/51816519/112687 


#ifndef __SSWITCH_H__

#define __SSWITCH_H__

#include <string.h>

    #ifndef SWITCH_CASE_INIT

    #define SWITCH_CASE_INIT

    #define SWITCH(X)  for(char* __switch_p__=X,__switch_next__=1;__switch_p__;__switch_p__=0,__switch_next__=1) {{

    #define CASE(X)    } if (!__switch_next__ || !(__switch_next__ = strcmp(__switch_p__, X))) {

    #define DEFAULT    } {

    #define END        }}

    #endif

#endif