diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/private/.tmcignore b/private/.tmcignore
new file mode 100644
index 0000000..e69de29
diff --git a/private/template_project/Makefile b/private/template_project/Makefile
new file mode 100644
index 0000000..570c07d
--- /dev/null
+++ b/private/template_project/Makefile
@@ -0,0 +1,22 @@
+MAIN_DIR = src
+TEST_DIR = test
+
+.PHONY: main test
+
+all: main test
+
+main:
+ $(MAKE) -C $(MAIN_DIR)
+
+test:
+ $(MAKE) -C $(TEST_DIR)
+
+clean:
+ $(MAKE) -C $(MAIN_DIR) clean
+ $(MAKE) -C $(TEST_DIR) clean
+
+run-main:
+ $(MAKE) -C $(MAIN_DIR) run
+
+run-test:
+ $(MAKE) -C $(TEST_DIR) run
diff --git a/private/template_project/nbproject/Package-Default.bash b/private/template_project/nbproject/Package-Default.bash
new file mode 100644
index 0000000..0d70205
--- /dev/null
+++ b/private/template_project/nbproject/Package-Default.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-MacOSX
+CND_CONF=Default
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=MissingOutputInProject
+OUTPUT_BASENAME=MissingOutputInProject
+PACKAGE_TOP_DIR=setready-AES/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/setready-AES"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/setready-AES.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/setready-AES.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/private/template_project/nbproject/configurations.xml b/private/template_project/nbproject/configurations.xml
new file mode 100644
index 0000000..26cce7f
--- /dev/null
+++ b/private/template_project/nbproject/configurations.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+ main.c
+
+
+ tmc-check.c
+ tmc-check.h
+
+
+
+ Makefile
+
+
+ ^(nbproject)$
+
+ .
+
+ Makefile
+
+
+
+ LOCAL_SOURCES
+ default
+
+
+
+
+
+ .
+ ${MAKE} -f Makefile
+ ${MAKE} -f Makefile clean
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
diff --git a/private/template_project/nbproject/private/Default.properties b/private/template_project/nbproject/private/Default.properties
new file mode 100644
index 0000000..e69de29
diff --git a/private/template_project/nbproject/private/configurations.xml b/private/template_project/nbproject/private/configurations.xml
new file mode 100644
index 0000000..736456b
--- /dev/null
+++ b/private/template_project/nbproject/private/configurations.xml
@@ -0,0 +1,39 @@
+
+
+ Makefile
+
+
+
+ localhost
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ gdb
+
+
+
+ "${OUTPUT_PATH}"
+
+ "${OUTPUT_PATH}"
+ .
+ true
+ 0
+ 0
+
+
+
+
+
+
diff --git a/private/template_project/nbproject/private/private.xml b/private/template_project/nbproject/private/private.xml
new file mode 100644
index 0000000..1c50948
--- /dev/null
+++ b/private/template_project/nbproject/private/private.xml
@@ -0,0 +1,11 @@
+
+
+
+ true
+
+
+ 0
+ 0
+
+
+
diff --git a/private/template_project/nbproject/project.xml b/private/template_project/nbproject/project.xml
new file mode 100644
index 0000000..a9c4bed
--- /dev/null
+++ b/private/template_project/nbproject/project.xml
@@ -0,0 +1,23 @@
+
+
+ org.netbeans.modules.cnd.makeproject
+
+
+ template_project
+ c
+
+ h
+ UTF-8
+
+
+ .
+
+
+
+ Default
+ 0
+
+
+
+
+
diff --git a/private/template_project/src/Makefile b/private/template_project/src/Makefile
new file mode 100644
index 0000000..05a27b6
--- /dev/null
+++ b/private/template_project/src/Makefile
@@ -0,0 +1,13 @@
+SRC_FILES=main.c
+
+all: main
+
+main: $(SRC_FILES)
+ gcc -Wall -o $@ $(SRC_FILES)
+
+clean:
+ rm -f main
+
+run: main
+ # Running our main function from file main.c
+ ./main
diff --git a/private/template_project/src/main.c b/private/template_project/src/main.c
new file mode 100644
index 0000000..1662620
--- /dev/null
+++ b/private/template_project/src/main.c
@@ -0,0 +1,6 @@
+#include
+
+int main( int argc, const char* argv[] )
+{
+ printf( "\nHello World\n" );
+}
\ No newline at end of file
diff --git a/private/template_project/test/Makefile b/private/template_project/test/Makefile
new file mode 100644
index 0000000..e36e266
--- /dev/null
+++ b/private/template_project/test/Makefile
@@ -0,0 +1,17 @@
+CHECK_CFLAGS=$(shell pkg-config --cflags check)
+CHECK_LDFLAGS=$(shell pkg-config --libs check)
+SRC_FILES=tmc-check.c
+
+all: test
+
+test: $(SRC_FILES)
+ gcc $(CHECK_CFLAGS) -Wall -o $@ $(SRC_FILES) $(CHECK_LDFLAGS)
+
+clean:
+ # rm -f test tmc_available_points.txt tmc_test_results.xml valgrind.log
+
+run: test
+ # Printing available points
+ ./test --print-available-points
+ # Running test. There should be one success and one failure.
+ ./test
diff --git a/private/template_project/test/tmc-check.c b/private/template_project/test/tmc-check.c
new file mode 100644
index 0000000..1bc0b37
--- /dev/null
+++ b/private/template_project/test/tmc-check.c
@@ -0,0 +1,233 @@
+
+#include "tmc-check.h"
+#include
+#include
+#include
+#include
+
+typedef struct SuitePoints
+{
+ Suite *s;
+ const char *s_name;
+ const char *points;
+ struct SuitePoints *next;
+} SuitePoints;
+
+typedef struct PointsAssoc
+{
+ TCase *tc;
+ const char *tc_name;
+ const char *points;
+ struct PointsAssoc *next;
+} PointsAssoc;
+
+typedef struct PointsList
+{
+ char *point;
+ struct PointsList *next;
+} PointsList;
+
+typedef struct MemTest
+{
+ const char *tf_name;
+ int check_leaks;
+ int max_bytes_allocated; // Value -1 will represent no max_alloc check
+ struct MemTest *next;
+} MemTest;
+
+static PointsAssoc *points_assocs = NULL;
+static SuitePoints *suite_points = NULL;
+static PointsList *all_points = NULL;
+static MemTest *memtests = NULL;
+
+static void parse_points(const char *points, PointsList **target_list);
+static void add_to_point_set(const char *point, ssize_t len, PointsList **target_list);
+static int points_list_contains(const PointsList *list, const char *point, ssize_t len);
+
+void _tmc_register_memtest(const char *tf_name, int check_leaks, int max_bytes_allocated)
+{
+ MemTest *memtest = malloc(sizeof(MemTest));
+ memtest->tf_name = tf_name;
+ memtest->check_leaks = check_leaks;
+ memtest->max_bytes_allocated = max_bytes_allocated;
+
+ memtest->next = memtests;
+ memtests = memtest;
+}
+
+void tmc_set_tcase_points(TCase *tc, const char *tc_name, const char *points)
+{
+ PointsAssoc *pa = (PointsAssoc*)malloc(sizeof(PointsAssoc));
+ pa->tc = tc;
+ pa->tc_name = tc_name;
+ pa->points = points;
+ pa->next = points_assocs;
+ points_assocs = pa;
+
+ parse_points(points, &all_points);
+}
+
+void _tmc_register_test(Suite *s, TFun tf, const char *fname, const char *points)
+{
+ TCase *tc = tcase_create(fname);
+ tmc_set_tcase_points(tc, fname, points);
+ _tcase_add_test(tc, tf, fname, 0, 0, 0, 1);
+ suite_add_tcase(s, tc);
+}
+
+void tmc_set_suite_points(Suite *s, const char *s_name, const char *points)
+{
+ SuitePoints *sp = (SuitePoints*) malloc(sizeof(SuitePoints));
+ sp->s = s;
+ sp->points = points;
+ sp->s_name = s_name;
+ sp->next = suite_points;
+ suite_points = sp;
+
+ parse_points(points, &all_points);
+}
+
+Suite* tmc_suite_create(const char *name, const char *points)
+{
+ Suite *s = suite_create(name);
+ tmc_set_suite_points(s, name, points);
+ return s;
+}
+
+int tmc_run_tests(int argc, const char **argv, Suite *s)
+{
+ int i;
+ for (i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "--print-available-points") == 0) {
+ return tmc_print_available_points(stdout, '\n');
+ }
+
+ if (strcmp(argv[i], "--print-memory-tests") == 0) {
+ return tmc_print_memory_tests(stdout, ' ', '\n');
+ }
+ }
+
+ FILE *points_file = fopen("tmc_available_points.txt", "wb");
+ FILE *memtest_file = fopen("tmc_memory_test_info.txt", "wb");
+ if (tmc_print_suite_points(points_file) != 0) {
+ fclose(points_file);
+ return EXIT_FAILURE;
+ }
+ if (tmc_print_test_points(points_file) != 0) {
+ fclose(points_file);
+ return EXIT_FAILURE;
+ }
+ if (tmc_print_memory_tests(memtest_file, ' ', '\n') != 0) {
+ fclose(memtest_file);
+ return EXIT_FAILURE;
+ }
+ fclose(points_file);
+ fclose(memtest_file);
+
+ SRunner *sr = srunner_create(s);
+ srunner_set_xml(sr, "tmc_test_results.xml");
+ srunner_run_all(sr, CK_VERBOSE);
+ srunner_free(sr);
+
+ return EXIT_SUCCESS;
+}
+
+int tmc_print_available_points(FILE *f, char delimiter)
+{
+ const PointsList *pl = all_points;
+ while (pl != NULL) {
+ fputs(pl->point, f);
+ fputc(delimiter, f);
+ pl = pl->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+int tmc_print_memory_tests(FILE *f, char attr_delimiter, char line_delimiter)
+{
+ const MemTest *mt = memtests;
+ while (mt != NULL) {
+ fputs(mt->tf_name, f);
+ fputc(attr_delimiter, f);
+ fprintf(f, "%d", mt->check_leaks);
+ fputc(attr_delimiter, f);
+ fprintf(f, "%d", mt->max_bytes_allocated);
+ fputc(line_delimiter, f);
+ mt = mt->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+int tmc_print_test_points(FILE *f)
+{
+ const PointsAssoc *pa = points_assocs;
+ while (pa != NULL) {
+ fprintf(f, "[test] %s %s\n", pa->tc_name, pa->points);
+ pa = pa->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+int tmc_print_suite_points(FILE *f)
+{
+ const SuitePoints *sp = suite_points;
+ while (sp != NULL) {
+ fprintf(f, "[suite] %s %s\n", sp->s_name, sp->points);
+ sp = sp->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+static void parse_points(const char *points, PointsList **target_list)
+{
+ const char *p = points;
+ const char *q = p;
+ while (*q != '\0') {
+ if (isspace(*q)) {
+ const ssize_t len = q - p;
+
+ if (!isspace(*p)) {
+ add_to_point_set(p, len, target_list);
+ }
+
+ p = q + 1;
+ q = p;
+ } else {
+ q++;
+ }
+ }
+
+ if (!isspace(*p) && q > p) {
+ const ssize_t len = q - p;
+ add_to_point_set(p, len, target_list);
+ }
+}
+
+static void add_to_point_set(const char *point, ssize_t len, PointsList **target_list)
+{
+ if (!points_list_contains(*target_list, point, len)) {
+ PointsList *pl = (PointsList*)malloc(sizeof(PointsList));
+ pl->point = malloc(len + 1);
+ memcpy(pl->point, point, len);
+ pl->point[len] = '\0';
+ pl->next = *target_list;
+ *target_list = pl;
+ }
+}
+
+static int points_list_contains(const PointsList *list, const char *point, ssize_t len)
+{
+ const PointsList *pl = all_points;
+ while (pl != NULL) {
+ if (strncmp(pl->point, point, len) == 0) {
+ return 1;
+ }
+ pl = pl->next;
+ }
+ return 0;
+}
+
diff --git a/private/template_project/test/tmc-check.h b/private/template_project/test/tmc-check.h
new file mode 100644
index 0000000..8100cbb
--- /dev/null
+++ b/private/template_project/test/tmc-check.h
@@ -0,0 +1,58 @@
+
+#include
+#include
+
+/***** Main API *****/
+
+/** A shorthand to make one test suite with the given points */
+Suite* tmc_suite_create(const char *name, const char *points);
+
+/** A shorthand to make a one function testcase with the given points into a suite. */
+#define tmc_register_test(suite, tf, points) _tmc_register_test((suite), (tf), "" # tf, points)
+void _tmc_register_test(Suite *s, TFun tf, const char *fname, const char *points);
+
+/** A shorthand to make one memory test for a test function with given parameters */
+#define tmc_register_memtest(tf, check_leaks, max_bytes_allocated) _tmc_register_memtest("" # tf, check_leaks, max_bytes_allocated)
+void _tmc_register_memtest(const char *tf_name, int chek_leaks, int max_bytes_allocated);
+
+/** A shorthand for registering a test with memtest at the same time */
+#define tmc_register_test_with_memtest(suite, tf, points, check_leaks, max_bytes_allocated) tmc_register_test(suite, tf, points); tmc_register_memtest(tf, check_leaks, max_bytes_allocated)
+
+/**
+ * Runs a test suite so that tmc_test_results.xml and tmc_test_points.txt are created.
+ *
+ * To be called from main() after creating the Suite.
+ *
+ * If --print-available-points is given, it only outputs all available points
+ * (in an undefined order) to stdout and exits.
+ *
+ * Returns an error code that can be returned from main.
+ * Normally this will be 0 even if test fail.
+ */
+int tmc_run_tests(int argc, const char **argv, Suite *s);
+
+
+/***** Low-level API *****/
+
+/**
+ * Set the points of a test case.
+ *
+ * This is a lower level alternative to using tmc_register_test.
+ */
+void tmc_set_tcase_points(TCase *tc, const char *tc_name, const char *points);
+
+/**
+ * Set the points of a test suite
+ *
+ * This is a lower level alternative to using tmc_suite_create.
+ */
+void tmc_set_suite_points (Suite *s, const char *s_name, const char *points);
+
+/** Prints all registered points once (in no particular order) to the given file. */
+int tmc_print_available_points(FILE *f, char delimiter);
+int tmc_print_memory_tests(FILE *f, char attr_delimiter, char line_delimiter);
+
+/** Prints lines like "[test] testname pointname1 pointname2" to the given file. */
+int tmc_print_test_points(FILE *f);
+/** Prints lines with "[suite] suitename pointname1 pointname2" to given file */
+int tmc_print_suite_points(FILE *f);
\ No newline at end of file
diff --git a/scripts/create-project b/scripts/create-project
new file mode 100755
index 0000000..d681496
--- /dev/null
+++ b/scripts/create-project
@@ -0,0 +1,45 @@
+#!/usr/bin/env ruby
+require 'fileutils'
+
+include FileUtils
+cd File.dirname(File.dirname(__FILE__))
+
+if !ARGV[0] || ['-h', '--help'].include?(ARGV[0])
+ puts"Creates a new project from the project template."
+ puts
+ puts "Usage: #{__FILE__} [category/]project-name"
+ puts
+ exit 0
+end
+
+def gsub_in_file!(filename, search, replacement)
+ text = File.read(filename)
+ text.gsub!(search, replacement)
+ File.open(filename, 'wb') {|f| f.write(text) }
+end
+
+
+dest_path = ARGV[0]
+
+dest_category = dest_path.split('/').reverse.drop(1).reverse.join('/')
+dest_name = dest_path.split('/').last
+
+template_name = 'template_project'
+template_path = "private/#{template_name}"
+
+puts "Copying from #{template_path} to #{dest_path}"
+mkdir_p dest_category unless dest_category.empty?
+cp_r template_path, dest_path
+
+puts "Replacing occurrences of #{template_name} with #{dest_name}"
+files_with_project_name = [
+ 'nbproject/project.xml'
+]
+for file in files_with_project_name
+ puts " in #{dest_path}/#{file}"
+ gsub_in_file!("#{dest_path}/#{file}", template_name, dest_name)
+end
+
+puts
+puts "Done!"
+puts
diff --git a/viikko1/demoTehtava/Makefile b/viikko1/demoTehtava/Makefile
new file mode 100644
index 0000000..ed79bd8
--- /dev/null
+++ b/viikko1/demoTehtava/Makefile
@@ -0,0 +1,25 @@
+MAIN_DIR = src
+TEST_DIR = test
+
+.PHONY: main test
+
+all: main test
+
+main:
+ $(MAKE) -C $(MAIN_DIR)
+
+test:
+ $(MAKE) -C $(TEST_DIR)
+
+clean:
+ $(MAKE) -C $(MAIN_DIR) clean
+ $(MAKE) -C $(TEST_DIR) clean
+
+get-points:
+ $(MAKE) -C $(TEST_DIR) get-points
+
+run-main:
+ $(MAKE) -C $(MAIN_DIR) run
+
+run-test:
+ $(MAKE) -C $(TEST_DIR) run
diff --git a/viikko1/demoTehtava/nbproject/Package-Default.bash b/viikko1/demoTehtava/nbproject/Package-Default.bash
new file mode 100644
index 0000000..0d70205
--- /dev/null
+++ b/viikko1/demoTehtava/nbproject/Package-Default.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-MacOSX
+CND_CONF=Default
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=MissingOutputInProject
+OUTPUT_BASENAME=MissingOutputInProject
+PACKAGE_TOP_DIR=setready-AES/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/setready-AES"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/setready-AES.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/setready-AES.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/viikko1/demoTehtava/nbproject/configurations.xml b/viikko1/demoTehtava/nbproject/configurations.xml
new file mode 100644
index 0000000..26cce7f
--- /dev/null
+++ b/viikko1/demoTehtava/nbproject/configurations.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+ main.c
+
+
+ tmc-check.c
+ tmc-check.h
+
+
+
+ Makefile
+
+
+ ^(nbproject)$
+
+ .
+
+ Makefile
+
+
+
+ LOCAL_SOURCES
+ default
+
+
+
+
+
+ .
+ ${MAKE} -f Makefile
+ ${MAKE} -f Makefile clean
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
diff --git a/viikko1/demoTehtava/nbproject/private/Default.properties b/viikko1/demoTehtava/nbproject/private/Default.properties
new file mode 100644
index 0000000..e69de29
diff --git a/viikko1/demoTehtava/nbproject/private/configurations.xml b/viikko1/demoTehtava/nbproject/private/configurations.xml
new file mode 100644
index 0000000..736456b
--- /dev/null
+++ b/viikko1/demoTehtava/nbproject/private/configurations.xml
@@ -0,0 +1,39 @@
+
+
+ Makefile
+
+
+
+ localhost
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ gdb
+
+
+
+ "${OUTPUT_PATH}"
+
+ "${OUTPUT_PATH}"
+ .
+ true
+ 0
+ 0
+
+
+
+
+
+
diff --git a/viikko1/demoTehtava/nbproject/private/private.xml b/viikko1/demoTehtava/nbproject/private/private.xml
new file mode 100644
index 0000000..1c50948
--- /dev/null
+++ b/viikko1/demoTehtava/nbproject/private/private.xml
@@ -0,0 +1,11 @@
+
+
+
+ true
+
+
+ 0
+ 0
+
+
+
diff --git a/viikko1/demoTehtava/nbproject/project.xml b/viikko1/demoTehtava/nbproject/project.xml
new file mode 100644
index 0000000..a6ea3e9
--- /dev/null
+++ b/viikko1/demoTehtava/nbproject/project.xml
@@ -0,0 +1,23 @@
+
+
+ org.netbeans.modules.cnd.makeproject
+
+
+ demoTehtava
+ c
+
+ h
+ UTF-8
+
+
+ .
+
+
+
+ Default
+ 0
+
+
+
+
+
diff --git a/viikko1/demoTehtava/src/Makefile b/viikko1/demoTehtava/src/Makefile
new file mode 100644
index 0000000..5247a67
--- /dev/null
+++ b/viikko1/demoTehtava/src/Makefile
@@ -0,0 +1,13 @@
+SRC_FILES=main.c tested.c
+
+all: main
+
+main: $(SRC_FILES)
+ gcc -Wall -o $@ $(SRC_FILES)
+
+clean:
+ rm -f main
+
+run: main
+ # Running our main function from file main.c
+ ./main
diff --git a/viikko1/demoTehtava/src/main.c b/viikko1/demoTehtava/src/main.c
new file mode 100644
index 0000000..1662620
--- /dev/null
+++ b/viikko1/demoTehtava/src/main.c
@@ -0,0 +1,6 @@
+#include
+
+int main( int argc, const char* argv[] )
+{
+ printf( "\nHello World\n" );
+}
\ No newline at end of file
diff --git a/viikko1/demoTehtava/src/tested.c b/viikko1/demoTehtava/src/tested.c
new file mode 100644
index 0000000..d0cbc12
--- /dev/null
+++ b/viikko1/demoTehtava/src/tested.c
@@ -0,0 +1,9 @@
+#include "tested.h"
+
+int my_sum_function(int a, int b) {
+ /* BEGIN SOLUTION */
+ return a + b;
+ /* END SOLUTION */
+
+ /* STUB: return 0 */
+}
\ No newline at end of file
diff --git a/viikko1/demoTehtava/src/tested.h b/viikko1/demoTehtava/src/tested.h
new file mode 100644
index 0000000..4809781
--- /dev/null
+++ b/viikko1/demoTehtava/src/tested.h
@@ -0,0 +1,5 @@
+#ifndef TESTED_H
+#define TESTED_H
+int my_sum_function(int a, int b);
+#endif /* TESTED_H */
+
diff --git a/viikko1/demoTehtava/test/Makefile b/viikko1/demoTehtava/test/Makefile
new file mode 100644
index 0000000..98484e5
--- /dev/null
+++ b/viikko1/demoTehtava/test/Makefile
@@ -0,0 +1,20 @@
+CHECK_CFLAGS=$(shell pkg-config --cflags check)
+CHECK_LDFLAGS=$(shell pkg-config --libs check)
+SRC_FILES=tmc-check.c test-file.c ../src/tested.c
+
+all: test
+
+test: $(SRC_FILES)
+ gcc $(CHECK_CFLAGS) -Wall -o $@ $(SRC_FILES) $(CHECK_LDFLAGS)
+
+clean:
+ # rm -f test tmc_available_points.txt tmc_test_results.xml valgrind.log
+
+get-points:
+ ./test --print-available-points
+
+run: test
+ # Printing available points
+ ./test --print-available-points
+ # Running test. There should be one success and one failure.
+ ./test
diff --git a/viikko1/demoTehtava/test/test b/viikko1/demoTehtava/test/test
new file mode 100755
index 0000000..6234d2e
Binary files /dev/null and b/viikko1/demoTehtava/test/test differ
diff --git a/viikko1/demoTehtava/test/test-file.c b/viikko1/demoTehtava/test/test-file.c
new file mode 100644
index 0000000..f6239e4
--- /dev/null
+++ b/viikko1/demoTehtava/test/test-file.c
@@ -0,0 +1,20 @@
+#include
+#include "tmc-check.h"
+#include "../src/tested.h"
+#include
+
+
+START_TEST(my_first)
+{
+ fail_unless(my_sum_function(1, 2) == 3, "My own sum function should sum 1 and 2 resulting in 3");
+}
+END_TEST
+
+int main(int argc, const char* argv[])
+{
+ Suite *s = suite_create("Test suite");
+
+ tmc_register_test(s, my_first_test, "1.1");
+
+ return tmc_run_tests(argc, argv, s);
+}
diff --git a/viikko1/demoTehtava/test/tmc-check.c b/viikko1/demoTehtava/test/tmc-check.c
new file mode 100644
index 0000000..1bc0b37
--- /dev/null
+++ b/viikko1/demoTehtava/test/tmc-check.c
@@ -0,0 +1,233 @@
+
+#include "tmc-check.h"
+#include
+#include
+#include
+#include
+
+typedef struct SuitePoints
+{
+ Suite *s;
+ const char *s_name;
+ const char *points;
+ struct SuitePoints *next;
+} SuitePoints;
+
+typedef struct PointsAssoc
+{
+ TCase *tc;
+ const char *tc_name;
+ const char *points;
+ struct PointsAssoc *next;
+} PointsAssoc;
+
+typedef struct PointsList
+{
+ char *point;
+ struct PointsList *next;
+} PointsList;
+
+typedef struct MemTest
+{
+ const char *tf_name;
+ int check_leaks;
+ int max_bytes_allocated; // Value -1 will represent no max_alloc check
+ struct MemTest *next;
+} MemTest;
+
+static PointsAssoc *points_assocs = NULL;
+static SuitePoints *suite_points = NULL;
+static PointsList *all_points = NULL;
+static MemTest *memtests = NULL;
+
+static void parse_points(const char *points, PointsList **target_list);
+static void add_to_point_set(const char *point, ssize_t len, PointsList **target_list);
+static int points_list_contains(const PointsList *list, const char *point, ssize_t len);
+
+void _tmc_register_memtest(const char *tf_name, int check_leaks, int max_bytes_allocated)
+{
+ MemTest *memtest = malloc(sizeof(MemTest));
+ memtest->tf_name = tf_name;
+ memtest->check_leaks = check_leaks;
+ memtest->max_bytes_allocated = max_bytes_allocated;
+
+ memtest->next = memtests;
+ memtests = memtest;
+}
+
+void tmc_set_tcase_points(TCase *tc, const char *tc_name, const char *points)
+{
+ PointsAssoc *pa = (PointsAssoc*)malloc(sizeof(PointsAssoc));
+ pa->tc = tc;
+ pa->tc_name = tc_name;
+ pa->points = points;
+ pa->next = points_assocs;
+ points_assocs = pa;
+
+ parse_points(points, &all_points);
+}
+
+void _tmc_register_test(Suite *s, TFun tf, const char *fname, const char *points)
+{
+ TCase *tc = tcase_create(fname);
+ tmc_set_tcase_points(tc, fname, points);
+ _tcase_add_test(tc, tf, fname, 0, 0, 0, 1);
+ suite_add_tcase(s, tc);
+}
+
+void tmc_set_suite_points(Suite *s, const char *s_name, const char *points)
+{
+ SuitePoints *sp = (SuitePoints*) malloc(sizeof(SuitePoints));
+ sp->s = s;
+ sp->points = points;
+ sp->s_name = s_name;
+ sp->next = suite_points;
+ suite_points = sp;
+
+ parse_points(points, &all_points);
+}
+
+Suite* tmc_suite_create(const char *name, const char *points)
+{
+ Suite *s = suite_create(name);
+ tmc_set_suite_points(s, name, points);
+ return s;
+}
+
+int tmc_run_tests(int argc, const char **argv, Suite *s)
+{
+ int i;
+ for (i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "--print-available-points") == 0) {
+ return tmc_print_available_points(stdout, '\n');
+ }
+
+ if (strcmp(argv[i], "--print-memory-tests") == 0) {
+ return tmc_print_memory_tests(stdout, ' ', '\n');
+ }
+ }
+
+ FILE *points_file = fopen("tmc_available_points.txt", "wb");
+ FILE *memtest_file = fopen("tmc_memory_test_info.txt", "wb");
+ if (tmc_print_suite_points(points_file) != 0) {
+ fclose(points_file);
+ return EXIT_FAILURE;
+ }
+ if (tmc_print_test_points(points_file) != 0) {
+ fclose(points_file);
+ return EXIT_FAILURE;
+ }
+ if (tmc_print_memory_tests(memtest_file, ' ', '\n') != 0) {
+ fclose(memtest_file);
+ return EXIT_FAILURE;
+ }
+ fclose(points_file);
+ fclose(memtest_file);
+
+ SRunner *sr = srunner_create(s);
+ srunner_set_xml(sr, "tmc_test_results.xml");
+ srunner_run_all(sr, CK_VERBOSE);
+ srunner_free(sr);
+
+ return EXIT_SUCCESS;
+}
+
+int tmc_print_available_points(FILE *f, char delimiter)
+{
+ const PointsList *pl = all_points;
+ while (pl != NULL) {
+ fputs(pl->point, f);
+ fputc(delimiter, f);
+ pl = pl->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+int tmc_print_memory_tests(FILE *f, char attr_delimiter, char line_delimiter)
+{
+ const MemTest *mt = memtests;
+ while (mt != NULL) {
+ fputs(mt->tf_name, f);
+ fputc(attr_delimiter, f);
+ fprintf(f, "%d", mt->check_leaks);
+ fputc(attr_delimiter, f);
+ fprintf(f, "%d", mt->max_bytes_allocated);
+ fputc(line_delimiter, f);
+ mt = mt->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+int tmc_print_test_points(FILE *f)
+{
+ const PointsAssoc *pa = points_assocs;
+ while (pa != NULL) {
+ fprintf(f, "[test] %s %s\n", pa->tc_name, pa->points);
+ pa = pa->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+int tmc_print_suite_points(FILE *f)
+{
+ const SuitePoints *sp = suite_points;
+ while (sp != NULL) {
+ fprintf(f, "[suite] %s %s\n", sp->s_name, sp->points);
+ sp = sp->next;
+ }
+ fflush(f);
+ return 0;
+}
+
+static void parse_points(const char *points, PointsList **target_list)
+{
+ const char *p = points;
+ const char *q = p;
+ while (*q != '\0') {
+ if (isspace(*q)) {
+ const ssize_t len = q - p;
+
+ if (!isspace(*p)) {
+ add_to_point_set(p, len, target_list);
+ }
+
+ p = q + 1;
+ q = p;
+ } else {
+ q++;
+ }
+ }
+
+ if (!isspace(*p) && q > p) {
+ const ssize_t len = q - p;
+ add_to_point_set(p, len, target_list);
+ }
+}
+
+static void add_to_point_set(const char *point, ssize_t len, PointsList **target_list)
+{
+ if (!points_list_contains(*target_list, point, len)) {
+ PointsList *pl = (PointsList*)malloc(sizeof(PointsList));
+ pl->point = malloc(len + 1);
+ memcpy(pl->point, point, len);
+ pl->point[len] = '\0';
+ pl->next = *target_list;
+ *target_list = pl;
+ }
+}
+
+static int points_list_contains(const PointsList *list, const char *point, ssize_t len)
+{
+ const PointsList *pl = all_points;
+ while (pl != NULL) {
+ if (strncmp(pl->point, point, len) == 0) {
+ return 1;
+ }
+ pl = pl->next;
+ }
+ return 0;
+}
+
diff --git a/viikko1/demoTehtava/test/tmc-check.h b/viikko1/demoTehtava/test/tmc-check.h
new file mode 100644
index 0000000..8100cbb
--- /dev/null
+++ b/viikko1/demoTehtava/test/tmc-check.h
@@ -0,0 +1,58 @@
+
+#include
+#include
+
+/***** Main API *****/
+
+/** A shorthand to make one test suite with the given points */
+Suite* tmc_suite_create(const char *name, const char *points);
+
+/** A shorthand to make a one function testcase with the given points into a suite. */
+#define tmc_register_test(suite, tf, points) _tmc_register_test((suite), (tf), "" # tf, points)
+void _tmc_register_test(Suite *s, TFun tf, const char *fname, const char *points);
+
+/** A shorthand to make one memory test for a test function with given parameters */
+#define tmc_register_memtest(tf, check_leaks, max_bytes_allocated) _tmc_register_memtest("" # tf, check_leaks, max_bytes_allocated)
+void _tmc_register_memtest(const char *tf_name, int chek_leaks, int max_bytes_allocated);
+
+/** A shorthand for registering a test with memtest at the same time */
+#define tmc_register_test_with_memtest(suite, tf, points, check_leaks, max_bytes_allocated) tmc_register_test(suite, tf, points); tmc_register_memtest(tf, check_leaks, max_bytes_allocated)
+
+/**
+ * Runs a test suite so that tmc_test_results.xml and tmc_test_points.txt are created.
+ *
+ * To be called from main() after creating the Suite.
+ *
+ * If --print-available-points is given, it only outputs all available points
+ * (in an undefined order) to stdout and exits.
+ *
+ * Returns an error code that can be returned from main.
+ * Normally this will be 0 even if test fail.
+ */
+int tmc_run_tests(int argc, const char **argv, Suite *s);
+
+
+/***** Low-level API *****/
+
+/**
+ * Set the points of a test case.
+ *
+ * This is a lower level alternative to using tmc_register_test.
+ */
+void tmc_set_tcase_points(TCase *tc, const char *tc_name, const char *points);
+
+/**
+ * Set the points of a test suite
+ *
+ * This is a lower level alternative to using tmc_suite_create.
+ */
+void tmc_set_suite_points (Suite *s, const char *s_name, const char *points);
+
+/** Prints all registered points once (in no particular order) to the given file. */
+int tmc_print_available_points(FILE *f, char delimiter);
+int tmc_print_memory_tests(FILE *f, char attr_delimiter, char line_delimiter);
+
+/** Prints lines like "[test] testname pointname1 pointname2" to the given file. */
+int tmc_print_test_points(FILE *f);
+/** Prints lines with "[suite] suitename pointname1 pointname2" to given file */
+int tmc_print_suite_points(FILE *f);
\ No newline at end of file
diff --git a/viikko1/demoTehtava/test/tmc_available_points.txt b/viikko1/demoTehtava/test/tmc_available_points.txt
new file mode 100644
index 0000000..89538e3
--- /dev/null
+++ b/viikko1/demoTehtava/test/tmc_available_points.txt
@@ -0,0 +1,2 @@
+[test] my_first_real_test 1.2
+[test] my_first_test 1.1
diff --git a/viikko1/demoTehtava/test/tmc_memory_test_info.txt b/viikko1/demoTehtava/test/tmc_memory_test_info.txt
new file mode 100644
index 0000000..e69de29
diff --git a/viikko1/demoTehtava/test/tmc_test_results.xml b/viikko1/demoTehtava/test/tmc_test_results.xml
new file mode 100644
index 0000000..f9cf2c6
--- /dev/null
+++ b/viikko1/demoTehtava/test/tmc_test_results.xml
@@ -0,0 +1,24 @@
+
+
+ 2013-05-08 12:07:36
+
+ Test suite
+
+ .
+ test-file.c:8
+ my_first_test
+ 0
+ my_first_test
+ Passed
+
+
+ .
+ test-file.c:14
+ my_first_real_test
+ 0
+ my_first_real_test
+ Passed
+
+
+ 0.000000
+