wzpan
10/1/2013 - 2:06 PM

Shell - A script I use to rapidly create a new C project skeleton.

Shell - A script I use to rapidly create a new C project skeleton.

#include "../src/minunit.h"
#include "../src/dbg.h"
#include "../src/myutil.h"
#include "../src/array_util.h"

char *test_util(void)
{
    int err = 0;
    /* put tests here */

    mu_assert(err == 0, "test util error!");
    return NULL;        
}

char *all_tests() {
    mu_suite_start();

    mu_run_test(test_util);

    return NULL;
}

RUN_TESTS(all_tests);
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 test $i: here's tests/tests.log"
            echo "------"
            tail tests/tests.log
        fi
    fi
done
 
echo ""
/**
 * @file   myutil.h
 * @author Joseph Pan <cs.wzpan@gmail.com>
 * @date   
 * 
 * @brief  for rapidly drafting programs
 * 
 */

#ifndef MY_UTIL_H
#define MY_UTIL_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dbg.h"
#include "array_util.h"

/* Put definitions of functions here */

#endif
/**
 * @file   myutil.c
 * @author Joseph Pan <cs.wzpan@gmail.com>
 * @date
 * 
 * @brief  for rapidly drafting programs
 * 
 * 
 */

#include "myutil.h"

/* Put declarations of functions here. */
/**
 * @file   minunit.h
 * @author Zed A.Shaw, Jera Design
 * @date   Thu Sep 19 19:48:35 2013
 * 
 * @brief  A minimal unit testing framework for C
 * 
 */
 
#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
#/bin/bash

if [[ $# -eq 0 ]]
then
	echo "Type the project name you want to create: "
	read project_name
else
	project_name=$1
fi

if [[ ! -d $project_name ]]
then
	mkdir -p $project_name
fi

for i in src bin build tests
do
	if [[ ! -d $i ]]
	then
		mkdir $project_name/$i
	fi
done

# download Makefile and test scripts
mkdir /tmp/fast-project
cd /tmp/fast-project
wget https://gist.github.com/wzpan/6778981/download
tar -xf /tmp/fast-project/download
cd -
cp /tmp/fast-project/gist*/Makefile $project_name/
cp /tmp/fast-project/gist*/*.h $project_name/src/
cp /tmp/fast-project/gist*/*util.c $project_name/src/
cp /tmp/fast-project/gist*/*_tests.* $project_name/tests/
cp /tmp/fast-project/gist*/runtests.sh $project_name/tests/
touch $project_name/README.md
touch $project_name/LICENSE
rm -r /tmp/fast-project
#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:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)

#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)

#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d:%s:) " M "\n", __FILE__, __LINE__, __func__, ##__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
/**
 * @file   array_util.h
 * @author Joseph Pan <cs.wzpan@gmail.com>
 * @date   Thu Sep 19 19:44:33 2013
 * 
 * @brief  useful functions to manage arrays
 * 
 */


#ifndef ARRAY_H
#define ARRAY_H

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define TRUE 1
#define FALSE 0
#define MAX 10

/* For input a integer. */
extern int read_num(void);

/* For input and output arrays. */
extern void print_array(int *array, int length);
extern void read_array(int *array, int length);
extern void generate_array(int *array, int length);  // randomly generate array

/* For input and output matrix. */
extern void read_matrix2(int matrix[MAX][MAX], int m, int n);
extern void print_matrix2(int matrix[MAX][MAX], int m, int n);

#endif
/**
 * @file   array_util.c
 * @author Joseph Pan <cs.wzpan@gmail.com>
 * @date   Thu Sep 19 19:46:26 2013
 * 
 * @brief  useful functions to manage arrays 
 * 
 */

#include "array_util.h"

/** 
 * read_num - input a number
 * Input an integer number.
 * @return the integer number
 *
 */
extern int read_num(void)
{
	int i;
    const int SIZE = 5;
    char input[SIZE];
    int sum = 0;
	int success = 0;
	
	while (0 == success){  // loop unless input a valid number
		i = 0;
		sum = 0;
		scanf("%s", input);		    
		while (TRUE){
			if (input[i] < '0' || input[i] > '9') {
				printf("Invalid input! Please input again: ");
				sum = -1;
				break;
			}
			sum = sum*10 + input[i] - '0';
			i++;
			if (input[i] == '\0') {
				success = 1;
				break;
			}			
		}
	}
    return sum;
}


/**
 * read_array - input an array
 * @param array		the array to be printed
 * @param length	the length of the array
 *
 * Input an integers array.
 */

extern void read_array(int *array, int length)
{
    int i = 0;
    for (i = 0; i < length; i++){
		*(array + i) = read_num();
    }
    return;
}


/**
 * print_array - print all the elements from an array
 * @param array		the array to be printed
 * @param length	the length of the array
 */
extern void print_array(int *array, int length)
{
    int i = 0;
    for (i = 0; i < length; i++){
		printf("%d ", array[i]);	
    }
    printf("\n");
    return;
}

/**
 * generate_array - randomly generate an integer array
 * @param array		the expected array
 * @param length	the length of the array
 *
 */
extern void generate_array(int *array, int length)
{
    srand((unsigned)time(NULL));
    
    int i;
    for (i = 0; i < length; i++){
		*(array + i) = random() % 100;
    }
    
    return;
}


/** 
 * read_matrix	-	input a matrix
 * @param matrix	the required matrix
 * @param m			rows of the matrix
 * @param n			cols of the matrix
 *
 */
extern void read_matrix2(int matrix[MAX][MAX], int m, int n)
{
    int i, j, temp;
    printf("Input elements of Matrix(%d*%d):\n", m, n);
    for(i = 0; i < m; i++)
        for(j = 0; j < n; j++){
            scanf("%d", &temp);
            matrix[i][j] = temp;
        }
    return;
}


/** 
 * print_matrix	-	print a matrix
 * @param matrix	the required matrix
 * @param m			rows of the matrix
 * @param n			cols of the matrix
 *
 */
extern void print_matrix2(int matrix[MAX][MAX], int m, int n)
{
    int i, j;
    
    for(i = 0; i < 2*n; i++)
        printf("-");
    putchar('\n');
    
    for(i = 0; i < m; i++){
        for(j = 0; j < n; j++){
            printf("%d ", matrix[i][j]);
        }
        putchar('\n');
    }

    for(i = 0; i < 2*n; i++)
        printf("-");
    putchar('\n');

    
    return;
}
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/libmyutil.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): %: %.c
	$(CC) $(CFLAGS) $< -o $@ -Lbuild -lmyutil -static
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