372 lines
7.9 KiB
Perl
Executable File
372 lines
7.9 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
# exotic 0.4
|
|
# Copyright (c) 2007-2012, Jan Vidar Krey
|
|
|
|
use strict;
|
|
|
|
my $program = $0;
|
|
my $file;
|
|
my $line;
|
|
my @tests;
|
|
my $found;
|
|
my $test;
|
|
my @files;
|
|
|
|
if ($#ARGV == -1)
|
|
{
|
|
die "Usage: $program files\n";
|
|
}
|
|
|
|
my $version = "0.4";
|
|
|
|
foreach my $arg (@ARGV)
|
|
{
|
|
push(@files, $arg);
|
|
}
|
|
|
|
|
|
print "/* THIS FILE IS AUTOMATICALLY GENERATED BY EXOTIC - DO NOT EDIT THIS FILE! */\n";
|
|
print "/* exotic/$version (Mon Nov 7 11:15:31 CET 2011) */\n\n";
|
|
|
|
print "#define __EXOTIC__STANDALONE__\n";
|
|
standalone_include_exotic_h();
|
|
|
|
if ($#ARGV >= 0)
|
|
{
|
|
foreach $file (@ARGV)
|
|
{
|
|
$found = 0;
|
|
open( FILE, "$file") || next;
|
|
my @data = <FILE>;
|
|
my $comment = 0;
|
|
|
|
foreach $line (@data) {
|
|
chomp($line);
|
|
|
|
if ($comment == 1)
|
|
{
|
|
if ($line =~ /^(.*\*\/)(.*)/)
|
|
{
|
|
$line = $2;
|
|
$comment = 0;
|
|
}
|
|
else
|
|
{
|
|
next; # ignore comment data
|
|
}
|
|
}
|
|
|
|
if ($line =~ /^(.*)\/\*(.*)\*\/(.*)$/)
|
|
{
|
|
$line = $1 . " " . $3; # exclude comment stuff in between "/*" and "*/".
|
|
}
|
|
|
|
if ($line =~ /^(.*)(\/\/.*)$/) {
|
|
$line = $1; # exclude stuff after "//" (FIXME: does not work if they are inside a string)
|
|
}
|
|
|
|
if ($line =~ /\/\*/) {
|
|
$comment = 1;
|
|
next;
|
|
}
|
|
|
|
if ($line =~ /^\s*EXO_TEST\(\s*(\w+)\s*,/)
|
|
{
|
|
$found++;
|
|
push(@tests, $1);
|
|
}
|
|
}
|
|
|
|
if ($found > 0) {
|
|
print "#include \"" . $file . "\"\n";
|
|
}
|
|
|
|
close(FILE);
|
|
}
|
|
print "\n";
|
|
}
|
|
|
|
# Write a main() that will start the test run
|
|
print "int main(int argc, char** argv)\n{\n";
|
|
print "\tstruct exotic_handle handle;\n\n";
|
|
print "\tif (exotic_initialize(&handle, argc, argv) == -1)\n\t\treturn -1;\n\n";
|
|
|
|
if ($#tests > 0)
|
|
{
|
|
print "\t/* Register the tests to be run */\n";
|
|
foreach $test (@tests)
|
|
{
|
|
print "\texotic_add_test(&handle, &exotic_test_" . $test . ", \"" . $test . "\");\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
print "\t/* No tests are found! */\n";
|
|
}
|
|
|
|
print "\n";
|
|
print "\treturn exotic_run(&handle);\n";
|
|
print "}\n\n";
|
|
|
|
|
|
standalone_include_exotic_c();
|
|
|
|
sub standalone_include_exotic_h {
|
|
print '
|
|
/*
|
|
* Exotic (EXtatic.Org Test InfrastuCture)
|
|
* Copyright (c) 2007, Jan Vidar Krey
|
|
*/
|
|
|
|
#ifndef EXO_TEST
|
|
#define EXO_TEST(NAME, block) int exotic_test_ ## NAME (void) block
|
|
#endif
|
|
|
|
#ifndef HAVE_EXOTIC_AUTOTEST_H
|
|
#define HAVE_EXOTIC_AUTOTEST_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef int(*exo_test_t)();
|
|
|
|
enum exo_toggle { cfg_default, cfg_off, cfg_on };
|
|
|
|
struct exotic_handle
|
|
{
|
|
enum exo_toggle config_show_summary;
|
|
enum exo_toggle config_show_pass;
|
|
enum exo_toggle config_show_fail;
|
|
unsigned int fail;
|
|
unsigned int pass;
|
|
struct exo_test_data* first;
|
|
struct exo_test_data* current;
|
|
};
|
|
|
|
extern int exotic_initialize(struct exotic_handle* handle, int argc, char** argv);
|
|
extern void exotic_add_test(struct exotic_handle* handle, exo_test_t, const char* name);
|
|
extern int exotic_run(struct exotic_handle* handle);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* HAVE_EXOTIC_AUTOTEST_H */
|
|
|
|
'; }
|
|
sub standalone_include_exotic_c {
|
|
print '
|
|
/*
|
|
* Exotic - C/C++ source code testing
|
|
* Copyright (c) 2007, Jan Vidar Krey
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static void exotic_version();
|
|
|
|
#ifndef __EXOTIC__STANDALONE__
|
|
#include "autotest.h"
|
|
static void exotic_version()
|
|
{
|
|
printf("Extatic.org Test Infrastructure: exotic " "${version}" "\n\n");
|
|
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
|
|
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
|
|
}
|
|
#endif
|
|
|
|
struct exo_test_data
|
|
{
|
|
exo_test_t test;
|
|
char* name;
|
|
struct exo_test_data* next;
|
|
};
|
|
|
|
|
|
static void exotic_summary(struct exotic_handle* handle)
|
|
{
|
|
int total = handle->pass + handle->fail;
|
|
int pass_rate = total ? (100*handle->pass / total) : 0;
|
|
int fail_rate = total ? (100*handle->fail / total) : 0;
|
|
|
|
printf("\n");
|
|
printf("--------------------------------------------\n");
|
|
printf("Results:\n");
|
|
printf(" * Total tests run: %8d\n", total);
|
|
printf(" * Tests passed: %8d (~%d%%)\n", (int) handle->pass, pass_rate);
|
|
printf(" * Tests failed: %8d (~%d%%)\n", (int) handle->fail, fail_rate);
|
|
printf("--------------------------------------------\n");
|
|
}
|
|
|
|
|
|
static void exotic_help(const char* program)
|
|
{
|
|
printf("Usage: %s [OPTIONS]\n\n", program);
|
|
printf("Options:\n");
|
|
printf(" --help -h Show this message\n");
|
|
printf(" --version -v Show version\n");
|
|
printf(" --summary -s show only summary)\n");
|
|
printf(" --fail -f show only test failures\n");
|
|
printf(" --pass -p show only test passes\n");
|
|
printf("\nExamples:\n");
|
|
printf(" %s -s -f\n\n", program);
|
|
}
|
|
|
|
|
|
int exotic_initialize(struct exotic_handle* handle, int argc, char** argv)
|
|
{
|
|
int n;
|
|
if (!handle || !argv) return -1;
|
|
|
|
memset(handle, 0, sizeof(struct exotic_handle));
|
|
|
|
for (n = 1; n < argc; n++)
|
|
{
|
|
if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help"))
|
|
{
|
|
exotic_help(argv[0]);
|
|
exit(0);
|
|
}
|
|
|
|
if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--version"))
|
|
{
|
|
exotic_version();
|
|
exit(0);
|
|
}
|
|
|
|
if (!strcmp(argv[n], "-s") || !strcmp(argv[n], "--summary"))
|
|
{
|
|
handle->config_show_summary = cfg_on;
|
|
continue;
|
|
}
|
|
|
|
if (!strcmp(argv[n], "-f") || !strcmp(argv[n], "--fail"))
|
|
{
|
|
handle->config_show_fail = cfg_on;
|
|
continue;
|
|
}
|
|
|
|
if (!strcmp(argv[n], "-p") || !strcmp(argv[n], "--pass"))
|
|
{
|
|
handle->config_show_pass = cfg_on;
|
|
continue;
|
|
}
|
|
|
|
fprintf(stderr, "Unknown argument: %s\n\n", argv[n]);
|
|
exotic_help(argv[0]);
|
|
exit(0);
|
|
}
|
|
|
|
if (handle->config_show_summary == cfg_on)
|
|
{
|
|
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_off;
|
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
|
|
|
}
|
|
else if (handle->config_show_pass == cfg_on)
|
|
{
|
|
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
|
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
|
}
|
|
else if (handle->config_show_fail == cfg_on)
|
|
{
|
|
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
|
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
|
}
|
|
else
|
|
{
|
|
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_on;
|
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_on;
|
|
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_on;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name)
|
|
{
|
|
if (!handle)
|
|
{
|
|
fprintf(stderr, "exotic_add_test: failed, no handle!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
struct exo_test_data* test = (struct exo_test_data*) malloc(sizeof(struct exo_test_data));
|
|
if (!test)
|
|
{
|
|
fprintf(stderr, "exotic_add_test: out of memory!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
/* Create the test */
|
|
memset(test, 0, sizeof(struct exo_test_data));
|
|
test->test = func;
|
|
test->name = strdup(name);
|
|
|
|
/* Register the test in the handle */
|
|
if (!handle->first)
|
|
{
|
|
handle->first = test;
|
|
handle->current = test;
|
|
}
|
|
else
|
|
{
|
|
handle->current->next = test;
|
|
handle->current = test;
|
|
}
|
|
}
|
|
|
|
|
|
int exotic_run(struct exotic_handle* handle)
|
|
{
|
|
struct exo_test_data* tmp = NULL;
|
|
|
|
if (!handle)
|
|
{
|
|
fprintf(stderr, "Error: exotic is not initialized\n");
|
|
return -1;
|
|
}
|
|
|
|
handle->current = handle->first;
|
|
while (handle->current)
|
|
{
|
|
tmp = handle->current;
|
|
|
|
if (handle->current->test()) {
|
|
if (handle->config_show_pass == cfg_on) printf("* PASS test \'%s\'\n", tmp->name);
|
|
handle->pass++;
|
|
} else {
|
|
if (handle->config_show_fail == cfg_on) printf("* FAIL test \'%s\'\n", tmp->name);
|
|
handle->fail++;
|
|
}
|
|
|
|
handle->current = handle->current->next;
|
|
|
|
free(tmp->name);
|
|
free(tmp);
|
|
}
|
|
|
|
if (!handle->first)
|
|
{
|
|
printf("(No tests added)\n");
|
|
}
|
|
|
|
if (handle->config_show_summary == cfg_on)
|
|
exotic_summary(handle);
|
|
|
|
return (handle->fail) ? handle->fail : 0;
|
|
}
|
|
|
|
|
|
static void exotic_version() {
|
|
printf("exotic 0.4-standalone\n\n");
|
|
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
|
|
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
|
|
}
|
|
'; }
|
|
|