he/they

jq(1) concept clone as a* C function

*it actually uses three (3) functons and a struct

for the longest time (about three months) i've been trying to *do things* with json files inside scripts (i wrote a whole timeline about this). doing it on python was like hell because i barely understood python and doing it in C was worse because i understood what i was doing but i depended on C (gcc) understanding too what i was trying to do. in both cases getting to a json key was a pain because python's json module makes a dict and The JSON-C Library moves one key at a time. bear in mind i got into all of this from using jq(1) on my silly zsh and some bash scripts so needing something more than '.foo[4].bar[] | .select("life" == 47)' was always so much.

i ate it whole when in python i could do >for bar in data["foo"][4]["bar"]: if bar["life"] is 47: but i lost my mind when in C i needed to create a json_object pointer, look for a value inside that key and create another pointer (or use the same one i don't know if that was bad tbh) if what i needed was nested so after the fourth call to json_object_object_get i started working in a parser so i could use that jq syntax (the dots and keys, not the functions) and i got the json_object.

the concept is extremely easy, get the string, slice it by the dots and loop through it call json_object_object_get with the current key and the slice of string. i googled how to get the string, got c++ stackoverflow first but just below was exactly what i was looking for using strtok. before thinking of testing with actual json-c i started working on the array thing (clueless). can't be more difficult that geting sscanf(str, "%s[%d]", token, &idx) right? i got segfaults on every try. i expected to get that working in less than 30 minutes so at that point i just gave up.

recently i finished all the fotmob ncurses interface stuff i wanted to do so a God touched my head and i thought well i CAN make a program that calculates promedios (the devil's worst creation, see Relegation on Argentine Primera División), where teams are ranked by the average points in the last three seasons in the top division, and have it for leagues other than Argentine Primera División itself (not only because tons of promedios tables are avalible but also because it uses two different league competitions that don't even work as a apertura and clausura). not gonna explain how this went because i spent more time crafting linked lists and never got to calculate a single average. this time something rang in my head and i remember about the jq-like parser now that i forgot that i didn't even understood what was wrong. i cluelessly got into it.

again slicing the tokens was easy, this time even i tested if the slices were in fact sliced and they were. next thing i see myself trying again the sscanf thing and guess what now that i outputed the results before trying to fetch a json object i got that i wasn't even getting the index. well not so bad there are like seven ways you (supposedly) can do that, ten seconds later im asking ch*tgpt how to separate "token[idx]" into char *token and int idx. lucifer's solution works i make a struct that has that char *token and int idx try it and it initially works... using atoi(3).

i mean, yea, its the thing i could have figured out if i ever knew what strchr(3) did and i thought about *checks gpt reply* substracting pointer... ? and as i said it initially works but atoi quirky little mask of strtol returns 0 when there is no number (because strtol does it) with the difference that strtol takes another argument, char** endptr that is the same as the char* nptr passed through atoi, only when endptr is not NULL (it is on the atoi, at least in the glibc specification, musl for example has an independent atoi function). anyways atoi didn't work to me in this case because i needed to account for the case in which no index is provided but i somehow stumbled upon strtol itself (not by looking at the source, i did that later) and found that "If there were no digits at all, strtol() stores the original value of nptr in *endptr (and returns 0)" in the manual and i felt that after some time god had finally touched my head because at any other time i wouldnt have ever thought that i could use that in my advantage.

with that i was done, i did the array thing and it worked, just compare nptr and *endptr and return -1 if they are the same thing (actually this wouldnt work if you tried to get the last item from a list but anywaysss...) and i couldnt believe it, it actually worked as a whole, if i tried printing the tokens i saw where an array was called and what index it had and when i plugged json_object_object_get i got results (not before misspelling some word and scratching my head until i rewrote that specific line) i was actually surprised by it because i had acutally gave up in between tries.

i refuse to use javascript on this page so i cant use those fancy coloured code boxes but i can use some tool from the web and leave the code file as always. function descriptions were on a header file for the whole project (#include "prom.h" is still in the image) but i think usage and returns are easy to understand and find errors (like doing malloc with strlen of a const char* im pretty sure i can just use sizeof).

more at tw/dauthubleis and m/dauthubleis

hosted by neocities