randoragon / libstaple Goto Github PK
View Code? Open in Web Editor NEWA general-purpose data structure library in pure C89.
License: GNU Lesser General Public License v2.1
A general-purpose data structure library in pure C89.
License: GNU Lesser General Public License v2.1
Self-explanatory. Luaparser should choose the correct type (and in the case of %zu
, drop the value cast to unsigned long
).
It might be nice to have access to functions such as stpcpy
even if we're writing C89. There are probably more examples, just look at newer C standards to see what they improved over the years.
This must happen for all O(1) getters such as sp_stack_peek
and sp_stack_get
. There should be NO reason or incentive to worry about loops such as
for (size_t i = 0; i < stack->size; i++) {
const int elem = sp_stack_geti(stack, i);
/* do something with elem */
}
generating a function call every iteration, which is (probably) way slower than accessing stack->data
directly. This should be trivially guaranteed.
I'm aware C89 does not support enforcing inlining. But most compilers support attributes which allow this. Staple is and always will be compiler-agnostic, but adding some attributes guarded by compiler-detecting ifdefs should be no problem. A bigger problem might be moving function definitions to headers. In any case, this will require some significant modifications to the lua generate tool.
Also, before anything, a benchmark should be conducted to make sure forcing an inlining actually leads to better performance.
Major oversight on my part, there should be a built-in suffix for operating on size_t
types. It should probably be z
(like in printf format), e.g. sp_stack_pushz()
etc.
Currently each bit is stored as a _Bool
type, which takes a whole byte. It's necessary to rewrite the entire boolean implementation to use binary operations to actually operate on individual bits.
Man pages will stay 100%, because they are a unique selling point in a world rid of simple, old solutions. However, I would like staple to integrate well with LSP clients, because those are the de facto status quo, even in editors like neovim. Furthermore, it would be nice to be able to generate an html documentation for online viewing, if I decide to take that step.
I haven't explored this topic much, I'm pretty sure Doxygen is still the standard for C code documenting. But I've never tested how well it integrates with LSP.
Another consideration: Maintaining Doxygen and man pages separately would be a huge pain. Doxygen has a man page output option, but I don't know how good it is. If it's no good, then it could be necessary to create my own format, which is also a lot of work.
Self-explanatory. The user must know.
The idx
argument should be explained properly, like it's done in *_get
functions (probably a matter of copy&paste).
When I was writing it, I was new to lua, did not use any static checkers such as lua-language-server
and in consequence there are a few poor design choices there. I would like to refactor it, get rid of all warnings, add assertions, ensure type safety with ---@type <type>
hints and review that the code base there is understandable (it's been long enough that I should be able to judge myself in terms of that).
Not super high-prio. Definitely don't want to delay 2.2.0 because of this.
While I originally vowed to avoid macros due to code clutter, I'm having second thoughts, because they would be particularly useful for inline looping through structures. As of now, the only way to execute code for each element is by writing a callback function, which is just silly for most scenarios, not to mention the extra overhead of a function call on each element.
I think the current callback functionality should be provided by *_map
functions, and there should be a new set of macros called *_foreach
that follow some kind of flexible inline convention, like so:
sp_stack_foreachi(stack, i, v) {
printf("index: %zu\n", i);
printf("element: %d\n", v);
}
The macros should probably be suffixed, because otherwise the user would have to manually cast a void pointer every time, which is completely avoidable with some effort on the library side.
One way to achieve this is to redefine malloc
to fail in a predictable way. Implementation could be sketchy and is rather low-priority, I may drop this idea entirely if it turns out too complicated.
This is a major oversight. All generic variants of functions that remove elements are geared towards returning the void pointer for the user to free. This is fine, except there is no way of removing an element with a destructor in one line. Currently one has to do:
sometype_t elem;
sp_stack_remove(stack, 0, &elem);
elem_dtor(elem);
If the user did just
sp_stack_remove(stack, 0, NULL);
...they could unknowingly leak memory (the deleted element is not run through any destructor). Ideally, there should be a semantic for doing this properly in one line.
I think the only reasonable solution is to scrap the element-returning feature of the generic *_pop
/*_remove
/*_qremove
functions altogether, and replace the output
argument with a dtor
argument. This would work like this:
sp_stack_remove(stack, 0, elem_dtor);
And If the user wanted to retrieve the element before removing it, they can just use *_peek
or *_get
:
now:
sometype_t elem;
sp_stack_remove(stack, 0, &elem);
/* do something with elem */
after the proposed change:
sometype_t elem;
elem = *(sometype_t*)sp_stack_get(stack, 0);
sp_stack_remove(stack, 0, &elem);
/* do something with elem */
I'm not so sure about this change yet -- it is a tradeoff in easiness of code writing. One advantage of the proposed approach is that it's harder to accidentally leak memory. The dereference-copy trick with sp_stack_get
is kind of nasty, but at least it's deliberate and requires an understanding of what's going on.
The C89 code relies on printing size_t
as unsigned long
, because a dedicated printf format specifier string wasn't introduced yet. This works with the assumption that size_t
fits in an unsigned long
, which is probably always true in C89. A compile-time assertion wouldn't hurt though.
Relevant discussion: https://stackoverflow.com/questions/47556181/is-it-safe-to-cast-size-t-to-unsigned-long-int
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.