Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit 18b725327f786ef16383a57377b715e13296eb46 0 parents
@txus authored
4 .gitignore
@@ -0,0 +1,4 @@
+build
+*.o
+tests/*_tests
+tests/tests.log
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Josep M. Bach
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
57 Makefile
@@ -0,0 +1,57 @@
+CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
+LIBS=-ldl $(OPTLIBS)
+PREFIX?=/usr/local
+
+SOURCES=$(wildcard src/**/*.c src/*.c)
+OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
+
+TEST_SRC=$(wildcard tests/*_tests.c)
+TESTS=$(patsubst %.c,%,$(TEST_SRC))
+
+TARGET=build/libYOUR_LIBRARY.a
+SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
+
+# The Target Build
+all: $(TARGET) $(SO_TARGET) tests
+
+dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
+dev: all
+
+$(TARGET): CFLAGS += -fPIC
+$(TARGET): build $(OBJECTS)
+ ar rcs $@ $(OBJECTS)
+ ranlib $@
+
+$(SO_TARGET): $(TARGET) $(OBJECTS)
+ $(CC) -shared -o $@ $(OBJECTS)
+
+build:
+ @mkdir -p build
+ @mkdir -p bin
+
+# The Unit Tests
+.PHONY: tests
+tests: CFLAGS += $(TARGET)
+tests: $(TESTS)
+ sh ./tests/runtests.sh
+
+valgrind:
+ VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
+
+# The Cleaner
+clean:
+ rm -rf build $(OBJECTS) $(TESTS)
+ rm -f tests/tests.log
+ find . -name "*.gc*" -exec rm {} \;
+ rm -rf `find . -name "*.dSYM" -print`
+
+# The Install
+install: all
+ install -d $(DESTDIR)/$(PREFIX)/lib/
+ install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
+
+# The Checker
+BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
+check:
+ @echo Files with potentially dangerous functions.
+ @egrep $(BADFUNCS) $(SOURCES) || true
15 README.md
@@ -0,0 +1,15 @@
+# C project
+
+TODO: Write a project description
+
+## Usage
+
+TODO: Write usage instructions here
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Added some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
30 src/dbg.h
@@ -0,0 +1,30 @@
+#ifndef __dbg_h__
+#define __dbg_h__
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef NDEBUG
+#define debug(M, ...)
+#else
+#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
+#endif
+
+#define clean_errno() (errno == 0 ? "None" : strerror(errno))
+
+#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
+
+#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
+
+#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
+
+#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
+
+#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
+
+#define check_mem(A) check((A), "Out of memory.")
+
+#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
+
+#endif
43 src/lib.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <ctype.h>
+#include "dbg.h"
+
+int print_a_message(const char *msg)
+{
+ printf("A STRING: %s\n", msg);
+
+ return 0;
+}
+
+int uppercase(const char *msg)
+{
+ int i = 0;
+
+ // BUG: \0 termination problems
+ for(i = 0; msg[i] != '\0'; i++) {
+ printf("%c", toupper(msg[i]));
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+int lowercase(const char *msg)
+{
+ int i = 0;
+
+ // BUG: \0 termination problems
+ for(i = 0; msg[i] != '\0'; i++) {
+ printf("%c", tolower(msg[i]));
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+int fail_on_purpose(const char *msg)
+{
+ return 1;
+}
64 tests/lib_tests.c
@@ -0,0 +1,64 @@
+#include "minunit.h"
+#include <dlfcn.h>
+
+typedef int (*lib_function)(const char *data);
+char *lib_file = "build/libYOUR_LIBRARY.so";
+void *lib = NULL;
+
+int check_function(const char *func_to_run, const char *data, int expected)
+{
+ lib_function func = dlsym(lib, func_to_run);
+ check(func != NULL, "Did not find %s function in the library %s: %s", func_to_run, lib_file, dlerror());
+
+ int rc = func(data);
+ check(rc == expected, "Function %s return %d for data: %s", func_to_run, rc, data);
+
+ return 1;
+error:
+ return 0;
+}
+
+char *test_dlopen()
+{
+ lib = dlopen(lib_file, RTLD_NOW);
+ mu_assert(lib != NULL, "Failed to open the library to test.");
+
+ return NULL;
+}
+
+char *test_functions()
+{
+ mu_assert(check_function("print_a_message", "Hello", 0), "print_a_message failed.");
+ mu_assert(check_function("uppercase", "Hello", 0), "uppercase failed.");
+ mu_assert(check_function("lowercase", "Hello", 0), "lowercase failed.");
+
+ return NULL;
+}
+
+char *test_failures()
+{
+ mu_assert(check_function("fail_on_purpose", "Hello", 1), "fail_on_purpose should fail.");
+
+ return NULL;
+}
+
+char *test_dlclose()
+{
+ int rc = dlclose(lib);
+ mu_assert(rc == 0, "Failed to close lib.");
+
+ return NULL;
+}
+
+char *all_tests() {
+ mu_suite_start();
+
+ mu_run_test(test_dlopen);
+ mu_run_test(test_functions);
+ mu_run_test(test_failures);
+ mu_run_test(test_dlclose);
+
+ return NULL;
+}
+
+RUN_TESTS(all_tests);
31 tests/minunit.h
@@ -0,0 +1,31 @@
+#undef NDEBUG
+#ifndef _minunit_h
+#define _minunit_h
+
+#include <stdio.h>
+#include <dbg.h>
+#include <stdlib.h>
+
+#define mu_suite_start() char *message = NULL
+#define mu_assert(test, message) if (!(test)) { log_err(message); return message; }
+#define mu_run_test(test) debug("\n-----%s", " " #test); \
+ message = test(); tests_run++; if (message) return message;
+
+#define RUN_TESTS(name) int main(int argc, char *argv[]) {\
+ argc = 1; \
+ debug("----- RUNNING: %s", argv[0]);\
+ printf("----\nRUNNING: %s\n", argv[0]);\
+ char *result = name();\
+ if (result != 0) {\
+ printf("FAILED: %s\n", result);\
+ }\
+ else {\
+ printf("ALL TESTS PASSED\n");\
+ }\
+ printf("Tests run: %d\n", tests_run);\
+ exit(result != 0);\
+}
+
+int tests_run;
+
+#endif
19 tests/runtests.sh
@@ -0,0 +1,19 @@
+echo "Running unit tests:"
+
+for i in tests/*_tests
+do
+ if test -f $i
+ then
+ if $VALGRIND ./$i 2>> tests/tests.log
+ then
+ echo $i PASS
+ else
+ echo "ERROR in tests $i: here's tests/tests.log"
+ echo "------"
+ tail tests/tests.log
+ exit 1
+ fi
+ fi
+done
+
+echo ""
Please sign in to comment.
Something went wrong with that request. Please try again.