I’d create another statement class, with its own Output function, for generating things like “fprint(fopen(placeholder1, placeholder2), placeholder3)”. The placeholder strings will be instantiated at generation time.
To increase the probability of a certain kind of statement, check Statement::InitProbabilityTable().
I plan to work on generating built-in functions with more flexible settings on this branch: https://github.com/csmith-project/csmith/tree/csmith-extendable
I am trying to adapt csmith to be able to generate some libc calls. As an example I will limit it to just fopen and fprintf. The kind of output I would like to achive is fprint(fopen("some string variable","w"),"random text") of arbitrary complexity, which preferably has a high probablity of not crashing on runtime.
I have managed to do this is by modifying bultin functions and abusing the csmith's type system. I've modified the initialize_builtin_functions() to include fprintf and fopen in the following way:
"Int; fprintf; (FILE,String5);
"FILE; fopen; (String5,Mode); x86",
FILE, String5 and Mode get translated into a special new category of types, for which constant initializers are defined and they can't be converted to any other type. For example Mode variables can only be "w" (for now). String5 is just a string of length5 and FILE can be either 0 or a result of fopen.
This essentially does what I want it to do, but it does feel very hacky. I haven't spent a huge amount of time looking at the rest of the code. I am wondering if there is already any preexisting code in csmith that would facilitate the overall goal in a better manner.
Also how would I increase the number of times builtin functions are called? I am currently running with these flags: --builtins --builtin-function-prob 100 --no-unions --max-expr-complexity 3 --no-arrays --max-funcs 50 --no-structs --no-pointers --no-comma-operators --no-embedded-assigns --no-compound-assignment, but I am still not happy with the density of bultin functions.