Running automated tests on several C files - c

I have several files in the structure
/algorithms
/a1
a1.c
/a2
a2.c
/a3
a3.c
Each of these files contains a function of the same name. Each has the same signature, except for the name (which is the same as the filename). Essentially, each algorithm is a different implementation of the same thing -- different means to the same end. There may however be small helper functions.
The content of the files (comments, functions, layout, etc) cannot change.
I want to create some method that will test each algorithm. This method is not confined to being implemented in C.
I have a C file that essentially contains three functions:
// Runs the algorithm, which modifies the given integer array.
void run(void (*algorithm) (int*, size_t));
// Checks that the algorithm successfully completed and
// the array is correct.
int check(int*, size_t);
// Should call run() with appropriate algorithm and a random data set
// and then call check() to make sure it worked.
int main(int, char**);
I need an automated way of including the appropriate files and then calling
the function within them. Currently, I have a bash file that gets all the algorithms, copies the tester file, prepends an #include statement at the beginning and a generated injected_main() function that gets called by the actual main() function. It runs the copied tester and then deletes it.
function testC() {
local tempout=temptest.c
local filename="$(basename -- $1)"
local functionname="${filename%.*}"
local main="void injectedMain() {test(&$functionname);}"
local include="#include\"$1\"\n$main"
touch $tempout
chmod +x $tempout
printf "$filename: "
cp $TESTER_C $tempout
printf "$include" >> $tempout
gcc $tempout -o tempout -Wall -Wextra -pedantic
./tempout
rm $tempout tempout
}
Where the function is run in a loop for every algorithm C file.
However, this method is prone to error, not extendable, and just downright ugly. Is there a better way to do this?

Combine your existing code and #Herve's answer.
You could let the bash script just collect all algorithms and build a C source like that proposed by #Herve. This way there will be no error prone manual step.
To run all tests compile this automatically generated source and link it to your test runner. Let the latter loop through all.

Can't you just a header including your algorithm implementations and loop through all of them?
Something like
#include "a1/a1.h"
#include "a2/a2.h"
#include "a3/a3.h"
typedef void (*AlgorithmImplemetation)(void); //Your algorithm function signature goes here
AlgorithmImplemetation *all = {
a1,
a2,
a3
};
Then include this header in your main.c and loop through all.

Related

Is it possible to compile multiple dependent C files, without creating header file?

I am having some issues with putting multiple .c files together.
I will mimic my situation with the following files.
mod.c
#include <stdio.h>
void print_hello() {
printf("Hello!");
}
mod_main.c
#include "mod.c"
int main() {
print_hello();
}
Compiling scenarios:
#1
$ cc -o mod_main mod_main.c
# No errors
#2
$ cc -c -o mod_main.o mod_main.c
$ cc -c -o mod.o mod.c
$ cc -o mod_main mod.o mod_main.o
duplicate symbol '_print_hello' in:
mod.o
mod_main.o
ld: 1 duplicate symbol for architecture x86_64
#3
$ cc -o mod_main mod.c mod_main.c
duplicate symbol '_print_hello' in:
Based on these attempts, I gather that, I can compile simply mod_main.c & get it working. Or, I can create a .h file as follows & get it working.
mod.h
void print_hello(void);
mod.c
#include <stdio.h>
#include "mod.h"
void print_hello() {
printf("Hello!");
}
mod_main.c
#include "mod.h"
int main() {
print_hello();
}
I like to know, if there are any other ways to compile multiple C files that has dependencies within each other. To be precise, is there a decent way to avoid writing header files?
Good day!
PS: I have explored similar questions on StackOverflow. None of them that I could find where asking the exact questions as mine.
First of all, including source files is generally a bad idea.
As for the problem itself, you can easily solve it by pretending you're writing a header file, but instead write all declarations, structure definitions and macros in a source file. Then copy-paste it into the other source files who needs it.
But, and this is a very important but, this is extremely error-prone. If the signature (e.g. argument list) of a function changes, or a structure is modified, or a macro gets a different value, then you must remember to modify this everywhere. If you have more than a couple of source files it becomes easy to miss one of the files.
If a function with the wrong signature is called, or you have structures that are not character-by-character copies of each other, then that will lead to undefined behavior. Mismatching macros might not be so serious, but if it's an array-limit that is changed (for example) then it's easy to go out of bounds where you miss to update the macro.
In short: It's possible, but not a good idea. Use one or more header files for common declarations, structures and macros.

Using Go code in an existing C project

Ever since Go 1.5 came out, I started taking another look at how I could integrate it into an existing project of mine.
The project's codebase is written entirely in C for low level access to to hardware and other fun stuff. However, some of the higher level things are tedious, and I would like to start writing them in a higher level language (Go)
Is there any way I can call Go code from a C program? I installed Go 1.5, which added -buildmode=c-archive (https://golang.org/s/execmodes) which I am trying to get working.
However, I can't seem to get Go to generate the appropriate header files to allow my project to actually compile. When I generate the archive, I see the function in the exported symbols (using objdump), but without the header files to include gcc complains about the function not existing (as expected)
I'm quite new to Go - however, I love the language and would like to make use of it. Is there any idiomatic way ("idiomatic" gets used a lot in the world of Go I see...) to get this to play nicely with each other?
The reason I asked this question and specifically mentioned Go 1.5 is that according to this document, https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcoke
Go 1.5 added support for non-Go programs to call Go code. Specifically, mentioned under the section "Go code linked into, and called from, a non-Go program"
To build an archive callable from C, you will need to mark them as exported CGo symbols.
For example, if I create a file foo.go with the following contents:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x int) {
fmt.Println(x)
}
func main() {}
The important things to note are:
The package needs to be called main
You need to have a main function, although it can be empty.
You need to import the package C
You need special //export comments to mark the functions you want callable from C.
I can compile it as a C callable static library with the following command:
go build -buildmode=c-archive foo.go
The results will be an archive foo.a and a header foo.h. In the header, we get the following (eliding irrelevant parts):
...
typedef long long GoInt64;
...
typedef GoInt64 GoInt;
...
extern void PrintInt(GoInt p0);
...
So that's enough to call the exported function. We can write a simple C program that calls it like so:
#include "foo.h"
int main(int argc, char **argv) {
PrintInt(42);
return 0;
}
We can compile it with a command like:
gcc -pthread foo.c foo.a -o foo
The -pthread option is needed because the Go runtime makes use of threads. When I run the resulting executable it prints 42.
The code above work just fine, but gcc will complain about functions and headers.
The includes should be:
#define _GNU_SOURCE
#include <stdio.h>
#include "mygopkg.h"
If you forget the #define _GNU_SOURCE, the gcc will complain:
warning: implicit declaration of function 'asprintf'; did you mean 'vsprintf'? [-Wimplicit-function-declaration]
If you forget the #include "mygopkg.h", the gcc will complain:
warning: implicit declaration of function 'PrintString' [-Wimplicit-function-declaration]
The last but not less important. The build command line I recommend for production code is:
go build -ldflags "-s -w" -buildmode c-archive -o mygopkg.a
It'll save you 53% size of final mygopkg.a.

Create a MATLAB MEX file for a C program

I'm an experienced MATLAB user but totally new to C and MEX files. I have a complex program written in C that I need to call from within MATLAB. The program consists of a few dozen files in a folder, including one called main.c that processes inputs from the command line passes the results to other classes that do the actual calculations.
Normally, to install this program from the command line, I would run ./configure, make at the UNIX command prompt. Then, to run the program, ./runMyProgram -f input_file.txt -p some_parameters. The program takes a text file consisting of a list of numbers as input and prints a table of results in the command window. I want to feed the program a MATLAB array (instead of a .txt file) and get back an array (instead of a printed table of results).
I have read the MEX documentation from The Mathworks (which I found rather opaque), as well as some other "tutorials", but I am totally lost - the examples are for very simple, single-file C programs and don't really discuss how to handle a larger and more complicated program. Is it enough to replace the main.c file with a MEX file that does the same things? Also, how do I compile the whole package within MATLAB?
I would be grateful for any plain-English advice on where to start with this, or pointers to any tutorials that deal with the subject in a comprehensible way.
Yes. Normally replacing a main.c file with MEX file is the process. In your case since you already have complex build setup, it might be easier to build a library and then build a separate mex file which just links against this library. This will be much easier than building the whole thing using mex command. If you export the function you need to call from your library, you can call it from your mexFunction. mexFunction can do all the creation and reading of mxArrays. A simple sample mexFunction can be,
#include "mex.h"
// Include headers for your library
void
mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
void* x = mxGetData(prhs[0]); // Assume one input. Check nrhs
plhs[0] = mxCreateDoubleMatrix(10,10,mxREAL); // Create 10x10 double matrix for output
void* y = mxGetData(plhs[0]);
yourLibraryFunction(x, y); // Read from x and write to y. Pass sizes in if needed
}

unused functions detection utility for c

I am trying to measure my code coverage utilization on a C project consist of several libraries, and main program.
Is there a utility that can help me find which function I dont use from both libraries and main program.
I want to build list of functions (public functions) that are not used by my main program, in order to ignore them in my code coverage report.
If you are using gcc you compile your code with option:
-Wunused-function
Warn whenever a static function is declared but not defined or a non-inline static function is unused. This warning is enabled by -Wall.
cflow can create a call graph for the program, but it doesn't work well with pointers to functions in some cases.
for eaxample:
#include <stdio.h>
static int f1(){
return 1;
}
int (*p_f1)() = f1;
int main() {
p_f1();
return 0;
}
There are coverage tools available for free - for example "gcov" that runs on go with the gcc tool suite. However, Code Coverage only tells you which functions get hit by your testing (or whatever you do to excercise the code), so for example
ptr = malloc(...);
if (!ptr)
{
allocation_failed(__FILE__, __LINE__);
}
would only show that allocation_failed is called if you are also using some tool that makes your allocations fail from time to time.
I'm not aware of a tool that will show you what functions are not used across larger systems (with multiple libraries, etc). I expect you could make something by using the output of "nm" and a bit of "pulling things in". It won't cover foo and bar as unusued in this case:
unit1.c:
extern int foo(void);
int bar()
{
return foo();
}
unit2.c:
int foo(void)
{
return 42;
}
int baz(void)
{
return bar();
}
and then baz isn't used anywhere. But if you remove baz, it will show that bar is not called, and then you can remove foo after that...
Edit: Crazy idea time - how about taking every C file in the project and just concatenating the whole thing into a a single .C file, then add static at the beginning of every function, and compiling with -Wunused-functon - I'm sure there will be some "interesting" effects from this if your code isn't extremely well written, but it may be worth a try [it would be fairly easy to do this in a Linux system, something like find . -name "*.c" -print | xargs cat {} > giantsource.c - you then need a little bit of sed or something to label all functions static, which I'm not quite sure how you'd go about doing - it depends very much on the formatting of your code.
You may want to have a look at this:
http://www.gedanken.demon.co.uk/cxref/
I haven't used it, but any decent cross referencing tool should be able to identify anything that is "not used" as not having any references. Of course, you'll probably still have to run over the code severa times to weed out the functions that are used by functions that aren't being called, etc.
cflow has an option to build a cross-reference table: --xref
The format of the output is described by GNU cflow: Cross-Reference
GNU cflow is also able to produce cross-reference listings. This mode is enabled by --xref (-x) command line option. Cross-reference output lists each symbol occurrence on a separate line. Each line shows the identifier and the source location where it appears. If this location is where the symbol is defined, it is additionally marked with an asterisk and followed by the definition. For example, here is a fragment of a cross-reference output for d.c program:
printdir * d.c:42 void printdir (int level,char *name)
printdir d.c:74
printdir d.c:102
It shows that the function printdir is defined in line 42 and referenced twice, in lines 74 and 102.
To detect unused functions, search the line with a star not followed by a line with the same prefix. The following GNU Awk code print the unused functions:
{
if( $2 == "*" ) {
if( f ) {
print f
}
f = $1
}
else {
f = ""
}
}
The command may be:
cflow -x src/*.c src-gen/*.c | awk -f find-unused-functions.awk

Calling methods from multiple C files without custom header files, Makefile Linking

This has gotten a bit lost in translation so I am going to be more precise:
we have classes recursion.c, fib.c, and countUp.c. from recursion.c we have to recursively call fib.c or countUp.c, decided by the input argument. I can't use header files and am only given that I must place prototypes:
int fib(int n);
and
void countUp(int n);
My Makefile
TAR = tar
COMPILER_FLAGS = -g -Wall -std=c99 -c
LINKER_FLAGS = -g -o
OBJS = recurse.o
C_FILES = recurse.c fib.c countUp.c
ASM_FILES = recurse.asm
TARGET_FILE = recurse
TARGET_TAR = PA5.tar
$(TARGET_TAR): $(TARGET_FILE)
$(TAR) -cvf $(TARGET_TAR) $(C_FILES) $(ASM_FILES) $(TARGET_FILE) Makefi$
recurse.o: recurse.c
$(C_COMPILER) $(COMPILER_FLAGS) $(C_FILES)
$(TARGET_FILE): $(OBJS)
$(LD_LINKER) $(LINKER_FLAGS) $(TARGET_FILE) $(OBJS)
where fib and countUp class methods must be called recursively. The recursive.c file is considered our c driver. Do not create or implement any header files OTHER than those that are standard c headers (stdio.h, string.h, etc.). When I try to run this I get:
make
gcc -g -o recurse recurse.o
recurse.o: In function `main':
(file root location)/recurse.c:43: undefined reference to `fib'
(file root location)/recurse.c:46: undefined reference to `countUp'
collect2: ld returned 1 exit status
make: *** [recurse] Error 1
Any clue what is going on.
Original Question:
I have multiple C files that I am combining into an executable. For example say I have math.c, the arguments are passed into it, and then if the input argument calls add it performs functions from add.c, if the argument calls subtract it will call functions from subtract.c, etc. The files are then compiled into a .o file, and then an executable is created. The issue I have is not being able to utilize header (.h) files. Is there any way to break into the separate classes or am I missing something? I really don't know exactly how to ask the question, jargon is pretty bad as far as C goes, sorry :(
I don't really get the idea of a driver I guess. (Not a device driver, she keeps telling us this is a c executable driver).
If I understood correctly, what I think you need to do is add the following prototypes above any of the functions you define in recursion.c. The prototypes will allow you to call these functions from within any function inside recursion.c (In fact, including a header file is akin to copy-pasting all of the prototypes defined in the file, as #Justin and #EdS already pointed out)
int fib(int n);
void countUp(int n);
int main() {
...
}
Then you need to make sure that your project file includes the files recursion.c, fib.c, and countUp.c - When you build your project, the linker will do its job and lookup the entry points in your compiled object files, and will proceed to assemble a single executable file.
What compiler are you using?
Including a header file is just a preprocessor directive to include the contents of that file at the location of the include. To achieve the same thing without a header file just copy and paste the code that you would have put in the header file into the top of each c file.
Of course this isn't very maintainable as if you want to change that contents you need to change it in many files, hence why header files exist in the first place.
Since this is homework and considering the fact that you have told us that A) You have no header files to use, and B) you have not been instructed to utilize the extern keyword, it seems to me that your only choice is to include the .c files themselves:
#include "add.c"
#include "subtract.c"
/* etc... */
int main()
{
// use functions defined in "add.c", "subtract.c", etc.
}
Note that this is bad form as you are including the implementation instead of the interface and likely pulling in a bunch of stuff you don't want or need. If that doesn't answer your question then there is something, some instruction from your teacher, missing in the question.

Resources