https://opensource.stackexchange.com/questions/10737/inclusi...
Do you have a scanner that checks these sorts of things or is it something that you are passionate about?
1. How silly to write such a thing in C from scratch. Such a project will invariably invent half of Lisp in order to have the right kind of infrastructure for doing this and that.
2. Let's look for some of it up and down the tree. Oh look, there is a bitset and hashmap, see? I don't see test cases for these anywhere; is it original work from this project or battle-tested code taken from elsewhere?
3. Open hashmap.c ...
GPL violation found in half a minute.
In this case there are is a custom string library. Functions returned owned heap-allocated strings.
However, I think there's a problem where static strings are used interchangably with heap-allocated strings, such as in the function `string class_simple_name(string full)` ( https://github.com/neocanable/garlic/blob/72357ddbcffdb75641... )
Sometimes it returns a static string like `g_str_int` and sometimes a newly heap-allocated string, such as returned by `class_type_array_name(g_str_int, depth)`.
Callers have no way to properly release the memory allocated by this function.
Of course literally running valgrind is still possible, but it is difficult to get useful information.
That's the beauty of the never free memory management strategy.
static bool is_java_identifier_start(char c)
{
return (isalpha(c) || c == '_' || c == '$');
}
Undefined behavior in isalpha if c happens to be negative (and not equal to EOF), like some UTF-8 byte.I think some <ctype.h> implementations are hardened against this issue, but not all.
At a basic level, you can create memory on the stack or on the heap. Obviously I will focus on the heap as that is dynamically allocating memory of a certain size.
The C programming language does not force you how to handle memory. You are pretty much on your own. For some C programmers (and likely more inexperienced ones) they will malloc individual variables like they are creating a 'new' instance in a typical OOP language like Java. This can be a telltale sign of a programmer working with C that comes from an OOP background. As they learn and improve on their C skills they realise they should create a chunk of memory of a certain type, but could still be malloc(ing) and free(ing) all over the code, making it difficult to understand what is being used and where -- especially if you are looking at code you did not write.
You can also have programs that do not bother free(ing) memory. For example, a simple shell program that just does simple input->process->output and terminates. For these types of programs, just let the OS deal with freeing the memory.
Good C code (in my opinion) uses malloc and free in only a handful of functions. There are higher level functions for proper Allocators. One example is an Arena Allocator. Then if you want a function which may require dynamic memory, you can tell it which allocator to use. It gives you control, generally speaking. You can create a simple string library or builder with an allocator.
Of course an Allocator does not have to use memory on the heap. It can still use on the stack as well.
There are various other patterns to use in the world of memory, especially in C.
I guess there's some history there that I'm not familiar with because JBoss also has a FernFlower decompiler library https://mvnrepository.com/artifact/org.jboss.windup.decompil...
Any plan to support `.dex` in the future? Also curious how you handle inner classes inside JARs.
It seems someone liked it and made a "v2" along with LSP support https://github.com/A-LPG/LPG2#lpg2
I was hoping that these days' Java would be "almost" as fast C/C++. Oh well.
$ ./objdir/garlic $the_jar_file -o out-dir -t $(nproc)
Progress : 85 (1024)Segmentation fault: 11
I want to hear about the reverse engineering, how you thought the code through. LLMs are boring.
Just write a blogpost at that point.
So "To some people the process leading to a finished project is the most interesting thing about posts like these." is bullshit, that is said by someone who has never used LLM properly. You can achieve it with LLMs. You definitely can, I know, I did, accurately (I double checked).
I will throw it out here, too: https://news.ycombinator.com/item?id=44163063 (My AI skeptic friends are all nuts)
That said, it is probably pointless to argue with full-blown AI-skeptics.
People had lots of great and productive-enhancing experiences with LLMs, you did not, great, that does not reflect the tool, it reflects your way of using the tool.
I will just throw it out here: https://news.ycombinator.com/item?id=44163063 (My AI skeptic friends are all nuts)
Additionally, "interesting" is highly subjective. It could be technically correct, yet uninteresting.
But stupid real-world analogies are stupid.
goto eject; ...more code we are going to ignore, it could be important but nah, ignore it, what could be happen?...
eject: up_through_the_roof();
:D
For example, if your structure contains a reference, and you read an instance of that from disk, then you now have a potentially invalid reference, bypassing Rust's guarantees. Reading a structure of i32 numbers is safe, but it also has endianness footguns.
The zerocopy crate implements traits and gives you a derive macro to mark types as being safe to serialize/deserialize in a safe way.
If someone mentions C, that's not a free invite to start educating them on why they SHOULD use Rust. No one at the party is going to talk to you again that night
And, yes, I know it's trivial to interface the Python C-API with C++ and quite often better as the 'object model' is very similar but the underlying concept I wanted to explore (guaranteed tailcalls) isn't possible in C++ from what I can tell.