diff --git a/.gitignore b/.gitignore index 8d60fe3..8f9e9b2 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ ruby/ohcount.so ruby/ohcount_wrap.c test/unit/run_tests.dSYM/ +build-python/ +python/ohcount.py +.rvmrc +.ruby-version diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches deleted file mode 100644 index 6857a8d..0000000 --- a/.pc/.quilt_patches +++ /dev/null @@ -1 +0,0 @@ -debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series deleted file mode 100644 index c206706..0000000 --- a/.pc/.quilt_series +++ /dev/null @@ -1 +0,0 @@ -series diff --git a/.pc/.version b/.pc/.version deleted file mode 100644 index 0cfbf08..0000000 --- a/.pc/.version +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/.pc/applied-patches b/.pc/applied-patches deleted file mode 100644 index 8ad8876..0000000 --- a/.pc/applied-patches +++ /dev/null @@ -1,5 +0,0 @@ -fix_null_dereference_2.patch -fix_null_dereference.patch -txx_support.patch -disabled_test_suite.patch -rbconfig.patch diff --git a/.pc/disabled_test_suite.patch/build b/.pc/disabled_test_suite.patch/build deleted file mode 100755 index ad71874..0000000 --- a/.pc/disabled_test_suite.patch/build +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env bash -# Build script for Ohcount. -# Written by Mitchell Foral. mitchellcaladbolg.net. - -# Options -# Change these for your system configuration. -if [ `uname` != "Darwin" ] -then - # Linux - INC_DIR= - LIB_DIR= - - if [ `uname` == "FreeBSD" ] - then - INC_DIR=/usr/local/include - LIB_DIR=/usr/local/lib - fi - - # You shouldn't have to change the following. - CFLAGS=-O3 - CFLAGS="$CFLAGS -DTMP_FILES_ARE_DT_UNKNOWN" # workaround bug on centos/SF servers - WARN="-Wall -Wno-pointer-to-int-cast -Wno-parentheses" - SHARED=-shared - SHARED_NAME=libohcount.so - RB_SHARED=-shared - RB_SHARED_NAME=ohcount.so -else - # Mac OSX - INC_DIR=/opt/local/include - LIB_DIR=/opt/local/lib - # You shouldn't have to change the following. - CFLAGS="-fno-common -g" - WARN="-Wall -Wno-parentheses" - SHARED="-dynamiclib -L$LIB_DIR -lpcre" - SHARED_NAME=libohcount.dylib - RB_SHARED="-dynamic -bundle -lruby" - RB_SHARED_NAME=ohcount.bundle -fi - -# C compiler and flags -cc="gcc -fPIC -g $CFLAGS $WARN -I$INC_DIR -L$LIB_DIR" - -# Ohcount source files -files="src/sourcefile.c \ - src/detector.c \ - src/licenses.c \ - src/parser.o \ - src/loc.c \ - src/log.c \ - src/diff.c \ - src/parsed_language.c \ - src/hash/language_hash.c" - -# If any src/hash/*.gperf file is newer than the header files (which were -# presumably generated together), regenerate the headers. -build_hash_headers() -{ - if [[ -z `ls src/hash/ | grep "_hash.h$"` || - ! -z `find src/hash/*.gperf -newer src/hash/parser_hash.h` ]] - then - echo "Generating hash headers" - sh -c "cd src/hash/ && ./generate_headers" || exit 1 - fi -} - -# If src/parser.o does not exist, or if there are Ragel parsers or parser -# header files newer than the existing parser.o, recompile parser.o. -build_parser_o() -{ - if [[ ! -f src/parser.o || - ! -z `find src/parsers/*.{h,rl} -newer src/parser.o` ]] - then - bash -c "cd src/parsers/ && bash ./compile" || exit 1 - echo "Building src/parser.c (will take a while)" - bash -c "$cc -c src/parser.c -o src/parser.o" || exit 1 - fi -} - -build_shared() -{ - build_hash_headers - build_parser_o - if [[ ! -f src/$SHARED_NAME || - ! -z `find src/*.{h,c} -newer src/$SHARED_NAME` ]] - then - echo "Building shared library" - sh -c "$cc $SHARED $files -o src/$SHARED_NAME" || exit 1 - fi -} - -build_ohcount() -{ - build_hash_headers - build_parser_o - echo "Building Ohcount" - mkdir -p bin/ - sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre" || exit 1 -} - -build_test_suite() -{ - build_hash_headers - build_parser_o - echo "Building test suite" - sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre" \ - || exit 1 -} - -run_test_suite() -{ - echo "Running test suite" - sh -c "cd test/unit/ && ./run_tests" -} - -build_ruby_bindings() -{ - arch=`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'` - echo "Generating Ruby bindings for $arch" - sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1 - mkdir -p ruby/$arch - sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \ - -I`ruby -rmkmf -e 'print Config::expand(CONFIG["archdir"])'` \ - -lpcre" || exit 1 - sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1 -} - -if [ $# -eq 0 ] || [ $1 == "all" ] -then - build_ohcount - build_test_suite - run_test_suite - echo $success -elif [ $1 == "shared" ] -then - build_shared - echo "Build successful; $SHARED_NAME is in src/" -elif [ $1 == "ohcount" ] -then - build_ohcount - echo "Build successful; ohcount is in bin/" -elif [ $1 == "tests" ] -then - build_test_suite - run_test_suite -elif [ $1 == "ruby" ] -then - build_ruby_bindings - echo "Build successful; $RB_SHARED_NAME is in ruby/$arch" -elif [ $1 == "clean" ] -then - rm -f bin/ohcount - rm -f test/unit/run_tests - rm -f src/parser.o - rm -f src/parsers/*.h - rm -f src/hash/*.h - rm -f src/hash/*.c - rm -f src/$SHARED_NAME - rm -f ruby/$RB_SHARED_NAME - rm -rf ruby/`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`/* -else - echo "Usage: build [all|ohcount|shared|tests|ruby|clean]" -fi diff --git a/.pc/fix_null_dereference.patch/src/detector.c b/.pc/fix_null_dereference.patch/src/detector.c deleted file mode 100644 index 5107c61..0000000 --- a/.pc/fix_null_dereference.patch/src/detector.c +++ /dev/null @@ -1,693 +0,0 @@ -// detector.c written by Mitchell Foral. mitchellcaladbolg.net. -// See COPYING for license information. - -#include -#include -#include -#include -#include - -#include "detector.h" -#include "languages.h" -#include "log.h" - -#include "hash/cppheader_hash.h" -#include "hash/disambiguatefunc_hash.h" -#include "hash/extension_hash.h" -#include "hash/filename_hash.h" - -#define ISBINARY(x) (x[0] == '\1') -#define ISAMBIGUOUS(x) (x[0] == '\2') -#define DISAMBIGUATEWHAT(x) &x[1] - -const char *ohcount_detect_language(SourceFile *sourcefile) { - const char *language = NULL; - char *p, *pe; - int length; - - // Attempt to detect based on file extension. - length = strlen(sourcefile->ext); - struct ExtensionMap *re = ohcount_hash_language_from_ext(sourcefile->ext, - length); - if (re) language = re->value; - if (language == NULL) { - // Try the lower-case version of this extension. - char lowerext[length + 1]; - strncpy(lowerext, sourcefile->ext, length); - lowerext[length] = '\0'; - for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p); - struct ExtensionMap *re = ohcount_hash_language_from_ext(lowerext, length); - if (re) return re->value; - } - if (language) { - if (ISAMBIGUOUS(language)) { - // Call the appropriate function for disambiguation. - length = strlen(DISAMBIGUATEWHAT(language)); - struct DisambiguateFuncsMap *rd = - ohcount_hash_disambiguate_func_from_id(DISAMBIGUATEWHAT(language), - length); - if (rd) return rd->value(sourcefile); - } else return ISBINARY(language) ? NULL : language; - } - - // Attempt to detect based on filename. - length = strlen(sourcefile->filename); - struct FilenameMap *rf = - ohcount_hash_language_from_filename(sourcefile->filename, length); - if (rf) return rf->value; - - char line[81] = { '\0' }, buf[81]; - - // Attempt to detect using Emacs mode line (/^-\*-\s*mode[\s:]*\w/i). - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get the contents of the first line. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - if (*line == '#' && *(line + 1) == '!') { - // First line was sh-bang; loop to get contents of second line. - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } else break; - } - char *eol = line + strlen(line); - for (p = line; p < eol; p++) *p = tolower(*p); - p = strstr(line, "-*-"); - if (p) { - p += 3; - while (*p == ' ' || *p == '\t') p++; - if (strncmp(p, "mode", 4) == 0) { - p += 4; - while (*p == ' ' || *p == '\t' || *p == ':') p++; - } - pe = p; - while (isalnum(*pe)) pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) return rl->name; - } - - // Attempt to detect based on Unix 'file' command. - int tmpfile = 0; - char *path = sourcefile->filepath; - if (sourcefile->diskpath) - path = sourcefile->diskpath; - if (access(path, F_OK) != 0) { // create temporary file - path = malloc(21); - strncpy(path, "/tmp/ohcount_XXXXXXX", 20); - *(path + 21) = '\0'; - int fd = mkstemp(path); - char *contents = ohcount_sourcefile_get_contents(sourcefile); - log_it("contents:"); - log_it(contents); - length = contents ? strlen(contents) : 0; - write(fd, contents, length); - close(fd); - tmpfile = 1; - } - char command[strlen(path) + 11]; - sprintf(command, "file -b '%s'", path); - FILE *f = popen(command, "r"); - if (f) { - fgets(line, sizeof(line), f); - char *eol = line + strlen(line); - for (p = line; p < eol; p++) *p = tolower(*p); - p = strstr(line, "script text"); - if (p && p == line) { // /^script text(?: executable)? for \w/ - p = strstr(line, "for "); - if (p) { - p += 4; - pe = p; - while (isalnum(*pe)) pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) language = rl->name; - } - } else if (p) { // /(\w+)(?: -\w+)* script text/ - do { - p--; - pe = p; - while (*p == ' ') p--; - while (p != line && isalnum(*(p - 1))) p--; - if (p != line && *(p - 1) == '-') p--; - } while (*p == '-'); // Skip over any switches. - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) language = rl->name; - } else if (strstr(line, "xml")) language = LANG_XML; - pclose(f); - if (tmpfile) { - remove(path); - free(path); - } - if (language) return language; - } - - return NULL; -} - -const char *disambiguate_aspx(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - for (; p < eof; p++) { - // /<%@\s*Page[^>]+Language="VB"[^>]+%>/ - p = strstr(p, "<%@"); - if (!p) - break; - char *pe = strstr(p, "%>"); - if (p && pe) { - p += 3; - const int length = pe - p; - char buf[length]; - strncpy(buf, p, length); - buf[length] = '\0'; - char *eol = buf + strlen(buf); - for (p = buf; p < eol; p++) *p = tolower(*p); - p = buf; - while (*p == ' ' || *p == '\t') p++; - if (strncmp(p, "page", 4) == 0) { - p += 4; - if (strstr(p, "language=\"vb\"")) - return LANG_VB_ASPX; - } - } - } - return LANG_CS_ASPX; -} - -const char *disambiguate_b(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (p < eof) { - // /(implement[ \t])|(include[ \t]+"[^"]*";)| - // ((return|break|continue).*;|(pick|case).*\{)/ - if (strncmp(p, "implement", 9) == 0 && - (*(p + 9) == ' ' || *(p + 9) == '\t')) - return LANG_LIMBO; - else if (strncmp(p, "include", 7) == 0 && - (*(p + 7) == ' ' || *(p + 7) == '\t')) { - p += 7; - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') { - while (*p != '"' && p < eof) p++; - if (*p == '"' && *(p + 1) == ';') - return LANG_LIMBO; - } - } else if (strncmp(p, "return", 6) == 0 || - strncmp(p, "break", 5) == 0 || - strncmp(p, "continue", 8) == 0) { - if (strstr(p, ";")) - return LANG_LIMBO; - } else if (strncmp(p, "pick", 4) == 0 || - strncmp(p, "case", 4) == 0) { - if (strstr(p, "{")) - return LANG_LIMBO; - } - p++; - } - return disambiguate_basic(sourcefile); -} - -const char *disambiguate_basic(SourceFile *sourcefile) { - char *p, *pe; - int length; - - // Attempt to detect based on file contents. - char line[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *line_end = pe; - - p = line; - if (isdigit(*p)) { - // /^\d+\s+\w/ - p++; - while (isdigit(*p)) p++; - if (*p == ' ' || *p == '\t') { - p++; - while (*p == ' ' || *p == '\t') p++; - if (isalnum(*p)) - return LANG_CLASSIC_BASIC; - } - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - // Attempt to detect from associated VB files in file context. - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - if (filenames) { - int i; - for (i = 0; filenames[i] != NULL; i++) { - pe = filenames[i] + strlen(filenames[i]); - p = pe; - while (p > filenames[i] && *(p - 1) != '.') p--; - length = pe - p; - if (length == 3 && - (strncmp(p, "frm", length) == 0 || - strncmp(p, "frx", length) == 0 || - strncmp(p, "vba", length) == 0 || - strncmp(p, "vbp", length) == 0 || - strncmp(p, "vbs", length) == 0)) { - return LANG_VISUALBASIC; - } - } - } - - return LANG_STRUCTURED_BASIC; -} - -const char *disambiguate_cs(SourceFile *sourcefile) { - // Attempt to detect based on file contents. - char *contents = ohcount_sourcefile_get_contents(sourcefile); - if (contents && strstr(contents, "filename); - if (strcmp(sourcefile->ext, "h") == 0) { - char path[length]; - strncpy(path, sourcefile->filename, length); - path[length] = '\0'; - *(path + length - 1) = 'm'; - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - if (filenames) { - int i; - for (i = 0; filenames[i] != NULL; i++) - if (strcmp(path, filenames[i]) == 0) - return LANG_OBJECTIVE_C; - } - } - - // Attempt to detect based on file contents. - char line[81], buf[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *eol = line + strlen(line); - char *line_end = pe; - - // Look for C++ headers. - if (*line == '#') { - p = line + 1; - while (*p == ' ' || *p == '\t') p++; - if (strncmp(p, "include", 7) == 0 && - (*(p + 7) == ' ' || *(p + 7) == '\t')) { - // /^#\s*include\s+[<"][^>"]+[>"]/ - p += 8; - while (*p == ' ' || *p == '\t') p++; - if (*p == '<' || *p == '"') { - // Is the header file a C++ header file? - p++; - pe = p; - while (pe < eol && *pe != '>' && *pe != '"') pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - if (ohcount_hash_is_cppheader(buf, length)) - return LANG_CPP; - // Is the extension for the header file a C++ file? - p = pe; - while (p > line && *(p - 1) != '.') p--; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct ExtensionMap *re = ohcount_hash_language_from_ext(buf, length); - if (re && strcmp(re->value, LANG_CPP) == 0) - return LANG_CPP; - } - } - } - - // Look for C++ keywords. - p = line; - while (p < eol) { - if (islower(*p) && p != line && !isalnum(*(p - 1)) && *(p - 1) != '_') { - pe = p; - while (islower(*pe)) pe++; - if (!isalnum(*pe) && *pe != '_') { - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - if (strcmp(buf, "class") == 0 || - strcmp(buf, "namespace") == 0 || - strcmp(buf, "template") == 0 || - strcmp(buf, "typename") == 0) - return LANG_CPP; - } - p = pe + 1; - } else p++; - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - // Nothing to suggest C++. - return LANG_C; -} - -const char *disambiguate_in(SourceFile *sourcefile) { - char *p, *pe; - int length; - const char *language = NULL; - - p = sourcefile->filepath; - pe = p + strlen(p) - 3; - if (strstr(p, ".") <= pe) { - // Only if the filename has an extension prior to the .in - length = pe - p; - char buf[length]; - strncpy(buf, p, length); - buf[length] = '\0'; - SourceFile *undecorated = ohcount_sourcefile_new(buf); - p = ohcount_sourcefile_get_contents(sourcefile); - if (!p) { - return NULL; - } - // The filepath without the '.in' extension does not exist on disk. The - // sourcefile->diskpath field must be set incase the detector needs to run - // 'file -b' on the file. - ohcount_sourcefile_set_diskpath(undecorated, sourcefile->filepath); - ohcount_sourcefile_set_contents(undecorated, p); - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - ohcount_sourcefile_set_filenames(undecorated, filenames); - language = ohcount_sourcefile_get_language(undecorated); - ohcount_sourcefile_free(undecorated); - } - return language; -} - -const char *disambiguate_inc(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + strlen(p); - while (p < eof) { - if (*p == '\0') - return BINARY; - else if (*p == '?' && strncmp(p + 1, "php", 3) == 0) - return LANG_PHP; - p++; - } - return NULL; -} - -const char *disambiguate_m(SourceFile *sourcefile) { - char *p, *pe; - int length; - - // Attempt to detect based on a weighted heuristic of file contents. - int matlab_score = 0; - int objective_c_score = 0; - int limbo_score = 0; - int octave_syntax_detected = 0; - - int i, has_h_headers = 0, has_c_files = 0; - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - if (filenames) { - for (i = 0; filenames[i] != NULL; i++) { - p = filenames[i]; - pe = p + strlen(p); - if (pe - p >= 4) { - if (*(pe - 4) == '.' && *(pe - 3) == 'c' && - ((*(pe - 2) == 'p' && *(pe - 1) == 'p') || - (*(pe - 2) == '+' && *(pe - 1) == '+') || - (*(pe - 2) == 'x' && *(pe - 1) == 'x'))) { - has_c_files = 1; - break; // short circuit - } - } else if (pe - p >= 3) { - if (*(pe - 3) == '.' && *(pe - 2) == 'c' && *(pe - 1) == 'c') { - has_c_files = 1; - break; // short circuit - } - } else if (pe - p >= 2) { - if (*(pe - 2) == '.') { - if (*(pe - 1) == 'h') - has_h_headers = 1; - else if (*(pe - 1) == 'c' || *(pe - 1) == 'C') { - has_c_files = 1; - break; // short circuit - } - } - } - } - } - if (has_h_headers && !has_c_files) - objective_c_score += 5; - - char line[81], buf[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *eol = line + strlen(line); - char *line_end = pe; - - // Look for tell-tale lines. - p = line; - while (*p == ' ' || *p == '\t') p++; - if (*p == '%') { // Matlab comment - matlab_score++; - } else if (*p == '#' && strncmp(p, "#import", 7) == 0) { // Objective C - objective_c_score++; - } else if (*p == '#') { // Limbo or Octave comment - while (*p == '#') p++; - if (*p == ' ' || *p == '\t') { - limbo_score++; - matlab_score++; - octave_syntax_detected = 1; - } - } else if (*p == '/' && *(p + 1) == '/' || *(p + 1) == '*') { - objective_c_score++; // Objective C comment - } else if (*p == '+' || *p == '-') { // Objective C method signature - objective_c_score++; - } else if (*p == '@' || *p == '#') { // Objective C method signature - if (strncmp(p, "@implementation", 15) == 0 || - strncmp(p, "@interface", 10) == 0) - objective_c_score++; - } else if (strncmp(p, "function", 8) == 0) { // Matlab or Octave function - p += 8; - while (*p == ' ' || *p == '\t') p++; - if (*p == '(') - matlab_score++; - } else if (strncmp(p, "include", 7) == 0) { // Limbo include - // /^include[ \t]+"[^"]+\.m";/ - p += 7; - if (*p == ' ' || *p == '\t') { - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') { - while (*p != '"' && p < eol) p++; - if (*p == '"' && *(p - 2) == '.' && *(p - 1) == 'm') - limbo_score++; - } - } - } - - // Look for Octave keywords. - p = line; - while (p < eol) { - if (islower(*p) && p != line && !isalnum(*(p - 1))) { - pe = p; - while (islower(*pe) || *pe == '_') pe++; - if (!isalnum(*pe)) { - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - if (strcmp(buf, "end_try_catch") == 0 || - strcmp(buf, "end_unwind_protect") == 0 || - strcmp(buf, "endfunction") == 0 || - strcmp(buf, "endwhile") == 0) - octave_syntax_detected = 1; - } - p = pe + 1; - } else p++; - } - - // Look for Limbo declarations - p = line; - while (p < eol) { - if (*p == ':' && (*(p + 1) == ' ' || *(p + 1) == '\t')) { - // /:[ \t]+(module|adt|fn ?\(|con[ \t])/ - p += 2; - if (strncmp(p, "module", 6) == 0 && !isalnum(*(p + 6)) || - strncmp(p, "adt", 3) == 0 && !isalnum(*(p + 3)) || - strncmp(p, "fn", 2) == 0 && - (*(p + 2) == ' ' && *(p + 3) == '(' || *(p + 2) == '(') || - strncmp(p, "con", 3) == 0 && - (*(p + 3) == ' ' || *(p + 3) == '\t')) - limbo_score++; - } else p++; - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - if (limbo_score > objective_c_score && limbo_score > matlab_score) - return LANG_LIMBO; - else if (objective_c_score > matlab_score) - return LANG_OBJECTIVE_C; - else - return octave_syntax_detected ? LANG_OCTAVE : LANG_MATLAB; -} - -#define QMAKE_SOURCES_SPACE "SOURCES +=" -#define QMAKE_SOURCES "SOURCES+=" -#define QMAKE_CONFIG_SPACE "CONFIG +=" -#define QMAKE_CONFIG "CONFIG+=" - -const char *disambiguate_pro(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - for (; p < eof; p++) { - if (strncmp(p, QMAKE_SOURCES_SPACE, strlen(QMAKE_SOURCES_SPACE)) == 0 || - strncmp(p, QMAKE_SOURCES, strlen(QMAKE_SOURCES)) == 0 || - strncmp(p, QMAKE_CONFIG_SPACE, strlen(QMAKE_CONFIG_SPACE)) == 0 || - strncmp(p, QMAKE_CONFIG, strlen(QMAKE_CONFIG)) == 0) - return LANG_MAKE; // really QMAKE - } - return LANG_IDL_PVWAVE; -} - -const char *disambiguate_st(SourceFile *sourcefile) { - char *p, *pe; - int length; - - // Attempt to detect based on file contents. - int found_assignment = 0, found_block_start = 0, found_block_end = 0; - - char line[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (p < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *eol = line + strlen(line); - char *line_end = pe; - - for (p = line; p < eol; p++) { - if (*p == ':') { - p++; - while (p < eol && (*p == ' ' || *p == '\t')) p++; - if (*p == '=') - found_assignment = 1; - else if (*p == '[') - found_block_start = 1; - } else if (*p == ']' && *(p + 1) == '.') found_block_end = 1; - if (found_assignment && found_block_start && found_block_end) - return LANG_SMALLTALK; - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - return NULL; -} - -int ohcount_is_binary_filename(const char *filename) { - char *p = (char *)filename + strlen(filename); - while (p > filename && *(p - 1) != '.') p--; - if (p > filename) { - struct ExtensionMap *re; - int length = strlen(p); - re = ohcount_hash_language_from_ext(p, length); - if (re) return ISBINARY(re->value); - // Try the lower-case version of this extension. - char lowerext[length]; - strncpy(lowerext, p, length); - lowerext[length] = '\0'; - for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p); - re = ohcount_hash_language_from_ext(lowerext, length); - if (re) return ISBINARY(re->value); - } - return 0; -} diff --git a/.pc/fix_null_dereference.patch/test/detect_files/empty.inc b/.pc/fix_null_dereference.patch/test/detect_files/empty.inc deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/fix_null_dereference.patch/test/unit/detector_test.h b/.pc/fix_null_dereference.patch/test/unit/detector_test.h deleted file mode 100644 index 48b6468..0000000 --- a/.pc/fix_null_dereference.patch/test/unit/detector_test.h +++ /dev/null @@ -1,133 +0,0 @@ -// detector_test.h written by Mitchell Foral. mitchellcaladbolg.net. -// See COPYING for license information. - -#include -#include -#include - -#include "../../src/detector.h" -#include "../../src/languages.h" -#include "../../src/sourcefile.h" - -#define ASSERT_DETECT(x, y) { \ - SourceFile *sf = ohcount_sourcefile_new("../detect_files/" y); \ - const char *lang = ohcount_detect_language(sf); \ - assert(lang); \ - assert(strcmp(x, lang) == 0); \ - ohcount_sourcefile_free(sf); \ -} -#define ASSERT_NODETECT(x) { \ - SourceFile *sf = ohcount_sourcefile_new("../detect_files/" x); \ - assert(ohcount_detect_language(sf) == NULL); \ - ohcount_sourcefile_free(sf); \ -} - -void test_detector_smalltalk() { - ASSERT_DETECT(LANG_SMALLTALK, "example.st"); - ASSERT_NODETECT("english.st"); -} - -void test_detector_disambiguate_m() { - ASSERT_DETECT(LANG_OBJECTIVE_C, "t1.m"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "t2.m"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "TCPSocket.m"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.m"); - ASSERT_DETECT(LANG_MATLAB, "foo_matlab.m"); - ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m"); -} - -void test_detector_disambiguate_in() { - ASSERT_NODETECT("empty.in"); -} -void test_detector_disambiguate_pro() { - ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); - ASSERT_DETECT(LANG_MAKE, "qmake.pro"); -} - -void test_detector_fortran_fixedfree() { - ASSERT_DETECT(LANG_FORTRANFIXED, "fortranfixed.f"); - ASSERT_DETECT(LANG_FORTRANFREE, "fortranfree.f"); -} - -void test_detector_detect_polyglot() { - ASSERT_DETECT(LANG_C, "foo.c"); - ASSERT_DETECT(LANG_C, "uses_no_cpp.h"); - ASSERT_DETECT(LANG_CPP, "uses_cpp_headers.h"); - ASSERT_DETECT(LANG_CPP, "uses_cpp_stdlib_headers.h"); - ASSERT_DETECT(LANG_CPP, "uses_cpp_keywords.h"); - ASSERT_DETECT(LANG_RUBY, "foo.rb"); - ASSERT_DETECT(LANG_MAKE, "foo.mk"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.h"); - ASSERT_DETECT(LANG_PHP, "upper_case_php"); - ASSERT_DETECT(LANG_SMALLTALK, "example.st"); - ASSERT_DETECT(LANG_VALA, "foo.vala"); - ASSERT_DETECT(LANG_TEX, "foo.tex"); - ASSERT_DETECT(LANG_XSLT, "example.xsl"); - ASSERT_DETECT(LANG_LISP, "core.lisp"); - ASSERT_DETECT(LANG_DMD, "foo.d"); - ASSERT_DETECT(LANG_VIM, "foo.vim"); - ASSERT_DETECT(LANG_EBUILD, "foo.ebuild"); - ASSERT_DETECT(LANG_EBUILD, "foo.eclass"); - ASSERT_DETECT(LANG_EXHERES, "foo.exheres-0"); - ASSERT_DETECT(LANG_EXHERES, "foo.exlib"); - ASSERT_DETECT(LANG_EIFFEL, "eiffel.e"); - ASSERT_DETECT(LANG_OCAML, "ocaml.ml"); - ASSERT_DETECT(LANG_STRATEGO, "stratego.str"); - ASSERT_DETECT(LANG_R, "foo.R"); - ASSERT_DETECT(LANG_GLSL, "foo.glsl"); - ASSERT_DETECT(LANG_GLSL, "foo_glsl.vert"); - ASSERT_DETECT(LANG_GLSL, "foo_glsl.frag"); - ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); - ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80"); - ASSERT_DETECT(LANG_PHP, "php.inc"); - ASSERT_DETECT(LANG_FSHARP, "fs1.fs"); -} - -void test_detector_upper_case_extensions() { - ASSERT_DETECT(LANG_CPP, "foo_upper_case.C"); - ASSERT_DETECT(LANG_RUBY, "foo_upper_case.RB"); -} - -void test_detector_no_extensions() { - ASSERT_DETECT(LANG_PYTHON, "py_script"); - ASSERT_DETECT(LANG_RUBY, "ruby_script"); - ASSERT_DETECT(LANG_SHELL, "bourne_again_script"); - ASSERT_DETECT(LANG_SHELL, "bash_script"); - ASSERT_DETECT(LANG_PERL, "perl_w"); - ASSERT_DETECT(LANG_DMD, "d_script"); - ASSERT_DETECT(LANG_TCL, "tcl_script"); - ASSERT_DETECT(LANG_PYTHON, "python.data"); - ASSERT_DETECT(LANG_PYTHON, "python2.data"); -} - -void test_detector_csharp_or_clearsilver() { - ASSERT_DETECT(LANG_CSHARP, "cs1.cs"); - ASSERT_DETECT(LANG_CLEARSILVER_TEMPLATE, "clearsilver_template1.cs"); -} - -void test_detector_basic() { - ASSERT_DETECT(LANG_VISUALBASIC, "visual_basic.bas"); - ASSERT_DETECT(LANG_CLASSIC_BASIC, "classic_basic.b"); - system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2"); - ASSERT_DETECT(LANG_STRUCTURED_BASIC, "visual_basic.bas"); - ASSERT_DETECT(LANG_STRUCTURED_BASIC, "structured_basic.b"); - system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx"); -} - -void test_detector_xml_with_custom_extension() { - ASSERT_DETECT(LANG_XML, "xml.custom_ext"); -} - -void all_detector_tests() { - test_detector_smalltalk(); - test_detector_disambiguate_m(); - test_detector_disambiguate_in(); - test_detector_disambiguate_pro(); - test_detector_fortran_fixedfree(); - test_detector_detect_polyglot(); - test_detector_upper_case_extensions(); - test_detector_no_extensions(); - test_detector_csharp_or_clearsilver(); - test_detector_basic(); - test_detector_xml_with_custom_extension(); -} diff --git a/.pc/fix_null_dereference_2.patch/src/detector.c b/.pc/fix_null_dereference_2.patch/src/detector.c deleted file mode 100644 index 4d0e1f4..0000000 --- a/.pc/fix_null_dereference_2.patch/src/detector.c +++ /dev/null @@ -1,690 +0,0 @@ -// detector.c written by Mitchell Foral. mitchellcaladbolg.net. -// See COPYING for license information. - -#include -#include -#include -#include -#include - -#include "detector.h" -#include "languages.h" -#include "log.h" - -#include "hash/cppheader_hash.h" -#include "hash/disambiguatefunc_hash.h" -#include "hash/extension_hash.h" -#include "hash/filename_hash.h" - -#define ISBINARY(x) (x[0] == '\1') -#define ISAMBIGUOUS(x) (x[0] == '\2') -#define DISAMBIGUATEWHAT(x) &x[1] - -const char *ohcount_detect_language(SourceFile *sourcefile) { - const char *language = NULL; - char *p, *pe; - int length; - - // Attempt to detect based on file extension. - length = strlen(sourcefile->ext); - struct ExtensionMap *re = ohcount_hash_language_from_ext(sourcefile->ext, - length); - if (re) language = re->value; - if (language == NULL) { - // Try the lower-case version of this extension. - char lowerext[length + 1]; - strncpy(lowerext, sourcefile->ext, length); - lowerext[length] = '\0'; - for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p); - struct ExtensionMap *re = ohcount_hash_language_from_ext(lowerext, length); - if (re) return re->value; - } - if (language) { - if (ISAMBIGUOUS(language)) { - // Call the appropriate function for disambiguation. - length = strlen(DISAMBIGUATEWHAT(language)); - struct DisambiguateFuncsMap *rd = - ohcount_hash_disambiguate_func_from_id(DISAMBIGUATEWHAT(language), - length); - if (rd) return rd->value(sourcefile); - } else return ISBINARY(language) ? NULL : language; - } - - // Attempt to detect based on filename. - length = strlen(sourcefile->filename); - struct FilenameMap *rf = - ohcount_hash_language_from_filename(sourcefile->filename, length); - if (rf) return rf->value; - - char line[81] = { '\0' }, buf[81]; - - // Attempt to detect using Emacs mode line (/^-\*-\s*mode[\s:]*\w/i). - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get the contents of the first line. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - if (*line == '#' && *(line + 1) == '!') { - // First line was sh-bang; loop to get contents of second line. - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } else break; - } - char *eol = line + strlen(line); - for (p = line; p < eol; p++) *p = tolower(*p); - p = strstr(line, "-*-"); - if (p) { - p += 3; - while (*p == ' ' || *p == '\t') p++; - if (strncmp(p, "mode", 4) == 0) { - p += 4; - while (*p == ' ' || *p == '\t' || *p == ':') p++; - } - pe = p; - while (isalnum(*pe)) pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) return rl->name; - } - - // Attempt to detect based on Unix 'file' command. - int tmpfile = 0; - char *path = sourcefile->filepath; - if (sourcefile->diskpath) - path = sourcefile->diskpath; - if (access(path, F_OK) != 0) { // create temporary file - path = malloc(21); - strncpy(path, "/tmp/ohcount_XXXXXXX", 20); - *(path + 21) = '\0'; - int fd = mkstemp(path); - char *contents = ohcount_sourcefile_get_contents(sourcefile); - log_it("contents:"); - log_it(contents); - length = contents ? strlen(contents) : 0; - write(fd, contents, length); - close(fd); - tmpfile = 1; - } - char command[strlen(path) + 11]; - sprintf(command, "file -b '%s'", path); - FILE *f = popen(command, "r"); - if (f) { - fgets(line, sizeof(line), f); - char *eol = line + strlen(line); - for (p = line; p < eol; p++) *p = tolower(*p); - p = strstr(line, "script text"); - if (p && p == line) { // /^script text(?: executable)? for \w/ - p = strstr(line, "for "); - if (p) { - p += 4; - pe = p; - while (isalnum(*pe)) pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) language = rl->name; - } - } else if (p) { // /(\w+)(?: -\w+)* script text/ - do { - p--; - pe = p; - while (*p == ' ') p--; - while (p != line && isalnum(*(p - 1))) p--; - if (p != line && *(p - 1) == '-') p--; - } while (*p == '-'); // Skip over any switches. - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) language = rl->name; - } else if (strstr(line, "xml")) language = LANG_XML; - pclose(f); - if (tmpfile) { - remove(path); - free(path); - } - if (language) return language; - } - - return NULL; -} - -const char *disambiguate_aspx(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - for (; p < eof; p++) { - // /<%@\s*Page[^>]+Language="VB"[^>]+%>/ - p = strstr(p, "<%@"); - if (!p) - break; - char *pe = strstr(p, "%>"); - if (p && pe) { - p += 3; - const int length = pe - p; - char buf[length]; - strncpy(buf, p, length); - buf[length] = '\0'; - char *eol = buf + strlen(buf); - for (p = buf; p < eol; p++) *p = tolower(*p); - p = buf; - while (*p == ' ' || *p == '\t') p++; - if (strncmp(p, "page", 4) == 0) { - p += 4; - if (strstr(p, "language=\"vb\"")) - return LANG_VB_ASPX; - } - } - } - return LANG_CS_ASPX; -} - -const char *disambiguate_b(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (p < eof) { - // /(implement[ \t])|(include[ \t]+"[^"]*";)| - // ((return|break|continue).*;|(pick|case).*\{)/ - if (strncmp(p, "implement", 9) == 0 && - (*(p + 9) == ' ' || *(p + 9) == '\t')) - return LANG_LIMBO; - else if (strncmp(p, "include", 7) == 0 && - (*(p + 7) == ' ' || *(p + 7) == '\t')) { - p += 7; - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') { - while (*p != '"' && p < eof) p++; - if (*p == '"' && *(p + 1) == ';') - return LANG_LIMBO; - } - } else if (strncmp(p, "return", 6) == 0 || - strncmp(p, "break", 5) == 0 || - strncmp(p, "continue", 8) == 0) { - if (strstr(p, ";")) - return LANG_LIMBO; - } else if (strncmp(p, "pick", 4) == 0 || - strncmp(p, "case", 4) == 0) { - if (strstr(p, "{")) - return LANG_LIMBO; - } - p++; - } - return disambiguate_basic(sourcefile); -} - -const char *disambiguate_basic(SourceFile *sourcefile) { - char *p, *pe; - int length; - - // Attempt to detect based on file contents. - char line[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *line_end = pe; - - p = line; - if (isdigit(*p)) { - // /^\d+\s+\w/ - p++; - while (isdigit(*p)) p++; - if (*p == ' ' || *p == '\t') { - p++; - while (*p == ' ' || *p == '\t') p++; - if (isalnum(*p)) - return LANG_CLASSIC_BASIC; - } - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - // Attempt to detect from associated VB files in file context. - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - if (filenames) { - int i; - for (i = 0; filenames[i] != NULL; i++) { - pe = filenames[i] + strlen(filenames[i]); - p = pe; - while (p > filenames[i] && *(p - 1) != '.') p--; - length = pe - p; - if (length == 3 && - (strncmp(p, "frm", length) == 0 || - strncmp(p, "frx", length) == 0 || - strncmp(p, "vba", length) == 0 || - strncmp(p, "vbp", length) == 0 || - strncmp(p, "vbs", length) == 0)) { - return LANG_VISUALBASIC; - } - } - } - - return LANG_STRUCTURED_BASIC; -} - -const char *disambiguate_cs(SourceFile *sourcefile) { - // Attempt to detect based on file contents. - char *contents = ohcount_sourcefile_get_contents(sourcefile); - if (contents && strstr(contents, "filename); - if (strcmp(sourcefile->ext, "h") == 0) { - char path[length]; - strncpy(path, sourcefile->filename, length); - path[length] = '\0'; - *(path + length - 1) = 'm'; - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - if (filenames) { - int i; - for (i = 0; filenames[i] != NULL; i++) - if (strcmp(path, filenames[i]) == 0) - return LANG_OBJECTIVE_C; - } - } - - // Attempt to detect based on file contents. - char line[81], buf[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *eol = line + strlen(line); - char *line_end = pe; - - // Look for C++ headers. - if (*line == '#') { - p = line + 1; - while (*p == ' ' || *p == '\t') p++; - if (strncmp(p, "include", 7) == 0 && - (*(p + 7) == ' ' || *(p + 7) == '\t')) { - // /^#\s*include\s+[<"][^>"]+[>"]/ - p += 8; - while (*p == ' ' || *p == '\t') p++; - if (*p == '<' || *p == '"') { - // Is the header file a C++ header file? - p++; - pe = p; - while (pe < eol && *pe != '>' && *pe != '"') pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - if (ohcount_hash_is_cppheader(buf, length)) - return LANG_CPP; - // Is the extension for the header file a C++ file? - p = pe; - while (p > line && *(p - 1) != '.') p--; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct ExtensionMap *re = ohcount_hash_language_from_ext(buf, length); - if (re && strcmp(re->value, LANG_CPP) == 0) - return LANG_CPP; - } - } - } - - // Look for C++ keywords. - p = line; - while (p < eol) { - if (islower(*p) && p != line && !isalnum(*(p - 1)) && *(p - 1) != '_') { - pe = p; - while (islower(*pe)) pe++; - if (!isalnum(*pe) && *pe != '_') { - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - if (strcmp(buf, "class") == 0 || - strcmp(buf, "namespace") == 0 || - strcmp(buf, "template") == 0 || - strcmp(buf, "typename") == 0) - return LANG_CPP; - } - p = pe + 1; - } else p++; - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - // Nothing to suggest C++. - return LANG_C; -} - -const char *disambiguate_in(SourceFile *sourcefile) { - char *p, *pe; - int length; - const char *language = NULL; - - p = sourcefile->filepath; - pe = p + strlen(p) - 3; - if (strstr(p, ".") <= pe) { - // Only if the filename has an extension prior to the .in - length = pe - p; - char buf[length]; - strncpy(buf, p, length); - buf[length] = '\0'; - SourceFile *undecorated = ohcount_sourcefile_new(buf); - p = ohcount_sourcefile_get_contents(sourcefile); - // The filepath without the '.in' extension does not exist on disk. The - // sourcefile->diskpath field must be set incase the detector needs to run - // 'file -b' on the file. - ohcount_sourcefile_set_diskpath(undecorated, sourcefile->filepath); - ohcount_sourcefile_set_contents(undecorated, p); - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - ohcount_sourcefile_set_filenames(undecorated, filenames); - language = ohcount_sourcefile_get_language(undecorated); - ohcount_sourcefile_free(undecorated); - } - return language; -} - -const char *disambiguate_inc(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + strlen(p); - while (p < eof) { - if (*p == '\0') - return BINARY; - else if (*p == '?' && strncmp(p + 1, "php", 3) == 0) - return LANG_PHP; - p++; - } - return NULL; -} - -const char *disambiguate_m(SourceFile *sourcefile) { - char *p, *pe; - int length; - - // Attempt to detect based on a weighted heuristic of file contents. - int matlab_score = 0; - int objective_c_score = 0; - int limbo_score = 0; - int octave_syntax_detected = 0; - - int i, has_h_headers = 0, has_c_files = 0; - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - if (filenames) { - for (i = 0; filenames[i] != NULL; i++) { - p = filenames[i]; - pe = p + strlen(p); - if (pe - p >= 4) { - if (*(pe - 4) == '.' && *(pe - 3) == 'c' && - ((*(pe - 2) == 'p' && *(pe - 1) == 'p') || - (*(pe - 2) == '+' && *(pe - 1) == '+') || - (*(pe - 2) == 'x' && *(pe - 1) == 'x'))) { - has_c_files = 1; - break; // short circuit - } - } else if (pe - p >= 3) { - if (*(pe - 3) == '.' && *(pe - 2) == 'c' && *(pe - 1) == 'c') { - has_c_files = 1; - break; // short circuit - } - } else if (pe - p >= 2) { - if (*(pe - 2) == '.') { - if (*(pe - 1) == 'h') - has_h_headers = 1; - else if (*(pe - 1) == 'c' || *(pe - 1) == 'C') { - has_c_files = 1; - break; // short circuit - } - } - } - } - } - if (has_h_headers && !has_c_files) - objective_c_score += 5; - - char line[81], buf[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *eol = line + strlen(line); - char *line_end = pe; - - // Look for tell-tale lines. - p = line; - while (*p == ' ' || *p == '\t') p++; - if (*p == '%') { // Matlab comment - matlab_score++; - } else if (*p == '#' && strncmp(p, "#import", 7) == 0) { // Objective C - objective_c_score++; - } else if (*p == '#') { // Limbo or Octave comment - while (*p == '#') p++; - if (*p == ' ' || *p == '\t') { - limbo_score++; - matlab_score++; - octave_syntax_detected = 1; - } - } else if (*p == '/' && *(p + 1) == '/' || *(p + 1) == '*') { - objective_c_score++; // Objective C comment - } else if (*p == '+' || *p == '-') { // Objective C method signature - objective_c_score++; - } else if (*p == '@' || *p == '#') { // Objective C method signature - if (strncmp(p, "@implementation", 15) == 0 || - strncmp(p, "@interface", 10) == 0) - objective_c_score++; - } else if (strncmp(p, "function", 8) == 0) { // Matlab or Octave function - p += 8; - while (*p == ' ' || *p == '\t') p++; - if (*p == '(') - matlab_score++; - } else if (strncmp(p, "include", 7) == 0) { // Limbo include - // /^include[ \t]+"[^"]+\.m";/ - p += 7; - if (*p == ' ' || *p == '\t') { - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') { - while (*p != '"' && p < eol) p++; - if (*p == '"' && *(p - 2) == '.' && *(p - 1) == 'm') - limbo_score++; - } - } - } - - // Look for Octave keywords. - p = line; - while (p < eol) { - if (islower(*p) && p != line && !isalnum(*(p - 1))) { - pe = p; - while (islower(*pe) || *pe == '_') pe++; - if (!isalnum(*pe)) { - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - if (strcmp(buf, "end_try_catch") == 0 || - strcmp(buf, "end_unwind_protect") == 0 || - strcmp(buf, "endfunction") == 0 || - strcmp(buf, "endwhile") == 0) - octave_syntax_detected = 1; - } - p = pe + 1; - } else p++; - } - - // Look for Limbo declarations - p = line; - while (p < eol) { - if (*p == ':' && (*(p + 1) == ' ' || *(p + 1) == '\t')) { - // /:[ \t]+(module|adt|fn ?\(|con[ \t])/ - p += 2; - if (strncmp(p, "module", 6) == 0 && !isalnum(*(p + 6)) || - strncmp(p, "adt", 3) == 0 && !isalnum(*(p + 3)) || - strncmp(p, "fn", 2) == 0 && - (*(p + 2) == ' ' && *(p + 3) == '(' || *(p + 2) == '(') || - strncmp(p, "con", 3) == 0 && - (*(p + 3) == ' ' || *(p + 3) == '\t')) - limbo_score++; - } else p++; - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - if (limbo_score > objective_c_score && limbo_score > matlab_score) - return LANG_LIMBO; - else if (objective_c_score > matlab_score) - return LANG_OBJECTIVE_C; - else - return octave_syntax_detected ? LANG_OCTAVE : LANG_MATLAB; -} - -#define QMAKE_SOURCES_SPACE "SOURCES +=" -#define QMAKE_SOURCES "SOURCES+=" -#define QMAKE_CONFIG_SPACE "CONFIG +=" -#define QMAKE_CONFIG "CONFIG+=" - -const char *disambiguate_pro(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - for (; p < eof; p++) { - if (strncmp(p, QMAKE_SOURCES_SPACE, strlen(QMAKE_SOURCES_SPACE)) == 0 || - strncmp(p, QMAKE_SOURCES, strlen(QMAKE_SOURCES)) == 0 || - strncmp(p, QMAKE_CONFIG_SPACE, strlen(QMAKE_CONFIG_SPACE)) == 0 || - strncmp(p, QMAKE_CONFIG, strlen(QMAKE_CONFIG)) == 0) - return LANG_MAKE; // really QMAKE - } - return LANG_IDL_PVWAVE; -} - -const char *disambiguate_st(SourceFile *sourcefile) { - char *p, *pe; - int length; - - // Attempt to detect based on file contents. - int found_assignment = 0, found_block_start = 0, found_block_end = 0; - - char line[81]; - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get a line at a time. - while (p < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - char *eol = line + strlen(line); - char *line_end = pe; - - for (p = line; p < eol; p++) { - if (*p == ':') { - p++; - while (p < eol && (*p == ' ' || *p == '\t')) p++; - if (*p == '=') - found_assignment = 1; - else if (*p == '[') - found_block_start = 1; - } else if (*p == ']' && *(p + 1) == '.') found_block_end = 1; - if (found_assignment && found_block_start && found_block_end) - return LANG_SMALLTALK; - } - - // Next line. - pe = line_end; - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } - - return NULL; -} - -int ohcount_is_binary_filename(const char *filename) { - char *p = (char *)filename + strlen(filename); - while (p > filename && *(p - 1) != '.') p--; - if (p > filename) { - struct ExtensionMap *re; - int length = strlen(p); - re = ohcount_hash_language_from_ext(p, length); - if (re) return ISBINARY(re->value); - // Try the lower-case version of this extension. - char lowerext[length]; - strncpy(lowerext, p, length); - lowerext[length] = '\0'; - for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p); - re = ohcount_hash_language_from_ext(lowerext, length); - if (re) return ISBINARY(re->value); - } - return 0; -} diff --git a/.pc/fix_null_dereference_2.patch/test/detect_files/empty.in b/.pc/fix_null_dereference_2.patch/test/detect_files/empty.in deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/fix_null_dereference_2.patch/test/unit/detector_test.h b/.pc/fix_null_dereference_2.patch/test/unit/detector_test.h deleted file mode 100644 index cd36b6d..0000000 --- a/.pc/fix_null_dereference_2.patch/test/unit/detector_test.h +++ /dev/null @@ -1,129 +0,0 @@ -// detector_test.h written by Mitchell Foral. mitchellcaladbolg.net. -// See COPYING for license information. - -#include -#include -#include - -#include "../../src/detector.h" -#include "../../src/languages.h" -#include "../../src/sourcefile.h" - -#define ASSERT_DETECT(x, y) { \ - SourceFile *sf = ohcount_sourcefile_new("../detect_files/" y); \ - const char *lang = ohcount_detect_language(sf); \ - assert(lang); \ - assert(strcmp(x, lang) == 0); \ - ohcount_sourcefile_free(sf); \ -} -#define ASSERT_NODETECT(x) { \ - SourceFile *sf = ohcount_sourcefile_new("../detect_files/" x); \ - assert(ohcount_detect_language(sf) == NULL); \ - ohcount_sourcefile_free(sf); \ -} - -void test_detector_smalltalk() { - ASSERT_DETECT(LANG_SMALLTALK, "example.st"); - ASSERT_NODETECT("english.st"); -} - -void test_detector_disambiguate_m() { - ASSERT_DETECT(LANG_OBJECTIVE_C, "t1.m"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "t2.m"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "TCPSocket.m"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.m"); - ASSERT_DETECT(LANG_MATLAB, "foo_matlab.m"); - ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m"); -} - -void test_detector_disambiguate_pro() { - ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); - ASSERT_DETECT(LANG_MAKE, "qmake.pro"); -} - -void test_detector_fortran_fixedfree() { - ASSERT_DETECT(LANG_FORTRANFIXED, "fortranfixed.f"); - ASSERT_DETECT(LANG_FORTRANFREE, "fortranfree.f"); -} - -void test_detector_detect_polyglot() { - ASSERT_DETECT(LANG_C, "foo.c"); - ASSERT_DETECT(LANG_C, "uses_no_cpp.h"); - ASSERT_DETECT(LANG_CPP, "uses_cpp_headers.h"); - ASSERT_DETECT(LANG_CPP, "uses_cpp_stdlib_headers.h"); - ASSERT_DETECT(LANG_CPP, "uses_cpp_keywords.h"); - ASSERT_DETECT(LANG_RUBY, "foo.rb"); - ASSERT_DETECT(LANG_MAKE, "foo.mk"); - ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.h"); - ASSERT_DETECT(LANG_PHP, "upper_case_php"); - ASSERT_DETECT(LANG_SMALLTALK, "example.st"); - ASSERT_DETECT(LANG_VALA, "foo.vala"); - ASSERT_DETECT(LANG_TEX, "foo.tex"); - ASSERT_DETECT(LANG_XSLT, "example.xsl"); - ASSERT_DETECT(LANG_LISP, "core.lisp"); - ASSERT_DETECT(LANG_DMD, "foo.d"); - ASSERT_DETECT(LANG_VIM, "foo.vim"); - ASSERT_DETECT(LANG_EBUILD, "foo.ebuild"); - ASSERT_DETECT(LANG_EBUILD, "foo.eclass"); - ASSERT_DETECT(LANG_EXHERES, "foo.exheres-0"); - ASSERT_DETECT(LANG_EXHERES, "foo.exlib"); - ASSERT_DETECT(LANG_EIFFEL, "eiffel.e"); - ASSERT_DETECT(LANG_OCAML, "ocaml.ml"); - ASSERT_DETECT(LANG_STRATEGO, "stratego.str"); - ASSERT_DETECT(LANG_R, "foo.R"); - ASSERT_DETECT(LANG_GLSL, "foo.glsl"); - ASSERT_DETECT(LANG_GLSL, "foo_glsl.vert"); - ASSERT_DETECT(LANG_GLSL, "foo_glsl.frag"); - ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); - ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80"); - ASSERT_DETECT(LANG_PHP, "php.inc"); - ASSERT_DETECT(LANG_FSHARP, "fs1.fs"); -} - -void test_detector_upper_case_extensions() { - ASSERT_DETECT(LANG_CPP, "foo_upper_case.C"); - ASSERT_DETECT(LANG_RUBY, "foo_upper_case.RB"); -} - -void test_detector_no_extensions() { - ASSERT_DETECT(LANG_PYTHON, "py_script"); - ASSERT_DETECT(LANG_RUBY, "ruby_script"); - ASSERT_DETECT(LANG_SHELL, "bourne_again_script"); - ASSERT_DETECT(LANG_SHELL, "bash_script"); - ASSERT_DETECT(LANG_PERL, "perl_w"); - ASSERT_DETECT(LANG_DMD, "d_script"); - ASSERT_DETECT(LANG_TCL, "tcl_script"); - ASSERT_DETECT(LANG_PYTHON, "python.data"); - ASSERT_DETECT(LANG_PYTHON, "python2.data"); -} - -void test_detector_csharp_or_clearsilver() { - ASSERT_DETECT(LANG_CSHARP, "cs1.cs"); - ASSERT_DETECT(LANG_CLEARSILVER_TEMPLATE, "clearsilver_template1.cs"); -} - -void test_detector_basic() { - ASSERT_DETECT(LANG_VISUALBASIC, "visual_basic.bas"); - ASSERT_DETECT(LANG_CLASSIC_BASIC, "classic_basic.b"); - system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2"); - ASSERT_DETECT(LANG_STRUCTURED_BASIC, "visual_basic.bas"); - ASSERT_DETECT(LANG_STRUCTURED_BASIC, "structured_basic.b"); - system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx"); -} - -void test_detector_xml_with_custom_extension() { - ASSERT_DETECT(LANG_XML, "xml.custom_ext"); -} - -void all_detector_tests() { - test_detector_smalltalk(); - test_detector_disambiguate_m(); - test_detector_disambiguate_pro(); - test_detector_fortran_fixedfree(); - test_detector_detect_polyglot(); - test_detector_upper_case_extensions(); - test_detector_no_extensions(); - test_detector_csharp_or_clearsilver(); - test_detector_basic(); - test_detector_xml_with_custom_extension(); -} diff --git a/.pc/rbconfig.patch/build b/.pc/rbconfig.patch/build deleted file mode 100755 index a990737..0000000 --- a/.pc/rbconfig.patch/build +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env bash -# Build script for Ohcount. -# Written by Mitchell Foral. mitchellcaladbolg.net. - -# Options -# Change these for your system configuration. -if [ `uname` != "Darwin" ] -then - # Linux - INC_DIR= - LIB_DIR= - - if [ `uname` == "FreeBSD" ] - then - INC_DIR=/usr/local/include - LIB_DIR=/usr/local/lib - fi - - # You shouldn't have to change the following. - CFLAGS=-O3 - CFLAGS="$CFLAGS -DTMP_FILES_ARE_DT_UNKNOWN" # workaround bug on centos/SF servers - WARN="-Wall -Wno-pointer-to-int-cast -Wno-parentheses" - SHARED=-shared - SHARED_NAME=libohcount.so - RB_SHARED=-shared - RB_SHARED_NAME=ohcount.so -else - # Mac OSX - INC_DIR=/opt/local/include - LIB_DIR=/opt/local/lib - # You shouldn't have to change the following. - CFLAGS="-fno-common -g" - WARN="-Wall -Wno-parentheses" - SHARED="-dynamiclib -L$LIB_DIR -lpcre" - SHARED_NAME=libohcount.dylib - RB_SHARED="-dynamic -bundle -lruby" - RB_SHARED_NAME=ohcount.bundle -fi - -# C compiler and flags -cc="gcc -fPIC -g $CFLAGS $WARN -I$INC_DIR -L$LIB_DIR" - -# Ohcount source files -files="src/sourcefile.c \ - src/detector.c \ - src/licenses.c \ - src/parser.o \ - src/loc.c \ - src/log.c \ - src/diff.c \ - src/parsed_language.c \ - src/hash/language_hash.c" - -# If any src/hash/*.gperf file is newer than the header files (which were -# presumably generated together), regenerate the headers. -build_hash_headers() -{ - if [[ -z `ls src/hash/ | grep "_hash.h$"` || - ! -z `find src/hash/*.gperf -newer src/hash/parser_hash.h` ]] - then - echo "Generating hash headers" - sh -c "cd src/hash/ && ./generate_headers" || exit 1 - fi -} - -# If src/parser.o does not exist, or if there are Ragel parsers or parser -# header files newer than the existing parser.o, recompile parser.o. -build_parser_o() -{ - if [[ ! -f src/parser.o || - ! -z `find src/parsers/*.{h,rl} -newer src/parser.o` ]] - then - bash -c "cd src/parsers/ && bash ./compile" || exit 1 - echo "Building src/parser.c (will take a while)" - bash -c "$cc -c src/parser.c -o src/parser.o" || exit 1 - fi -} - -build_shared() -{ - build_hash_headers - build_parser_o - if [[ ! -f src/$SHARED_NAME || - ! -z `find src/*.{h,c} -newer src/$SHARED_NAME` ]] - then - echo "Building shared library" - sh -c "$cc $SHARED $files -o src/$SHARED_NAME" || exit 1 - fi -} - -build_ohcount() -{ - build_hash_headers - build_parser_o - echo "Building Ohcount" - mkdir -p bin/ - sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre" || exit 1 -} - -build_test_suite() -{ - build_hash_headers - build_parser_o - echo "Building test suite" - sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre" \ - || exit 1 -} - -run_test_suite() -{ - echo "Running test suite" - echo "disabled test suite, does not work" -} - -build_ruby_bindings() -{ - arch=`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'` - echo "Generating Ruby bindings for $arch" - sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1 - mkdir -p ruby/$arch - sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \ - -I`ruby -rmkmf -e 'print Config::expand(CONFIG["archdir"])'` \ - -lpcre" || exit 1 - sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1 -} - -if [ $# -eq 0 ] || [ $1 == "all" ] -then - build_ohcount - build_test_suite - run_test_suite - echo $success -elif [ $1 == "shared" ] -then - build_shared - echo "Build successful; $SHARED_NAME is in src/" -elif [ $1 == "ohcount" ] -then - build_ohcount - echo "Build successful; ohcount is in bin/" -elif [ $1 == "tests" ] -then - build_test_suite - run_test_suite -elif [ $1 == "ruby" ] -then - build_ruby_bindings - echo "Build successful; $RB_SHARED_NAME is in ruby/$arch" -elif [ $1 == "clean" ] -then - rm -f bin/ohcount - rm -f test/unit/run_tests - rm -f src/parser.o - rm -f src/parsers/*.h - rm -f src/hash/*.h - rm -f src/hash/*.c - rm -f src/$SHARED_NAME - rm -f ruby/$RB_SHARED_NAME - rm -rf ruby/`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`/* -else - echo "Usage: build [all|ohcount|shared|tests|ruby|clean]" -fi diff --git a/.pc/txx_support.patch/src/hash/extensions.gperf b/.pc/txx_support.patch/src/hash/extensions.gperf deleted file mode 100644 index fcadae6..0000000 --- a/.pc/txx_support.patch/src/hash/extensions.gperf +++ /dev/null @@ -1,181 +0,0 @@ -%{ -#include "../languages.h" - -#define BINARY "\1" -#define DISAMBIGUATE(x) ("\2" x) -%} -struct ExtensionMap { const char *key; const char *value; }; -%% -C, LANG_CPP -H, LANG_CPP -ada, LANG_ADA -adb, LANG_ADA -ads, LANG_ADA -aiff, BINARY -as, LANG_ACTIONSCRIPT -ascx, DISAMBIGUATE("aspx") -asm, LANG_ASSEMBLER -aspx, DISAMBIGUATE("aspx") -au, BINARY -avi, BINARY -awk, LANG_AWK -b, DISAMBIGUATE("b") -bas, DISAMBIGUATE("basic") -bat, LANG_BAT -bi, DISAMBIGUATE("basic") -bmp, BINARY -bmx, LANG_BLITZMAX -boo, LANG_BOO -c, LANG_C -c++, LANG_CPP -cache, BINARY -cc, LANG_CPP -cmake, LANG_CMAKE -com, LANG_DCL -cpp, LANG_CPP -cs, DISAMBIGUATE("cs") -csproj, LANG_XML -css, LANG_CSS -ctp, LANG_PHP -cxx, LANG_CPP -d, LANG_DMD -dat, BINARY -di, LANG_DMD -doc, BINARY -dylan, LANG_DYLAN -e, LANG_EIFFEL -ebuild, LANG_EBUILD -eclass, LANG_EBUILD -el, LANG_EMACSLISP -erl, LANG_ERLANG -exheres-0, LANG_EXHERES -exlib, LANG_EXHERES -f, DISAMBIGUATE("fortran") -f03, DISAMBIGUATE("fortran") -f77, DISAMBIGUATE("fortran") -f90, DISAMBIGUATE("fortran") -f95, DISAMBIGUATE("fortran") -factor, LANG_FACTOR -frag, LANG_GLSL -frm, LANG_VISUALBASIC -frx, LANG_VISUALBASIC -fs, LANG_FSHARP -ftn, DISAMBIGUATE("fortran") -gif, BINARY -glsl, LANG_GLSL -groovy, LANG_GROOVY -gz, BINARY -h, DISAMBIGUATE("h") -h++, LANG_CPP -haml, LANG_HAML -hh, LANG_CPP -hpp, LANG_CPP -hrl, LANG_ERLANG -hs, LANG_HASKELL -htm, LANG_HTML -html, LANG_HTML -hx, LANG_HAXE -hxx, LANG_CPP -icns, BINARY -in, DISAMBIGUATE("in") -inc, DISAMBIGUATE("inc") -j, LANG_OBJECTIVE_J -jar, BINARY -java, LANG_JAVA -jpeg, BINARY -jpg, BINARY -js, LANG_JAVASCRIPT -jsp, LANG_JSP -kdebuild-1, LANG_EBUILD -latex, LANG_TEX -lisp, LANG_LISP -lsp, LANG_LISP -ltx, LANG_TEX -lua, LANG_LUA -m, DISAMBIGUATE("m") -m4a, BINARY -mf, LANG_METAFONT -mk, LANG_MAKE -ml, LANG_OCAML -ml4, LANG_OCAML -mli, LANG_OCAML -mm, LANG_OBJECTIVE_C -mov, BINARY -mp, LANG_METAPOST_WITH_TEX -mp3, BINARY -mpg, BINARY -mxml, LANG_MXML -nix, LANG_NIX -nse, LANG_LUA -ogg, BINARY -p6, LANG_PERL -pas, LANG_PASCAL -perl, LANG_PERL -pdf, BINARY -ph, LANG_PERL -php, LANG_PHP -php3, LANG_PHP -php4, LANG_PHP -php5, LANG_PHP -pike, LANG_PIKE -pl, LANG_PERL -pm, LANG_PERL -pmc, LANG_C -pmod, LANG_PIKE -png, BINARY -pnt, BINARY -pod, LANG_PERL -pp, LANG_PASCAL -ppt, BINARY -pro, DISAMBIGUATE("pro") -py, LANG_PYTHON -qt, BINARY -r, LANG_R -ra, BINARY -rb, LANG_RUBY -rex, LANG_REXX -rexx, LANG_REXX -rhtml, LANG_RHTML -s, LANG_ASSEMBLER -sc, LANG_SCHEME -scala, LANG_SCALA -sce, LANG_SCILAB -sci, LANG_SCILAB -scm, LANG_SCHEME -sh, LANG_SHELL -sls, LANG_SCHEME -sps, LANG_SCHEME -sql, LANG_SQL -ss, LANG_SCHEME -st, DISAMBIGUATE("st") -str, LANG_STRATEGO -svg, BINARY -svgz, BINARY -svn, BINARY -swf, BINARY -t, LANG_PERL -tar, BINARY -tcl, LANG_TCL -tex, LANG_TEX -tgz, BINARY -tif, BINARY -tiff, BINARY -tpl, LANG_HTML -vala, LANG_VALA -vb, LANG_VISUALBASIC -vba, LANG_VISUALBASIC -vbs, LANG_VISUALBASIC -vert, LANG_GLSL -vhd, LANG_VHDL -vhdl, LANG_VHDL -vim, LANG_VIM -wav, BINARY -xaml, LANG_XAML -xls, BINARY -xlw, BINARY -xml, LANG_XML -xs, LANG_C -xsd, LANG_XMLSCHEMA -xsl, LANG_XSLT -z80, LANG_ASSEMBLER -zip, BINARY diff --git a/README b/README deleted file mode 100644 index dfea440..0000000 --- a/README +++ /dev/null @@ -1,90 +0,0 @@ -== Ohcount - -NOTE: THE PRIMARY DOCUMENTATION FOR OHCOUNT IS EXTRACTED FROM SOURCE CODE -BY DOXYGEN. FOR THE MOST UP-TO-DATE DOCS, PLEASE SEE BELOW FOR INFO -ON BUILDING AND REFERING TO THE DOXYGEN DOCS. - -Ohloh/SourceForge's source code line counter. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License Version 2 as -published by the Free Software Foundation. - -Ohcount is specifically licensed under GPL v2.0, and no later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -== Overview - -Ohcount is a library for counting lines of source code. -It was originally developed at Ohloh, and is used to generate -the reports at www.ohloh.net. - -Ohcount supports multiple languages within a single file: for example, -a complex HTML document might include regions of both CSS and JavaScript. - -Ohcount has two main components: a detector which determines the primary -language family used by a particular source file, and a parser which -provides a line-by-line breakdown of the contents of a source file. - -Ohcount includes a command line tool that allows you to count individual -files or whole directory trees. It also allows you to find source code -files by language family, or to create a detailed annotation of an -individual source file. - -Ohcount includes a Ruby binding which allows you to directly access its -language detection features from a Ruby application. - -== System Requirements - -Ohcount is supported on Mac OS X 10.4 and 10.5 and Ubuntu 8.04 LTS. Other Linux -environments should also work, but your mileage may vary. - -Ohcount does not support Windows. - -Ohcount targets Ruby 1.8.6. The build script requires a bash shell. You -also need a C compiler to build the native extensions. - -== Source Code == - -Ohcount source code is available as a Git repository: - - git clone git://github.com/andyverprauskus/ohcount.git - -== Doc files == - -To build the more extensive Doxygen docs, do - > cd doc - > Doxygen Doxyfile - -After building the docs, view them with a browser by opening doc/html/index.html. -On a mac, you can install Doxygen with "sudo port install Doxygen". -On Debian/Ubuntu, install with "sudo apt-get instal doxygen". - -== Building Ohcount == - -You will need ragel 6.3 or higher, bash, pcre, gcc (version 4.1.2 or greater) and SWIG to build ohcount. Once you have them, go to the top directory of ohcount and type: - - > bash build -or > ./build - -== Using Ohcount == - -Once you've building ohcount, the executable program will be at bin/ohcount. The most basic use is to count lines of code in a directory tree, run: - "ohcount" to count the current directory and source code in any child directories - -== For additional docs, including how to add a new language, see the Doxygen docs == - -Particularly, for instructions on adding a new language, follow the instructions at doc/html/detector_doc.html -Read http://labs.ohloh.net/ohcount/wiki/HowToSubmitPatches for information about having your patch accepted. - - -DEPENDENCIES -============ -SWIG, pcre, ragel, bash diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4b477e --- /dev/null +++ b/README.md @@ -0,0 +1,100 @@ +Ohcount +======= + +Ohloh's source code line counter. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License Version 2 as +published by the Free Software Foundation. + +License +------- + +Ohcount is specifically licensed under GPL v2.0, and no later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Overview +-------- + +Ohcount is a library for counting lines of source code. +It was originally developed at Ohloh, and is used to generate +the reports at www.openhub.net. + +Ohcount supports multiple languages within a single file: for example, +a complex HTML document might include regions of both CSS and JavaScript. + +Ohcount has two main components: a detector which determines the primary +language family used by a particular source file, and a parser which +provides a line-by-line breakdown of the contents of a source file. + +Ohcount includes a command line tool that allows you to count individual +files or whole directory trees. It also allows you to find source code +files by language family, or to create a detailed annotation of an +individual source file. + +Ohcount includes a Ruby binding which allows you to directly access its +language detection features from a Ruby application. + +System Requirements +------------------- + +Ohcount is supported on Ubuntu 14.04 LTS. Other Linux +environments should also work, but your mileage may vary. + +Ohcount does not support Windows. + +Ohcount targets Ruby 1.9.3. The build script requires a bash shell. You +also need a C compiler to build the native extensions. + +Source Code +----------- + +Ohcount source code is available as a Git repository: + + git clone git://github.com/blackducksw/ohcount.git + +Building Ohcount +---------------- + +You will need ragel 6.8 or higher, bash, gperf, libpcre3-dev, libmagic-dev, gcc (version 4.8.2 or greater) +and SWIG (2.0.11). Once you have them, go to the top directory of ohcount and run + +``` +./build +``` + +Using Ohcount +------------- + +Once you've built ohcount, the executable program will be at bin/ohcount. The most basic use is to count lines of code in a directory tree. run: + +``` +bin/ohcount +``` + +Ohcount support several options. Run `ohcount --help` for more information. + +Building Ruby and Python Libraries +---------------------------------- + +To build the ruby wrapper: + +``` +./build ruby +``` + +To build the python wrapper, run + +``` +python python/setup.py build +python python/setup.py install +``` + +The python wrapper is currently unsupported. diff --git a/build b/build index 235834d..d3d79c0 100755 --- a/build +++ b/build @@ -18,7 +18,6 @@ # You shouldn't have to change the following. CFLAGS=-O3 - CFLAGS="$CFLAGS -DTMP_FILES_ARE_DT_UNKNOWN" # workaround bug on centos/SF servers WARN="-Wall -Wno-pointer-to-int-cast -Wno-parentheses" SHARED=-shared SHARED_NAME=libohcount.so @@ -39,6 +38,9 @@ # C compiler and flags cc="gcc -fPIC -g $CFLAGS $WARN -I$INC_DIR -L$LIB_DIR" + +# ARCHITECTURE +arch=`ruby/print_arch` # Ohcount source files files="src/sourcefile.c \ @@ -94,7 +96,7 @@ build_parser_o echo "Building Ohcount" mkdir -p bin/ - sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre" || exit 1 + sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre -lmagic" || exit 1 } build_test_suite() @@ -102,25 +104,28 @@ build_hash_headers build_parser_o echo "Building test suite" - sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre" \ + sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre -lmagic" \ || exit 1 } run_test_suite() { echo "Running test suite" - echo "disabled test suite, does not work" + sh -c "cd test/unit/ && ./run_tests" } + +RUBY_HEADER_DIR=`ruby -rmkmf -e 'print RbConfig::expand(CONFIG["rubyhdrdir"])'` +rbconfig_arch=`ruby -rmkmf -e 'print RbConfig::expand(CONFIG["arch"])'` +RUBY_CONFIG_DIR="$RUBY_HEADER_DIR/$rbconfig_arch" build_ruby_bindings() { - arch=`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'` echo "Generating Ruby bindings for $arch" sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1 mkdir -p ruby/$arch sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \ - -I`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["archdir"])'` \ - -lpcre" || exit 1 + -I$RUBY_HEADER_DIR -I$RUBY_CONFIG_DIR \ + -lpcre -lmagic" || exit 1 sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1 } @@ -129,6 +134,7 @@ build_ohcount build_test_suite run_test_suite + build_ruby_bindings echo $success elif [ $1 == "shared" ] then @@ -156,7 +162,8 @@ rm -f src/hash/*.c rm -f src/$SHARED_NAME rm -f ruby/$RB_SHARED_NAME - rm -rf ruby/`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'`/* + rm -rf ruby/$arch/* + rm -f ruby/ohcount_wrap.c else echo "Usage: build [all|ohcount|shared|tests|ruby|clean]" fi diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 815e282..0000000 --- a/debian/changelog +++ /dev/null @@ -1,120 +0,0 @@ -ohcount (3.0.0-8.4) unstable; urgency=medium - - * Standards-Version updated to 4.1.3 - * Update of Vcs-* - * Update of the homepage - * Add a watch file - - -- Sylvestre Ledru Sun, 14 Jan 2018 19:03:49 +0100 - -ohcount (3.0.0-8.3) unstable; urgency=medium - - * Non-maintainer upload. - * Remove ruby files from ohcount-doc, which only get installed - when building for Arch: all. (Closes: #818239) - - -- Christian Hofstaedtler Thu, 22 Dec 2016 06:54:28 +0000 - -ohcount (3.0.0-8.2) unstable; urgency=medium - - * Non-maintainer upload. - * Source-ful, binary-less upload to get rid of /ruby directory. - Probably somehow my fault? (Closes: #818239) - - -- Christian Hofstaedtler Sun, 17 Jul 2016 19:58:32 +0000 - -ohcount (3.0.0-8.1) unstable; urgency=medium - - * Non-maintainer upload. - * Fix build system being broken by removal of deprecated "Config" - object in Ruby 2.2. (Closes: #805674) - - -- Christian Hofstaedtler Tue, 01 Mar 2016 22:02:31 +0100 - -ohcount (3.0.0-8) unstable; urgency=low - - * Remove the explicit dependency on ruby 1.8 - Thanks to Jonas Genannt (Closes: #733724) - * Switch from cdbs to dh. Thanks to Jonas Genannt - * Standards-Version updated to 3.9.5 - - -- Sylvestre Ledru Thu, 16 Jan 2014 16:26:45 +0100 - -ohcount (3.0.0-7) unstable; urgency=low - - * Standards-Version updated to 3.9.4 - * libdifflcs-ruby dep renamed to ruby-diff-lcs (Closes: #707792) - * Remove Torsten from the uploaders (I have been DD for a while :) - * ACK NMU (thanks btw) - - -- Sylvestre Ledru Sat, 11 May 2013 19:17:57 +0200 - -ohcount (3.0.0-6.1) unstable; urgency=low - - * Non-maintainer upload. - * Add dependency on file (Closes: #677494). - - -- Luk Claes Wed, 04 Jul 2012 17:18:12 +0000 - -ohcount (3.0.0-6) unstable; urgency=low - - * Update some issues with the documentation (Closes: #650685) - - -- Sylvestre Ledru Sat, 10 Dec 2011 19:38:15 +0100 - -ohcount (3.0.0-5) unstable; urgency=low - - * Oups. Plug back the patches - * Manpage of ohcount added - - -- Sylvestre Ledru Fri, 30 Sep 2011 21:37:34 +0200 - -ohcount (3.0.0-4) unstable; urgency=low - - * Support of the txx extension (considered as C++). Thanks to Sébastien Dinot - for the patch. - * Switch to dpkg-source 3.0 (quilt) format - * Standards-Version updated to version 3.9.2 - * Fix debian-rules-uses-deprecated-makefile lintian warning - - -- Sylvestre Ledru Mon, 26 Sep 2011 13:42:49 +0200 - -ohcount (3.0.0-3) unstable; urgency=low - - * Standards-Version updated to version 3.9.1 - * Fix a seg fault when checking lintian source code. Thanks to - Raphael Geissert for investigating for me. (Closes: #608837) - (LP: #605631) - * Fix lintian warning copyright-refers-to-deprecated-bsd-license-file - - -- Sylvestre Ledru Sat, 15 Jan 2011 09:34:05 +0100 - -ohcount (3.0.0-2) unstable; urgency=low - - * Missing dependency (Closes: #558491) - - -- Sylvestre Ledru Sun, 29 Nov 2009 18:19:46 +0100 - -ohcount (3.0.0-1) unstable; urgency=low - - * New upstream release - * New package ohcount-doc added - * Homepage updated - * Vcs-* added - * Many changes on the debian/rules due to a refactoring from upstream which - has been done (patches are now obsolete or upstream) - * Upstream has redeveloped ohcount with C (instead of ruby). (Closes: #542892) - * Update of the watch file - * Repack script updated (upstream has a .so) - * Standards-Version updated to version 3.8.3 - * Change of my email address since I am now DD - * Standards-Version updated to 3.8.3 - * DM-Upload-Allowed removed - - -- Sylvestre Ledru Fri, 27 Nov 2009 11:22:21 +0100 - -ohcount (2.0.1-1) unstable; urgency=low - - * Initial release (Closes: #523006) - - -- Sylvestre Ledru Tue, 07 Apr 2009 20:18:38 +0200 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7f8f011..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/debian/control b/debian/control deleted file mode 100644 index 1d76f36..0000000 --- a/debian/control +++ /dev/null @@ -1,40 +0,0 @@ -Source: ohcount -Section: utils -Priority: optional -Maintainer: Sylvestre Ledru -Build-Depends: debhelper (>= 7), libpcre3-dev, gem2deb, rake, - ragel (>= 6.3), ruby-diff-lcs, doxygen, gperf, file -Standards-Version: 4.1.3 -Homepage: https://github.com/blackducksoftware/ohcount -Vcs-Git: https://salsa.debian.org/debian/ohcount.git -Vcs-Browser: https://salsa.debian.org/debian/ohcount -XS-Ruby-Versions: all - -Package: ohcount -XB-Ruby-Versions: ${ruby:Versions} -Architecture: any -Depends: ruby | ruby-interpreter, ${shlibs:Depends}, ${misc:Depends}, - ruby-diff-lcs, file -Suggests: ohcount-doc -Description: Source code line counter - Ohcount supports over 70 popular programming languages. - Ohcount does more than just count lines of code. It can also detect - popular open source licenses such as GPL within a large directory of source - code. It can also detect code that targets a particular programming API, - such as Win32 or KDE. - Ohcount is the line counter which powers http://www.ohloh.net/ - . - -Package: ohcount-doc -Section: doc -Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: Source code line counter - Documentation - Ohcount supports over 70 popular programming languages. - Ohcount does more than just count lines of code. It can also detect - popular open source licenses such as GPL within a large directory of source - code. It can also detect code that targets a particular programming API, - such as Win32 or KDE. - Ohcount is the line counter which powers http://www.ohloh.net/ - . - This package contains the documentation. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index cae0691..0000000 --- a/debian/copyright +++ /dev/null @@ -1,132 +0,0 @@ -This package was debianized by Sylvestre Ledru on -Tue, 07 Apr 2009 20:18:38 +0200. - -It was downloaded from - -Upstream Author: - - Ohloh - -Copyright: - - Copyright (C) 2007-2009 Ohloh - -License: - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -The full text of the license can be found in -`/usr/share/common-licenses/GPL-2'. - -The Debian packaging is (C) 2009, Sylvestre Ledru and -is licensed under the GPL, see `/usr/share/common-licenses/GPL'. - -ohcount incorporates some piece of code in order to test during build time -its capabilities. These files are not included in the binary. - - -Files: test/expected_dir/haxe1.hx test/src_dir/haxe1.hx - -Copyright: - Thomas Pfeiffer - kiroukou - Niel Drummond - -License: - Copyright the original author or authors. - Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.mozilla.org/MPL/MPL-1.1.html - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -Files: test/src_dir/pascal2.pp test/expected_dir/pascal2.pp - -Copyright: - Simon Steele 1998-2000 - -License: - BSD - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -Files: test/src_dir/js1.js test/expected_dir/js1.js - -Copyright: - 2005-2008 Sam Stephenson - -License: - MIT - - 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 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. - - -Files: test/src_dir/foo.ebuild test/detect_files/foo.ebuild - -License: - GPL-2 - -Files: test/src_dir/as1.as test/expected_dir/as1.as - -Copyright: - Sean Chatman and Garrett Woodworth 2008 - -License: - MIT - -Files: test/src_dir/perl_module.pm test/expected_dir/perl_module.pm - -Copyright: - Audrey Tang 2003-2007 - -License: - This program is free software; you can redistribute it and/or modify it - under the same terms as Perl itself. - - a) the GNU General Public License as published by the Free Software - Foundation; either version 1, or (at your option) any later - version, or - - b) the "Artistic License" which comes with Perl. - - On Debian GNU/Linux systems, the complete text of the GNU General - Public License can be found in `/usr/share/common-licenses/GPL' and - the Artistic Licence in `/usr/share/common-licenses/Artistic'. diff --git a/debian/ohcount-doc.doc-base b/debian/ohcount-doc.doc-base deleted file mode 100644 index dbb3297..0000000 --- a/debian/ohcount-doc.doc-base +++ /dev/null @@ -1,9 +0,0 @@ -Document: ohcount -Title: Debian ohcount Manual -Author: Ohloh -Abstract: ohcount manual -Section: Programming/Ruby - -Format: HTML -Index: /usr/share/doc/ohcount-doc/index.html -Files: /usr/share/doc/ohcount-doc/* diff --git a/debian/ohcount-doc.docs b/debian/ohcount-doc.docs deleted file mode 100644 index e845566..0000000 --- a/debian/ohcount-doc.docs +++ /dev/null @@ -1 +0,0 @@ -README diff --git a/debian/ohcount.1 b/debian/ohcount.1 deleted file mode 100644 index 4001863..0000000 --- a/debian/ohcount.1 +++ /dev/null @@ -1,67 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.39.4. -.TH OHCOUNT "1" "September 2011" "ohcount 3.0.0" "User Commands" -.SH NAME -ohcount \- manual page for ohcount 3.0.0 -.SH SYNOPSIS -.B ohcount -[\fIoption\fR] [\fIpaths\fR...] -.SH DESCRIPTION -Ohloh source code line counter command line tool. -.IP -http://www.ohloh.net/ -.SS "[option] can be one of the following:" -.HP -\fB\-a\fR, \fB\-\-annotate\fR -.HP -\fB\-d\fR, \fB\-\-detect\fR -.HP -\fB\-h\fR, \fB\-\-help\fR -.HP -\fB\-i\fR, \fB\-\-individual\fR -.HP -\fB\-l\fR, \fB\-\-license\fR -.HP -\fB\-re\fR -.HP -\fB\-s\fR, \fB\-\-summary\fR -.PP -\fB\-a\fR, \fB\-\-annotate\fR Show annotated source code -.IP -The contents of all source code files found within the given -paths will be emitted to stdout. Each line will be prefixed with -a tab\-delimited language name and semantic categorization (code, -comment, or blank). -.PP -\fB\-d\fR, \fB\-\-detect\fR Find source code files -.IP -Recursively find all source code files within the given paths. -For each source code file found, the file name will be emitted to -stdout prefixed with a tab\-delimited language name. -.PP -\fB\-h\fR, \fB\-\-help\fR Display this message -.PP -\fB\-i\fR, \fB\-\-individual\fR Count lines of code per file -.IP -Count lines in all source code files within the given paths, and -emit a report of the lines of code, comments, and blanks in each -language per file. -.PP -\fB\-l\fR, \fB\-\-license\fR -.IP -Displays detected licensing information contained in each source -code file. -.PP -\fB\-re\fR -.IP -Prints raw entity information to the screen (mainly for debugging). -.PP -\fB\-s\fR, \fB\-\-summary\fR Count lines of code (default) -.IP -Count lines in all source code files within the given paths, and -emit a report of the total number of lines of code, comments, -and blanks in each language. This is the default action. -.PP -[paths] can refer to any number of individual files or directories. -.IP -Directories will be probed recursively. If no path is given, -the current directory will be used. diff --git a/debian/ohcount.manpages b/debian/ohcount.manpages deleted file mode 100644 index fe3bc2c..0000000 --- a/debian/ohcount.manpages +++ /dev/null @@ -1,2 +0,0 @@ -debian/ohcount.1 - diff --git a/debian/orig-tar.exclude b/debian/orig-tar.exclude deleted file mode 100644 index 140f8cf..0000000 --- a/debian/orig-tar.exclude +++ /dev/null @@ -1 +0,0 @@ -*.so diff --git a/debian/orig-tar.sh b/debian/orig-tar.sh deleted file mode 100755 index 40c888c..0000000 --- a/debian/orig-tar.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -e - -# called by uscan with '--upstream-version' -DIR=ohcount-$2 -TAR=../ohcount_$2.orig.tar.gz - -# clean up the upstream tarball -tar zxf $3 -# Remove vendor/ because it is including -tar -c -z -X debian/orig-tar.exclude -f $TAR $DIR/ -rm -rf $DIR - -# move to directory 'tarballs' -if [ -r .svn/deb-layout ]; then - . .svn/deb-layout - mv $TAR $origDir - echo "moved $TAR to $origDir" -fi - diff --git a/debian/patches/disabled_test_suite.patch b/debian/patches/disabled_test_suite.patch deleted file mode 100644 index 8e6f3c2..0000000 --- a/debian/patches/disabled_test_suite.patch +++ /dev/null @@ -1,15 +0,0 @@ -Description: disable test suite on build time, does not work -Author: Jonas Genannt -Forwarded: not-needed - ---- a/build -+++ b/build -@@ -109,7 +109,7 @@ build_test_suite() - run_test_suite() - { - echo "Running test suite" -- sh -c "cd test/unit/ && ./run_tests" -+ echo "disabled test suite, does not work" - } - - build_ruby_bindings() diff --git a/debian/patches/fix_null_dereference.patch b/debian/patches/fix_null_dereference.patch deleted file mode 100644 index 01271dd..0000000 --- a/debian/patches/fix_null_dereference.patch +++ /dev/null @@ -1,58 +0,0 @@ -From a6783afcf61f18e9f1aef3e2655b30af7501c902 Mon Sep 17 00:00:00 2001 -From: Robin Luckey -Date: Thu, 1 Oct 2009 14:32:16 -0700 -Subject: [PATCH] [FIX] Avoid null dereference in disambiguate_inc() - ---- - src/detector.c | 18 ++++++++++-------- - test/unit/detector_test.h | 1 + - 2 files changed, 11 insertions(+), 8 deletions(-) - create mode 100644 test/detect_files/empty.inc - -diff --git a/src/detector.c b/src/detector.c -index 4d0e1f4..9b4d8d2 100644 ---- a/src/detector.c -+++ b/src/detector.c -@@ -452,14 +452,16 @@ const char *disambiguate_in(SourceFile *sourcefile) { - - const char *disambiguate_inc(SourceFile *sourcefile) { - char *p = ohcount_sourcefile_get_contents(sourcefile); -- char *eof = p + strlen(p); -- while (p < eof) { -- if (*p == '\0') -- return BINARY; -- else if (*p == '?' && strncmp(p + 1, "php", 3) == 0) -- return LANG_PHP; -- p++; -- } -+ if (p) { -+ char *eof = p + strlen(p); -+ while (p < eof) { -+ if (*p == '\0') -+ return BINARY; -+ else if (*p == '?' && strncmp(p + 1, "php", 3) == 0) -+ return LANG_PHP; -+ p++; -+ } -+ } - return NULL; - } - -diff --git a/test/detect_files/empty.inc b/test/detect_files/empty.inc -new file mode 100644 -index 0000000..e69de29 -diff --git a/test/unit/detector_test.h b/test/unit/detector_test.h -index cd36b6d..628b6cc 100644 ---- a/test/unit/detector_test.h -+++ b/test/unit/detector_test.h -@@ -77,6 +77,7 @@ void test_detector_detect_polyglot() { - ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); - ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80"); - ASSERT_DETECT(LANG_PHP, "php.inc"); -+ ASSERT_NODETECT("empty.inc"); - ASSERT_DETECT(LANG_FSHARP, "fs1.fs"); - } - --- -1.7.0.1 - diff --git a/debian/patches/fix_null_dereference_2.patch b/debian/patches/fix_null_dereference_2.patch deleted file mode 100644 index dd3c735..0000000 --- a/debian/patches/fix_null_dereference_2.patch +++ /dev/null @@ -1,53 +0,0 @@ -From c0b28d67f27f6e954c93dabd71d098854896d679 Mon Sep 17 00:00:00 2001 -From: Robin Luckey -Date: Thu, 1 Oct 2009 15:43:42 -0700 -Subject: [PATCH] [FIX] Null dereference error in disambiguate_in() - ---- - src/detector.c | 3 +++ - test/unit/detector_test.h | 4 ++++ - 2 files changed, 7 insertions(+), 0 deletions(-) - create mode 100644 test/detect_files/empty.in - -diff --git a/src/detector.c b/src/detector.c -index 9b4d8d2..863b379 100644 ---- a/src/detector.c -+++ b/src/detector.c -@@ -437,6 +437,9 @@ const char *disambiguate_in(SourceFile *sourcefile) { - buf[length] = '\0'; - SourceFile *undecorated = ohcount_sourcefile_new(buf); - p = ohcount_sourcefile_get_contents(sourcefile); -+ if (!p) { -+ return NULL; -+ } - // The filepath without the '.in' extension does not exist on disk. The - // sourcefile->diskpath field must be set incase the detector needs to run - // 'file -b' on the file. -diff --git a/test/detect_files/empty.in b/test/detect_files/empty.in -new file mode 100644 -index 0000000..e69de29 -diff --git a/test/unit/detector_test.h b/test/unit/detector_test.h -index 628b6cc..a26adaa 100644 ---- a/test/unit/detector_test.h -+++ b/test/unit/detector_test.h -@@ -36,6 +36,9 @@ void test_detector_disambiguate_m() { - ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m"); - } - -+void test_detector_disambiguate_in() { -+ ASSERT_NODETECT("empty.in"); -+} - void test_detector_disambiguate_pro() { - ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); - ASSERT_DETECT(LANG_MAKE, "qmake.pro"); -@@ -119,6 +122,7 @@ void test_detector_xml_with_custom_extension() { - void all_detector_tests() { - test_detector_smalltalk(); - test_detector_disambiguate_m(); -+ test_detector_disambiguate_in(); - test_detector_disambiguate_pro(); - test_detector_fortran_fixedfree(); - test_detector_detect_polyglot(); --- -1.7.0.1 - diff --git a/debian/patches/rbconfig.patch b/debian/patches/rbconfig.patch deleted file mode 100644 index 123e773..0000000 --- a/debian/patches/rbconfig.patch +++ /dev/null @@ -1,28 +0,0 @@ -Index: ohcount-3.0.0/build -=================================================================== ---- ohcount-3.0.0.orig/build -+++ ohcount-3.0.0/build -@@ -114,12 +114,12 @@ run_test_suite() - - build_ruby_bindings() - { -- arch=`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'` -+ arch=`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'` - echo "Generating Ruby bindings for $arch" - sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1 - mkdir -p ruby/$arch - sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \ -- -I`ruby -rmkmf -e 'print Config::expand(CONFIG["archdir"])'` \ -+ -I`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["archdir"])'` \ - -lpcre" || exit 1 - sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1 - } -@@ -156,7 +156,7 @@ then - rm -f src/hash/*.c - rm -f src/$SHARED_NAME - rm -f ruby/$RB_SHARED_NAME -- rm -rf ruby/`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`/* -+ rm -rf ruby/`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'`/* - else - echo "Usage: build [all|ohcount|shared|tests|ruby|clean]" - fi diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index 8ad8876..0000000 --- a/debian/patches/series +++ /dev/null @@ -1,5 +0,0 @@ -fix_null_dereference_2.patch -fix_null_dereference.patch -txx_support.patch -disabled_test_suite.patch -rbconfig.patch diff --git a/debian/patches/txx_support.patch b/debian/patches/txx_support.patch deleted file mode 100644 index 5f62401..0000000 --- a/debian/patches/txx_support.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur ohcount-3.0.0/src/hash/extensions.gperf ohcount-3.0.1/src/hash/extensions.gperf ---- ohcount-3.0.0/src/hash/extensions.gperf 2009-09-30 17:30:19.000000000 +0000 -+++ ohcount-3.0.1/src/hash/extensions.gperf 2011-09-26 09:32:34.000000000 +0000 -@@ -161,6 +161,7 @@ - tif, BINARY - tiff, BINARY - tpl, LANG_HTML -+txx, LANG_CPP - vala, LANG_VALA - vb, LANG_VISUALBASIC - vba, LANG_VISUALBASIC - diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 71438b1..0000000 --- a/debian/rules +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/make -f - -%: - dh $@ --buildsystem=ruby --with ruby - -override_dh_auto_clean: - dh_auto_clean -O--buildsystem=ruby - ./build clean - rm -rf doc_build - -override_dh_install: - ./build all - dh_install --buildsystem=ruby --with ruby - install -d debian/ohcount/usr/lib/ruby/vendor_ruby/ohcount - install -d debian/ohcount/usr/bin - install -d debian/ohcount-doc/usr/share/doc/ohcount-doc - cp bin/ohcount debian/ohcount/usr/bin/ - cp -R ruby/gestalt ruby/gestalt.rb ruby/ohcount.rb debian/ohcount/usr/lib/ruby/vendor_ruby/ohcount/ - # build doxygen - mkdir doc_build - cp -aR doc/* doc_build/ - (cd doc_build && doxygen Doxyfile) - cp -aR doc_build/html/* debian/ohcount-doc/usr/share/doc/ohcount-doc - rm -rf debian/ohcount/ruby debian/ohcount-doc/ruby - -get-orig-source: - uscan --force-download diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8..0000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/debian/watch b/debian/watch deleted file mode 100644 index b74a5ea..0000000 --- a/debian/watch +++ /dev/null @@ -1,6 +0,0 @@ -version=4 -opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%ohcount-$1.tar.gz%" \ - https://github.com/blackducksoftware/ohcount/tags \ - (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate - - diff --git a/doc/examples/parser_doc_3 b/doc/examples/parser_doc_3 index f72667f..f6f4c17 100644 --- a/doc/examples/parser_doc_3 +++ b/doc/examples/parser_doc_3 @@ -1,7 +1,7 @@ %%{ machine c; write data; - include "common.rl"; + include common "common.rl"; ... }%% diff --git a/python/__init__.py b/python/__init__.py new file mode 100644 index 0000000..d84397d --- /dev/null +++ b/python/__init__.py @@ -0,0 +1,234 @@ +import os, collections +from abc import abstractmethod +import ohcount + +class _OhcountBase(object): + + def __init__(self, base): + self._base = base + + def __getattr__(self, name): + if name == '_base': + return object.__getattr__(self, name) + raise AttributeError + + def __setattr__(self, name, value): + if name == '_base': + return object.__setattr__(self, name, value) + raise AttributeError + +class _OhcountDict(_OhcountBase, collections.Mapping, collections.KeysView): + + def __init__(self, base, mapping): + _OhcountBase.__init__(self, base) + collections.KeysView.__init__(self, mapping) + + def __getattr__(self, name): + if name == '_mapping': + return collections.KeysView.__getattr__(self, name) + try: + return _OhcountBase.__getattr__(self, name) + except AttributeError: + try: + return self.__getitem__(name) + except KeyError: + raise AttributeError + except: + raise + + def __setattr__(self, name, value): + if name == '_mapping': + return collections.KeysView.__setattr__(self, name, value) + try: + return _OhcountBase.__setattr__(self, name, value) + except AttributeError: + try: + return self.__setitem__(name, value) + except KeyError: + raise AttributeError + except: + raise + + def keys(self): + return self._mapping + + def __setitem__(self, key, item): + raise KeyError + + def __delitem__(self, key): + raise KeyError + + def __str__(self): + return dict([(key, self[key]) for key in self.keys()]).__str__() + + def iterkeys(self): + return iter(self.keys()) + + def itervalues(self): + for key in self.keys(): + yield self[key] + + def iteritems(self): + for key in self.keys(): + yield (key, self[key]) + + def items(self): + return [(key, self[key]) for key in self.keys()] + + def values(self): + return [self[key] for key in self.keys()] + +class _OhcountList(_OhcountBase): + + @abstractmethod + def _get_value(self, inner): + raise NotImplementedError + + def __len__(self): + count = 0 + for e in self: + count += 1 + return count + + def __iter__(self): + return self.next() + + def next(self): + iter = self._base.head + while iter is not None: + yield self._get_value(iter) + iter = iter.next + + def __str__(self): + return [v for v in self].__str__() + +class License(_OhcountDict): + + def __init__(self, base): + _OhcountDict.__init__(self, base, + ['name','url','nice_name']) + + def __getitem__(self, key): + if key == 'name': + return self._base.name + if key == 'url': + return self._base.url + if key == 'nice_name': + return self._base.nice_name + raise KeyError + +class Loc(_OhcountDict): + + def __init__(self, base): + _OhcountDict.__init__(self, base, + ['lang','code','comments','blanks','filecount','total']) + + def __getitem__(self, key): + if key == 'lang' or key == 'language': + return self._base.language + if key == 'code': + return self._base.code + if key == 'comments': + return self._base.comments + if key == 'blanks': + return self._base.blanks + if key == 'filecount': + return self._base.filecount + if key == 'total': + return self._base.total() + raise KeyError + +class LocList(_OhcountDict, _OhcountList): + + def __init__(self, base): + _OhcountDict.__init__(self, base, + ['code','comments','blanks','filecount','total']) + + def _get_value(self, inner): + return Loc(inner.loc) + + def __getitem__(self, key): + if key == 'code': + return self._base.code() + if key == 'comments': + return self._base.comments() + if key == 'blanks': + return self._base.blanks() + if key == 'filecount': + return self._base.filecount() + if key == 'total': + return self._base.total() + raise KeyError + + def __str__(self): + return _OhcountDict.__str__(self) + + def compact(self): + return LocList(self._base.compact()) + +class SourceFile(_OhcountDict): + + def __init__(self, base): + _OhcountDict.__init__(self, base, + ['filepath','filename','ext','contents','size','language', + 'licenses','locs']) + + def _get_licenses(self): + result = [] + list = self._base.get_license_list() + if list is not None: + iter = list.head + while iter is not None: + result.append(License(iter.lic)) + iter = iter.next + return result + + def _get_locs(self): + return LocList(self._base.get_loc_list()) + + def __getitem__(self, key): + if key == 'filepath': + return self._base.filepath + if key == 'filename': + return self._base.filename + if key == 'ext': + return self._base.ext + if key == 'contents': + return self._base.get_contents() + if key == 'size': + return self._base.contents_size() + if key == 'language': + return self._base.get_language() + if key == 'licenses': + return self._get_licenses() + if key == 'locs': + return self._get_locs() + raise AttributeError + + def annotate(self): + return self._base.annotate() + + def raw_entities(self): + return self._base.raw_entities() + +class SourceFileList(_OhcountList): + + def __init__(self, **kwargs): + _OhcountList.__init__(self, ohcount.SourceFileList(kwargs)) + + def _get_value(self, inner): + return SourceFile(inner.sf) + + def analyze_languages(self): + return LocList( self._base.analyze_languages() ) + + def add_directory(self, path): + if not os.path.isdir(path): + raise SyntaxError('Input path is not a directory: %s' % path) + self._base.add_directory(path) + + def add_file(self, filepath): + if not os.path.isfile(filepath): + raise SyntaxError('Input path is not a file: %s' % filepath) + self._base.add_file(filepath) + diff --git a/python/mingw_setup.py b/python/mingw_setup.py new file mode 100644 index 0000000..1be8a29 --- /dev/null +++ b/python/mingw_setup.py @@ -0,0 +1,100 @@ +#=== mingw_setup.py by Phillip J. Eby +"""Create pythonNN.def and libpythonNN.a in 'PythonNN/libs' directory + +This script makes it possible to use the MinGW compiler tools to +build C extensions that work with the standard Windows Python +distribution. + +Before running, you should have installed the MinGW compiler toolset, +and placed its 'bin' directory on your PATH. An easy way to do this +is to install Cygwin's "binutils", "gcc", and "mingw-*" packages, +then run this script from the Cygwin shell. (Be sure to use *Windows* +Python, not Cygwin python!) + +Once this script has been run, you should be able to build extensions +using distutils in the standard way, as long as you select the +'mingw32' compiler, and the required tools are on your PATH. See +the "Installing Python Modules" manual for more information on +selecting a compiler. +""" + + +from distutils.spawn import find_executable +from distutils.sysconfig import get_config_var +from distutils import __file__ as distutils_file +import os, re, sys + +if sys.platform=='cygwin': + print "Please run this script using Windows python,", + print "not Cygwin python. E.g, try:" + print + print "/cygdrive/c/PythonNN/python", " ".join(sys.argv) + print + print "(where NN is the major/minor python version number)" + sys.exit() + +basename = 'python%d%d' % sys.version_info[:2] + +libs_dir = os.path.join(get_config_var('prefix'),'libs') +lib_file = os.path.join(libs_dir,basename+'.lib') +def_file = os.path.join(libs_dir,basename+'.def') +ming_lib = os.path.join(libs_dir,'lib%s.a' % basename) + +distutils_cfg = os.path.join(os.path.dirname(distutils_file),'distutils.cfg') + +export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match + +nm = find_executable('nm') +dlltool = find_executable('dlltool') + +if not nm or not dlltool: + print "'nm' and/or 'dlltool' were not found;" + print "Please make sure they're on your PATH." + sys.exit() + +nm_command = '%s -Cs %s' % (nm, lib_file) + +print "Building", def_file, "using", nm_command +f = open(def_file,'w') +print >>f, "LIBRARY %s.dll" % basename +print >>f, "EXPORTS" + + +nm_pipe = os.popen(nm_command) +for line in nm_pipe.readlines(): + m = export_match(line) + if m: + print >>f, m.group(1) +f.close() + +exit = nm_pipe.close() +if exit: + print "nm exited with status", exit + print "Please check that", lib_file, "exists and is valid." + sys.exit() + + +print "Building",ming_lib,"using",dlltool +dlltool_pipe = os.popen( + "%s --dllname %s.dll --def %s --output-lib %s" % + (dlltool, basename, def_file, ming_lib) +) + +dlltool_pipe.readlines() +exit = dlltool_pipe.close() +if exit: + print "dlltool exited with status", exit + print "Unable to proceed." + sys.exit() + +print +print "Installation complete. You may wish to add the following" +print "lines to", distutils_cfg, ':' +print +print "[build]" +print "compiler = mingw32" +print +print "This will make the distutils use MinGW as the default" +print "compiler, so that you don't need to configure this for" +print "every 'setup.py' you run." + diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 0000000..5c78c60 --- /dev/null +++ b/python/setup.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python + +import distutils.ccompiler +from distutils.core import setup, Extension +from distutils.command.build import build +from distutils.command.build_ext import build_ext +from distutils.command.install_lib import install_lib +import os, sys +from glob import glob + +if not hasattr(sys, 'version_info') or sys.version_info < (2,6,0,'final'): + raise SystemExit("Ohcount requires Python 2.6 or later.") + +class build_ohcount(build): + """Ohcount already have a script named 'build', from the original package, + so it conflicts with Python default build path. To solve this, setup.py + will use the directory 'build-python' instead. The original distutils + execute 'build_py' before 'build_ext', but we need the wrapper ohcount.py + created by SWIG to be installed too, so we need to invert this order. + """ + + sub_commands = [('build_ext', build.has_ext_modules), # changed + ('build_py', build.has_pure_modules), # changed + ('build_clib', build.has_c_libraries), + ('build_scripts', build.has_scripts), + ] + + def initialize_options(self): + build.initialize_options(self) + self.build_base = 'build-python' + +def newer_than(srclist, dstlist): + for left, right in zip(srclist, dstlist): + if not os.path.exists(right): + return True + left_stat = os.lstat(left) + right_stat = os.lstat(right) + if left_stat.st_mtime > right_stat.st_mtime: + return True + return False + +class build_ohcount_ext(build_ext): + """This class implements extra steps needed by Ohcount build process.""" + + def run(self): + parsers = glob('src/parsers/*.rl') + parsers_h = [f.replace('.rl', '.h') for f in parsers] + if newer_than(parsers, parsers_h): + os.system('cd src/parsers/ && bash ./compile') + hash_files = glob('src/hash/*.gperf') + hash_srcs = [] + for f in hash_files: + if not f.endswith('languages.gperf'): + hash_srcs.append(f.replace('s.gperf', '_hash.h')) + else: + hash_srcs.append(f.replace('s.gperf', '_hash.c')) + if newer_than(hash_files, hash_srcs): + os.system('cd src/hash/ && bash ./generate_headers') + return build_ext.run(self) + +# Overwrite default Mingw32 compiler +(module_name, class_name, long_description) = \ + distutils.ccompiler.compiler_class['mingw32'] +module_name = "distutils." + module_name +__import__(module_name) +module = sys.modules[module_name] +Mingw32CCompiler = vars(module)[class_name] + +class Mingw32CCompiler_ohcount(Mingw32CCompiler): + """Ohcount CCompiler version for Mingw32. There is a problem linking + against msvcrXX for Python 2.6.4: as both DLLs msvcr and msvcr90 are + loaded, it seems to happen some unexpected segmentation faults in + several function calls.""" + + def __init__(self, *args, **kwargs): + Mingw32CCompiler.__init__(self, *args, **kwargs) + self.dll_libraries=[] # empty link libraries list + +_new_compiler = distutils.ccompiler.new_compiler + +def ohcount_new_compiler(plat=None,compiler=None,verbose=0,dry_run=0,force=0): + if compiler == 'mingw32': + inst = Mingw32CCompiler_ohcount(None, dry_run, force) + else: + inst = _new_compiler(plat,compiler,verbose,dry_run,force) + return inst + +distutils.ccompiler.new_compiler = ohcount_new_compiler + +# Ohcount python extension +ext_modules=[ + Extension( + name='ohcount._ohcount', + sources= [ + 'ruby/ohcount.i', + 'src/sourcefile.c', + 'src/detector.c', + 'src/licenses.c', + 'src/parser.c', + 'src/loc.c', + 'src/log.c', + 'src/diff.c', + 'src/parsed_language.c', + 'src/hash/language_hash.c', + ], + libraries=['pcre'], + swig_opts=['-outdir', './python/'], + ) +] + +setup( + name='ohcount', + version = '3.0.0', + description = 'Ohcount is the source code line counter that powers Ohloh.', + long_description = + 'Ohcount supports over 70 popular programming languages, and has been ' + 'used to count over 6 billion lines of code by 300,000 developers! ' + 'Ohcount does more more than just count lines of code. It can also ' + 'detect popular open source licenses such as GPL within a large ' + 'directory of source code. It can also detect code that targets a ' + 'particular programming API, such as Win32 or KDE.', + author = 'Mitchell Foral', + author_email = 'mitchell@caladbolg.net', + license = 'GNU GPL', + platforms = ['Linux','Mac OSX'], + keywords = ['ohcount','ohloh','loc','source','code','line','counter'], + url = 'http://www.ohloh.net/p/ohcount', + download_url = 'http://sourceforge.net/projects/ohcount/files/', + packages = ['ohcount'], + package_dir = {'ohcount': 'python'}, + classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'License :: OSI Approved :: GNU General Public License (GPL)' + 'Intended Audience :: Developers', + 'Natural Language :: English', + 'Programming Language :: C', + 'Programming Language :: Python', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], + ext_modules=ext_modules, + cmdclass={ + 'build': build_ohcount, + 'build_ext': build_ohcount_ext, + }, +) + diff --git a/ruby/gestalt/definition.rb b/ruby/gestalt/definition.rb index 9d9419a..b565fe1 100644 --- a/ruby/gestalt/definition.rb +++ b/ruby/gestalt/definition.rb @@ -13,7 +13,6 @@ require 'gestalt/rules/gestalt_rule' require 'gestalt/rules/java_import_rule' require 'gestalt/rules/csharp_using_rule' -require 'gestalt/rules/find_java_imports_rule' require 'gestalt/rules/maven_parser' require 'gestalt/rules/maven_rule' require 'gestalt/rules/csproj_parser' diff --git a/ruby/gestalt/dot_net_definitions.rb b/ruby/gestalt/dot_net_definitions.rb index abb6701..78d5a1b 100644 --- a/ruby/gestalt/dot_net_definitions.rb +++ b/ruby/gestalt/dot_net_definitions.rb @@ -2,89 +2,17 @@ module Gestalt define_platform 'dot_net' do - language :csharp, :min_percent => 10 + _or do + language :csharp, :min_percent => 10 + gestalt :platform, 'asp_net' + gestalt :platform, 'wpf' + gestalt :platform, 'silverlight' + end end define_platform 'asp_net' do filenames('\.(aspx|ascx|ashx|asax|axd)$') end - - define_platform 'nunit' do - _and do - gestalt(:platform, 'dot_net') - csharp_using /^NUnit\b/ - end - end - - define_platform 'nhibernate' do - _and do - gestalt(:platform, 'dot_net') - csharp_using /^NHibernate\b/ - end - end - - # BizTalk - define_platform 'dot_net_biztalk' do - _and do - gestalt(:platform, 'dot_net') - _or do - csharp_using /^Microsoft\.Solutions\b/ - csharp_using /^Microsoft\.BizTalk\b/ - end - end - end - - # Connected Services Framework - define_platform 'dot_net_csf' do - _and do - gestalt(:platform, 'dot_net') - csharp_using /^Microsoft\.Csf\b/ - end - end - - # Microsoft Content Management Server - define_platform 'dot_net_cms' do - _and do - gestalt(:platform, 'dot_net') - csharp_using /^Microsoft\.ContentManagement\b/ - end - end - - # Exchange - define_platform 'dot_net_exchange' do - _and do - gestalt(:platform, 'dot_net') - csharp_using /^Microsoft\.Exchange\b/ - end - end - - # Microsoft Operations Manager (Mom) - define_platform 'dot_net_mom' do - _and do - gestalt(:platform, 'dot_net') - csharp_using /^Microsoft\.EnterpriseManagement\.Mom\b/ - end - end - - # A general category of software. - # Not a particular technology, but it "smells" like middle-tier/enterprise software. - define_platform 'dot_net_enterprise' do - _and do - gestalt(:platform, 'dot_net') - _or do - gestalt(:platform, 'dot_net_biztalk') - gestalt(:platform, 'dot_net_exchange') - gestalt(:platform, 'dot_net_cms') - gestalt(:platform, 'dot_net_csf') - gestalt(:platform, 'dot_net_mom') - csharp_using /^System\.Runtime\.Remoting\b/ - csharp_using /^System\.DirectoryServices\b/ - csharp_using /^System\.ServiceModel\b/ - csharp_using /^System\.(Data\.)?Linq\b/ - csharp_using /^System\.Data\b/ - end - end - end define_platform 'wpf' do filenames '\.xaml$' diff --git a/ruby/gestalt/jasper_definitions.rb b/ruby/gestalt/jasper_definitions.rb index 70609f2..fd6ba52 100644 --- a/ruby/gestalt/jasper_definitions.rb +++ b/ruby/gestalt/jasper_definitions.rb @@ -29,7 +29,7 @@ define_platform 'jasper_reports_java' do _or do maven_dependency /jasperreports/ - java_keywords '\bnet\.sf\.jasperreports\b' + java_keywords '\bnet\.sf\.jasperreports\b' end end diff --git a/ruby/gestalt/java_definitions.rb b/ruby/gestalt/java_definitions.rb index 2c31103..4a82a2d 100644 --- a/ruby/gestalt/java_definitions.rb +++ b/ruby/gestalt/java_definitions.rb @@ -1,13 +1,5 @@ module Ohcount module Gestalt - - define_java_jar do - find_filenames /([^\\^\/]*\.jar)/i, :name_from_match => 1 - end - - define_java_import do - find_java_imports - end # Java Application Servers diff --git a/ruby/gestalt/rules/filename_rule.rb b/ruby/gestalt/rules/filename_rule.rb index 8f14e13..a658c7c 100644 --- a/ruby/gestalt/rules/filename_rule.rb +++ b/ruby/gestalt/rules/filename_rule.rb @@ -11,7 +11,7 @@ end def process_source_file(source_file) - @count += 1 if regex.match(source_file.filename) + @count += 1 if regex.match(source_file.filepath) end def regex diff --git a/ruby/gestalt/rules/find_java_imports_rule.rb b/ruby/gestalt/rules/find_java_imports_rule.rb deleted file mode 100644 index 3625706..0000000 --- a/ruby/gestalt/rules/find_java_imports_rule.rb +++ /dev/null @@ -1,54 +0,0 @@ -module Ohcount - module Gestalt - - # Will yield one trigger per java import - each with the name of the imported - # namespace. Example java source file: - # - # import com.foo.bar; - # - # will yield a trigger with name='com.foo.bar' - class FindJavaImportsRule < FileRule - attr_reader :keywords, :language - - def initialize(*args) - @trigger_hash = {} - super(*args) - end - - def process_source_file(source_file) - return unless source_file.language_breakdown('java') - - java_code = source_file.language_breakdown('java').code - java_code.scan(import_regexp).each do |matches| - name = matches[0] - @trigger_hash[name] = @trigger_hash[name].to_i + 1 - end - end - - # implement deep clone - def clone - self.class.new(:min => @min_count) - end - - def triggers(gestalt_engine) - triggers = [] - @trigger_hash.each do |k,v| - triggers << Trigger.new(:name => FindJavaImportsRule.truncate_name(k, 3), :count => v) - end - triggers - end - - def import_regexp - /^\s*import\s+([a-zA-Z][\w\.\*\-]*)\b/ - end - - # Truncates the java import namespace to a maximum depth. - # For instance, - # truncate_name("com.sun.identity.authentication", 3) => "com.sun.identity" - def self.truncate_name(s, max_depth) - s.to_s.split('.')[0, max_depth].join('.') - end - - end - end -end diff --git a/ruby/gestalt/rules/logical_rule.rb b/ruby/gestalt/rules/logical_rule.rb index d62b838..32d1856 100644 --- a/ruby/gestalt/rules/logical_rule.rb +++ b/ruby/gestalt/rules/logical_rule.rb @@ -85,10 +85,6 @@ new_rule FindFilenamesRule, *args end - def find_java_imports(*args) - new_rule FindJavaImportsRule, *args - end - def method_missing(m,*args, &block) if m.to_s =~ /^(.*)_keywords$/ language = $1 diff --git a/ruby/ohcount.i b/ruby/ohcount.i index f0b4004..38212fa 100644 --- a/ruby/ohcount.i +++ b/ruby/ohcount.i @@ -8,10 +8,12 @@ %include typemaps.i +#if defined(SWIGRUBY) + %typemap(in) (register const char *str, register unsigned int len) { Check_Type($input, T_STRING); - $1 = STR2CSTR($input); - $2 = RSTRING($input)->len; + $1 = StringValuePtr($input); + $2 = RSTRING_LEN($input); }; %typemap(out) char ** { @@ -22,12 +24,60 @@ $result = arr; }; +#elif defined(SWIGPYTHON) + +%typemap(in) (register const char *str, register unsigned int len) { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_SyntaxError, "Invalid parameter"); + return NULL; + } + $1 = PyString_AsString($input); + $2 = PyString_Size($input); +}; + +%typemap(out) char ** { + int i; + PyObject *arr = PyList_New(0); + for (i = 0; $1[i] != NULL; i++) + PyList_Append(arr, PyString_FromString($1[i])); + $result = arr; +}; + + +#else +#error "You should define specific translation rules for this language." +#endif + %nodefaultctor SourceFile; %immutable; %include "../src/languages.h" %include "../src/structs.h" %mutable; +%extend Loc { + int total() { + return ohcount_loc_total(self); + } +} + +%extend LocListItem { + int code() { + return ohcount_loc_list_code(self); + } + int comments() { + return ohcount_loc_list_comments(self); + } + int blanks() { + return ohcount_loc_list_blanks(self); + } + int total() { + return ohcount_loc_list_total(self); + } + int filecount() { + return ohcount_loc_list_filecount(self); + } +} + %extend SourceFile { void set_diskpath(const char *diskpath) { ohcount_sourcefile_set_diskpath(self, diskpath); @@ -59,14 +109,14 @@ LocDeltaList *_diff(SourceFile *to) { return ohcount_sourcefile_diff(self, to); } +#if defined(SWIGRUBY) void set_filenames(VALUE filenames) { - int i, length = RARRAY(filenames)->len; + int i, length = RARRAY_LEN(filenames); char **fnames = calloc(length + 1, sizeof(char *)); - VALUE *iter = RARRAY(filenames)->ptr; + VALUE *iter = RARRAY_PTR(filenames); for (i = 0; i < length; i++, iter++) - fnames[i] = STR2CSTR(*iter); - ohcount_sourcefile_set_filenames(self, fnames); - free(fnames); + fnames[i] = StringValuePtr(*iter); + self->filenames = fnames; } SourceFile(const char *filepath, VALUE opt_hash=NULL) { SourceFile *sourcefile = ohcount_sourcefile_new(filepath); @@ -74,38 +124,162 @@ VALUE val; val = rb_hash_aref(opt_hash, ID2SYM(rb_intern("contents"))); if (val && rb_type(val) == T_STRING) - ohcount_sourcefile_set_contents(sourcefile, STR2CSTR(val)); + ohcount_sourcefile_set_contents(sourcefile, StringValuePtr(val)); val = rb_hash_aref(opt_hash, ID2SYM(rb_intern("file_location"))); if (val && rb_type(val) == T_STRING) - ohcount_sourcefile_set_diskpath(sourcefile, STR2CSTR(val)); + ohcount_sourcefile_set_diskpath(sourcefile, StringValuePtr(val)); val = rb_hash_aref(opt_hash, ID2SYM(rb_intern("filenames"))); if (val && rb_type(val) == T_ARRAY) SourceFile_set_filenames(sourcefile, val); } return sourcefile; } +#elif defined(SWIGPYTHON) + void set_filenames(PyObject *filenames) { + int i, length; + char **fnames; + if (!PyList_Check(filenames)) { + PyErr_SetString(PyExc_SyntaxError, "Invalid parameter, expected a list of strings"); + return; + } + length = PyList_Size(filenames); + fnames = calloc(length + 1, sizeof(char *)); + for (i = 0; i < length; i++) { + PyObject *s = PyList_GetItem(filenames, i); + if (!PyString_Check(s)) { + PyErr_SetString(PyExc_SyntaxError, "Invalid parameter, expected a list of strings"); + return; + } + fnames[i] = PyString_AsString(s); + } + ohcount_sourcefile_set_filenames(self, fnames); + free(fnames); + } + static void py_annotate_callback(const char *language, const char *entity, + int start, int end, void *userdata) { + PyObject *list = (PyObject *) userdata; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, PyString_FromString("language"), + PyString_FromString(language)); + PyDict_SetItem(dict, PyString_FromString("entity"), + PyString_FromString(entity)); + PyDict_SetItem(dict, PyString_FromString("start"), + PyInt_FromLong(start)); + PyDict_SetItem(dict, PyString_FromString("end"), + PyInt_FromLong(end)); + PyList_Append(list, dict); + } + PyObject *annotate() { + PyObject *list = PyList_New(0); + ohcount_sourcefile_parse_with_callback(self, SourceFile_py_annotate_callback, list); + return list; + } + PyObject *raw_entities() { + PyObject *list = PyList_New(0); + ohcount_sourcefile_parse_entities_with_callback(self, SourceFile_py_annotate_callback, list); + return list; + } + SourceFile(const char *filepath, PyObject *args) { + SourceFile *sourcefile = ohcount_sourcefile_new(filepath); + if (args) { + PyObject *val; + if (!PyDict_Check(args)) { + PyErr_SetString(PyExc_SyntaxError, "Invalid argument"); + ohcount_sourcefile_free(sourcefile); + return NULL; + } + val = PyDict_GetItem(args, PyString_FromString("contents")); + if (val && PyString_Check(val)) + ohcount_sourcefile_set_contents(sourcefile, PyString_AsString(val)); + val = PyDict_GetItem(args, PyString_FromString("file_location")); + if (val && PyString_Check(val)) + ohcount_sourcefile_set_diskpath(sourcefile, PyString_AsString(val)); + val = PyDict_GetItem(args, PyString_FromString("filenames")); + if (val && PyString_Check(val)) + SourceFile_set_filenames(sourcefile, val); + } + return sourcefile; + } + +#endif ~SourceFile() { + if (self->filenames) + free(self->filenames); ohcount_sourcefile_free(self); } }; -%extend SourceFileList { +%extend SourceFileListItem { +#if defined(SWIGRUBY) + static VALUE rb_add_directory(VALUE directory, SourceFileList *list) { if (directory && rb_type(directory) == T_STRING) - ohcount_sourcefile_list_add_directory(list, STR2CSTR(directory)); + ohcount_sourcefile_list_add_directory(list, StringValuePtr(directory)); return Qnil; } - SourceFileList(VALUE opt_hash=NULL) { + static VALUE rb_add_file(VALUE file, SourceFileList *list) { + if (file && rb_type(file) == T_STRING) + ohcount_sourcefile_list_add_file(list, StringValuePtr(file)); + return Qnil; + } + SourceFileListItem(VALUE opt_hash=NULL) { SourceFileList *list = ohcount_sourcefile_list_new(); if (opt_hash) { VALUE val; val = rb_hash_aref(opt_hash, ID2SYM(rb_intern("paths"))); if (val && rb_type(val) == T_ARRAY) - rb_iterate(rb_each, val, SourceFileList_rb_add_directory, (VALUE)list); - } - return list; - } - ~SourceFileList() { + rb_iterate(rb_each, val, SourceFileListItem_rb_add_directory, (VALUE)list); + val = rb_hash_aref(opt_hash, ID2SYM(rb_intern("files"))); + if (val && rb_type(val) == T_ARRAY) + rb_iterate(rb_each, val, SourceFileListItem_rb_add_file, (VALUE)list); + } + return list; + } + +#elif defined(SWIGPYTHON) + + SourceFileListItem(PyObject *args) { + SourceFileList *list = ohcount_sourcefile_list_new(); + if (args) { + PyObject *val; + if (!PyDict_Check(args)) { + PyErr_SetString(PyExc_SyntaxError, "Invalid argument"); + ohcount_sourcefile_list_free(list); + return NULL; + } + val = PyDict_GetItem(args, PyString_FromString("paths")); + if (val && PyList_Check(val)) { + int i, length = PyList_Size(val); + for (i = 0; i < length; i++) { + PyObject *s = PyList_GetItem(val, i); + if (!PyString_Check(s)) { + PyErr_SetString(PyExc_SyntaxError, "Invalid 'paths', expected a list of strings"); + ohcount_sourcefile_list_free(list); + return NULL; + } + ohcount_sourcefile_list_add_directory(list, PyString_AsString(s)); + } + } + val = PyDict_GetItem(args, PyString_FromString("files")); + if (val && PyList_Check(val)) { + int i, length = PyList_Size(val); + for (i = 0; i < length; i++) { + PyObject *s = PyList_GetItem(val, i); + if (!PyString_Check(s)) { + PyErr_SetString(PyExc_SyntaxError, "Invalid 'files', expected a list of strings"); + ohcount_sourcefile_list_free(list); + return NULL; + } + ohcount_sourcefile_list_add_file(list, PyString_AsString(s)); + } + } + } + return list; + } + +#endif + + ~SourceFileListItem() { ohcount_sourcefile_list_free(self); } void add_file(const char *filepath) { diff --git a/ruby/ohcount.rb b/ruby/ohcount.rb index c238bc0..7596a69 100644 --- a/ruby/ohcount.rb +++ b/ruby/ohcount.rb @@ -3,22 +3,21 @@ # Ohcount module tweaked for use by Ohloh. $: << File.expand_path(File.dirname(__FILE__)) +$: << "#{File.expand_path(File.dirname(__FILE__))}/#{`#{File.dirname(__FILE__)}/print_arch`.strip}" -begin - require 'ohcount.so' -rescue LoadError - require 'rbconfig' - include Config - require "#{Config::CONFIG['arch']}/ohcount.so" -end +require 'ohcount.so' module Ohcount class SourceFile def file_location=(value) set_diskpath(value) end def file_location() diskpath() end def filenames=(value) set_filenames(value) end - def contents() get_contents() end def polyglot() get_language() end + + def contents + data = get_contents() + data.force_encoding(Encoding.default_external) + end def language_breakdowns list = get_parsed_language_list() diff --git a/ruby/print_arch b/ruby/print_arch new file mode 100755 index 0000000..c42e70a --- /dev/null +++ b/ruby/print_arch @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +require 'mkmf' + +arch = RbConfig::expand(CONFIG["arch"]) + +distro = if File.exist?("/etc/issue") + # this is "", "CentOS" or "Ubuntu" + `cat /etc/issue`.split.first.downcase +end + +unless ["centos", nil, "ubuntu"].include? distro + STDERR.puts "unhandled /etc/issue result: #{distro}" +end + +# either or _ if distro is non-null +puts [arch, distro].compact.join("_") diff --git a/ruby/x86_64-linux_ubuntu/ohcount.so b/ruby/x86_64-linux_ubuntu/ohcount.so new file mode 100755 index 0000000..fffe1b6 Binary files /dev/null and b/ruby/x86_64-linux_ubuntu/ohcount.so differ diff --git a/src/detector.c b/src/detector.c index 863b379..d6b693d 100644 --- a/src/detector.c +++ b/src/detector.c @@ -2,6 +2,7 @@ // See COPYING for license information. #include +#include #include #include #include @@ -20,6 +21,102 @@ #define ISAMBIGUOUS(x) (x[0] == '\2') #define DISAMBIGUATEWHAT(x) &x[1] +#ifdef _WIN32 +# include +# define mkstemp(p) _open(_mktemp(p), _O_CREAT | _O_SHORT_LIVED | _O_EXCL) +#endif + +/* Parse the output of libmagic and return a language, if any. + * The contents of string `line` will be destroyed. + */ +const char *magic_parse(char *line) { + char *p, *pe; + char *eol = line + strlen(line); + + char buf[80]; + size_t length; + + for (p = line; p < eol; p++) *p = tolower(*p); + p = strstr(line, "script text"); // Example: "script text executable for perl -w," + if (p && p == line) { + p = strstr(line, "for "); + if (p) { + p += 4; + pe = p; + while (isalnum(*pe)) pe++; + length = pe - p; + strncpy(buf, p, length); + buf[length] = '\0'; + struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); + if (rl) return(rl->name); + } + } + + p = strstr(line, "script"); // Example: "PHP script, ASCII text" + if (p) { + do { + p--; + pe = p; + while (*p == ' ') p--; + while (p != line && isalnum(*(p - 1))) p--; + if (p != line && *(p - 1) == '-') p--; + } while (*p == '-'); // Skip over any switches. + length = pe - p; + strncpy(buf, p, length); + buf[length] = '\0'; + struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); + if (rl) return(rl->name); + } else if (strstr(line, "xml")) return(LANG_XML); + + return NULL; +} + +/* Use libmagic to detect file language + */ +const char *detect_language_magic(SourceFile *sourcefile) { + char line[80]; + + magic_t cookie = magic_open(MAGIC_NONE); + if (cookie == NULL) { + fprintf(stderr, "libmagic: %s\n", magic_error(cookie)); + exit(1); + } + if (magic_load(cookie, NULL) != 0) { + fprintf(stderr, "libmagic: %s\n", magic_error(cookie)); + magic_close(cookie); + exit(1); + } + + if (sourcefile->diskpath) { + const char *magic = magic_file(cookie, sourcefile->diskpath); + if (magic == NULL) { + fprintf(stderr, "libmagic: %s\n", magic_error(cookie)); + magic_close(cookie); + exit(1); + } + strncpy(line, magic, sizeof(line)); + line[sizeof(line)-1] = '\0'; + } else { + char *p = ohcount_sourcefile_get_contents(sourcefile); + if (!p) return NULL; + + const char *magic = magic_buffer(cookie, p, strlen(p)); + if (magic == NULL) { + fprintf(stderr, "libmagic: %s\n", magic_error(cookie)); + magic_close(cookie); + exit(1); + } + strncpy(line, magic, sizeof(line)); + line[sizeof(line)-1] = '\0'; + } + + magic_close(cookie); + + return magic_parse(line); +} + +/* Use all available means to detect file language + */ const char *ohcount_detect_language(SourceFile *sourcefile) { const char *language = NULL; char *p, *pe; @@ -28,17 +125,92 @@ // Attempt to detect based on file extension. length = strlen(sourcefile->ext); struct ExtensionMap *re = ohcount_hash_language_from_ext(sourcefile->ext, - length); + length); if (re) language = re->value; - if (language == NULL) { + if (!language) { // Try the lower-case version of this extension. char lowerext[length + 1]; strncpy(lowerext, sourcefile->ext, length); lowerext[length] = '\0'; for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p); struct ExtensionMap *re = ohcount_hash_language_from_ext(lowerext, length); - if (re) return re->value; - } + if (re) language = re->value; + } + + // Attempt to detect using Emacs mode line (/^-\*-\s*mode[\s:]*\w/i). + if(!language) { + char line[81] = { '\0' }, buf[81]; + p = ohcount_sourcefile_get_contents(sourcefile); + pe = p; + char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); + while (pe < eof) { + // Get the contents of the first line. + while (pe < eof && *pe != '\r' && *pe != '\n') pe++; + length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); + strncpy(line, p, length); + line[length] = '\0'; + if (*line == '#' && *(line + 1) == '!') { + // First line was sh-bang; loop to get contents of second line. + while (*pe == '\r' || *pe == '\n') pe++; + p = pe; + } else break; + } + p = strstr(line, "-*-"); + if (p) { + p += 3; + while (*p == ' ' || *p == '\t') p++; + // detect "mode" (any capitalization) + if (strncasecmp(p, "mode", 4) == 0) { + p += 4; + while (*p == ' ' || *p == '\t' || *p == ':') p++; + } + pe = p; + while (!isspace(*pe) && *pe != ';' && pe != strstr(pe, "-*-")) pe++; + length = (pe - p <= sizeof(buf)) ? pe - p : sizeof(buf); + strncpy(buf, p, length); + buf[length] = '\0'; + + // Special case for "c" or "C" emacs mode header: always means C, not C++ + if (strcasecmp(buf, "c") == 0) { + return LANG_C; + } + + // First try it with the language name. + struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); + if (rl) language = rl->name; + if(!language) { + // Then try it with the extension table. + struct ExtensionMap *re = ohcount_hash_language_from_ext(buf, length); + if (re) language = re->value; + } + if (!language) { + // Try the lower-case version of this modeline. + for (pe = buf; pe < buf+length; pe++) *pe = tolower(*pe); + // First try it with the language name. + rl = ohcount_hash_language_from_name(buf, length); + if (rl) language = rl->name; + } + if (!language) { + // Then try it with the extension table. + struct ExtensionMap *re = ohcount_hash_language_from_ext(buf, length); + if (re) language = re->value; + } + } + } + + // Attempt to detect based on filename. + if(!language) { + length = strlen(sourcefile->filename); + struct FilenameMap *rf = + ohcount_hash_language_from_filename(sourcefile->filename, length); + if (rf) language = rf->value; + } + + // Attempt to detect based on Unix 'file' command. + if(!language) { + language = detect_language_magic(sourcefile); + } + if (language) { if (ISAMBIGUOUS(language)) { // Call the appropriate function for disambiguation. @@ -46,114 +218,10 @@ struct DisambiguateFuncsMap *rd = ohcount_hash_disambiguate_func_from_id(DISAMBIGUATEWHAT(language), length); - if (rd) return rd->value(sourcefile); - } else return ISBINARY(language) ? NULL : language; - } - - // Attempt to detect based on filename. - length = strlen(sourcefile->filename); - struct FilenameMap *rf = - ohcount_hash_language_from_filename(sourcefile->filename, length); - if (rf) return rf->value; - - char line[81] = { '\0' }, buf[81]; - - // Attempt to detect using Emacs mode line (/^-\*-\s*mode[\s:]*\w/i). - p = ohcount_sourcefile_get_contents(sourcefile); - pe = p; - char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); - while (pe < eof) { - // Get the contents of the first line. - while (pe < eof && *pe != '\r' && *pe != '\n') pe++; - length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); - strncpy(line, p, length); - line[length] = '\0'; - if (*line == '#' && *(line + 1) == '!') { - // First line was sh-bang; loop to get contents of second line. - while (*pe == '\r' || *pe == '\n') pe++; - p = pe; - } else break; - } - char *eol = line + strlen(line); - for (p = line; p < eol; p++) *p = tolower(*p); - p = strstr(line, "-*-"); - if (p) { - p += 3; - while (*p == ' ' || *p == '\t') p++; - if (strncmp(p, "mode", 4) == 0) { - p += 4; - while (*p == ' ' || *p == '\t' || *p == ':') p++; - } - pe = p; - while (isalnum(*pe)) pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) return rl->name; - } - - // Attempt to detect based on Unix 'file' command. - int tmpfile = 0; - char *path = sourcefile->filepath; - if (sourcefile->diskpath) - path = sourcefile->diskpath; - if (access(path, F_OK) != 0) { // create temporary file - path = malloc(21); - strncpy(path, "/tmp/ohcount_XXXXXXX", 20); - *(path + 21) = '\0'; - int fd = mkstemp(path); - char *contents = ohcount_sourcefile_get_contents(sourcefile); - log_it("contents:"); - log_it(contents); - length = contents ? strlen(contents) : 0; - write(fd, contents, length); - close(fd); - tmpfile = 1; - } - char command[strlen(path) + 11]; - sprintf(command, "file -b '%s'", path); - FILE *f = popen(command, "r"); - if (f) { - fgets(line, sizeof(line), f); - char *eol = line + strlen(line); - for (p = line; p < eol; p++) *p = tolower(*p); - p = strstr(line, "script text"); - if (p && p == line) { // /^script text(?: executable)? for \w/ - p = strstr(line, "for "); - if (p) { - p += 4; - pe = p; - while (isalnum(*pe)) pe++; - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) language = rl->name; - } - } else if (p) { // /(\w+)(?: -\w+)* script text/ - do { - p--; - pe = p; - while (*p == ' ') p--; - while (p != line && isalnum(*(p - 1))) p--; - if (p != line && *(p - 1) == '-') p--; - } while (*p == '-'); // Skip over any switches. - length = pe - p; - strncpy(buf, p, length); - buf[length] = '\0'; - struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length); - if (rl) language = rl->name; - } else if (strstr(line, "xml")) language = LANG_XML; - pclose(f); - if (tmpfile) { - remove(path); - free(path); - } - if (language) return language; - } - - return NULL; + if (rd) language = rd->value(sourcefile); + } else language = ISBINARY(language) ? NULL : language; + } + return language; } const char *disambiguate_aspx(SourceFile *sourcefile) { @@ -185,6 +253,31 @@ return LANG_CS_ASPX; } +// 6502 assembly or XML-based Advanced Stream Redirector ? +const char *disambiguate_asx(SourceFile *sourcefile) { + char *p = ohcount_sourcefile_get_contents(sourcefile); + char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); + for (; p < eof; p++) { + switch (*p) { + case ' ': + case '\t': + case '\n': + case '\r': + break; + case '<': + case '\0': + // byte-order marks: + case (char) 0xef: + case (char) 0xfe: + case (char) 0xff: + return NULL; // XML + default: + return LANG_ASSEMBLER; + } + } + return LANG_ASSEMBLER; // only blanks - not valid XML, may be valid asm +} + const char *disambiguate_b(SourceFile *sourcefile) { char *p = ohcount_sourcefile_get_contents(sourcefile); char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); @@ -255,7 +348,7 @@ } // Attempt to detect from associated VB files in file context. - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); + char **filenames = sourcefile->filenames; if (filenames) { int i; for (i = 0; filenames[i] != NULL; i++) { @@ -286,48 +379,141 @@ return LANG_CSHARP; } +const char *disambiguate_dat(SourceFile *sourcefile) { + char *p = ohcount_sourcefile_get_contents(sourcefile); + char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); + for (; p < eof; p++) { + switch (*p) { + case ' ': + case '\t': + case '\n': + case '\r': + break; + case '/': + if (p[1] == '*') // AMPL comment + return LANG_AMPL; + return NULL; + case '#': + return LANG_AMPL; // AMPL comment + case 'd': + if (strncmp(p, "data", 4) == 0) // AMPL data statement + return LANG_AMPL; + return BINARY; + case 'p': + if (strncmp(p, "param", 5) == 0) // AMPL param statement + return LANG_AMPL; + return BINARY; + case 's': + if (strncmp(p, "set", 3) == 0) // AMPL set statement + return LANG_AMPL; + return BINARY; + default: + return BINARY; + } + } + return NULL; // only blanks +} + +const char *disambiguate_def(SourceFile *sourcefile) { + char *p = ohcount_sourcefile_get_contents(sourcefile); + char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); + for (; p < eof; p++) { + switch (*p) { + case ' ': + case '\t': + case '\n': + case '\r': + break; + case '(': + if (p[1] == '*') // Modula-2 comment + return LANG_MODULA2; + return NULL; + case 'D': + if (strncmp(p, "DEFINITION", 10) == 0) // Modula-2 "DEFINITION MODULE" + return LANG_MODULA2; + return NULL; + default: + return NULL; // not Modula-2 + } + } + return NULL; // only blanks +} + const char *disambiguate_fortran(SourceFile *sourcefile) { - char *p, *pe; + char *p; p = ohcount_sourcefile_get_contents(sourcefile); char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); + + // Try the assumption of a fixed formatted source code, and return free + // format if anything opposes this assumption. + // Rules based on the Fortran standard, page 47: + // ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1830.pdf while (p < eof) { - if (*p == ' ' && p + 5 < eof) { - int i; - for (i = 1; i <= 5; i++) - if (!isdigit(*(p + i)) && *(p + i) != ' ') - return LANG_FORTRANFIXED; // definately not f77 - // Possibly fixed (doesn't match /^\s*\d+\s*$/). - pe = p; - while (*pe == ' ' || *pe == '\t') pe++; - if (pe - p <= 5) { - if (!isdigit(*pe)) - return LANG_FORTRANFIXED; - while (isdigit(*pe)) pe++; - while (*pe == ' ' || *pe == '\t') pe++; - if (*pe != '\r' && *pe != '\n' && pe - p == 5) - return LANG_FORTRANFIXED; - } - } - while (*p != '\r' && *p != '\n' && *p != '&' && p < eof) p++; - if (*p == '&') { - p++; - // Look for free-form continuation. - while (*p == ' ' || *p == '\t') p++; - if (*p == '\r' || *p == '\n') { - pe = p; - while (*pe == '\r' || *pe == '\n' || *pe == ' ' || *pe == '\t') pe++; - if (*pe == '&') + int i = 1; + int blanklabel; + // Process a single line; tabulators are not valid in Fortran code + // but some compilers accept them to skip the first 5 columns. + if (*p == ' ' || *p == '\t' || isdigit(*p)) { + // Only consider lines starting with a blank or digit + // (non-comment in fixed) + if (*p == '\t') i = 5; + blanklabel = (*p == ' ' || *p == '\t'); + while (*p != '\r' && *p != '\n' && p < eof) { + p++; i++; + if (i <= 5) { + blanklabel = blanklabel && (*p == ' '); + if ( !isdigit(*p) && *p != ' ' && *p != '!') + // Non-digit, non-blank, non-comment character in the label field + // definetly not valid fixed formatted code! + return LANG_FORTRANFREE; + } + if ((i == 6) && !blanklabel && *p != ' ' && *p != '0') + // Fixed format continuation line with non-blank label field + // not allowed, assume free format: return LANG_FORTRANFREE; - } - } - while (*p == '\r' || *p == '\n') p++; - } - return LANG_FORTRANFREE; // might as well be free-form + // Ignore comments (a ! character in column 6 is a continuation in + // fixed form) + if (*p == '!' && i != 6) { + while (*p != '\r' && *p != '\n' && p < eof) p++; + } else { + // Ignore quotes + if (*p == '"') { + if (p < eof) {p++; i++;} + while (*p != '"' && *p != '\r' && *p != '\n' && p < eof) { + p++; i++; + } + } + if (*p == '\'') { + if (p < eof) {p++; i++;} + while (*p != '\'' && *p != '\r' && *p != '\n' && p < eof) { + p++; i++; + } + } + // Check for free format line continuation + if (i > 6 && i <= 72 && *p == '&') + // Found an unquoted free format continuation character in the fixed + // format code section. This has to be free format. + return LANG_FORTRANFREE; + } + } + } else { + // Not a statement line in fixed format... + if (*p != 'C' && *p != 'c' && *p != '*' && *p != '!') + // Not a valid fixed form comment, has to be free formatted source + return LANG_FORTRANFREE; + // Comment in fixed form, ignore this line + while (*p != '\r' && *p != '\n' && p < eof) p++; + } + // Skip all line ends + while ((*p == '\r' || *p == '\n') && p < eof) p++; + } + // Assume fixed format if none of the lines broke the assumptions + return LANG_FORTRANFIXED; } const char *disambiguate_h(SourceFile *sourcefile) { - char *p, *pe; + char *p, *pe, *bof; int length; // If the directory contains a matching *.m file, likely Objective C. @@ -337,7 +523,7 @@ strncpy(path, sourcefile->filename, length); path[length] = '\0'; *(path + length - 1) = 'm'; - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); + char **filenames = sourcefile->filenames; if (filenames) { int i; for (i = 0; filenames[i] != NULL; i++) @@ -348,7 +534,8 @@ // Attempt to detect based on file contents. char line[81], buf[81]; - p = ohcount_sourcefile_get_contents(sourcefile); + bof = ohcount_sourcefile_get_contents(sourcefile); + p = bof; pe = p; char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); while (pe < eof) { @@ -395,7 +582,7 @@ // Look for C++ keywords. p = line; while (p < eol) { - if (islower(*p) && p != line && !isalnum(*(p - 1)) && *(p - 1) != '_') { + if (islower(*p) && p != bof && !isalnum(*(p - 1)) && *(p - 1) != '_') { pe = p; while (islower(*pe)) pe++; if (!isalnum(*pe) && *pe != '_') { @@ -435,18 +622,21 @@ char buf[length]; strncpy(buf, p, length); buf[length] = '\0'; - SourceFile *undecorated = ohcount_sourcefile_new(buf); p = ohcount_sourcefile_get_contents(sourcefile); if (!p) { return NULL; } - // The filepath without the '.in' extension does not exist on disk. The - // sourcefile->diskpath field must be set incase the detector needs to run - // 'file -b' on the file. - ohcount_sourcefile_set_diskpath(undecorated, sourcefile->filepath); + + // A SourceFile's filepath and diskpath need not be the same. + // Here, we'll take advantage of this to set up a new SourceFile + // whose filepath does not have the *.in extension, but whose + // diskpath still points back to the original file on disk (if any). + SourceFile *undecorated = ohcount_sourcefile_new(buf); + if (sourcefile->diskpath) { + ohcount_sourcefile_set_diskpath(undecorated, sourcefile->diskpath); + } ohcount_sourcefile_set_contents(undecorated, p); - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); - ohcount_sourcefile_set_filenames(undecorated, filenames); + undecorated->filenames = sourcefile->filenames; language = ohcount_sourcefile_get_language(undecorated); ohcount_sourcefile_free(undecorated); } @@ -473,13 +663,14 @@ int length; // Attempt to detect based on a weighted heuristic of file contents. + int mathematica_score = 0; int matlab_score = 0; int objective_c_score = 0; int limbo_score = 0; int octave_syntax_detected = 0; int i, has_h_headers = 0, has_c_files = 0; - char **filenames = ohcount_sourcefile_get_filenames(sourcefile); + char **filenames = sourcefile->filenames; if (filenames) { for (i = 0; filenames[i] != NULL; i++) { p = filenames[i]; @@ -530,8 +721,8 @@ while (*p == ' ' || *p == '\t') p++; if (*p == '%') { // Matlab comment matlab_score++; - } else if (*p == '#' && strncmp(p, "#import", 7) == 0) { // Objective C - objective_c_score++; + } else if (*p == '#' && strncmp(p, "#import", 7) == 0) { // Objective C + objective_c_score++; } else if (*p == '#') { // Limbo or Octave comment while (*p == '#') p++; if (*p == ' ' || *p == '\t') { @@ -539,7 +730,7 @@ matlab_score++; octave_syntax_detected = 1; } - } else if (*p == '/' && *(p + 1) == '/' || *(p + 1) == '*') { + } else if (*p == '/' && *(p + 1) == '/' || *p == '/' && *(p + 1) == '*') { objective_c_score++; // Objective C comment } else if (*p == '+' || *p == '-') { // Objective C method signature objective_c_score++; @@ -601,18 +792,129 @@ } else p++; } + // Look for Mathematica pattern definitions + p = line; + while (p < eol) { + // & as postfix operator + if (*p == '&') { + p++; + while (*p == ' ' || *p == '\t') p++; + if (*p == ',' || *p == ')' || *p == ']') mathematica_score++; + } + // Mathematica comment + if (*p == '(' && *(p + 1) == '*') mathematica_score++; + // some Mathematica operators + if (*p == '/' && *(p + 1) == '.') mathematica_score++; + if (*p == '_' && *(p + 1) == '_') mathematica_score++; + if (*p == '@' && *(p + 1) == '@') mathematica_score++; + p++; + } + // Next line. pe = line_end; while (*pe == '\r' || *pe == '\n') pe++; p = pe; } - if (limbo_score > objective_c_score && limbo_score > matlab_score) + if (limbo_score > objective_c_score && + limbo_score > matlab_score && + limbo_score > mathematica_score) return LANG_LIMBO; - else if (objective_c_score > matlab_score) + else if (objective_c_score > matlab_score && + objective_c_score > mathematica_score) return LANG_OBJECTIVE_C; + else if (mathematica_score > matlab_score) + return LANG_MATHEMATICA; else return octave_syntax_detected ? LANG_OCTAVE : LANG_MATLAB; +} + +const char *disambiguate_mod(SourceFile *sourcefile) { + char *p = ohcount_sourcefile_get_contents(sourcefile); + char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); + for (; p < eof; p++) { + switch (*p) { + case ' ': + case '\t': + case '\n': + case '\r': + break; + case '(': + if (p[1] == '*') // Modula-2 comment + return LANG_MODULA2; + return NULL; + case 'I': + if (strncmp(p, "IMPLEMENTATION", 14) == 0) // Modula-2 "IMPLEMENTATION MODULE" + return LANG_MODULA2; + return NULL; + case 'M': + if (strncmp(p, "MODULE", 6) == 0) // Modula-2 "MODULE" + return LANG_MODULA2; + return NULL; + default: + return LANG_AMPL; + } + } + return NULL; // only blanks +} + +#include + +// strnlen is not available on OS X, so we roll our own +size_t mystrnlen(const char *begin, size_t maxlen) { + if (begin == NULL) + return 0; + const char *end = memchr(begin, '\0', maxlen); + return end ? (end - begin) : maxlen; +} + +const char *disambiguate_pp(SourceFile *sourcefile) { + char *p = ohcount_sourcefile_get_contents(sourcefile); + + if (!p) + return NULL; + + /* prepare regular expressions */ + const char *error; + int erroffset; + + /* try harder with optional spaces */ + pcre *keyword; + keyword = pcre_compile("^\\s*(ensure|content|notify|require|source)\\s+=>", + PCRE_MULTILINE, &error, &erroffset, NULL); + + if (pcre_exec(keyword, NULL, p, mystrnlen(p, 10000), 0, 0, NULL, 0) > -1) + return LANG_PUPPET; + + /* check for standard puppet constructs */ + pcre *construct; + construct = pcre_compile("^\\s*(define\\s+[\\w:-]+\\s*\\(|class\\s+[\\w:-]+(\\s+inherits\\s+[\\w:-]+)?\\s*[\\({]|node\\s+\\'?[\\w:\\.-]+\\'?\\s*{|import\\s+\"|include\\s+[\"']?[\\w:-][\"']?)", + PCRE_MULTILINE, &error, &erroffset, NULL); + + if (pcre_exec(construct, NULL, p, mystrnlen(p, 10000), 0, 0, NULL, 0) > -1) + return LANG_PUPPET; + + return LANG_PASCAL; +} + +const char *disambiguate_pl(SourceFile *sourcefile) { + char *contents = ohcount_sourcefile_get_contents(sourcefile); + if (!contents) + return NULL; + + // Check for a perl shebang on first line of file + const char *error; + int erroffset; + pcre *re = pcre_compile("#![^\\n]*perl", PCRE_CASELESS, &error, &erroffset, NULL); + if (pcre_exec(re, NULL, contents, mystrnlen(contents, 100), 0, PCRE_ANCHORED, NULL, 0) > -1) + return LANG_PERL; + + // Check for prolog :- rules + if (strstr(contents, ":- ") || strstr(contents, ":-\n")) + return LANG_PROLOG; + + // Perl by default. + return LANG_PERL; } #define QMAKE_SOURCES_SPACE "SOURCES +=" @@ -633,6 +935,55 @@ return LANG_IDL_PVWAVE; } +const char *disambiguate_r(SourceFile *sourcefile) { + char *contents = ohcount_sourcefile_get_contents(sourcefile); + if (!contents) + return LANG_R; + + char *eof = contents + ohcount_sourcefile_get_contents_size(sourcefile); + + // Detect REBOL by looking for the occurence of "rebol" in the contents + // (case-insensitive). Correct REBOL scripts have a "REBOL [...]" header + // block. + char *needle = "rebol"; + int len = strlen(needle); + for (; contents < eof - len; ++contents) + if (tolower(*contents) == *needle && + !strncasecmp(contents, needle, len)) + return LANG_REBOL; + + return LANG_R; +} + +const char *disambiguate_rs(SourceFile *sourcefile) { + // .rs is normally Rust, but it might be RenderScript. RenderScript is + // expected to have a "#pragma version(1)" line at the very start, possibly + // after comments. To help with supporting future versions of RenderScript, + // we'll skip the number part. + // As RenderScript is not implemented in ohcount yet, it's returned as NULL. + char *contents = ohcount_sourcefile_get_contents(sourcefile); + if (!contents) { + return LANG_RUST; + } + + char *needle = "\n#pragma version"; + int len = strlen(needle); + if (strncasecmp(contents, needle + 1, len - 1) == 0) { + // "#pragma version" at the very start of the file is RenderScript. + return NULL; + } + + char *eof = contents + ohcount_sourcefile_get_contents_size(sourcefile); + + for (; contents < eof - len; ++contents) { + if (!strncmp(contents, needle, len)) { + return NULL; + } + } + + return LANG_RUST; +} + const char *disambiguate_st(SourceFile *sourcefile) { char *p, *pe; int length; @@ -646,7 +997,7 @@ char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile); while (pe < eof) { // Get a line at a time. - while (p < eof && *pe != '\r' && *pe != '\n') pe++; + while (pe < eof && *pe != '\r' && *pe != '\n') pe++; length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line); strncpy(line, p, length); line[length] = '\0'; diff --git a/src/detector.h b/src/detector.h index 53277b8..48d19dc 100644 --- a/src/detector.h +++ b/src/detector.h @@ -31,4 +31,7 @@ int ohcount_is_binary_filename(const char *filename); +/* Exported for unit testing */ +void escape_path(char *safe, const char *unsafe); + #endif diff --git a/src/diff.c b/src/diff.c index 1aa6bcf..019a119 100644 --- a/src/diff.c +++ b/src/diff.c @@ -1,6 +1,11 @@ #include #include #include + +#ifdef _WIN32 +# include +# define mkstemp(p) _open(_mktemp(p), _O_CREAT | _O_SHORT_LIVED | _O_EXCL) +#endif /* * The bulk of this software is derived from Plan 9 and is thus distributed @@ -619,9 +624,12 @@ char *tmp_file_from_buf(const char *buf) { char *template = "/tmp/ohcount_diff_XXXXXXX"; char *path = strdup(template); - + int fd = mkstemp(path); - write(fd, buf, strlen(buf)); + if (write(fd, buf, strlen(buf)) != strlen(buf)) { + fprintf(stderr, "src/diff.c: Could not write temporary file %s.\n", path); + exit(1); + } close(fd); return path; } diff --git a/src/hash/disambiguatefuncs.gperf b/src/hash/disambiguatefuncs.gperf index 1390d08..a805b7d 100644 --- a/src/hash/disambiguatefuncs.gperf +++ b/src/hash/disambiguatefuncs.gperf @@ -3,27 +3,43 @@ #include "../sourcefile.h" const char *disambiguate_aspx(SourceFile *sourcefile); +const char *disambiguate_asx(SourceFile *sourcefile); const char *disambiguate_b(SourceFile *sourcefile); const char *disambiguate_basic(SourceFile *sourcefile); const char *disambiguate_cs(SourceFile *sourcefile); +const char *disambiguate_dat(SourceFile *sourcefile); +const char *disambiguate_def(SourceFile *sourcefile); const char *disambiguate_fortran(SourceFile *sourcefile); const char *disambiguate_h(SourceFile *sourcefile); const char *disambiguate_in(SourceFile *sourcefile); const char *disambiguate_inc(SourceFile *sourcefile); const char *disambiguate_m(SourceFile *sourcefile); +const char *disambiguate_mod(SourceFile *sourcefile); +const char *disambiguate_pl(SourceFile *sourcefile); +const char *disambiguate_pp(SourceFile *sourcefile); const char *disambiguate_pro(SourceFile *sourcefile); +const char *disambiguate_r(SourceFile *sourcefile); +const char *disambiguate_rs(SourceFile *sourcefile); const char *disambiguate_st(SourceFile *sourcefile); %} struct DisambiguateFuncsMap { const char *key; const char* (*value)(SourceFile*); }; %% aspx, disambiguate_aspx +asx, disambiguate_asx b, disambiguate_b basic, disambiguate_basic cs, disambiguate_cs +dat, disambiguate_dat +def, disambiguate_def fortran, disambiguate_fortran h, disambiguate_h in, disambiguate_in inc, disambiguate_inc m, disambiguate_m +mod, disambiguate_mod +pl, disambiguate_pl +pp, disambiguate_pp pro, disambiguate_pro +r, disambiguate_r +rs, disambiguate_rs st, disambiguate_st diff --git a/src/hash/extensions.gperf b/src/hash/extensions.gperf old file mode 100644 new file mode 100755 index 8394eee..62923f9 100755 --- a/src/hash/extensions.gperf +++ b/src/hash/extensions.gperf @@ -6,6 +6,7 @@ %} struct ExtensionMap { const char *key; const char *value; }; %% +4th, LANG_FORTH C, LANG_CPP H, LANG_CPP ada, LANG_ADA @@ -13,15 +14,20 @@ ads, LANG_ADA aiff, BINARY as, LANG_ACTIONSCRIPT +as8, LANG_ASSEMBLER ascx, DISAMBIGUATE("aspx") asm, LANG_ASSEMBLER aspx, DISAMBIGUATE("aspx") +asx, DISAMBIGUATE("asx") au, BINARY +aug, LANG_AUGEAS avi, BINARY awk, LANG_AWK b, DISAMBIGUATE("b") bas, DISAMBIGUATE("basic") bat, LANG_BAT +bf, LANG_BRAINFUCK +bfpp, LANG_BFPP bi, DISAMBIGUATE("basic") bmp, BINARY bmx, LANG_BLITZMAX @@ -30,40 +36,58 @@ c++, LANG_CPP cache, BINARY cc, LANG_CPP +chai, LANG_CHAISCRIPT +clj, LANG_CLOJURE +cls, LANG_TEX cmake, LANG_CMAKE +coffee, LANG_COFFEESCRIPT com, LANG_DCL cpp, LANG_CPP cs, DISAMBIGUATE("cs") csproj, LANG_XML css, LANG_CSS ctp, LANG_PHP +cu, LANG_CUDA cxx, LANG_CPP d, LANG_DMD -dat, BINARY +dat, DISAMBIGUATE("dat") +def, DISAMBIGUATE("def") di, LANG_DMD doc, BINARY +dtx, LANG_TEX_DTX dylan, LANG_DYLAN e, LANG_EIFFEL ebuild, LANG_EBUILD +ec, LANG_EC eclass, LANG_EBUILD +eh, LANG_EC el, LANG_EMACSLISP erl, LANG_ERLANG exheres-0, LANG_EXHERES exlib, LANG_EXHERES f, DISAMBIGUATE("fortran") f03, DISAMBIGUATE("fortran") +f08, DISAMBIGUATE("fortran") f77, DISAMBIGUATE("fortran") f90, DISAMBIGUATE("fortran") f95, DISAMBIGUATE("fortran") factor, LANG_FACTOR +fr, LANG_FORTH frag, LANG_GLSL +for, DISAMBIGUATE("fortran") +fpp, DISAMBIGUATE("fortran") frm, LANG_VISUALBASIC frx, LANG_VISUALBASIC fs, LANG_FSHARP ftn, DISAMBIGUATE("fortran") +gemspec, LANG_RUBY gif, BINARY glsl, LANG_GLSL +go, LANG_GOLANG groovy, LANG_GROOVY +grace, LANG_GRACE +grc, LANG_GRACE +gs, LANG_GENIE gz, BINARY h, DISAMBIGUATE("h") h++, LANG_CPP @@ -76,6 +100,7 @@ html, LANG_HTML hx, LANG_HAXE hxx, LANG_CPP +i3, LANG_MODULA3 icns, BINARY in, DISAMBIGUATE("in") inc, DISAMBIGUATE("inc") @@ -91,8 +116,11 @@ lisp, LANG_LISP lsp, LANG_LISP ltx, LANG_TEX +lgt, LANG_LOGTALK lua, LANG_LUA m, DISAMBIGUATE("m") +m3, LANG_MODULA3 +m4, LANG_AUTOCONF m4a, BINARY mf, LANG_METAFONT mk, LANG_MAKE @@ -100,13 +128,20 @@ ml4, LANG_OCAML mli, LANG_OCAML mm, LANG_OBJECTIVE_C +mod, DISAMBIGUATE("mod") mov, BINARY mp, LANG_METAPOST_WITH_TEX mp3, BINARY mpg, BINARY +mt, LANG_MATHEMATICA +mustache, LANG_HTML mxml, LANG_MXML nix, LANG_NIX nse, LANG_LUA +nsi, LANG_NSIS +nsh, LANG_NSIS +ob2, LANG_OBERON +obn, LANG_OBERON ogg, BINARY p6, LANG_PERL pas, LANG_PASCAL @@ -118,24 +153,35 @@ php4, LANG_PHP php5, LANG_PHP pike, LANG_PIKE -pl, LANG_PERL +pl, DISAMBIGUATE("pl") pm, LANG_PERL pmc, LANG_C pmod, LANG_PIKE png, BINARY pnt, BINARY pod, LANG_PERL -pp, LANG_PASCAL +pp, DISAMBIGUATE("pp") ppt, BINARY pro, DISAMBIGUATE("pro") py, LANG_PYTHON +qml, LANG_QML qt, BINARY -r, LANG_R +r, DISAMBIGUATE("r") +r3, LANG_REBOL ra, BINARY rb, LANG_RUBY +rbw, LANG_RUBY +reb, LANG_REBOL +rebol, LANG_REBOL rex, LANG_REXX rexx, LANG_REXX rhtml, LANG_RHTML +rkt, LANG_RACKET +rktd, LANG_RACKET +rktl, LANG_RACKET +rs, DISAMBIGUATE("rs") +ru, LANG_RUBY +run, LANG_AMPL s, LANG_ASSEMBLER sc, LANG_SCHEME scala, LANG_SCALA @@ -149,6 +195,7 @@ ss, LANG_SCHEME st, DISAMBIGUATE("st") str, LANG_STRATEGO +sty, LANG_TEX svg, BINARY svgz, BINARY svn, BINARY @@ -161,8 +208,11 @@ tif, BINARY tiff, BINARY tpl, LANG_HTML -txx, LANG_CPP +ts, LANG_TYPESCRIPT +tsx, LANG_TYPESCRIPT vala, LANG_VALA +vapi, LANG_VALA +v, LANG_COQ vb, LANG_VISUALBASIC vba, LANG_VISUALBASIC vbs, LANG_VISUALBASIC @@ -171,6 +221,8 @@ vhdl, LANG_VHDL vim, LANG_VIM wav, BINARY +wl, LANG_MATHEMATICA +wlt, LANG_MATHEMATICA xaml, LANG_XAML xls, BINARY xlw, BINARY diff --git a/src/hash/filenames.gperf b/src/hash/filenames.gperf index 54b1685..b149019 100644 --- a/src/hash/filenames.gperf +++ b/src/hash/filenames.gperf @@ -4,10 +4,17 @@ struct FilenameMap { const char *key; const char *value; }; %% CMakeLists.txt, LANG_CMAKE +Jamfile, LANG_JAM +Jamrules, LANG_JAM GNUmakefile, LANG_MAKE Makefile, LANG_MAKE Makefile.am, LANG_AUTOMAKE configure, LANG_AUTOCONF configure.ac, LANG_AUTOCONF configure.in, LANG_AUTOCONF +init.pp, LANG_PUPPET makefile, LANG_MAKE +Rakefile, LANG_RUBY +rakefile, LANG_RUBY +Gemfile, LANG_RUBY +Vagrantfile, LANG_RUBY diff --git a/src/hash/generate_headers b/src/hash/generate_headers index 679a8b3..07af20a 100755 --- a/src/hash/generate_headers +++ b/src/hash/generate_headers @@ -1,4 +1,13 @@ #!/bin/sh + +# Check for gperf +if `type gperf > /dev/null 2> /dev/null` +then + echo "Found gperf, making headers..." +else + echo "gperf not found, aborting" >&2 + exit 1 +fi gperf -L ANSI-C -E -D -K key -H ohcount_hash_language -N ohcount_hash_language_from_name -t languages.gperf > language_hash.c gperf -L ANSI-C -E -D -K key -H ohcount_hash_extension -N ohcount_hash_language_from_ext -t extensions.gperf > extension_hash.h diff --git a/src/hash/languages.gperf b/src/hash/languages.gperf old file mode 100644 new file mode 100755 index 037b2bc..1cf037e 100755 --- a/src/hash/languages.gperf +++ b/src/hash/languages.gperf @@ -5,54 +5,77 @@ %% actionscript, LANG_ACTIONSCRIPT, "ActionScript", 0 ada, LANG_ADA, "Ada", 0 +ampl, LANG_AMPL, "AMPL", 0 assembler, LANG_ASSEMBLER, "Assembler", 0 +augeas, LANG_AUGEAS, "Augeas", 0 autoconf, LANG_AUTOCONF, "Autoconf", 2 automake, LANG_AUTOMAKE, "Automake", 2 awk, LANG_AWK, "AWK", 0 bat, LANG_BAT, "DOS batch script", 0 +bash, LANG_SHELL, "shell script", 0 blitzmax, LANG_BLITZMAX, "BlitzMax", 0 boo, LANG_BOO, "Boo", 0 +brainfuck, LANG_BRAINFUCK, "Brainfuck", 0 +bfpp, LANG_BFPP, "Brainfuck++", 0 c, LANG_C, "C", 0 +chaiscript, LANG_CHAISCRIPT, "ChaiScript", 0 classic_basic, LANG_CLASSIC_BASIC, "Classic Basic", 0 clearsilver, LANG_CLEARSILVER, "ClearSilver", 0 clearsilver_template, LANG_CLEARSILVER_TEMPLATE, "ClearSilver", 0 +clojure, LANG_CLOJURE, "Clojure", 0 cmake, LANG_CMAKE, "Cmake script", 2 +coffescript, LANG_COFFEESCRIPT, "CoffeeScript", 0 +coq, LANG_COQ, "Coq", 0 cpp, LANG_CPP, "C++", 0 cs_aspx, LANG_CS_ASPX, "", 0 csharp, LANG_CSHARP, "C#", 0 css, LANG_CSS, "CSS", 1 +cuda, LANG_CUDA, "CUDA", 0 dcl, LANG_DCL, "DCL", 0 dmd, LANG_DMD, "D", 0 +dtx, LANG_TEX_DTX, "DTX for TeX/LaTeX", 1 dylan, LANG_DYLAN, "Dylan", 0 ebuild, LANG_EBUILD, "Ebuild", 0 +ec, LANG_EC, "eC", 0 eiffel, LANG_EIFFEL, "Eiffel", 0 emacslisp, LANG_EMACSLISP, "Emacs lisp", 0 erlang, LANG_ERLANG, "Erlang", 0 exheres, LANG_EXHERES, "Exheres", 0 factor, LANG_FACTOR, "Factor", 0 +forth, LANG_FORTH, "Forth", 0 fortranfixed, LANG_FORTRANFIXED, "Fortan (Fixed-format)", 0 fortranfree, LANG_FORTRANFREE, "Fortan (Free-format)", 0 fsharp, LANG_FSHARP, "F#", 0 +genie, LANG_GENIE, "Genie", 0 glsl, LANG_GLSL, "OpenGL Shading Language", 0 +golang, LANG_GOLANG, "Golang", 0 +grace, LANG_GRACE, "Grace", 0 groovy, LANG_GROOVY, "Groovy", 0 haml, LANG_HAML, "Haml", 1 haskell, LANG_HASKELL, "Haskell", 0 haxe, LANG_HAXE, "HaXe", 0 html, LANG_HTML, "HTML", 1 idl_pvwave, LANG_IDL_PVWAVE, "IDL/PV-WAVE/GDL", 0 +jam, LANG_JAM, "Jam", 2 java, LANG_JAVA, "Java", 0 javascript, LANG_JAVASCRIPT, "JavaScript", 0 jsp, LANG_JSP, "", 0 limbo, LANG_LIMBO, "Limbo", 0 lisp, LANG_LISP, "Lisp", 0 +logtalk, LANG_LOGTALK, "Logtalk", 0 lua, LANG_LUA, "Lua", 0 make, LANG_MAKE, "Make", 2 +mathematica, LANG_MATHEMATICA, "Mathematica", 0 matlab, LANG_MATLAB, "Matlab", 0 metafont, LANG_METAFONT, "MetaFont", 1 metapost, LANG_METAPOST, "MetaPost", 1 metapost_with_tex, LANG_METAPOST_WITH_TEX, "", 0 +modula2, LANG_MODULA2, "Modula-2", 0 +modula3, LANG_MODULA3, "Modula-3", 0 mxml, LANG_MXML, "MXML", 1 nix, LANG_NIX, "Nix", 0 +nsis, LANG_NSIS, "NSIS", 0 +oberon, LANG_OBERON, "Oberon", 0 objective_c, LANG_OBJECTIVE_C, "Objective-C", 0 objective_j, LANG_OBJECTIVE_J, "Objective-J", 0 ocaml, LANG_OCAML, "Objective Caml", 0 @@ -61,11 +84,17 @@ perl, LANG_PERL, "Perl", 0 php, LANG_PHP, "PHP", 0 pike, LANG_PIKE, "Pike", 0 +prolog, LANG_PROLOG, "Prolog", 0 +puppet, LANG_PUPPET, "Puppet", 0 python, LANG_PYTHON, "Python", 0 +qml, LANG_QML, "QML", 1 r, LANG_R, "R", 0 +racket, LANG_RACKET, "Racket", 0 +rebol, LANG_REBOL, "REBOL", 0 rexx, LANG_REXX, "rexx", 0 rhtml, LANG_RHTML, "", 0 ruby, LANG_RUBY, "Ruby", 0 +rust, LANG_RUST, "Rust", 0 scala, LANG_SCALA, "Scala", 0 scheme, LANG_SCHEME, "Scheme", 0 scilab, LANG_SCILAB, "Scilab", 0 @@ -76,6 +105,7 @@ sql, LANG_SQL, "SQL", 0 tcl, LANG_TCL, "TCL", 0 tex, LANG_TEX, "TeX/LaTeX", 1 +typescript, LANG_TYPESCRIPT, "TypeScript", 0 vala, LANG_VALA, "Vala", 0 vb_aspx, LANG_VB_ASPX, "", 0 vhdl, LANG_VHDL, "VHDL", 0 diff --git a/src/hash/parsers.gperf b/src/hash/parsers.gperf index ae37503..2446162 100644 --- a/src/hash/parsers.gperf +++ b/src/hash/parsers.gperf @@ -1,18 +1,25 @@ %{ #include "../parsers/actionscript.h" #include "../parsers/ada.h" +#include "../parsers/ampl.h" #include "../parsers/assembler.h" +#include "../parsers/augeas.h" #include "../parsers/autoconf.h" #include "../parsers/automake.h" #include "../parsers/awk.h" #include "../parsers/bat.h" #include "../parsers/blitzmax.h" #include "../parsers/boo.h" +#include "../parsers/brainfuck.h" +#include "../parsers/bfpp.h" #include "../parsers/c.h" +#include "../parsers/chaiscript.h" #include "../parsers/classic_basic.h" #include "../parsers/clearsilver.h" #include "../parsers/clearsilverhtml.h" +#include "../parsers/coffeescript.h" #include "../parsers/cmake.h" +#include "../parsers/coq.h" #include "../parsers/cs_aspx.h" #include "../parsers/css.h" #include "../parsers/d.h" @@ -23,29 +30,39 @@ #include "../parsers/erlang.h" #include "../parsers/exheres.h" #include "../parsers/factor.h" +#include "../parsers/forth.h" #include "../parsers/fortranfixed.h" #include "../parsers/fortranfree.h" #include "../parsers/fsharp.h" #include "../parsers/glsl.h" +#include "../parsers/golang.h" +#include "../parsers/grace.h" #include "../parsers/groovy.h" #include "../parsers/haml.h" #include "../parsers/haskell.h" #include "../parsers/haxe.h" #include "../parsers/html.h" #include "../parsers/idl_pvwave.h" +#include "../parsers/jam.h" #include "../parsers/java.h" #include "../parsers/javascript.h" #include "../parsers/jsp.h" #include "../parsers/lisp.h" #include "../parsers/limbo.h" +#include "../parsers/logtalk.h" #include "../parsers/lua.h" #include "../parsers/makefile.h" +#include "../parsers/mathematica.h" #include "../parsers/matlab.h" #include "../parsers/metafont.h" #include "../parsers/metapost.h" #include "../parsers/metapost_with_tex.h" +#include "../parsers/modula2.h" +#include "../parsers/modula3.h" #include "../parsers/mxml.h" #include "../parsers/nix.h" +#include "../parsers/nsis.h" +#include "../parsers/oberon.h" #include "../parsers/objective_c.h" #include "../parsers/objective_j.h" #include "../parsers/ocaml.h" @@ -54,10 +71,14 @@ #include "../parsers/perl.h" #include "../parsers/phphtml.h" #include "../parsers/pike.h" +#include "../parsers/prolog.h" +#include "../parsers/puppet.h" #include "../parsers/python.h" #include "../parsers/r.h" +#include "../parsers/rebol.h" #include "../parsers/rexx.h" #include "../parsers/ruby.h" +#include "../parsers/rust.h" #include "../parsers/rhtml.h" #include "../parsers/scala.h" #include "../parsers/scilab.h" @@ -68,6 +89,7 @@ #include "../parsers/sql.h" #include "../parsers/tcl.h" #include "../parsers/tex.h" +#include "../parsers/tex_dtx.h" #include "../parsers/vb_aspx.h" #include "../parsers/vhdl.h" #include "../parsers/vim.h" @@ -81,54 +103,75 @@ %% actionscript, parse_actionscript ada, parse_ada +ampl, parse_ampl assembler, parse_assembler +augeas, parse_augeas autoconf, parse_autoconf automake, parse_automake awk, parse_awk bat, parse_bat blitzmax, parse_blitzmax boo, parse_boo +brainfuck, parse_brainfuck +bfpp, parse_bfpp c, parse_c +chaiscript, parse_chaiscript cmake, parse_cmake classic_basic, parse_classic_basic clearsilver, parse_clearsilver clearsilver_template, parse_cshtml +clojure, parse_clojure +coffeescript, parse_coffeescript +coq, parse_coq cpp, parse_cpp cs_aspx, parse_cs_aspx csharp, parse_csharp css, parse_css +cuda, parse_cuda dcl, parse_dcl dmd, parse_d dylan, parse_dylan ebuild, parse_ebuild +ec, parse_ec eiffel, parse_eiffel erlang, parse_erlang exheres, parse_exheres emacslisp, parse_emacslisp factor, parse_factor +forth, parse_forth fortranfixed, parse_fortranfixed fortranfree, parse_fortranfree fsharp, parse_fsharp +genie, parse_genie glsl, parse_glsl +golang, parse_golang +grace, parse_grace groovy, parse_groovy haskell, parse_haskell haml, parse_haml haxe, parse_haxe html, parse_html idl_pvwave, parse_idl_pvwave +jam, parse_jam java, parse_java javascript, parse_javascript jsp, parse_jsp lisp, parse_lisp limbo, parse_limbo +logtalk, parse_logtalk lua, parse_lua make, parse_makefile +mathematica, parse_mathematica matlab, parse_matlab metafont, parse_metafont metapost, parse_metapost metapost_with_tex, parse_mptex +modula2, parse_modula2 +modula3, parse_modula3 mxml, parse_mxml nix, parse_nix +nsis, parse_nsis +oberon, parse_oberon objective_c, parse_objective_c objective_j, parse_objective_j ocaml, parse_ocaml @@ -137,11 +180,17 @@ perl, parse_perl php, parse_phtml pike, parse_pike +prolog, parse_prolog +puppet, parse_puppet python, parse_python +qml, parse_qml r, parse_r +racket, parse_racket +rebol, parse_rebol rexx, parse_rexx rhtml, parse_rhtml ruby, parse_ruby +rust, parse_rust scala, parse_scala scheme, parse_scheme scilab, parse_scilab @@ -152,6 +201,8 @@ sql, parse_sql tcl, parse_tcl tex, parse_tex +tex_dtx, parse_tex_dtx +typescript, parse_typescript vala, parse_vala vb_aspx, parse_vb_aspx vhdl, parse_vhdl diff --git a/src/languages.h b/src/languages.h old file mode 100644 new file mode 100755 index b19a649..acdc5c0 100755 --- a/src/languages.h +++ b/src/languages.h @@ -1,96 +1,125 @@ -// languages.h written by Mitchell Foral. mitchellcaladbolg.net. -// See COPYING for license information. - -#ifndef OHCOUNT_LANGUAGES_H -#define OHCOUNT_LANGUAGES_H - -#include - -#define LANG_ACTIONSCRIPT "actionscript" -#define LANG_ADA "ada" -#define LANG_ASSEMBLER "assembler" -#define LANG_AUTOCONF "autoconf" -#define LANG_AUTOMAKE "automake" -#define LANG_AWK "awk" -#define LANG_BAT "bat" -#define LANG_BLITZMAX "blitzmax" -#define LANG_BOO "boo" -#define LANG_C "c" -#define LANG_CLASSIC_BASIC "classic_basic" -#define LANG_CLEARSILVER "clearsilver" -#define LANG_CLEARSILVER_TEMPLATE "clearsilver_template" -#define LANG_CMAKE "cmake" -#define LANG_CPP "cpp" -#define LANG_CS_ASPX "cs_aspx" -#define LANG_CSHARP "csharp" -#define LANG_CSS "css" -#define LANG_DCL "dcl" -#define LANG_DMD "dmd" -#define LANG_DYLAN "dylan" -#define LANG_EBUILD "ebuild" -#define LANG_EIFFEL "eiffel" -#define LANG_ERLANG "erlang" -#define LANG_EXHERES "exheres" -#define LANG_EMACSLISP "emacslisp" -#define LANG_FACTOR "factor" -#define LANG_FORTRANFIXED "fortranfixed" -#define LANG_FORTRANFREE "fortranfree" -#define LANG_FSHARP "fsharp" -#define LANG_GLSL "glsl" -#define LANG_GROOVY "groovy" -#define LANG_HASKELL "haskell" -#define LANG_HAML "haml" -#define LANG_HAXE "haxe" -#define LANG_HTML "html" -#define LANG_IDL_PVWAVE "idl_pvwave" -#define LANG_JAVA "java" -#define LANG_JAVASCRIPT "javascript" -#define LANG_JSP "jsp" -#define LANG_LIMBO "limbo" -#define LANG_LISP "lisp" -#define LANG_LUA "lua" -#define LANG_MAKE "make" -#define LANG_MATLAB "matlab" -#define LANG_METAFONT "metafont" -#define LANG_METAPOST "metapost" -#define LANG_METAPOST_WITH_TEX "metapost_with_tex" -#define LANG_MXML "mxml" -#define LANG_NIX "nix" -#define LANG_OBJECTIVE_C "objective_c" -#define LANG_OBJECTIVE_J "objective_j" -#define LANG_OCAML "ocaml" -#define LANG_OCTAVE "octave" -#define LANG_PASCAL "pascal" -#define LANG_PERL "perl" -#define LANG_PHP "php" -#define LANG_PIKE "pike" -#define LANG_PYTHON "python" -#define LANG_R "r" -#define LANG_REXX "rexx" -#define LANG_RHTML "rhtml" -#define LANG_RUBY "ruby" -#define LANG_SCALA "scala" -#define LANG_SCHEME "scheme" -#define LANG_SCILAB "scilab" -#define LANG_SHELL "shell" -#define LANG_SMALLTALK "smalltalk" -#define LANG_STRATEGO "stratego" -#define LANG_STRUCTURED_BASIC "structured_basic" -#define LANG_SQL "sql" -#define LANG_TCL "tcl" -#define LANG_TEX "tex" -#define LANG_VALA "vala" -#define LANG_VB_ASPX "vb_aspx" -#define LANG_VHDL "vhdl" -#define LANG_VIM "vim" -#define LANG_VISUALBASIC "visualbasic" -#define LANG_XAML "xaml" -#define LANG_XML "xml" -#define LANG_XSLT "xslt" -#define LANG_XMLSCHEMA "xmlschema" - -// For gperf. -struct LanguageMap { const char *key; const char *name; const char *nice_name; int category; }; -struct LanguageMap *ohcount_hash_language_from_name(register const char *str, register unsigned int len); - -#endif +// languages.h written by Mitchell Foral. mitchellcaladbolg.net. +// See COPYING for license information. + +#ifndef OHCOUNT_LANGUAGES_H +#define OHCOUNT_LANGUAGES_H + +#include + +#define LANG_ACTIONSCRIPT "actionscript" +#define LANG_ADA "ada" +#define LANG_AMPL "ampl" +#define LANG_ASSEMBLER "assembler" +#define LANG_AUGEAS "augeas" +#define LANG_AUTOCONF "autoconf" +#define LANG_AUTOMAKE "automake" +#define LANG_AWK "awk" +#define LANG_BRAINFUCK "brainfuck" +#define LANG_BFPP "bfpp" +#define LANG_BAT "bat" +#define LANG_BLITZMAX "blitzmax" +#define LANG_BOO "boo" +#define LANG_C "c" +#define LANG_CHAISCRIPT "chaiscript" +#define LANG_CLASSIC_BASIC "classic_basic" +#define LANG_CLEARSILVER "clearsilver" +#define LANG_CLEARSILVER_TEMPLATE "clearsilver_template" +#define LANG_CLOJURE "clojure" +#define LANG_CMAKE "cmake" +#define LANG_COFFEESCRIPT "coffeescript" +#define LANG_COQ "coq" +#define LANG_CPP "cpp" +#define LANG_CS_ASPX "cs_aspx" +#define LANG_CSHARP "csharp" +#define LANG_CSS "css" +#define LANG_CUDA "cuda" +#define LANG_DCL "dcl" +#define LANG_DMD "dmd" +#define LANG_DYLAN "dylan" +#define LANG_EBUILD "ebuild" +#define LANG_EC "ec" +#define LANG_EIFFEL "eiffel" +#define LANG_ERLANG "erlang" +#define LANG_EXHERES "exheres" +#define LANG_EMACSLISP "emacslisp" +#define LANG_FACTOR "factor" +#define LANG_FORTH "forth" +#define LANG_FORTRANFIXED "fortranfixed" +#define LANG_FORTRANFREE "fortranfree" +#define LANG_FSHARP "fsharp" +#define LANG_GENIE "genie" +#define LANG_GLSL "glsl" +#define LANG_GOLANG "golang" +#define LANG_GRACE "grace" +#define LANG_GROOVY "groovy" +#define LANG_HASKELL "haskell" +#define LANG_HAML "haml" +#define LANG_HAXE "haxe" +#define LANG_HTML "html" +#define LANG_IDL_PVWAVE "idl_pvwave" +#define LANG_JAM "jam" +#define LANG_JAVA "java" +#define LANG_JAVASCRIPT "javascript" +#define LANG_JSP "jsp" +#define LANG_LIMBO "limbo" +#define LANG_LISP "lisp" +#define LANG_LOGTALK "logtalk" +#define LANG_LUA "lua" +#define LANG_MAKE "make" +#define LANG_MATHEMATICA "mathematica" +#define LANG_MATLAB "matlab" +#define LANG_METAFONT "metafont" +#define LANG_METAPOST "metapost" +#define LANG_METAPOST_WITH_TEX "metapost_with_tex" +#define LANG_MODULA2 "modula2" +#define LANG_MODULA3 "modula3" +#define LANG_MXML "mxml" +#define LANG_NIX "nix" +#define LANG_NSIS "nsis" +#define LANG_OBERON "oberon" +#define LANG_OBJECTIVE_C "objective_c" +#define LANG_OBJECTIVE_J "objective_j" +#define LANG_OCAML "ocaml" +#define LANG_OCTAVE "octave" +#define LANG_PASCAL "pascal" +#define LANG_PERL "perl" +#define LANG_PHP "php" +#define LANG_PIKE "pike" +#define LANG_PROLOG "prolog" +#define LANG_PUPPET "puppet" +#define LANG_PYTHON "python" +#define LANG_QML "qml" +#define LANG_R "r" +#define LANG_RACKET "racket" +#define LANG_REBOL "rebol" +#define LANG_REXX "rexx" +#define LANG_RHTML "rhtml" +#define LANG_RUBY "ruby" +#define LANG_RUST "rust" +#define LANG_SCALA "scala" +#define LANG_SCHEME "scheme" +#define LANG_SCILAB "scilab" +#define LANG_SHELL "shell" +#define LANG_SMALLTALK "smalltalk" +#define LANG_STRATEGO "stratego" +#define LANG_STRUCTURED_BASIC "structured_basic" +#define LANG_SQL "sql" +#define LANG_TCL "tcl" +#define LANG_TEX "tex" +#define LANG_TEX_DTX "tex_dtx" +#define LANG_TYPESCRIPT "typescript" +#define LANG_VALA "vala" +#define LANG_VB_ASPX "vb_aspx" +#define LANG_VHDL "vhdl" +#define LANG_VIM "vim" +#define LANG_VISUALBASIC "visualbasic" +#define LANG_XAML "xaml" +#define LANG_XML "xml" +#define LANG_XSLT "xslt" +#define LANG_XMLSCHEMA "xmlschema" + +// For gperf. +struct LanguageMap { const char *key; const char *name; const char *nice_name; int category; }; +struct LanguageMap *ohcount_hash_language_from_name(register const char *str, register unsigned int len); + +#endif diff --git a/src/licenses.c b/src/licenses.c index f0cd90f..6cbaae6 100644 --- a/src/licenses.c +++ b/src/licenses.c @@ -718,6 +718,16 @@ PCRE_MULTILINE, "(The Regents of the University of California)|(used to endorse or promote\\s+.*products\\s+.*prior\\s+.*written\\s+.*permission\\.)", PCRE_MULTILINE, + NULL, NULL + }, + { + LIC_WTFPL2, + "", + "WTF Public License", + "(\\bwtfpl\\b)|(\\bwtf\\s*public\\s*license\\b)|(\\b(do\\s*)?what\\s*the\\s*\\fuck\\s*public\\s*license\\b)", + PCRE_CASELESS, + NULL, + 0, NULL, NULL }, { NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL }, diff --git a/src/licenses.h b/src/licenses.h index cc8acee..82dc149 100644 --- a/src/licenses.h +++ b/src/licenses.h @@ -95,6 +95,7 @@ #define LIC_APACHE_ISH "apache_ish" #define LIC_BSD_ISH "bsd_ish" #define LIC_BSD_2CLAUSE_ISH "bsd_2clause_ish" +#define LIC_WTFPL2 "wtfpl_2" /** * Attempts to detect the source code licenses for a given file. diff --git a/src/ohcount.c b/src/ohcount.c index 4a0bb72..ccf7c35 100644 --- a/src/ohcount.c +++ b/src/ohcount.c @@ -173,7 +173,7 @@ printf(" %10d", liter->loc->blanks); printf(" %10d", liter->loc->code + liter->loc->comments + liter->loc->blanks); - printf(" %s\n", iter->sf->filename); + printf(" %s\n", iter->sf->filepath); liter = liter->next; } iter = iter->next; @@ -272,7 +272,7 @@ ohcount_sourcefile_list_add_directory(list, argv[i]); closedir(dir); } else { - FILE *f = fopen(argv[i], "r"); + FILE *f = fopen(argv[i], "rb"); if (f) { ohcount_sourcefile_list_add_file(list, argv[i]); fclose(f); diff --git a/src/ohcount.h b/src/ohcount.h index f9f1182..3024ec1 100644 --- a/src/ohcount.h +++ b/src/ohcount.h @@ -64,6 +64,7 @@ * @li Ragel 6.3 or later - http://research.cs.queensu.ca/~thurston/ragel/ * @li GNU gperf - http://www.gnu.org/software/gperf/ * @li PCRE - http://pcre.sourceforge.net/ + * @li Bash - http://www.gnu.org/software/bash/ * * Run the 'build' script to build Ohcount. * @@ -84,6 +85,15 @@ * * You may then link or copy 'ruby/ohcount.{rb,so}' and 'ruby/gestalt{/,.rb}' * to the appropriate places in your Ruby installation. + * + * Building the Doxygen docs requires: + * + * @li Doxygen - http://www.doxygen.org/ + * + * @code + * $ cd doc + * $ Doxygen Doxyfile + * @endcode * * @section start First Steps * @@ -124,7 +134,7 @@ * * @section contact Contact Ohloh * - * For more information visit the Ohloh website: http://labs.ohloh.net + * For more information visit the Ohloh website: https://sourceforge.net/projects/ohcount * * You can reach Ohloh via email at: info@ohloh.net */ diff --git a/src/parser.c b/src/parser.c index cb28935..d362acf 100644 --- a/src/parser.c +++ b/src/parser.c @@ -6,6 +6,8 @@ #include "sourcefile.h" #include "log.h" #include "hash/parser_hash.h" + +struct ParserMap * ohcount_hash_parser_from_language (register const char *str, register unsigned int len); int ohcount_parse(SourceFile *sourcefile, int count, void (*callback) (const char *, const char *, int, int, diff --git a/src/parser.h b/src/parser.h index 370fbe5..3daa675 100644 --- a/src/parser.h +++ b/src/parser.h @@ -275,7 +275,7 @@ * input source file that goes in the 'test/src_dir/' and an expected output * file that goes in the 'test/expected_dir/' directory. * - * The header file will need to be "#include"ed in 'test/unit/test_parsers.h'. + * The header file will need to be "#include"ed in 'test/unit/parser_test.h'. * Then add the "all_[lang]_tests()" function to the "all_parser_tests()" * function. * diff --git a/src/parsers/ampl.rl b/src/parsers/ampl.rl new file mode 100644 index 0000000..4b4bd17 --- /dev/null +++ b/src/parsers/ampl.rl @@ -0,0 +1,113 @@ +// ampl.rl written by Victor Zverovich. victor.zverovich@gmail.com + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_AMPL_PARSER_H +#define OHCOUNT_AMPL_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *AMPL_LANG = LANG_AMPL; + +// the languages entities +const char *ampl_entities[] = { + "space", "comment", "any" +}; + +// constants associated with the entities +enum { + AMPL_SPACE = 0, AMPL_COMMENT, AMPL_ANY +}; + +/*****************************************************************************/ + +%%{ + machine ampl; + write data; + include common "common.rl"; + + # Line counting machine + + action ampl_ccallback { + switch(entity) { + case AMPL_SPACE: + ls + break; + case AMPL_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(AMPL_LANG) + break; + case NEWLINE: + std_newline(AMPL_LANG) + } + } + + ampl_line_comment = '#' @comment nonnewline*; + ampl_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %ampl_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '*/'; + ampl_comment = ampl_line_comment | ampl_block_comment; + + ampl_line := |* + spaces ${ entity = AMPL_SPACE; } => ampl_ccallback; + ampl_comment; + newline ${ entity = NEWLINE; } => ampl_ccallback; + ^space ${ entity = AMPL_ANY; } => ampl_ccallback; + *|; + + # Entity machine + + action ampl_ecallback { + callback(AMPL_LANG, ampl_entities[entity], cint(ts), cint(te), userdata); + } + + ampl_line_comment_entity = '#' nonnewline*; + ampl_block_comment_entity = '/*' any* :>> '*/'; + ampl_comment_entity = + ampl_line_comment_entity | ampl_block_comment_entity; + + ampl_entity := |* + space+ ${ entity = AMPL_SPACE; } => ampl_ecallback; + ampl_comment_entity ${ entity = AMPL_COMMENT; } => ampl_ecallback; + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with AMPL code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_ampl(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? ampl_en_ampl_line : ampl_en_ampl_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(AMPL_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/augeas.rl b/src/parsers/augeas.rl new file mode 100644 index 0000000..bfc89d1 --- /dev/null +++ b/src/parsers/augeas.rl @@ -0,0 +1,129 @@ +// augeas.rl, based on ocaml.rl +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_AUGEAS_PARSER_H +#define OHCOUNT_AUGEAS_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *AUGEAS_LANG = LANG_AUGEAS; + +// the languages entities +const char *augeas_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + AUGEAS_SPACE = 0, AUGEAS_COMMENT, AUGEAS_STRING, AUGEAS_ANY +}; + +/*****************************************************************************/ + +%%{ + machine augeas; + write data; + include common "common.rl"; + + # Line counting machine + + action augeas_ccallback { + switch(entity) { + case AUGEAS_SPACE: + ls + break; + case AUGEAS_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(AUGEAS_LANG) + break; + case NEWLINE: + std_newline(AUGEAS_LANG) + } + } + + action augeas_comment_nc_res { nest_count = 0; } + action augeas_comment_nc_inc { nest_count++; } + action augeas_comment_nc_dec { nest_count--; } + + augeas_nested_block_comment = + '(*' >augeas_comment_nc_res @comment ( + newline %{ entity = INTERNAL_NL; } %augeas_ccallback + | + ws + | + '(*' @augeas_comment_nc_inc @comment + | + '*)' @augeas_comment_nc_dec @comment + | + (nonnewline - ws) @comment + )* :>> ('*)' when { nest_count == 0 }) @comment; + + augeas_comment = augeas_nested_block_comment; + augeas_string = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"'; + + + augeas_line := |* + spaces ${ entity = AUGEAS_SPACE; } => augeas_ccallback; + augeas_comment; + augeas_string; + newline ${ entity = NEWLINE; } => augeas_ccallback; + ^space ${ entity = AUGEAS_ANY; } => augeas_ccallback; + *|; + + # Entity machine + + action augeas_ecallback { + callback(AUGEAS_LANG, augeas_entities[entity], cint(ts), cint(te), userdata); + } + + augeas_comment_entity = '(*' >augeas_comment_nc_res ( + '(*' @augeas_comment_nc_inc + | + '*)' @augeas_comment_nc_dec + | + any + )* :>> ('*)' when { nest_count == 0 }); + + augeas_entity := |* + space+ ${ entity = AUGEAS_SPACE; } => augeas_ecallback; + augeas_comment_entity ${ entity = AUGEAS_COMMENT; } => augeas_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Objective Caml code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_augeas(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + int nest_count = 0; + + %% write init; + cs = (count) ? augeas_en_augeas_line : augeas_en_augeas_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(AUGEAS_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/bat.rl b/src/parsers/bat.rl index 682720c..9966a21 100644 --- a/src/parsers/bat.rl +++ b/src/parsers/bat.rl @@ -44,7 +44,7 @@ } } - bat_comment = /rem/i @comment nonnewline*; + bat_comment = ( /rem/i | /@rem/i | '::' ) @comment nonnewline*; bat_line := |* spaces ${ entity = BAT_SPACE; } => bat_ccallback; @@ -59,7 +59,7 @@ callback(BAT_LANG, bat_entities[entity], cint(ts), cint(te), userdata); } - bat_comment_entity = /rem/i nonnewline*; + bat_comment_entity = ( /rem/i | /@rem/i | '::' ) nonnewline*; bat_entity := |* space+ ${ entity = BAT_SPACE; } => bat_ecallback; diff --git a/src/parsers/bfpp.rl b/src/parsers/bfpp.rl new file mode 100644 index 0000000..fcb029e --- /dev/null +++ b/src/parsers/bfpp.rl @@ -0,0 +1,126 @@ +// bfpp.rl written by Boris 'billiob' Faure billiobgmailcom + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_BFPP_PARSER_H +#define OHCOUNT_BFPP_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *BFPP_LANG = LANG_BFPP; + +// the languages entities +const char *bfpp_entities[] = { + "space", "comment", "operator", "include" +}; + +// constants associated with the entities +enum { + BFPP_SPACE = 0, BFPP_COMMENT, BFPP_OPERATOR, BFPP_INCLUDE +}; + +/*****************************************************************************/ + +%%{ + machine bfpp; + write data; + include common "common.rl"; + + # Line counting machine + + action bfpp_ccallback { + switch(entity) { + case BFPP_SPACE: + ls + break; + case BFPP_OPERATOR: + case BFPP_INCLUDE: + code + break; + case BFPP_COMMENT: + comment + break; + case INTERNAL_NL: + std_internal_newline(BFPP_LANG) + break; + case NEWLINE: + std_newline(BFPP_LANG) + } + } + + bfpp_operator = [+\-<>.,\[\]\%\!\#\^\:\;] @code; + + bfpp_line_comment = ('=') @comment nonnewline*; + + bfpp_include = '@include(' @code ( + newline %{ entity = INTERNAL_NL; } %bfpp_ccallback + | + ws + | + (nonnewline - ws) @code + )* :>> ')'; + + bfpp_line := |* + spaces ${ entity = BFPP_SPACE; } => bfpp_ccallback; + newline ${ entity = NEWLINE; } => bfpp_ccallback; + bfpp_line_comment; + bfpp_include; + bfpp_operator ${ entity = BFPP_OPERATOR; } => bfpp_ccallback; + ^space ${ entity = BFPP_COMMENT; } => bfpp_ccallback; + *|; + + # Entity machine + + action bfpp_ecallback { + callback(BFPP_LANG, bfpp_entities[entity], cint(ts), cint(te), userdata); + } + + bfpp_operator_entity = [+\-<>.,\[\]%\#^;:]; + + bfpp_include_entity = '@include(' any* :>> ')'; + + bfpp_line_comment_entity = '=' (escaped_newline | nonnewline)*; + + bfpp_comment_entity = (bfpp_line_comment_entity | + !(space | bfpp_operator_entity | bfpp_include_entity)); + + bfpp_entity := |* + space+ ${ entity = BFPP_SPACE; } => bfpp_ecallback; + bfpp_operator_entity ${ entity = BFPP_OPERATOR; } => bfpp_ecallback; + bfpp_include_entity ${ entity = BFPP_INCLUDE; } => bfpp_ecallback; + bfpp_comment_entity ${ entity = BFPP_COMMENT; } => bfpp_ecallback; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Brainfuck++ code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_bfpp(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? bfpp_en_bfpp_line : bfpp_en_bfpp_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(BFPP_LANG) } +} + +#endif + +/*****************************************************************************/ + diff --git a/src/parsers/brainfuck.rl b/src/parsers/brainfuck.rl new file mode 100644 index 0000000..fbebfea --- /dev/null +++ b/src/parsers/brainfuck.rl @@ -0,0 +1,107 @@ +// brainfuck.rl written by Boris 'billiob' Faure billiobgmailcom + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_BRAINFUCK_PARSER_H +#define OHCOUNT_BRAINFUCK_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *BRAINFUCK_LANG = LANG_BRAINFUCK; + +// the languages entities +const char *brainfuck_entities[] = { + "space", "comment", "operator" +}; + +// constants associated with the entities +enum { + BRAINFUCK_SPACE = 0, BRAINFUCK_COMMENT, BRAINFUCK_OPERATOR +}; + +/*****************************************************************************/ + +%%{ + machine brainfuck; + write data; + include common "common.rl"; + + # Line counting machine + + action brainfuck_ccallback { + switch(entity) { + case BRAINFUCK_SPACE: + ls + break; + case BRAINFUCK_OPERATOR: + code + break; + case BRAINFUCK_COMMENT: + comment + break; + case INTERNAL_NL: + std_internal_newline(BRAINFUCK_LANG) + break; + case NEWLINE: + std_newline(BRAINFUCK_LANG) + } + } + + brainfuck_operator = [+\-<>.,\[\]] @code; + + brainfuck_line := |* + spaces ${ entity = BRAINFUCK_SPACE; } => brainfuck_ccallback; + newline ${ entity = NEWLINE; } => brainfuck_ccallback; + brainfuck_operator ${ entity = BRAINFUCK_OPERATOR; } => brainfuck_ccallback; + ^space ${ entity = BRAINFUCK_COMMENT; } => brainfuck_ccallback; + *|; + + # Entity machine + + action brainfuck_ecallback { + callback(BRAINFUCK_LANG, brainfuck_entities[entity], cint(ts), cint(te), userdata); + } + + brainfuck_operator_entity = [+\-<>.,\[\]]; + + brainfuck_comment_entity = !(space | brainfuck_operator_entity); + + brainfuck_entity := |* + space+ ${ entity = BRAINFUCK_SPACE; } => brainfuck_ecallback; + brainfuck_operator_entity ${ entity = BRAINFUCK_OPERATOR; } => brainfuck_ecallback; + brainfuck_comment_entity ${ entity = BRAINFUCK_COMMENT; } => brainfuck_ecallback; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Brainfuck code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_brainfuck(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? brainfuck_en_brainfuck_line : brainfuck_en_brainfuck_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(BRAINFUCK_LANG) } +} + +#endif + +/*****************************************************************************/ + diff --git a/src/parsers/c.rl b/src/parsers/c.rl old file mode 100644 new file mode 100755 index c887e83..0ba4008 100755 --- a/src/parsers/c.rl +++ b/src/parsers/c.rl @@ -211,6 +211,39 @@ C_LANG = ORIG_C_LANG; } +const char *GENIE_LANG = LANG_GENIE; +void parse_genie(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, + int s, int e, void *udata), + void *userdata + ) { + C_LANG = GENIE_LANG; + parse_c(buffer, length, count, callback, userdata); + C_LANG = ORIG_C_LANG; +} + +const char *CUDA_LANG = LANG_CUDA; +void parse_cuda(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + C_LANG = CUDA_LANG; + parse_c(buffer, length, count, callback, userdata); + C_LANG = ORIG_C_LANG; +} + +const char *EC_LANG = LANG_EC; +void parse_ec(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + C_LANG = EC_LANG; + parse_c(buffer, length, count, callback, userdata); + C_LANG = ORIG_C_LANG; +} + #endif /*****************************************************************************/ diff --git a/src/parsers/chaiscript.rl b/src/parsers/chaiscript.rl new file mode 100644 index 0000000..5491e36 --- /dev/null +++ b/src/parsers/chaiscript.rl @@ -0,0 +1,138 @@ +// Chaiscript.rl written by Jason Turner. lefticusgmailcom +// based on Javascript.rl written by Mitchell Foral. mitchellcaladbolgnet. + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_CHAISCRIPT_PARSER_H +#define OHCOUNT_CHAISCRIPT_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *CHAI_LANG = LANG_CHAISCRIPT; + +// the languages entities +const char *chai_entities[] = { + "space", "comment", "string", "number", "keyword", + "identifier", "operator", "any" +}; + +// constants associated with the entities +enum { + CHAI_SPACE = 0, CHAI_COMMENT, CHAI_STRING, CHAI_NUMBER, CHAI_KEYWORD, + CHAI_IDENTIFIER, CHAI_OPERATOR, CHAI_ANY +}; + +/*****************************************************************************/ + +%%{ + machine chaiscript; + write data; + include common "common.rl"; + + # Line counting machine + + action chai_ccallback { + switch(entity) { + case CHAI_SPACE: + ls + break; + case CHAI_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(CHAI_LANG) + break; + case NEWLINE: + std_newline(CHAI_LANG) + } + } + + chai_line_comment = '//' @comment nonnewline*; + chai_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %chai_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '*/'; + chai_comment = chai_line_comment | chai_block_comment; + + # Does Javascript allow newlines inside strings? + # I can't find a definitive answer. + chai_sq_str = + '\'' @code ( + escaped_newline %{ entity = INTERNAL_NL; } %chai_ccallback + | + ws + | + [^\t '\\] @code + | + '\\' nonnewline @code + )* '\''; + chai_dq_str = + '"' @code ( + escaped_newline %{ entity = INTERNAL_NL; } %chai_ccallback + | + ws + | + [^\t "\\] @code + | + '\\' nonnewline @code + )* '"'; + chai_regex_str = '/' [^/*] ([^\r\n\f/\\] | '\\' nonnewline)* '/' @code; + chai_string = chai_sq_str | chai_dq_str | chai_regex_str; + + chai_line := |* + spaces ${ entity = CHAI_SPACE; } => chai_ccallback; + chai_comment; + chai_string; + newline ${ entity = NEWLINE; } => chai_ccallback; + ^space ${ entity = CHAI_ANY; } => chai_ccallback; + *|; + + # Entity machine + + action chai_ecallback { + callback(CHAI_LANG, chai_entities[entity], cint(ts), cint(te), userdata); + } + + chai_line_comment_entity = '//' nonnewline*; + chai_block_comment_entity = '/*' any* :>> '*/'; + chai_comment_entity = chai_line_comment_entity | chai_block_comment_entity; + + chai_entity := |* + space+ ${ entity = CHAI_SPACE; } => chai_ecallback; + chai_comment_entity ${ entity = CHAI_COMMENT; } => chai_ecallback; + # TODO: + ^space; + *|; +}%% + +/* Parses a string buffer with Chaiscript code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_chaiscript(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, + int s, int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? chaiscript_en_chai_line : chaiscript_en_chai_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(CHAI_LANG) } +} + +#endif diff --git a/src/parsers/coffeescript.rl b/src/parsers/coffeescript.rl new file mode 100644 index 0000000..b08a653 --- /dev/null +++ b/src/parsers/coffeescript.rl @@ -0,0 +1,170 @@ +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_COFFEESCRIPT_PARSER_H +#define OHCOUNT_COFFEESCRIPT_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *COFFEESCRIPT_LANG = LANG_COFFEESCRIPT; + +// the languages entities +const char *coffeescript_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + COFFEESCRIPT_SPACE = 0, COFFEESCRIPT_COMMENT, COFFEESCRIPT_STRING, COFFEESCRIPT_ANY +}; + +/*****************************************************************************/ + +#include "javascript.h" + +%%{ + machine coffeescript; + write data; + include common "common.rl"; + #EMBED(javascript) + + # Line counting machine + + action coffeescript_ccallback { + switch(entity) { + case COFFEESCRIPT_SPACE: + ls + break; + case COFFEESCRIPT_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(COFFEESCRIPT_LANG) + break; + case NEWLINE: + std_newline(COFFEESCRIPT_LANG) + } + } + + coffeescript_line_comment = ('#') @comment nonnewline*; + coffeescript_block_comment = + '###' @comment ( + newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '###'; + coffeescript_comment = coffeescript_line_comment | coffeescript_block_comment; + + coffeescript_sq_str = + '\'' @enqueue @code ( + newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback + | + ws + | + [^\r\n\f\t '\\] @code + | + '\\' nonnewline @code + )* '\'' @commit @code; + coffeescript_dq_str = + '"' @enqueue @code ( + newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback + | + ws + | + [^\r\n\f\t "\\] @code + | + '\\' nonnewline @code + )* '"' @commit @code; + coffeescript_sq_here_doc = + '\'\'\'' @code ( + newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback + | + ws + | + (nonnewline - ws) @code + )* :>> '\'\'\'' @code; + coffeescript_dq_here_doc = + '"""' @code ( + newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback + | + ws + | + (nonnewline - ws) @code + )* :>> '"""' @code; + coffeescript_string = (coffeescript_sq_str | coffeescript_dq_str | + coffeescript_sq_here_doc | coffeescript_dq_here_doc) @code; + + coffeescript_js_entry = '`' @code; + coffeescript_js_outry = '`' @check_blank_outry @code; + coffeescript_js_line := |* + coffeescript_js_outry @{ p = ts; fret; }; + # unmodified JavaScript patterns + spaces ${ entity = JS_SPACE; } => js_ccallback; + js_comment; + js_string; + newline ${ entity = NEWLINE; } => js_ccallback; + ^space ${ entity = JS_ANY; } => js_ccallback; + *|; + + coffeescript_line := |* + coffeescript_js_entry @coffeescript_ccallback + @{ saw(JS_LANG); } => { fcall coffeescript_js_line; }; + spaces ${ entity = COFFEESCRIPT_SPACE; } => coffeescript_ccallback; + coffeescript_comment; + coffeescript_string; + newline ${ entity = NEWLINE; } => coffeescript_ccallback; + ^space ${ entity = COFFEESCRIPT_ANY; } => coffeescript_ccallback; + *|; + + # Entity machine + + action coffeescript_ecallback { + callback(COFFEESCRIPT_LANG, coffeescript_entities[entity], cint(ts), cint(te), + userdata); + } + + coffeescript_line_comment_entity = ('#') nonnewline*; + coffeescript_block_comment_entity = '###' any* :>> '###'; + coffeescript_comment_entity = coffeescript_line_comment_entity | + coffeescript_block_comment_entity; + + coffeescript_entity := |* + space+ ${ entity = COFFEESCRIPT_SPACE; } => coffeescript_ecallback; + coffeescript_comment_entity ${ entity = COFFEESCRIPT_COMMENT; } => coffeescript_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with CoffeeScript code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_coffeescript(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? coffeescript_en_coffeescript_line : coffeescript_en_coffeescript_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(COFFEESCRIPT_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/compile b/src/parsers/compile index 1327c59..e23527a 100755 --- a/src/parsers/compile +++ b/src/parsers/compile @@ -1,6 +1,15 @@ #!/bin/sh # Compiles all .rl files for Ohcount. # Written by Mitchell Foral. mitchellcaladbolgnet. + +# check to make sure we have ragel +if `type ragel > /dev/null 2> /dev/null` +then + echo "Found ragel, compiling..." +else + echo "ragel not found, aborting" >&2 + exit 1 +fi for file in *.rl do diff --git a/src/parsers/coq.rl b/src/parsers/coq.rl new file mode 100644 index 0000000..eaa3330 --- /dev/null +++ b/src/parsers/coq.rl @@ -0,0 +1,135 @@ +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_COQ_PARSER_H +#define OHCOUNT_COQ_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *COQ_LANG = LANG_COQ; + +// the languages entities +const char *coq_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + COQ_SPACE = 0, COQ_COMMENT, COQ_STRING, COQ_ANY +}; + +/*****************************************************************************/ + +%%{ + machine coq; + write data; + include common "common.rl"; + + # Line counting machine + + action coq_ccallback { + switch(entity) { + case COQ_SPACE: + ls + break; + case COQ_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(COQ_LANG) + break; + case NEWLINE: + std_newline(COQ_LANG) + } + } + + action coq_comment_nc_res { nest_count = 0; } + action coq_comment_nc_inc { nest_count++; } + action coq_comment_nc_dec { nest_count--; } + + coq_nested_block_comment = + '(*' >coq_comment_nc_res @comment ( + newline %{ entity = INTERNAL_NL; } %coq_ccallback + | + ws + | + '(*' @coq_comment_nc_inc @comment + | + '*)' @coq_comment_nc_dec @comment + | + (nonnewline - ws) @comment + )* :>> ('*)' when { nest_count == 0 }) @comment; + + coq_comment = coq_nested_block_comment; + + coq_string = + '"' @code ( + newline %{ entity = INTERNAL_NL; } %coq_ccallback + | + ws + | + [^"] @code + )* '"'; + + coq_line := |* + spaces ${ entity = COQ_SPACE; } => coq_ccallback; + coq_comment; + coq_string; + newline ${ entity = NEWLINE; } => coq_ccallback; + ^space ${ entity = COQ_ANY; } => coq_ccallback; + *|; + + # Entity machine + + action coq_ecallback { + callback(COQ_LANG, coq_entities[entity], cint(ts), cint(te), userdata); + } + + coq_comment_entity = '(*' >coq_comment_nc_res ( + '(*' @coq_comment_nc_inc + | + '*)' @coq_comment_nc_dec + | + any + )* :>> ('*)' when { nest_count == 0 }); + + coq_entity := |* + space+ ${ entity = COQ_SPACE; } => coq_ecallback; + coq_comment_entity ${ entity = COQ_COMMENT; } => coq_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Coq code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_coq(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + int nest_count = 0; + + %% write init; + cs = (count) ? coq_en_coq_line : coq_en_coq_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(COQ_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/forth.rl b/src/parsers/forth.rl new file mode 100644 index 0000000..c7c53c0 --- /dev/null +++ b/src/parsers/forth.rl @@ -0,0 +1,117 @@ +// forth.rl +// derived from code written by Mitchell Foral. mitchellcaladbolgnet. + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_FORTH_PARSER_H +#define OHCOUNT_FORTH_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *FORTH_LANG = LANG_FORTH; + +// the languages entities +const char *forth_entities[] = { + "space", "comment", "string", "any", +}; + +// constants associated with the entities +enum { + FORTH_SPACE = 0, FORTH_COMMENT, FORTH_STRING, FORTH_ANY +}; + +/*****************************************************************************/ + +%%{ + machine forth; + write data; + include common "common.rl"; + + # Line counting machine + + action forth_ccallback { + switch(entity) { + case FORTH_SPACE: + ls + break; + case FORTH_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(FORTH_LANG) + break; + case NEWLINE: + std_newline(FORTH_LANG) + } + } + + forth_line_comment = '\\' @comment nonnewline*; + forth_block_comment = + '(' @comment ( + newline %{ entity = INTERNAL_NL; } %forth_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> ')'; + forth_comment = forth_line_comment | forth_block_comment; + + forth_string = '"' @code ([^\r\n\f"])* '"'; + + forth_line := |* + spaces ${ entity = FORTH_SPACE; } => forth_ccallback; + forth_comment; + forth_string; + newline ${ entity = NEWLINE; } => forth_ccallback; + ^space ${ entity = FORTH_ANY; } => forth_ccallback; + *|; + + # Entity machine + + action forth_ecallback { + callback(FORTH_LANG, forth_entities[entity], cint(ts), cint(te), userdata); + } + + forth_line_comment_entity = '\\' nonnewline*; + forth_block_comment_entity = '(' any* :>> ')'; + forth_comment_entity = forth_line_comment_entity | forth_block_comment_entity; + + forth_entity := |* + space+ ${ entity = FORTH_SPACE; } => forth_ecallback; + forth_comment_entity ${ entity = FORTH_COMMENT; } => forth_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Forth code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_forth(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? forth_en_forth_line : forth_en_forth_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(FORTH_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/golang.rl b/src/parsers/golang.rl new file mode 100644 index 0000000..f845ca0 --- /dev/null +++ b/src/parsers/golang.rl @@ -0,0 +1,184 @@ +// golang.rl written by Scott Lawrence + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_GOLANG_PARSER_H +#define OHCOUNT_GOLANG_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *GOLANG_LANG = LANG_GOLANG; + +// the languages entities +const char *golang_entities[] = { + "space", "comment", "string", "number", "preproc", + "keyword", "identifier", "operator", "any" +}; + +// constants associated with the entities +enum { + GOLANG_SPACE = 0, GOLANG_COMMENT, GOLANG_STRING, GOLANG_NUMBER, GOLANG_PREPROC, + GOLANG_KEYWORD, GOLANG_IDENTIFIER, GOLANG_OPERATOR, GOLANG_ANY +}; + +/*****************************************************************************/ + +%%{ + machine golang; + write data; + include common "common.rl"; + + # Line counting machine + + action golang_ccallback { + switch(entity) { + case GOLANG_SPACE: + ls + break; + case GOLANG_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(GOLANG_LANG) + break; + case NEWLINE: + std_newline(GOLANG_LANG) + } + } + + golang_line_comment = + '//' @comment ( + escaped_newline %{ entity = INTERNAL_NL; } %golang_ccallback + | + ws + | + (nonnewline - ws) @comment + )*; + golang_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %golang_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '*/'; + golang_comment = golang_line_comment | golang_block_comment; + + golang_sq_str = + '\'' @code ( + escaped_newline %{ entity = INTERNAL_NL; } %golang_ccallback + | + ws + | + [^\t '\\] @code + | + '\\' nonnewline @code + )* '\''; + golang_dq_str = + '"' @code ( + escaped_newline %{ entity = INTERNAL_NL; } %golang_ccallback + | + ws + | + [^\t "\\] @code + | + '\\' nonnewline @code + )* '"'; + golang_string = golang_sq_str | golang_dq_str; + + golang_line := |* + spaces ${ entity = GOLANG_SPACE; } => golang_ccallback; + golang_comment; + golang_string; + newline ${ entity = NEWLINE; } => golang_ccallback; + ^space ${ entity = GOLANG_ANY; } => golang_ccallback; + *|; + + # Entity machine + + action golang_ecallback { + callback(GOLANG_LANG, golang_entities[entity], cint(ts), cint(te), userdata); + } + + golang_line_comment_entity = '//' (escaped_newline | nonnewline)*; + golang_block_comment_entity = '/*' any* :>> '*/'; + golang_comment_entity = golang_line_comment_entity | golang_block_comment_entity; + + golang_string_entity = sq_str_with_escapes | dq_str_with_escapes; + + golang_number_entity = float | integer; + + golang_preprogolang_word = + 'define' | 'elif' | 'else' | 'endif' | 'error' | 'if' | 'ifdef' | + 'ifndef' | 'import' | 'include' | 'line' | 'pragma' | 'undef' | + 'using' | 'warning'; + # TODO: find some way of making preproc match the beginning of a line. + # Putting a 'when starts_line' conditional throws an assertion error. + golang_preprogolang_entity = + '#' space* (golang_block_comment_entity space*)? + golang_preprogolang_word (escaped_newline | nonnewline)*; + + golang_identifier_entity = (alpha | '_') (alnum | '_')*; + + golang_keyword_entity = + 'and' | 'and_eq' | 'asm' | 'auto' | 'bitand' | 'bitor' | 'bool' | + 'break' | 'case' | 'catch' | 'char' | 'class' | 'compl' | 'const' | + 'const_cast' | 'continue' | 'default' | 'delete' | 'do' | 'double' | + 'dynamigolang_cast' | 'else' | 'enum' | 'explicit' | 'export' | 'extern' | + 'false' | 'float' | 'for' | 'friend' | 'goto' | 'if' | 'inline' | 'int' | + 'long' | 'mutable' | 'namespace' | 'new' | 'not' | 'not_eq' | + 'operator' | 'or' | 'or_eq' | 'private' | 'protected' | 'public' | + 'register' | 'reinterpret_cast' | 'return' | 'short' | 'signed' | + 'sizeof' | 'static' | 'statigolang_cast' | 'struct' | 'switch' | + 'template' | 'this' | 'throw' | 'true' | 'try' | 'typedef' | 'typeid' | + 'typename' | 'union' | 'unsigned' | 'using' | 'virtual' | 'void' | + 'volatile' | 'wchar_t' | 'while' | 'xor' | 'xor_eq'; + + golang_operator_entity = [+\-/*%<>!=^&|?~:;.,()\[\]{}]; + + golang_entity := |* + space+ ${ entity = GOLANG_SPACE; } => golang_ecallback; + golang_comment_entity ${ entity = GOLANG_COMMENT; } => golang_ecallback; + golang_string_entity ${ entity = GOLANG_STRING; } => golang_ecallback; + golang_number_entity ${ entity = GOLANG_NUMBER; } => golang_ecallback; + golang_preprogolang_entity ${ entity = GOLANG_PREPROC; } => golang_ecallback; + golang_identifier_entity ${ entity = GOLANG_IDENTIFIER; } => golang_ecallback; + golang_keyword_entity ${ entity = GOLANG_KEYWORD; } => golang_ecallback; + golang_operator_entity ${ entity = GOLANG_OPERATOR; } => golang_ecallback; + ^(space | digit) ${ entity = GOLANG_ANY; } => golang_ecallback; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with C/C++ code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_golang(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? golang_en_golang_line : golang_en_golang_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(GOLANG_LANG) } +} + +const char *ORIG_GOLANG_LANG = LANG_GOLANG; + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/grace.rl b/src/parsers/grace.rl new file mode 100644 index 0000000..daf60dd --- /dev/null +++ b/src/parsers/grace.rl @@ -0,0 +1,113 @@ +// grace.rl written by Michael Homer, based on shell.rl +// by Mitchell Foral. mitchellcaladbolgnet + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_GRACE_PARSER_H +#define OHCOUNT_GRACE_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *GRACE_LANG = LANG_GRACE; + +// the languages entities +const char *grace_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + GRACE_SPACE = 0, GRACE_COMMENT, GRACE_STRING, GRACE_ANY +}; + +/*****************************************************************************/ + +%%{ + machine grace; + write data; + include common "common.rl"; + + # Line counting machine + + action grace_ccallback { + switch(entity) { + case GRACE_SPACE: + ls + break; + case GRACE_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(GRACE_LANG) + break; + case NEWLINE: + std_newline(GRACE_LANG) + } + } + + grace_comment = '//' @comment nonnewline*; + + grace_string = + '"' @enqueue @code ( + newline %{ entity = INTERNAL_NL; } %grace_ccallback + | + ws + | + [^\r\n\f\t "\\] @code + )* '"' @commit; + + grace_line := |* + spaces ${ entity = GRACE_SPACE; } => grace_ccallback; + grace_comment; + grace_string; + newline ${ entity = NEWLINE; } => grace_ccallback; + ^space ${ entity = GRACE_ANY; } => grace_ccallback; + *|; + + # Entity machine + + action grace_ecallback { + callback(GRACE_LANG, grace_entities[entity], cint(ts), cint(te), userdata); + } + + grace_comment_entity = '//' nonnewline*; + + grace_entity := |* + space+ ${ entity = GRACE_SPACE; } => grace_ecallback; + grace_comment_entity ${ entity = GRACE_COMMENT; } => grace_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Grace code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_grace(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? grace_en_grace_line : grace_en_grace_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(GRACE_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/jam.rl b/src/parsers/jam.rl new file mode 100644 index 0000000..3b4ccc7 --- /dev/null +++ b/src/parsers/jam.rl @@ -0,0 +1,126 @@ +// jam.rl written by Scott Lawrence. bytbox@gmail.com + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_JAM_PARSER_H +#define OHCOUNT_JAM_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *JAM_LANG = LANG_JAM; + +// the languages entities +const char *jam_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + JAM_SPACE = 0, JAM_COMMENT, JAM_STRING, JAM_ANY +}; + +/*****************************************************************************/ + +%%{ + machine jam; + write data; + include common "common.rl"; + + # Line counting machine + + action jam_ccallback { + switch(entity) { + case JAM_SPACE: + ls + break; + case JAM_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(JAM_LANG) + break; + case NEWLINE: + std_newline(JAM_LANG) + } + } + + jam_comment = '#' @comment nonnewline*; + + jam_sq_str = + '\'' @enqueue @code ( + newline %{ entity = INTERNAL_NL; } %jam_ccallback + | + ws + | + [^\r\n\f\t '\\] @code + | + '\\' nonnewline @code + )* '\'' @commit; + jam_dq_str = + '"' @enqueue @code ( + newline %{ entity = INTERNAL_NL; } %jam_ccallback + | + ws + | + [^\r\n\f\t "\\] @code + | + '\\' nonnewline @code + )* '"' @commit; + # TODO: heredocs; see ruby.rl for details + jam_string = jam_sq_str | jam_dq_str; + + jam_line := |* + spaces ${ entity = JAM_SPACE; } => jam_ccallback; + jam_comment; + jam_string; + newline ${ entity = NEWLINE; } => jam_ccallback; + ^space ${ entity = JAM_ANY; } => jam_ccallback; + *|; + + # Entity machine + + action jam_ecallback { + callback(JAM_LANG, jam_entities[entity], cint(ts), cint(te), userdata); + } + + jam_comment_entity = '#' nonnewline*; + + jam_entity := |* + space+ ${ entity = JAM_SPACE; } => jam_ecallback; + jam_comment_entity ${ entity = JAM_COMMENT; } => jam_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Jam code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_jam(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? jam_en_jam_line : jam_en_jam_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(JAM_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/javascript.rl b/src/parsers/javascript.rl index 1f34177..172989e 100644 --- a/src/parsers/javascript.rl +++ b/src/parsers/javascript.rl @@ -134,4 +134,28 @@ if (count) { process_last_line(JS_LANG) } } +const char *QML_LANG = LANG_QML; +const char *TS_LANG = LANG_TYPESCRIPT; +const char *ORIG_JS_LANG = LANG_JAVASCRIPT; + +void parse_qml(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, + int s, int e, void *udata), + void *userdata + ) { + JS_LANG = QML_LANG; + parse_javascript(buffer, length, count, callback, userdata); + JS_LANG = ORIG_JS_LANG; +} + +void parse_typescript(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, + int s, int e, void *udata), + void *userdata + ) { + JS_LANG = TS_LANG; + parse_javascript(buffer, length, count, callback, userdata); + JS_LANG = ORIG_JS_LANG; +} + #endif diff --git a/src/parsers/lisp.rl b/src/parsers/lisp.rl index 8276699..0698964 100644 --- a/src/parsers/lisp.rl +++ b/src/parsers/lisp.rl @@ -148,4 +148,27 @@ LISP_LANG = ORIG_LISP_LANG; } +const char *CLOJURE_LANG = LANG_CLOJURE; +void parse_clojure(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + LISP_LANG = CLOJURE_LANG; + parse_lisp(buffer, length, count, callback, userdata); + LISP_LANG = ORIG_LISP_LANG; +} + +const char *RACKET_LANG = LANG_RACKET; +void parse_racket(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + LISP_LANG = RACKET_LANG; + parse_lisp(buffer, length, count, callback, userdata); + LISP_LANG = ORIG_LISP_LANG; +} + + #endif diff --git a/src/parsers/logtalk.rl b/src/parsers/logtalk.rl new file mode 100644 index 0000000..439a901 --- /dev/null +++ b/src/parsers/logtalk.rl @@ -0,0 +1,119 @@ +// logtalk.rl written by Paulo Moura. pmouralogtalkorg. + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_LOGTALK_PARSER_H +#define OHCOUNT_LOGTALK_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *LOGTALK_LANG = LANG_LOGTALK; + +// the languages entities +const char *logtalk_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + LOGTALK_SPACE = 0, LOGTALK_COMMENT, LOGTALK_STRING, LOGTALK_ANY +}; + +/*****************************************************************************/ + +%%{ + machine logtalk; + write data; + include common "common.rl"; + + # Line counting machine + + action logtalk_ccallback { + switch(entity) { + case LOGTALK_SPACE: + ls + break; + case LOGTALK_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(LOGTALK_LANG) + break; + case NEWLINE: + std_newline(LOGTALK_LANG) + } + } + + logtalk_line_comment = '%' @comment nonnewline*; + logtalk_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %logtalk_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '*/'; + logtalk_comment = logtalk_line_comment | logtalk_block_comment; + + logtalk_sq_str = '\'' @code ([^\r\n\f'\\] | '\\' nonnewline)* '\''; + logtalk_dq_str = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"'; + logtalk_string = logtalk_sq_str | logtalk_dq_str; + + logtalk_line := |* + spaces ${ entity = LOGTALK_SPACE; } => logtalk_ccallback; + logtalk_comment; + logtalk_string; + newline ${ entity = NEWLINE; } => logtalk_ccallback; + ^space ${ entity = LOGTALK_ANY; } => logtalk_ccallback; + *|; + + # Entity machine + + action logtalk_ecallback { + callback(LOGTALK_LANG, logtalk_entities[entity], cint(ts), cint(te), + userdata); + } + + logtalk_line_comment_entity = '%' nonnewline*; + logtalk_block_comment_entity = '/*' any* :>> '*/'; + logtalk_comment_entity = logtalk_line_comment_entity | logtalk_block_comment_entity; + + logtalk_entity := |* + space+ ${ entity = LOGTALK_SPACE; } => logtalk_ecallback; + logtalk_comment_entity ${ entity = LOGTALK_COMMENT; } => logtalk_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Logtalk code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_logtalk(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? logtalk_en_logtalk_line : logtalk_en_logtalk_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(LOGTALK_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/mathematica.rl b/src/parsers/mathematica.rl new file mode 100644 index 0000000..72b5957 --- /dev/null +++ b/src/parsers/mathematica.rl @@ -0,0 +1,131 @@ +// mathematica.rl written by Erik Schnetter + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_MATHEMATICA_PARSER_H +#define OHCOUNT_MATHEMATICA_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *MATHEMATICA_LANG = LANG_MATHEMATICA; + +// the languages entities +const char *mathematica_entities[] = { + "space", "comment", "string", "any", +}; + +// constants associated with the entities +enum { + MATHEMATICA_SPACE = 0, MATHEMATICA_COMMENT, MATHEMATICA_STRING, MATHEMATICA_ANY +}; + +/*****************************************************************************/ + +%%{ + machine mathematica; + write data; + include common "common.rl"; + + # Line counting machine + + action mathematica_ccallback { + switch(entity) { + case MATHEMATICA_SPACE: + ls + break; + case MATHEMATICA_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(MATHEMATICA_LANG) + break; + case NEWLINE: + std_newline(MATHEMATICA_LANG) + } + } + + action mathematica_comment_nc_res { nest_count = 0; } + action mathematica_comment_nc_inc { nest_count++; } + action mathematica_comment_nc_dec { nest_count--; } + + mathematica_nested_block_comment = + '(*' >mathematica_comment_nc_res @comment ( + newline %{ entity = INTERNAL_NL; } %mathematica_ccallback + | + ws + | + '(*' @mathematica_comment_nc_inc @comment + | + '*)' @mathematica_comment_nc_dec @comment + | + (nonnewline - ws) @comment + )* :>> ('*)' when { nest_count == 0 }) @comment; + + mathematica_comment = mathematica_nested_block_comment; + + mathematica_string = '"' @code ([^"]) '"'; + + mathematica_line := |* + spaces ${ entity = MATHEMATICA_SPACE; } => mathematica_ccallback; + mathematica_comment; + mathematica_string; + newline ${ entity = NEWLINE; } => mathematica_ccallback; + ^space ${ entity = MATHEMATICA_ANY; } => mathematica_ccallback; + *|; + + # Entity machine + + action mathematica_ecallback { + callback(MATHEMATICA_LANG, mathematica_entities[entity], cint(ts), cint(te), + userdata); + } + + mathematica_comment_entity = '(*' >mathematica_comment_nc_res ( + '(*' @mathematica_comment_nc_inc + | + '*)' @mathematica_comment_nc_dec + | + any + )* :>> ('*)' when { nest_count == 0 }); + + mathematica_entity := |* + space+ ${ entity = MATHEMATICA_SPACE; } => mathematica_ecallback; + mathematica_comment_entity ${ entity = MATHEMATICA_COMMENT; } => mathematica_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with MATHEMATICA code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_mathematica(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + int nest_count = 0; + + %% write init; + cs = (count) ? mathematica_en_mathematica_line : mathematica_en_mathematica_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(MATHEMATICA_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/modula2.rl b/src/parsers/modula2.rl new file mode 100644 index 0000000..27d6156 --- /dev/null +++ b/src/parsers/modula2.rl @@ -0,0 +1,147 @@ +// modula2.rl, +// derived from code written by Mitchell Foral. mitchellcaladbolgnet + + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_MODULA2_PARSER_H +#define OHCOUNT_MODULA2_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *MODULA2_LANG = LANG_MODULA2; + +// the languages entities +const char *modula2_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + MODULA2_SPACE = 0, MODULA2_COMMENT, MODULA2_STRING, MODULA2_ANY +}; + +/*****************************************************************************/ + +%%{ + machine modula2; + write data; + include common "common.rl"; + + # Line counting machine + + action modula2_ccallback { + switch(entity) { + case MODULA2_SPACE: + ls + break; + case MODULA2_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(MODULA2_LANG) + break; + case NEWLINE: + std_newline(MODULA2_LANG) + } + } + + + # Modula-2 comments + + action modula2_comment_nc_res { nest_count = 0; } + action modula2_comment_nc_inc { nest_count++; } + action modula2_comment_nc_dec { nest_count--; } + + modula2_comment = + '(*' >modula2_comment_nc_res @comment ( + newline %{ entity = INTERNAL_NL; } %modula2_ccallback + | + ws + | + '(*' @modula2_comment_nc_inc @comment + | + '*)' @modula2_comment_nc_dec @comment + | + ^space @comment + )* :>> ('*)' when { nest_count == 0 }) @comment; + + + # Modula-2 string literals + + modula2_singlequoted_string = '\'' @code [^\r\n\f"]* '\''; + modula2_doublequoted_string = '"' @code [^\r\n\f"]* '"'; + + modula2_string = modula2_singlequoted_string | modula2_doublequoted_string; + + + # Line counter + + modula2_line := |* + spaces ${ entity = MODULA2_SPACE; } => modula2_ccallback; + modula2_comment; + modula2_string; + newline ${ entity = NEWLINE; } => modula2_ccallback; + ^space ${ entity = MODULA2_ANY; } => modula2_ccallback; + *|; + + + # Entity machine + + action modula2_ecallback { + callback(MODULA2_LANG, modula2_entities[entity], cint(ts), cint(te), + userdata); + } + + modula2_comment_entity = '(*' >modula2_comment_nc_res ( + '(*' @modula2_comment_nc_inc + | + '*)' @modula2_comment_nc_dec + | + any + )* :>> ('*)' when { nest_count == 0 }); + + modula2_string_entity = sq_str | dq_str; + + modula2_entity := |* + space+ ${ entity = MODULA2_SPACE; } => modula2_ecallback; + modula2_comment_entity ${ entity = MODULA2_COMMENT; } => modula2_ecallback; + modula2_string_entity ${ entity = MODULA2_STRING; } => modula2_ecallback; + # TODO: detecting other entities may be useful to differentiate dialects + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Modula-2 code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_modula2(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + int nest_count = 0; + + %% write init; + cs = (count) ? modula2_en_modula2_line : modula2_en_modula2_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(MODULA2_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/modula3.rl b/src/parsers/modula3.rl new file mode 100644 index 0000000..2166f0f --- /dev/null +++ b/src/parsers/modula3.rl @@ -0,0 +1,165 @@ +// modula3.rl, +// derived from code written by Mitchell Foral. mitchellcaladbolgnet + + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_MODULA3_PARSER_H +#define OHCOUNT_MODULA3_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *MODULA3_LANG = LANG_MODULA3; + +// the languages entities +const char *modula3_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + MODULA3_SPACE = 0, MODULA3_COMMENT, MODULA3_STRING, MODULA3_ANY +}; + +/*****************************************************************************/ + +%%{ + machine modula3; + write data; + include common "common.rl"; + + # Line counting machine + + action modula3_ccallback { + switch(entity) { + case MODULA3_SPACE: + ls + break; + case MODULA3_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(MODULA3_LANG) + break; + case NEWLINE: + std_newline(MODULA3_LANG) + } + } + + + # Modula-3 comments + + action modula3_comment_nc_res { nest_count = 0; } + action modula3_comment_nc_inc { nest_count++; } + action modula3_comment_nc_dec { nest_count--; } + + modula3_comment = + '(*' >modula3_comment_nc_res @comment ( + newline %{ entity = INTERNAL_NL; } %modula3_ccallback + | + ws + | + '(*' @modula3_comment_nc_inc @comment + | + '*)' @modula3_comment_nc_dec @comment + | + ^space @comment + )* :>> ('*)' when { nest_count == 0 }) @comment; + + + # Modula-3 string literals + + modula3_singlequoted_string = + '\'' @code ( + escaped_newline %{ entity = INTERNAL_NL; } %modula3_ccallback + | + ws + | + [^\t '\\] @code + | + '\\' nonnewline @code + )* '\''; + modula3_doublequoted_string = + '"' @code ( + escaped_newline %{ entity = INTERNAL_NL; } %modula3_ccallback + | + ws + | + [^\t "\\] @code + | + '\\' nonnewline @code + )* '"'; + modula3_string = modula3_singlequoted_string | modula3_doublequoted_string; + + + # Line counter + + modula3_line := |* + spaces ${ entity = MODULA3_SPACE; } => modula3_ccallback; + modula3_comment; + modula3_string; + newline ${ entity = NEWLINE; } => modula3_ccallback; + ^space ${ entity = MODULA3_ANY; } => modula3_ccallback; + *|; + + + # Entity machine + + action modula3_ecallback { + callback(MODULA3_LANG, modula3_entities[entity], cint(ts), cint(te), + userdata); + } + + modula3_comment_entity = '(*' >modula3_comment_nc_res ( + '(*' @modula3_comment_nc_inc + | + '*)' @modula3_comment_nc_dec + | + any + )* :>> ('*)' when { nest_count == 0 }); + + modula3_string_entity = sq_str_with_escapes | + dq_str_with_escapes; + + modula3_entity := |* + space+ ${ entity = MODULA3_SPACE; } => modula3_ecallback; + modula3_comment_entity ${ entity = MODULA3_COMMENT; } => modula3_ecallback; + modula3_string_entity ${ entity = MODULA3_STRING; } => modula3_ecallback; + # TODO: detecting other entities may be useful to differentiate dialects + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Modula-3 code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_modula3(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + int nest_count = 0; + + %% write init; + cs = (count) ? modula3_en_modula3_line : modula3_en_modula3_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(MODULA3_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/nsis.rl b/src/parsers/nsis.rl new file mode 100644 index 0000000..8b21586 --- /dev/null +++ b/src/parsers/nsis.rl @@ -0,0 +1,119 @@ +// nsis.rl written by Chris Morgan. + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_NSIS_PARSER_H +#define OHCOUNT_NSIS_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *NSIS_LANG = LANG_NSIS; + +// the languages entities +const char *nsis_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + NSIS_SPACE = 0, NSIS_COMMENT, NSIS_STRING, NSIS_ANY +}; + +/*****************************************************************************/ + +%%{ + machine nsis; + write data; + include common "common.rl"; + + # Line counting machine + + action nsis_ccallback { + switch(entity) { + case NSIS_SPACE: + ls + break; + case NSIS_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(NSIS_LANG) + break; + case NEWLINE: + std_newline(NSIS_LANG) + } + } + + nsis_line_comment = ('#' | ';') @comment nonnewline*; + nsis_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %nsis_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '*/'; + nsis_comment = nsis_line_comment | nsis_block_comment; + + nsis_bt_str = '`' @code ([^\r\n\f`\\] | '\\' nonnewline)* '`'; + nsis_sq_str = '\'' @code ([^\r\n\f'\\] | '\\' nonnewline)* '\''; + nsis_dq_str = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"'; + nsis_string = nsis_bt_str | nsis_sq_str | nsis_dq_str; + + nsis_line := |* + spaces ${ entity = NSIS_SPACE; } => nsis_ccallback; + nsis_comment; + nsis_string; + newline ${ entity = NEWLINE; } => nsis_ccallback; + ^space ${ entity = NSIS_ANY; } => nsis_ccallback; + *|; + + # Entity machine + + action nsis_ecallback { + callback(NSIS_LANG, nsis_entities[entity], cint(ts), cint(te), userdata); + } + + nsis_line_comment_entity = ('#' | '//') nonnewline*; + nsis_block_comment_entity = '/*' any* :>> '*/'; + nsis_comment_entity = nsis_line_comment_entity | nsis_block_comment_entity; + + nsis_entity := |* + space+ ${ entity = NSIS_SPACE; } => nsis_ecallback; + nsis_comment_entity ${ entity = NSIS_COMMENT; } => nsis_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with NSIS code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_nsis(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? nsis_en_nsis_line : nsis_en_nsis_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(NSIS_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/oberon.rl b/src/parsers/oberon.rl new file mode 100644 index 0000000..ee0e30e --- /dev/null +++ b/src/parsers/oberon.rl @@ -0,0 +1,147 @@ +// oberon.rl, +// derived from code written by Mitchell Foral. mitchellcaladbolgnet + + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_OBERON_PARSER_H +#define OHCOUNT_OBERON_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *OBERON_LANG = LANG_OBERON; + +// the languages entities +const char *oberon_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + OBERON_SPACE = 0, OBERON_COMMENT, OBERON_STRING, OBERON_ANY +}; + +/*****************************************************************************/ + +%%{ + machine oberon; + write data; + include common "common.rl"; + + # Line counting machine + + action oberon_ccallback { + switch(entity) { + case OBERON_SPACE: + ls + break; + case OBERON_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(OBERON_LANG) + break; + case NEWLINE: + std_newline(OBERON_LANG) + } + } + + + # Oberon comments + + action oberon_comment_nc_res { nest_count = 0; } + action oberon_comment_nc_inc { nest_count++; } + action oberon_comment_nc_dec { nest_count--; } + + oberon_comment = + '(*' >oberon_comment_nc_res @comment ( + newline %{ entity = INTERNAL_NL; } %oberon_ccallback + | + ws + | + '(*' @oberon_comment_nc_inc @comment + | + '*)' @oberon_comment_nc_dec @comment + | + ^space @comment + )* :>> ('*)' when { nest_count == 0 }) @comment; + + + # Oberon string literals + + oberon_singlequoted_string = '\'' @code [^\r\n\f"]* '\''; + oberon_doublequoted_string = '"' @code [^\r\n\f"]* '"'; + + oberon_string = oberon_singlequoted_string | oberon_doublequoted_string; + + + # Line counter + + oberon_line := |* + spaces ${ entity = OBERON_SPACE; } => oberon_ccallback; + oberon_comment; + oberon_string; + newline ${ entity = NEWLINE; } => oberon_ccallback; + ^space ${ entity = OBERON_ANY; } => oberon_ccallback; + *|; + + + # Entity machine + + action oberon_ecallback { + callback(OBERON_LANG, oberon_entities[entity], cint(ts), cint(te), + userdata); + } + + oberon_comment_entity = '(*' >oberon_comment_nc_res ( + '(*' @oberon_comment_nc_inc + | + '*)' @oberon_comment_nc_dec + | + any + )* :>> ('*)' when { nest_count == 0 }); + + oberon_string_entity = sq_str | dq_str; + + oberon_entity := |* + space+ ${ entity = OBERON_SPACE; } => oberon_ecallback; + oberon_comment_entity ${ entity = OBERON_COMMENT; } => oberon_ecallback; + oberon_string_entity ${ entity = OBERON_STRING; } => oberon_ecallback; + # TODO: detecting other entities may be useful to differentiate dialects + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Oberon code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_oberon(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + int nest_count = 0; + + %% write init; + cs = (count) ? oberon_en_oberon_line : oberon_en_oberon_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(OBERON_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/prolog.rl b/src/parsers/prolog.rl new file mode 100644 index 0000000..3301f02 --- /dev/null +++ b/src/parsers/prolog.rl @@ -0,0 +1,119 @@ +// prolog.rl written by Paulo Moura. pmouraprologorg. + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_PROLOG_PARSER_H +#define OHCOUNT_PROLOG_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *PROLOG_LANG = LANG_PROLOG; + +// the languages entities +const char *prolog_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + PROLOG_SPACE = 0, PROLOG_COMMENT, PROLOG_STRING, PROLOG_ANY +}; + +/*****************************************************************************/ + +%%{ + machine prolog; + write data; + include common "common.rl"; + + # Line counting machine + + action prolog_ccallback { + switch(entity) { + case PROLOG_SPACE: + ls + break; + case PROLOG_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(PROLOG_LANG) + break; + case NEWLINE: + std_newline(PROLOG_LANG) + } + } + + prolog_line_comment = '%' @comment nonnewline*; + prolog_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %prolog_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '*/'; + prolog_comment = prolog_line_comment | prolog_block_comment; + + prolog_sq_str = '\'' @code ([^\r\n\f'\\] | '\\' nonnewline)* '\''; + prolog_dq_str = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"'; + prolog_string = prolog_sq_str | prolog_dq_str; + + prolog_line := |* + spaces ${ entity = PROLOG_SPACE; } => prolog_ccallback; + prolog_comment; + prolog_string; + newline ${ entity = NEWLINE; } => prolog_ccallback; + ^space ${ entity = PROLOG_ANY; } => prolog_ccallback; + *|; + + # Entity machine + + action prolog_ecallback { + callback(PROLOG_LANG, prolog_entities[entity], cint(ts), cint(te), + userdata); + } + + prolog_line_comment_entity = '%' nonnewline*; + prolog_block_comment_entity = '/*' any* :>> '*/'; + prolog_comment_entity = prolog_line_comment_entity | prolog_block_comment_entity; + + prolog_entity := |* + space+ ${ entity = PROLOG_SPACE; } => prolog_ecallback; + prolog_comment_entity ${ entity = PROLOG_COMMENT; } => prolog_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Prolog code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_prolog(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? prolog_en_prolog_line : prolog_en_prolog_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(PROLOG_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/puppet.rl b/src/parsers/puppet.rl new file mode 100644 index 0000000..d862f7f --- /dev/null +++ b/src/parsers/puppet.rl @@ -0,0 +1,128 @@ +// puppet.rl written by Ken Barber +// Based on pascal.rl by Mitchell Foral. mitchellcaladbolgnet + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_PUPPET_PARSER_H +#define OHCOUNT_PUPPET_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *PUPPET_LANG = LANG_PUPPET; + +// the languages entities +const char *puppet_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + PUPPET_SPACE = 0, PUPPET_COMMENT, PUPPET_STRING, PUPPET_ANY +}; + +/*****************************************************************************/ + +%%{ + machine puppet; + write data; + include common "common.rl"; + + # Line counting machine + + action puppet_ccallback { + switch(entity) { + case PUPPET_SPACE: + ls + break; + case PUPPET_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(PUPPET_LANG) + break; + case NEWLINE: + std_newline(PUPPET_LANG) + } + } + + puppet_line_comment = '#' @comment nonnewline*; + puppet_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %puppet_ccallback + | + ws + | + (nonnewline - ws) @code + )* :>> '*/'; + puppet_comment = puppet_line_comment | puppet_block_comment; + + puppet_string = + '\'' @code ( + newline %{ entity = INTERNAL_NL; } %puppet_ccallback + | + ws + | + [^\r\n\f\t '\\] @code + | + '\\' nonnewline @code + )* '\''; + + puppet_line := |* + spaces ${ entity = PUPPET_SPACE; } => puppet_ccallback; + puppet_comment; + puppet_string; + newline ${ entity = NEWLINE; } => puppet_ccallback; + ^space ${ entity = PUPPET_ANY; } => puppet_ccallback; + *|; + + # Entity machine + + action puppet_ecallback { + callback(PUPPET_LANG, puppet_entities[entity], cint(ts), cint(te), + userdata); + } + + puppet_line_comment_entity = '#' nonnewline*; + puppet_block_comment_entity = '/*' any* :>> '*/'; + puppet_comment_entity = puppet_line_comment_entity | + puppet_block_comment_entity; + + puppet_entity := |* + space+ ${ entity = PUPPET_SPACE; } => puppet_ecallback; + puppet_comment_entity ${ entity = PUPPET_COMMENT; } => puppet_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Puppet DSL code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_puppet(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? puppet_en_puppet_line : puppet_en_puppet_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(PUPPET_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/rebol.rl b/src/parsers/rebol.rl new file mode 100644 index 0000000..eb7fc59 --- /dev/null +++ b/src/parsers/rebol.rl @@ -0,0 +1,128 @@ +// rebol.rl written by Andreas Bolka. + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_REBOL_PARSER_H +#define OHCOUNT_REBOL_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *REBOL_LANG = LANG_REBOL; + +// the languages entities +const char *rebol_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + REBOL_SPACE = 0, REBOL_COMMENT, REBOL_STRING, REBOL_ANY +}; + +/*****************************************************************************/ + +%%{ + machine rebol; + write data; + include common "common.rl"; + + action rebol_inc_string { ++rebol_string_level; } + action rebol_dec_string { --rebol_string_level; } + action rebol_is_nested { rebol_string_level > 0 } + + rebol_cb_str_nest = '{' %rebol_inc_string + | '}' when rebol_is_nested %rebol_dec_string; + + # Line counting machine + + action rebol_ccallback { + switch(entity) { + case REBOL_SPACE: + ls + break; + case REBOL_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(REBOL_LANG) + break; + case NEWLINE: + std_newline(REBOL_LANG) + } + } + + rebol_line_comment = ';' @comment nonnewline*; + rebol_comment = rebol_line_comment; + + rebol_dq_str = '"' @code ([^\r\n\f"] | '^"')* [\r\n\f"]; + rebol_cb_str_inner = [^{}] | '^{' | '^}' + | newline %{ entity = INTERNAL_NL; } %rebol_ccallback + | rebol_cb_str_nest; + rebol_cb_str = '{' @code rebol_cb_str_inner* @code '}' @code; + rebol_string = rebol_dq_str | rebol_cb_str; + + rebol_line := |* + spaces ${ entity = REBOL_SPACE; } => rebol_ccallback; + rebol_comment; + rebol_string; + newline ${ entity = NEWLINE; } => rebol_ccallback; + ^space ${ entity = REBOL_ANY; } => rebol_ccallback; + *|; + + # Entity machine + + action rebol_ecallback { + callback(REBOL_LANG, rebol_entities[entity], cint(ts), cint(te), userdata); + } + + rebol_line_comment_entity = ';' nonnewline*; + rebol_comment_entity = rebol_line_comment_entity; + + rebol_dq_str_entity = '"' ([^\r\n\f"] | '^"')* [\r\n\f"]; + rebol_cb_str_entity = '{' ([^{}] | '^{' | '^}' | rebol_cb_str_nest)* '}'; + rebol_string_entiy = rebol_dq_str_entity | rebol_cb_str_entity; + + rebol_entity := |* + space+ ${ entity = REBOL_SPACE; } => rebol_ecallback; + rebol_comment_entity ${ entity = REBOL_COMMENT; } => rebol_ecallback; + rebol_string_entiy ${ entity = REBOL_STRING; } => rebol_ecallback; + ^space ${ entity = REBOL_ANY; } => rebol_ecallback; + *|; + +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with REBOL code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_rebol(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + // For {..} multi-line strings which require proper balancing of {}'s. + int rebol_string_level = 0; + init + + %% write init; + cs = (count) ? rebol_en_rebol_line : rebol_en_rebol_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(REBOL_LANG) } +} + +#endif + +/*****************************************************************************/ + +// vim: set ts=2 syn=c: diff --git a/src/parsers/rust.rl b/src/parsers/rust.rl new file mode 100644 index 0000000..e3b17c3 --- /dev/null +++ b/src/parsers/rust.rl @@ -0,0 +1,174 @@ +// rust.rl written by Sébastien Crozet +// Inpired by golang.rl + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_RUST_PARSER_H +#define OHCOUNT_RUST_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *RUST_LANG = LANG_RUST; + +// the languages entities +const char *rust_entities[] = { + "space", "comment", "string", "number", + "keyword", "identifier", "operator", "any" +}; + +// constants associated with the entities +enum { + RUST_SPACE = 0, RUST_COMMENT, RUST_STRING, RUST_NUMBER, + RUST_KEYWORD, RUST_IDENTIFIER, RUST_OPERATOR, RUST_ANY +}; + +/*****************************************************************************/ + +%%{ + machine rust; + write data; + include common "common.rl"; + + # Line counting machine + + action rust_ccallback { + switch(entity) { + case RUST_SPACE: + ls + break; + case RUST_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(RUST_LANG) + break; + case NEWLINE: + std_newline(RUST_LANG) + } + } + + rust_line_comment = + '//' @comment ( + escaped_newline %{ entity = INTERNAL_NL; } %rust_ccallback + | + ws + | + (nonnewline - ws) @comment + )*; + rust_block_comment = + '/*' @comment ( + newline %{ entity = INTERNAL_NL; } %rust_ccallback + | + ws + | + (nonnewline - ws) @comment + )* :>> '*/'; + rust_comment = rust_line_comment | rust_block_comment; + + rust_dq_str = + '"' @code ( + escaped_newline %{ entity = INTERNAL_NL; } %rust_ccallback + | + ws + | + [^\t "\\] @code + | + '\\' nonnewline @code + )* '"'; + rust_string = rust_dq_str; + + rust_line := |* + spaces ${ entity = RUST_SPACE; } => rust_ccallback; + rust_comment; + rust_string; + newline ${ entity = NEWLINE; } => rust_ccallback; + ^space ${ entity = RUST_ANY; } => rust_ccallback; + *|; + + # Entity machine + + action rust_ecallback { + callback(RUST_LANG, rust_entities[entity], cint(ts), cint(te), userdata); + } + + rust_line_comment_entity = '//' (escaped_newline | nonnewline)*; + rust_block_comment_entity = '/*' any* :>> '*/'; + rust_comment_entity = rust_line_comment_entity | rust_block_comment_entity; + + rust_string_entity = dq_str_with_escapes; + + # Up to and including "the number entity" these are almost verbatim from the + # "number literals" section of the Rust reference manual + rust_int_suffix = [iu] ('8' | '16' | '32' | '64')?; + + rust_float_suffix_ty = 'f' ('32' | '64'); + rust_dec_lit = [0-9_]+; + rust_exponent = [Ee] [\-+]? rust_dec_lit; + rust_float_suffix = (rust_exponent | '.' rust_dec_lit rust_exponent?)? + rust_float_suffix_ty?; + + rust_num_suffix = rust_int_suffix | rust_float_suffix; + + rust_number_entity = [1-9] [0-9_]* rust_num_suffix? + | '0' ( [0-9_]* rust_num_suffix? + | 'b' [01_]+ rust_int_suffix? + | 'o' [0-7_]+ rust_int_suffix? + | 'x' [0-9A-Fa-f_]+ rust_int_suffix?); + + rust_identifier_entity = (alpha | '_') (alnum | '_')*; + + rust_keyword_entity = + 'alignof' | 'as' | 'be' | 'break' | 'const' | 'continue' | 'do' | 'else' | + 'enum' | 'extern' | 'false' | 'fn' | 'for' | 'if' | 'impl' | 'impl' | + 'in' | 'let' | 'let' | 'log' | 'log' | 'loop' | 'match' | 'mod' | 'mod' | + 'mut' | 'offsetof' | 'once' | 'priv' | 'pub' | 'pure' | 'ref' | 'return' | + 'self' | 'sizeof' | 'static' | 'struct' | 'super' | 'trait' | 'true' | + 'type' | 'typeof' | 'unsafe' | 'use' | 'while' | 'yield'; + + rust_operator_entity = [+\-/*%<>!=^&|?~:;.,()\[\]{}@]; + + rust_entity := |* + space+ ${ entity = RUST_SPACE; } => rust_ecallback; + rust_comment_entity ${ entity = RUST_COMMENT; } => rust_ecallback; + rust_string_entity ${ entity = RUST_STRING; } => rust_ecallback; + rust_number_entity ${ entity = RUST_NUMBER; } => rust_ecallback; + rust_identifier_entity ${ entity = RUST_IDENTIFIER; } => rust_ecallback; + rust_keyword_entity ${ entity = RUST_KEYWORD; } => rust_ecallback; + rust_operator_entity ${ entity = RUST_OPERATOR; } => rust_ecallback; + ^(space | digit) ${ entity = RUST_ANY; } => rust_ecallback; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with C/C++ code. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_rust(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? rust_en_rust_line : rust_en_rust_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(RUST_LANG) } +} + +const char *ORIG_RUST_LANG = LANG_RUST; + +#endif + +/*****************************************************************************/ diff --git a/src/parsers/shell.rl b/src/parsers/shell.rl index 0010381..567afa1 100644 --- a/src/parsers/shell.rl +++ b/src/parsers/shell.rl @@ -50,6 +50,8 @@ '\'' @enqueue @code ( newline %{ entity = INTERNAL_NL; } %shell_ccallback | + '\\' newline %{ entity = INTERNAL_NL; } %shell_ccallback + | ws | [^\r\n\f\t '\\] @code @@ -59,6 +61,8 @@ shell_dq_str = '"' @enqueue @code ( newline %{ entity = INTERNAL_NL; } %shell_ccallback + | + '\\' newline %{ entity = INTERNAL_NL; } %shell_ccallback | ws | diff --git a/src/parsers/tex_dtx.rl b/src/parsers/tex_dtx.rl new file mode 100644 index 0000000..f0b562d --- /dev/null +++ b/src/parsers/tex_dtx.rl @@ -0,0 +1,103 @@ +// tex_dtx.rl written by Raphael Pinson, +// based on tex.rl by Mitchell Foral. mitchellcaladbolgnet. + +/************************* Required for every parser *************************/ +#ifndef OHCOUNT_TEX_DTX_PARSER_H +#define OHCOUNT_TEX_DTX_PARSER_H + +#include "../parser_macros.h" + +// the name of the language +const char *TEX_DTX_LANG = LANG_TEX_DTX; + +// the languages entities +const char *tex_dtx_entities[] = { + "space", "comment", "string", "any" +}; + +// constants associated with the entities +enum { + TEX_DTX_SPACE = 0, TEX_DTX_COMMENT, TEX_DTX_STRING, TEX_DTX_ANY +}; + +/*****************************************************************************/ + +%%{ + machine tex_dtx; + write data; + include common "common.rl"; + + # Line counting machine + + action tex_dtx_ccallback { + switch(entity) { + case TEX_DTX_SPACE: + ls + break; + case TEX_DTX_ANY: + code + break; + case INTERNAL_NL: + std_internal_newline(TEX_DTX_LANG) + break; + case NEWLINE: + std_newline(TEX_DTX_LANG) + } + } + + tex_dtx_comment = '%%' @comment nonnewline*; + + tex_dtx_line := |* + spaces ${ entity = TEX_DTX_SPACE; } => tex_dtx_ccallback; + tex_dtx_comment; + newline ${ entity = NEWLINE; } => tex_dtx_ccallback; + ^space ${ entity = TEX_DTX_ANY; } => tex_dtx_ccallback; + *|; + + # Entity machine + + action tex_dtx_ecallback { + callback(TEX_DTX_LANG, tex_dtx_entities[entity], cint(ts), cint(te), userdata); + } + + tex_dtx_comment_entity = '%%' nonnewline*; + + tex_dtx_entity := |* + space+ ${ entity = TEX_DTX_SPACE; } => tex_dtx_ecallback; + tex_dtx_comment_entity ${ entity = TEX_DTX_COMMENT; } => tex_dtx_ecallback; + # TODO: + ^space; + *|; +}%% + +/************************* Required for every parser *************************/ + +/* Parses a string buffer with Tex markup. + * + * @param *buffer The string to parse. + * @param length The length of the string to parse. + * @param count Integer flag specifying whether or not to count lines. If yes, + * uses the Ragel machine optimized for counting. Otherwise uses the Ragel + * machine optimized for returning entity positions. + * @param *callback Callback function. If count is set, callback is called for + * every line of code, comment, or blank with 'lcode', 'lcomment', and + * 'lblank' respectively. Otherwise callback is called for each entity found. + */ +void parse_tex_dtx(char *buffer, int length, int count, + void (*callback) (const char *lang, const char *entity, int s, + int e, void *udata), + void *userdata + ) { + init + + %% write init; + cs = (count) ? tex_dtx_en_tex_dtx_line : tex_dtx_en_tex_dtx_entity; + %% write exec; + + // if no newline at EOF; callback contents of last line + if (count) { process_last_line(TEX_DTX_LANG) } +} + +#endif + +/*****************************************************************************/ diff --git a/src/sourcefile.c b/src/sourcefile.c index a46f755..27a7327 100644 --- a/src/sourcefile.c +++ b/src/sourcefile.c @@ -5,6 +5,10 @@ #include #include #include + +#include +#include +#include #include "detector.h" #include "diff.h" @@ -80,7 +84,7 @@ char *path = sourcefile->filepath; if (sourcefile->diskpath) path = sourcefile->diskpath; - FILE *f = fopen(path, "r"); + FILE *f = fopen(path, "rb"); if (f) { fseek(f, 0, SEEK_END); int size = ftell(f); @@ -319,61 +323,9 @@ return delta; } -void ohcount_sourcefile_set_filenames(SourceFile *sourcefile, - char **filenames) { - if (sourcefile->filenames) { - int i = 0; - while (sourcefile->filenames[i]) - free(sourcefile->filenames[i++]); - free(sourcefile->filenames); - } - - if (filenames != NULL) { - int length = 0; - while (filenames[length] != NULL) length++; - char **fnames = calloc(length + 1, sizeof(char *)); - - int i; - for (i = 0; i < length; i++) { - int len = strlen(filenames[i]); - char *fname = malloc(len + 1); - strncpy(fname, filenames[i], len); - fname[len] = '\0'; - fnames[i] = fname; - } - sourcefile->filenames = fnames; - } else sourcefile->filenames = NULL; -} - -char **ohcount_sourcefile_get_filenames(SourceFile *sourcefile) { - if (sourcefile->filenames == NULL) { - char dirpath[FILENAME_MAX]; - strncpy(dirpath, sourcefile->filepath, sourcefile->dirpath); - dirpath[sourcefile->dirpath] = '\0'; - struct dirent *file; - DIR *d = opendir((const char *)dirpath); - if (d) { - int length = 0; - while ((file = readdir(d))) length++; - closedir(d); - - char **filenames = calloc(length + 1, sizeof(char *)); - int i = 0; - d = opendir((const char *)dirpath); - while ((file = readdir(d))) { - int len = strlen(file->d_name); - char *filename = malloc(len + 1); - strncpy(filename, file->d_name, len); - filename[len] = '\0'; - filenames[i++] = filename; - } - closedir(d); - sourcefile->filenames = filenames; - } - } - return sourcefile->filenames; -} - +/* NOTE! Does not free sourcefile->filenames. + * Calling code is responsible for alloc+free of filenames. + */ void ohcount_sourcefile_free(SourceFile *sourcefile) { free(sourcefile->filepath); if (sourcefile->diskpath) @@ -386,12 +338,6 @@ ohcount_license_list_free(sourcefile->license_list); if (sourcefile->loc_list) ohcount_loc_list_free(sourcefile->loc_list); - if (sourcefile->filenames) { - int i = 0; - while (sourcefile->filenames[i]) - free(sourcefile->filenames[i++]); - free(sourcefile->filenames); - } free(sourcefile); } @@ -429,24 +375,25 @@ char *f_p = filepath + strlen(directory) + 1; struct dirent *file; - DIR *d = opendir(directory); + DIR *d = NULL; + d = opendir(directory); if (d) { while ((file = readdir(d))) { + struct stat st; int length = strlen(file->d_name); strncpy(f_p, (const char *)file->d_name, length); *(f_p + length) = '\0'; - if (file->d_type == DT_DIR && *file->d_name != '.') // no hidden dirs + lstat(filepath, &st); + if(S_ISLNK(st.st_mode)) + continue; + + if (S_ISDIR(st.st_mode) && *file->d_name != '.') // no hidden dirs ohcount_sourcefile_list_add_directory(list, filepath); - else if (file->d_type == DT_REG -#ifdef TMP_FILES_ARE_DT_UNKNOWN - || file->d_type == DT_UNKNOWN -#endif - ) + else if (S_ISREG(st.st_mode)) ohcount_sourcefile_list_add_file(list, filepath); } closedir(d); - ohcount_sourcefile_list_add_file(list, directory); } } diff --git a/src/sourcefile.h b/src/sourcefile.h index 0d63ab1..e1d8fa6 100644 --- a/src/sourcefile.h +++ b/src/sourcefile.h @@ -155,27 +155,6 @@ SourceFile *to); /** - * Sets the given SourceFile's directory contents to the string array given. - * The given array is copied and may be 'free'd immediately. - * @param sourcefile A SourceFile created by ohcount_sourcefile_new(). - * @param filenames String array of filenames. If NULL, the next call to - * ohcount_sourcefile_get_filenames will access the SourceFile's directory. - */ -void ohcount_sourcefile_set_filenames(SourceFile *sourcefile, - char **filenames); - -/** - * Returns a string array of the given SourceFile's directory contents. - * If the existing 'filenames' field is NULL, the directory is accessed and its - * listing is returned. - * The returned pointer and its contents are used internally and must not be - * 'free'd. - * @param sourcefile A SourceFile created by ohcount_sourcefile_new(). - * @return pointer to a list of filenames (NULL-pointer terminated). - */ -char **ohcount_sourcefile_get_filenames(SourceFile *sourcefile); - -/** * Frees a SourceFile created by ohcount_sourcefile_new(). * @param sourcefile A SourceFile created by ohcount_sourcefile_new(). */ diff --git a/src/structs.h b/src/structs.h index 3bd9b67..82cdfc0 100644 --- a/src/structs.h +++ b/src/structs.h @@ -303,10 +303,7 @@ */ LocList *loc_list; - /** - * A string array of all filenames in this file's directory. - * Do not use this field. Use ohcount_sourcefile_get_filenames() instead. - */ + /** A string array of all filenames in this file's directory. */ char **filenames; } SourceFile; diff --git a/test/detect_files/AdvancedStreamRedirector.asx b/test/detect_files/AdvancedStreamRedirector.asx new file mode 100644 index 0000000..9aed988 --- /dev/null +++ b/test/detect_files/AdvancedStreamRedirector.asx @@ -0,0 +1,11 @@ + + Example.com Live Stream + + Short Announcement to Play Before Main Stream + + + + Example radio + + + diff --git a/test/detect_files/ampl.dat b/test/detect_files/ampl.dat new file mode 100644 index 0000000..a68b3a0 --- /dev/null +++ b/test/detect_files/ampl.dat @@ -0,0 +1,2 @@ +data; +param p := 42; diff --git a/test/detect_files/ampl.mod b/test/detect_files/ampl.mod new file mode 100644 index 0000000..20037d8 --- /dev/null +++ b/test/detect_files/ampl.mod @@ -0,0 +1,3 @@ +# An AMPL model +var x >= 42; +minimize o: x; diff --git a/test/detect_files/assembler6502.asx b/test/detect_files/assembler6502.asx new file mode 100644 index 0000000..09846ae --- /dev/null +++ b/test/detect_files/assembler6502.asx @@ -0,0 +1,21 @@ +; "Hello world" in 6502 assembly language for 8-bit Atari. +; Assembler: http://xasm.atari.org/ or http://mads.atari8.info/ + + org $3000 +main lda #$21 + sta $22f + lda #
dl + sta $231 + jmp * + +text dta d' HELLO, ',d'WORLD! '* + +; Display List +dl dta b($70),b($70),b($70),b($47),a(text),b($41),a(dl) + + org $2e0 + dta a(main) + + end diff --git a/test/detect_files/binary.dat b/test/detect_files/binary.dat new file mode 100644 index 0000000..4268632 --- /dev/null +++ b/test/detect_files/binary.dat @@ -0,0 +1 @@ +some data diff --git a/test/detect_files/client-osx.gs b/test/detect_files/client-osx.gs new file mode 100644 index 0000000..21d5773 --- /dev/null +++ b/test/detect_files/client-osx.gs @@ -0,0 +1,38 @@ +/* + * WebSoy - Client for OSX + * Copyright (C) 2011,2012 Copyleft Games Group + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program; if not, see http://www.gnu.org/licenses + * + */ + +#if XP_MACOSX + +[indent=4] +uses + GLib + GL + +class Client : Object + scene : soy.scenes.Scene + window : soy.widgets.Window + + construct (window : NP.Window) + self.scene = new soy.scenes.Scene() + self.window = new soy.widgets.Window(null) + + // TODO + +#endif + diff --git a/test/detect_files/coq.v b/test/detect_files/coq.v new file mode 100644 index 0000000..37ae74c --- /dev/null +++ b/test/detect_files/coq.v @@ -0,0 +1,10 @@ +Require Import String. +(* comment *) +Check "multiline +string"%string. + +(* multiline + comment *) + +(* recursion in (* a + comment *) to complicate things *) diff --git a/test/detect_files/emacs_mode_c b/test/detect_files/emacs_mode_c new file mode 100644 index 0000000..f55d1f5 --- /dev/null +++ b/test/detect_files/emacs_mode_c @@ -0,0 +1,2 @@ +/* -*- mode: C; -*- + * The upper-case "C" mode should be interpreted as straight C, not C++ */ diff --git a/test/detect_files/empty.in b/test/detect_files/empty.in new file mode 100644 index 0000000..e69de29 diff --git a/test/detect_files/empty.inc b/test/detect_files/empty.inc new file mode 100644 index 0000000..e69de29 diff --git a/test/detect_files/foo.R b/test/detect_files/foo.R deleted file mode 100644 index 29f47e4..0000000 --- a/test/detect_files/foo.R +++ /dev/null @@ -1,5 +0,0 @@ -dummy<-function() { -# A dummy function to test the R language parser. - 1.0 -} - diff --git a/test/detect_files/foo.bf b/test/detect_files/foo.bf new file mode 100644 index 0000000..2220679 --- /dev/null +++ b/test/detect_files/foo.bf @@ -0,0 +1,16 @@ +>++++++[>+++[<<++++>>-]<-]<. +>+++++[<++++++>-]<-. ++++++++. +. ++++. +>>++++[<++++++>-]<++[<--->-]<-. +>>++[<+++++>-]<+[<+++++>-]<. +>++++[<++++++>-]<. ++++. +------. +>++[<---->-]<. +>>++[<+++++>-]<+[<------>-]<-. +. +. +. +. diff --git a/test/detect_files/foo.bfpp b/test/detect_files/foo.bfpp new file mode 100644 index 0000000..ce9ec71 --- /dev/null +++ b/test/detect_files/foo.bfpp @@ -0,0 +1,50 @@ += comment +>++++++[>+++[<<++++>>-]<-]<. +>+++++[<++++++>-]<-. ++++++++. +. ++++. +>>++++[<++++++>-]<++[<--->-]<-. +>>++[<+++++>-]<+[<+++++>-]<. +>++++[<++++++>-]<. ++++. +------. +>++[<---->-]<. +>>++++[<++++>-]<+[<---->-]<. +>+++++++[<++++++>-]<-. +>++++++[<++++++>-]<+. +>>++++[<++++++>-]<++[<--->-]<. +>+++++[<+++++++>-]<-. +>++++[>++++[<<+++>>-]<-]<. +>++++[<---->-]<-. +>++[<++++>-]<. ++++++. +>++[<---->-]<. +>+++[<+++++>-]<. +>+++[<------>-]<. +>++[<++++>-]<. +>++++[>++++[<<---->>-]<-]<. +. +>++[<----->-]<. +. +. +. +. +[-] += Try to open b file +>+++++++[>+++++++[<<++>>-]<-]<. +#[ + >>++++[<++++>-]<+[<++++++>-]<. + +++. + +++. + -------. + >>++++[<++++++>-]<-[<--->-]<. + >>++[<+++++>-]<+[<++++++>-]<. + >>++[<+++++>-]<+[<------>-]<. + >>++++[<++++++>-]<++[<+++>-]<+. + +. + >++[<----->-]<-. + >+++[<+++>-]<. + >+++[<--->-]<. + -. +#] diff --git a/test/detect_files/foo.chai b/test/detect_files/foo.chai new file mode 100644 index 0000000..f8dc571 --- /dev/null +++ b/test/detect_files/foo.chai @@ -0,0 +1,4 @@ +//ChaiScript file +def dosomething() +{ +} diff --git a/test/detect_files/foo.coffee b/test/detect_files/foo.coffee new file mode 100644 index 0000000..f5fa263 --- /dev/null +++ b/test/detect_files/foo.coffee @@ -0,0 +1,2 @@ +# CoffeeScript sample +square = (x) -> x * x diff --git a/test/detect_files/foo.dtx b/test/detect_files/foo.dtx new file mode 100644 index 0000000..d8cb14d --- /dev/null +++ b/test/detect_files/foo.dtx @@ -0,0 +1,9 @@ +\begin{document} +\texbf Hello world + + +% \acommand +% \anothercommand +%% sample comment + +\end{document} diff --git a/test/detect_files/foo.ec b/test/detect_files/foo.ec new file mode 100755 index 0000000..b169291 --- /dev/null +++ b/test/detect_files/foo.ec @@ -0,0 +1,17 @@ +import "ecere" + +class HelloForm : Window +{ + text = "My First eC Application"; + borderStyle = sizable; + size = { 280, 100 }; + hasClose = true; + + Label label + { + this, position = { 10, 10 }, font = { "Arial", 30 }, + text = "Hello, World!!" + }; +}; + +HelloForm hello { }; diff --git a/test/detect_files/foo.eh b/test/detect_files/foo.eh new file mode 100755 index 0000000..1ed173f --- /dev/null +++ b/test/detect_files/foo.eh @@ -0,0 +1,315 @@ +/* A Bison parser, made by GNU Bison 2.0. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + IDENTIFIER = 258, + CONSTANT = 259, + STRING_LITERAL = 260, + SIZEOF = 261, + PTR_OP = 262, + INC_OP = 263, + DEC_OP = 264, + LEFT_OP = 265, + RIGHT_OP = 266, + LE_OP = 267, + GE_OP = 268, + EQ_OP = 269, + NE_OP = 270, + AND_OP = 271, + OR_OP = 272, + MUL_ASSIGN = 273, + DIV_ASSIGN = 274, + MOD_ASSIGN = 275, + ADD_ASSIGN = 276, + SUB_ASSIGN = 277, + LEFT_ASSIGN = 278, + RIGHT_ASSIGN = 279, + AND_ASSIGN = 280, + XOR_ASSIGN = 281, + OR_ASSIGN = 282, + TYPE_NAME = 283, + TYPEDEF = 284, + EXTERN = 285, + STATIC = 286, + AUTO = 287, + REGISTER = 288, + CHAR = 289, + SHORT = 290, + INT = 291, + UINT = 292, + INT64 = 293, + LONG = 294, + SIGNED = 295, + UNSIGNED = 296, + FLOAT = 297, + DOUBLE = 298, + CONST = 299, + VOLATILE = 300, + VOID = 301, + VALIST = 302, + STRUCT = 303, + UNION = 304, + ENUM = 305, + ELLIPSIS = 306, + CASE = 307, + DEFAULT = 308, + IF = 309, + SWITCH = 310, + WHILE = 311, + DO = 312, + FOR = 313, + GOTO = 314, + CONTINUE = 315, + BREAK = 316, + RETURN = 317, + IFX = 318, + ELSE = 319, + CLASS = 320, + THISCLASS = 321, + CLASS_NAME = 322, + PROPERTY = 323, + SETPROP = 324, + GETPROP = 325, + NEWOP = 326, + RENEW = 327, + DELETE = 328, + EXT_DECL = 329, + EXT_STORAGE = 330, + IMPORT = 331, + DEFINE = 332, + VIRTUAL = 333, + EXT_ATTRIB = 334, + PUBLIC = 335, + PRIVATE = 336, + TYPED_OBJECT = 337, + ANY_OBJECT = 338, + _INCREF = 339, + EXTENSION = 340, + ASM = 341, + TYPEOF = 342, + WATCH = 343, + STOPWATCHING = 344, + FIREWATCHERS = 345, + WATCHABLE = 346, + CLASS_DESIGNER = 347, + CLASS_NO_EXPANSION = 348, + CLASS_FIXED = 349, + ISPROPSET = 350, + CLASS_DEFAULT_PROPERTY = 351, + PROPERTY_CATEGORY = 352, + CLASS_DATA = 353, + CLASS_PROPERTY = 354, + SUBCLASS = 355, + NAMESPACE = 356, + NEW0OP = 357, + RENEW0 = 358, + VAARG = 359, + DBTABLE = 360, + DBFIELD = 361, + DBINDEX = 362, + DATABASE_OPEN = 363 + }; +#endif +#define IDENTIFIER 258 +#define CONSTANT 259 +#define STRING_LITERAL 260 +#define SIZEOF 261 +#define PTR_OP 262 +#define INC_OP 263 +#define DEC_OP 264 +#define LEFT_OP 265 +#define RIGHT_OP 266 +#define LE_OP 267 +#define GE_OP 268 +#define EQ_OP 269 +#define NE_OP 270 +#define AND_OP 271 +#define OR_OP 272 +#define MUL_ASSIGN 273 +#define DIV_ASSIGN 274 +#define MOD_ASSIGN 275 +#define ADD_ASSIGN 276 +#define SUB_ASSIGN 277 +#define LEFT_ASSIGN 278 +#define RIGHT_ASSIGN 279 +#define AND_ASSIGN 280 +#define XOR_ASSIGN 281 +#define OR_ASSIGN 282 +#define TYPE_NAME 283 +#define TYPEDEF 284 +#define EXTERN 285 +#define STATIC 286 +#define AUTO 287 +#define REGISTER 288 +#define CHAR 289 +#define SHORT 290 +#define INT 291 +#define UINT 292 +#define INT64 293 +#define LONG 294 +#define SIGNED 295 +#define UNSIGNED 296 +#define FLOAT 297 +#define DOUBLE 298 +#define CONST 299 +#define VOLATILE 300 +#define VOID 301 +#define VALIST 302 +#define STRUCT 303 +#define UNION 304 +#define ENUM 305 +#define ELLIPSIS 306 +#define CASE 307 +#define DEFAULT 308 +#define IF 309 +#define SWITCH 310 +#define WHILE 311 +#define DO 312 +#define FOR 313 +#define GOTO 314 +#define CONTINUE 315 +#define BREAK 316 +#define RETURN 317 +#define IFX 318 +#define ELSE 319 +#define CLASS 320 +#define THISCLASS 321 +#define CLASS_NAME 322 +#define PROPERTY 323 +#define SETPROP 324 +#define GETPROP 325 +#define NEWOP 326 +#define RENEW 327 +#define DELETE 328 +#define EXT_DECL 329 +#define EXT_STORAGE 330 +#define IMPORT 331 +#define DEFINE 332 +#define VIRTUAL 333 +#define EXT_ATTRIB 334 +#define PUBLIC 335 +#define PRIVATE 336 +#define TYPED_OBJECT 337 +#define ANY_OBJECT 338 +#define _INCREF 339 +#define EXTENSION 340 +#define ASM 341 +#define TYPEOF 342 +#define WATCH 343 +#define STOPWATCHING 344 +#define FIREWATCHERS 345 +#define WATCHABLE 346 +#define CLASS_DESIGNER 347 +#define CLASS_NO_EXPANSION 348 +#define CLASS_FIXED 349 +#define ISPROPSET 350 +#define CLASS_DEFAULT_PROPERTY 351 +#define PROPERTY_CATEGORY 352 +#define CLASS_DATA 353 +#define CLASS_PROPERTY 354 +#define SUBCLASS 355 +#define NAMESPACE 356 +#define NEW0OP 357 +#define RENEW0 358 +#define VAARG 359 +#define DBTABLE 360 +#define DBFIELD 361 +#define DBINDEX 362 +#define DATABASE_OPEN 363 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 42 "grammar.y" +typedef union YYSTYPE { + SpecifierType specifierType; + int i; + AccessMode declMode; + Identifier id; + Expression exp; + Specifier specifier; + OldList * list; + Enumerator enumerator; + Declarator declarator; + Pointer pointer; + Initializer initializer; + InitDeclarator initDeclarator; + TypeName typeName; + Declaration declaration; + Statement stmt; + FunctionDefinition function; + External external; + Context context; + AsmField asmField; + + Instantiation instance; + MembersInit membersInit; + MemberInit memberInit; + ClassFunction classFunction; + ClassDefinition _class; + ClassDef classDef; + PropertyDef prop; + char * string; + Symbol symbol; + PropertyWatch propertyWatch; + TemplateParameter templateParameter; + TemplateArgument templateArgument; + TemplateDatatype templateDatatype; + + DBTableEntry dbtableEntry; + DBIndexItem dbindexItem; + DBTableDef dbtableDef; +} YYSTYPE; +/* Line 1318 of yacc.c. */ +#line 293 "grammar.eh" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + +#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED) +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + +extern YYLTYPE yylloc; + + diff --git a/test/detect_files/foo.in.in b/test/detect_files/foo.in.in new file mode 100644 index 0000000..32f8e97 --- /dev/null +++ b/test/detect_files/foo.in.in @@ -0,0 +1,2 @@ +[Foo] +Foo=Bar diff --git a/test/detect_files/foo.lgt b/test/detect_files/foo.lgt new file mode 100644 index 0000000..673fab2 --- /dev/null +++ b/test/detect_files/foo.lgt @@ -0,0 +1,9 @@ +% this is a Logtalk source file + +:- object(hello_world). + + % the initialization/1 directive argument is automatically executed + % when the object is loaded into memory: + :- initialization((nl, write('********** Hello World! **********'), nl)). + +:- end_object. diff --git a/test/detect_files/foo.nsh b/test/detect_files/foo.nsh new file mode 100644 index 0000000..f5faef9 --- /dev/null +++ b/test/detect_files/foo.nsh @@ -0,0 +1 @@ +; No need for special content in here, detected by extension diff --git a/test/detect_files/foo.nsi b/test/detect_files/foo.nsi new file mode 100644 index 0000000..f5faef9 --- /dev/null +++ b/test/detect_files/foo.nsi @@ -0,0 +1 @@ +; No need for special content in here, detected by extension diff --git a/test/detect_files/foo.qml b/test/detect_files/foo.qml new file mode 100644 index 0000000..e30475a --- /dev/null +++ b/test/detect_files/foo.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + color: "crimson" +} diff --git a/test/detect_files/foo.run b/test/detect_files/foo.run new file mode 100644 index 0000000..644ff17 --- /dev/null +++ b/test/detect_files/foo.run @@ -0,0 +1,2 @@ +# An AMPL script +print 42; diff --git a/test/detect_files/foo_mathematica.m b/test/detect_files/foo_mathematica.m new file mode 100644 index 0000000..ceb605c --- /dev/null +++ b/test/detect_files/foo_mathematica.m @@ -0,0 +1,2 @@ +foo[x_] := b +(* a comment *) diff --git a/test/detect_files/foo_perl1.pl b/test/detect_files/foo_perl1.pl new file mode 100644 index 0000000..8371027 --- /dev/null +++ b/test/detect_files/foo_perl1.pl @@ -0,0 +1,2 @@ +#!/usr/bin/perl +print "Hello, world!\n"; diff --git a/test/detect_files/foo_perl2.pl b/test/detect_files/foo_perl2.pl new file mode 100644 index 0000000..2f94700 --- /dev/null +++ b/test/detect_files/foo_perl2.pl @@ -0,0 +1,3 @@ + +# Also a Perl file but without the shebang line +print "Hello, world!\n"; \ No newline at end of file diff --git a/test/detect_files/foo_prolog1.pl b/test/detect_files/foo_prolog1.pl new file mode 100644 index 0000000..af8467d --- /dev/null +++ b/test/detect_files/foo_prolog1.pl @@ -0,0 +1,6 @@ + +% select(Element, List, Remaining) + +select(H, [H| T], T). +select(H, [X| R], [X| T]) :- + select(H, R, T). \ No newline at end of file diff --git a/test/detect_files/foo_r.R b/test/detect_files/foo_r.R new file mode 100644 index 0000000..29f47e4 --- /dev/null +++ b/test/detect_files/foo_r.R @@ -0,0 +1,5 @@ +dummy<-function() { +# A dummy function to test the R language parser. + 1.0 +} + diff --git a/test/detect_files/foo_rebol_lower.r b/test/detect_files/foo_rebol_lower.r new file mode 100644 index 0000000..22eda4b --- /dev/null +++ b/test/detect_files/foo_rebol_lower.r @@ -0,0 +1,7 @@ +; a rebol script +rebol [] + +; A dummy function to test the REBOL language parser. +dummy: func [] [ + read %blah +] diff --git a/test/detect_files/foo_rebol_upper.r b/test/detect_files/foo_rebol_upper.r new file mode 100644 index 0000000..a5ff223 --- /dev/null +++ b/test/detect_files/foo_rebol_upper.r @@ -0,0 +1,7 @@ +; a rebol script +REBOL [] + +; A dummy function to test the REBOL language parser. +dummy: func [] [ + read %blah +] diff --git a/test/detect_files/forth.4th b/test/detect_files/forth.4th new file mode 100644 index 0000000..75ce18d --- /dev/null +++ b/test/detect_files/forth.4th @@ -0,0 +1,7 @@ +\ Sample Forth code + +( This is a comment + spanning multiple lines ) + +: somedefinition ; + diff --git a/test/detect_files/forth.fr b/test/detect_files/forth.fr new file mode 100644 index 0000000..75ce18d --- /dev/null +++ b/test/detect_files/forth.fr @@ -0,0 +1,7 @@ +\ Sample Forth code + +( This is a comment + spanning multiple lines ) + +: somedefinition ; + diff --git a/test/detect_files/fortranfree.f b/test/detect_files/fortranfree.f index 5da5944..d980995 100644 --- a/test/detect_files/fortranfree.f +++ b/test/detect_files/fortranfree.f @@ -1,8 +1,8 @@ ! -*- F90 -*- - program fortranfreecheck -! Simple check. Not valid fixed form thanks to the continuation. - write(*,*) 2 + & -& 2 - goto 22 +program fortranfreecheck +! Simple check. Not valid fixed form thanks to code starting in first column. + write(*,*) 2 + & + & 2 + goto 22 22 write(*,*) 'bar' - end +end program fortranfreecheck diff --git a/test/detect_files/grace1.grace b/test/detect_files/grace1.grace new file mode 100644 index 0000000..ecef509 --- /dev/null +++ b/test/detect_files/grace1.grace @@ -0,0 +1,7 @@ +// Sample Grace code + +import "parsers-test" as parsers + +class exports { + def program = rule {codeSequence ~ rep(ws) ~ end} +} diff --git a/test/detect_files/grace2.grc b/test/detect_files/grace2.grc new file mode 100644 index 0000000..0d500ff --- /dev/null +++ b/test/detect_files/grace2.grc @@ -0,0 +1,2 @@ +// Sample Grace code +print "OK" diff --git a/test/detect_files/java_emac.rb b/test/detect_files/java_emac.rb new file mode 100644 index 0000000..e9c0abd --- /dev/null +++ b/test/detect_files/java_emac.rb @@ -0,0 +1,5 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +# a ruby script +File.open("blah") do |io| + a = io.read +end diff --git a/test/detect_files/javascript_emacs.js b/test/detect_files/javascript_emacs.js new file mode 100644 index 0000000..3adad9c --- /dev/null +++ b/test/detect_files/javascript_emacs.js @@ -0,0 +1,7 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +'use strict'; + +require('./external/shelljs/make'); +var builder = require('./external/builder/builder.js'); +var crlfchecker = require('./external/crlfchecker/crlfchecker.js'); +var path = require('path'); diff --git a/test/detect_files/m4.m4 b/test/detect_files/m4.m4 new file mode 100644 index 0000000..2962d6d --- /dev/null +++ b/test/detect_files/m4.m4 @@ -0,0 +1,6 @@ +# Sample M4 file + +AC_DEFUN([SAMPLE],[ +AC_REQUIRE([ANOTHER_SAMPLE]) +printf "$2" >> "$1" +]) diff --git a/test/detect_files/modula2.mod b/test/detect_files/modula2.mod new file mode 100644 index 0000000..89898a1 --- /dev/null +++ b/test/detect_files/modula2.mod @@ -0,0 +1,6 @@ +(* Modula-2 module *) +MODULE Hello; +FROM STextIO IMPORT WriteString; +BEGIN + WriteString("Hello World!"); +END Hello. diff --git a/test/detect_files/module-definition.def b/test/detect_files/module-definition.def new file mode 100644 index 0000000..b3a1d21 --- /dev/null +++ b/test/detect_files/module-definition.def @@ -0,0 +1,5 @@ +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE diff --git a/test/detect_files/perl_shebang_prolog_body.pl b/test/detect_files/perl_shebang_prolog_body.pl new file mode 100644 index 0000000..6e2cad5 --- /dev/null +++ b/test/detect_files/perl_shebang_prolog_body.pl @@ -0,0 +1,3 @@ +#!%PERL% +% This is prolog code, but the shebang says perl, so we respect the shebang and choose perl. +Head :- Body. diff --git a/test/detect_files/perl_with_smiley.pl b/test/detect_files/perl_with_smiley.pl new file mode 100644 index 0000000..076bdd0 --- /dev/null +++ b/test/detect_files/perl_with_smiley.pl @@ -0,0 +1,2 @@ +# This is not prolog. Do not be confused by the smiley, which looks like a Prolog rule. +print "Hello, world :-)\n" diff --git a/test/detect_files/puppet_import.pp b/test/detect_files/puppet_import.pp new file mode 100644 index 0000000..6cc1969 --- /dev/null +++ b/test/detect_files/puppet_import.pp @@ -0,0 +1,2 @@ +import "classes/*.pp" +import "definitions/*.pp" diff --git a/test/detect_files/puppet_import_annotated.pp b/test/detect_files/puppet_import_annotated.pp new file mode 100644 index 0000000..f2db624 --- /dev/null +++ b/test/detect_files/puppet_import_annotated.pp @@ -0,0 +1,2 @@ +puppet lcode import "classes/*.pp" +puppet lcode import "definitions/*.pp" diff --git a/test/detect_files/puppet_test.pp b/test/detect_files/puppet_test.pp new file mode 100644 index 0000000..0b9192d --- /dev/null +++ b/test/detect_files/puppet_test.pp @@ -0,0 +1,3 @@ +class main::sub { + include substuff +} diff --git a/test/detect_files/puppet_test_annotated.pp b/test/detect_files/puppet_test_annotated.pp new file mode 100644 index 0000000..b5de2ef --- /dev/null +++ b/test/detect_files/puppet_test_annotated.pp @@ -0,0 +1,3 @@ +puppet lcode class main::sub { +puppet lcode include substuff +puppet lcode } diff --git a/test/detect_files/renderscript.rs b/test/detect_files/renderscript.rs new file mode 100644 index 0000000..12fcd96 --- /dev/null +++ b/test/detect_files/renderscript.rs @@ -0,0 +1,32 @@ +/** + * We could easily have a comment of significant length here at the top. + * + * It might well have a boilerplate copyright notice, which could go on for + * quite some lines. + * + * But as it is, this example is boring, containing merely a self-referential + * comment in that location. + */ + +#pragma version(1) +#pragma rs java_package_name(com.example.example.example.example.example) +#pragma stateFragment(parent) + +#include "rs_foo.rsh" + +static int panic = 0; + +float away = 1.f; + +typedef struct __attribute__((packed, aligned(4))) Foo { +} Foo_t; +Foo_t *foo; + +rs_mesh gears; + +/** + * This example is pretty poorly written, ain't it? + */ +void warranty() { + with(pleasure); +} diff --git a/test/detect_files/rust.rs b/test/detect_files/rust.rs new file mode 100644 index 0000000..03906b0 --- /dev/null +++ b/test/detect_files/rust.rs @@ -0,0 +1,16 @@ +/* + * This is the example given by www.rust-lang.org + */ +// Line comments work too +fn main() { + let nums = [1, 2]; + let noms = ["Tim", "Eston", "Aaron", "Ben"]; + + let mut odds = nums.iter().map(|&x| x * 2 - 1); + + for num in odds { + do spawn { + println!("{:s} says hello from a lightweight thread!", noms[num]); + } + } +} diff --git a/test/detect_files/sampleDef.def b/test/detect_files/sampleDef.def new file mode 100644 index 0000000..cd7c9ed --- /dev/null +++ b/test/detect_files/sampleDef.def @@ -0,0 +1,12 @@ +DEFINITION MODULE Sample; (* in Modula-2 *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString = 'this is a string within "a string" ...'; + dqString = "this is a string within 'a string' ..."; + +END Sample. diff --git a/test/detect_files/uses_cpp_modeline b/test/detect_files/uses_cpp_modeline new file mode 100644 index 0000000..11f0cf3 --- /dev/null +++ b/test/detect_files/uses_cpp_modeline @@ -0,0 +1,2 @@ +/* -*- C++ -*- */ + diff --git a/test/expected_dir/ampl.mod b/test/expected_dir/ampl.mod new file mode 100644 index 0000000..3afde0d --- /dev/null +++ b/test/expected_dir/ampl.mod @@ -0,0 +1,7 @@ +ampl comment /* This is a test file for AMPL +ampl comment * This is a multiline comment +ampl comment */ +ampl blank +ampl comment # An AMPL model +ampl code var x >= 42; # variable definition. +ampl code minimize o: x; diff --git a/test/expected_dir/assembler6502.as8 b/test/expected_dir/assembler6502.as8 new file mode 100644 index 0000000..177ebcf --- /dev/null +++ b/test/expected_dir/assembler6502.as8 @@ -0,0 +1,21 @@ +assembler comment ; "Hello world" in 6502 assembly language for 8-bit Atari. +assembler comment ; Assembler: http://xasm.atari.org/ or http://mads.atari8.info/ +assembler blank +assembler code org $3000 +assembler code main lda #$21 +assembler code sta $22f +assembler code lda #
dl +assembler code sta $231 +assembler code jmp * +assembler blank +assembler code text dta d' HELLO, ',d'WORLD! '* +assembler blank +assembler comment ; Display List +assembler code dl dta b($70),b($70),b($70),b($47),a(text),b($41),a(dl) +assembler blank +assembler code org $2e0 +assembler code dta a(main) +assembler blank +assembler code end diff --git a/test/expected_dir/assembler6502.asx b/test/expected_dir/assembler6502.asx new file mode 100644 index 0000000..177ebcf --- /dev/null +++ b/test/expected_dir/assembler6502.asx @@ -0,0 +1,21 @@ +assembler comment ; "Hello world" in 6502 assembly language for 8-bit Atari. +assembler comment ; Assembler: http://xasm.atari.org/ or http://mads.atari8.info/ +assembler blank +assembler code org $3000 +assembler code main lda #$21 +assembler code sta $22f +assembler code lda #
dl +assembler code sta $231 +assembler code jmp * +assembler blank +assembler code text dta d' HELLO, ',d'WORLD! '* +assembler blank +assembler comment ; Display List +assembler code dl dta b($70),b($70),b($70),b($47),a(text),b($41),a(dl) +assembler blank +assembler code org $2e0 +assembler code dta a(main) +assembler blank +assembler code end diff --git a/test/expected_dir/augeas.aug b/test/expected_dir/augeas.aug new file mode 100644 index 0000000..f09e7e0 --- /dev/null +++ b/test/expected_dir/augeas.aug @@ -0,0 +1,14 @@ +augeas comment (** documentation *) +augeas code module Augeas = +augeas code autoload xfm +augeas comment (**/**) +augeas comment (* extra comment *) +augeas blank +augeas comment (* multiline +augeas comment comment*) +augeas code let lns = Shellvars.lns +augeas blank +augeas comment (* recursion in (* a +augeas comment comment *) to complicate things *) +augeas code let filter = incl "/foo/bar" +augeas code let xfm = transform lns filter diff --git a/test/expected_dir/b.bfpp b/test/expected_dir/b.bfpp new file mode 100644 index 0000000..b3a4ce6 --- /dev/null +++ b/test/expected_dir/b.bfpp @@ -0,0 +1,54 @@ +bfpp blank +bfpp comment = comment +bfpp code >++++++[>+++[<<++++>>-]<-]<. +bfpp code >+++++[<++++++>-]<-. +bfpp code +++++++. +bfpp code . +bfpp code +++. +bfpp code >>++++[<++++++>-]<++[<--->-]<-. +bfpp code >>++[<+++++>-]<+[<+++++>-]<. +bfpp code >++++[<++++++>-]<. +bfpp code +++. +bfpp code ------. +bfpp code >++[<---->-]<. +bfpp code >>++++[<++++>-]<+[<---->-]<. +bfpp code >+++++++[<++++++>-]<-. +bfpp code >++++++[<++++++>-]<+. +bfpp code >>++++[<++++++>-]<++[<--->-]<. +bfpp code >+++++[<+++++++>-]<-. +bfpp code >++++[>++++[<<+++>>-]<-]<. +bfpp code >++++[<---->-]<-. +bfpp code >++[<++++>-]<. +bfpp code +++++. +bfpp code >++[<---->-]<. +bfpp code >+++[<+++++>-]<. +bfpp code >+++[<------>-]<. +bfpp code >++[<++++>-]<. +bfpp code >++++[>++++[<<---->>-]<-]<. +bfpp code . +bfpp code >++[<----->-]<. +bfpp code . +bfpp code . +bfpp code . +bfpp code . +bfpp code [-] +bfpp comment = [-] is used to clear a cell +bfpp blank +bfpp comment = Try to open b file +bfpp code >+++++++[>+++++++[<<++>>-]<-]<. +bfpp code #[ +bfpp code >>++++[<++++>-]<+[<++++++>-]<. +bfpp code +++. +bfpp code +++. +bfpp code -------. +bfpp code >>++++[<++++++>-]<-[<--->-]<. +bfpp code >>++[<+++++>-]<+[<++++++>-]<. +bfpp code >>++[<+++++>-]<+[<------>-]<. +bfpp code >>++++[<++++++>-]<++[<+++>-]<+. +bfpp code +. +bfpp code >++[<----->-]<-. +bfpp code >+++[<+++>-]<. +bfpp code >+++[<--->-]<. +bfpp code -. +bfpp code #] +bfpp code @include(nothing.bfpp) diff --git a/test/expected_dir/bat1.bat b/test/expected_dir/bat1.bat index 037c64d..fa70f7f 100644 --- a/test/expected_dir/bat1.bat +++ b/test/expected_dir/bat1.bat @@ -1,6 +1,11 @@ bat comment REM comment 1 bat comment rem comment 2 bat comment rEm comment 3 +bat comment rEm.comment 4 +bat comment Rem=comment 5 +bat comment @Rem comment 6 +bat comment @reM=comment 7 +bat comment ::comment 8 bat blank bat code echo not a rem comment! bat blank diff --git a/test/expected_dir/brainfuck.bf b/test/expected_dir/brainfuck.bf new file mode 100644 index 0000000..6a0b41e --- /dev/null +++ b/test/expected_dir/brainfuck.bf @@ -0,0 +1,19 @@ +brainfuck comment Print "Hello World!!!!!" +brainfuck blank +brainfuck code Line that does nothing: >< +brainfuck code >++++++[>+++[<<++++>>-]<-]<. +brainfuck code >+++++[<++++++>-]<-. +brainfuck code +++++++. +brainfuck code . +brainfuck code +++. +brainfuck code >>++++[<++++++>-]<++[<--->-]<-. +brainfuck code >>++[<+++++>-]<+[<+++++>-]<. +brainfuck code >++++[<++++++>-]<. +brainfuck code +++. +brainfuck code ------. +brainfuck code >++[<---->-]<. +brainfuck code >>++[<+++++>-]<+[<------>-]<-. +brainfuck code . +brainfuck code . +brainfuck code . +brainfuck code . diff --git a/test/expected_dir/chaiscript.chai b/test/expected_dir/chaiscript.chai new file mode 100644 index 0000000..c92ee13 --- /dev/null +++ b/test/expected_dir/chaiscript.chai @@ -0,0 +1,17 @@ +chaiscript comment /* +chaiscript comment Random Comments +chaiscript comment Foo Foo Foo +chaiscript comment */ +chaiscript code var submenu=1; +chaiscript comment // comment +chaiscript comment // another comment +chaiscript code submenu += 10 +chaiscript code var f = fun() { 5 }; +chaiscript code def myFun(i) : i > 0 { +chaiscript code return i + 10; +chaiscript code } +chaiscript blank +chaiscript blank +chaiscript comment // some comment +chaiscript code var delay_hide=500 +chaiscript code b=0 diff --git a/test/expected_dir/clj1.clj b/test/expected_dir/clj1.clj new file mode 100644 index 0000000..89c7966 --- /dev/null +++ b/test/expected_dir/clj1.clj @@ -0,0 +1,16 @@ +clojure comment ;;; Copyright (C) 2009 Brendan Ribera. All rights reserved. +clojure comment ;;; Distributed under the MIT License; see the file LICENSE +clojure comment ;;; at the root of this distribution. +clojure code (ns kdtree) +clojure blank +clojure code (defn dist-squared [a b] +clojure code "Compute the K-dimensional distance between two points" +clojure code (reduce + (for [i (range (count a))] +clojure code (let [v (- (nth a i) +clojure code (nth b i))] +clojure code (* v v))))) +clojure blank +clojure comment ;;; Simple accessors +clojure code (defn- node-value [n] (first n)) +clojure code (defn- node-left [n] (first (rest n))) +clojure code (defn- node-right [n] (first (rest (rest n)))) diff --git a/test/expected_dir/components.cu b/test/expected_dir/components.cu new file mode 100644 index 0000000..689200b --- /dev/null +++ b/test/expected_dir/components.cu @@ -0,0 +1,163 @@ +cuda code #include +cuda code #include +cuda code #include +cuda code #include +cuda code #include +cuda code #include +cuda blank +cuda code #include "components.h" +cuda code #include "common.h" +cuda blank +cuda code #define THREADS 256 +cuda blank +cuda comment /* Store 3 RGB float components */ +cuda code __device__ void storeComponents(float *d_r, float *d_g, float *d_b, float r, float g, float b, int pos) +cuda code { +cuda code d_r[pos] = (r/255.0f) - 0.5f; +cuda code d_g[pos] = (g/255.0f) - 0.5f; +cuda code d_b[pos] = (b/255.0f) - 0.5f; +cuda code } +cuda blank +cuda comment /* Store 3 RGB intege components */ +cuda code __device__ void storeComponents(int *d_r, int *d_g, int *d_b, int r, int g, int b, int pos) +cuda code { +cuda code d_r[pos] = r - 128; +cuda code d_g[pos] = g - 128; +cuda code d_b[pos] = b - 128; +cuda code } +cuda blank +cuda comment /* Store float component */ +cuda code __device__ void storeComponent(float *d_c, float c, int pos) +cuda code { +cuda code d_c[pos] = (c/255.0f) - 0.5f; +cuda code } +cuda blank +cuda comment /* Store integer component */ +cuda code __device__ void storeComponent(int *d_c, int c, int pos) +cuda code { +cuda code d_c[pos] = c - 128; +cuda code } +cuda blank +cuda comment /* Copy img src data into three separated component buffers */ +cuda code template +cuda code __global__ void c_CopySrcToComponents(T *d_r, T *d_g, T *d_b, +cuda code unsigned char * d_src, +cuda code int pixels) +cuda code { +cuda code int x = threadIdx.x; +cuda code int gX = blockDim.x*blockIdx.x; +cuda blank +cuda code __shared__ unsigned char sData[THREADS*3]; +cuda blank +cuda comment /* Copy data to shared mem by 4bytes other checks are not necessary, since d_src buffer is aligned to sharedDataSize */ +cuda code if ( (x*4) < THREADS*3 ) { +cuda code float *s = (float *)d_src; +cuda code float *d = (float *)sData; +cuda code d[x] = s[((gX*3)>>2) + x]; +cuda code } +cuda code __syncthreads(); +cuda blank +cuda code T r, g, b; +cuda blank +cuda code int offset = x*3; +cuda code r = (T)(sData[offset]); +cuda code g = (T)(sData[offset+1]); +cuda code b = (T)(sData[offset+2]); +cuda blank +cuda code int globalOutputPosition = gX + x; +cuda code if (globalOutputPosition < pixels) { +cuda code storeComponents(d_r, d_g, d_b, r, g, b, globalOutputPosition); +cuda code } +cuda code } +cuda blank +cuda comment /* Copy img src data into three separated component buffers */ +cuda code template +cuda code __global__ void c_CopySrcToComponent(T *d_c, unsigned char * d_src, int pixels) +cuda code { +cuda code int x = threadIdx.x; +cuda code int gX = blockDim.x*blockIdx.x; +cuda blank +cuda code __shared__ unsigned char sData[THREADS]; +cuda blank +cuda comment /* Copy data to shared mem by 4bytes other checks are not necessary, since d_src buffer is aligned to sharedDataSize */ +cuda code if ( (x*4) < THREADS) { +cuda code float *s = (float *)d_src; +cuda code float *d = (float *)sData; +cuda code d[x] = s[(gX>>2) + x]; +cuda code } +cuda code __syncthreads(); +cuda blank +cuda code T c; +cuda blank +cuda code c = (T)(sData[x]); +cuda blank +cuda code int globalOutputPosition = gX + x; +cuda code if (globalOutputPosition < pixels) { +cuda code storeComponent(d_c, c, globalOutputPosition); +cuda code } +cuda code } +cuda blank +cuda blank +cuda comment /* Separate compoents of 8bit RGB source image */ +cuda code template +cuda code void rgbToComponents(T *d_r, T *d_g, T *d_b, unsigned char * src, int width, int height) +cuda code { +cuda code unsigned char * d_src; +cuda code int pixels = width*height; +cuda code int alignedSize = DIVANDRND(width*height, THREADS) * THREADS * 3; //aligned to thread block size -- THREADS +cuda blank +cuda comment /* Alloc d_src buffer */ +cuda code cudaMalloc((void **)&d_src, alignedSize); +cuda code cudaCheckAsyncError("Cuda malloc") +cuda code cudaMemset(d_src, 0, alignedSize); +cuda blank +cuda comment /* Copy data to device */ +cuda code cudaMemcpy(d_src, src, pixels*3, cudaMemcpyHostToDevice); +cuda code cudaCheckError("Copy data to device") +cuda blank +cuda comment /* Kernel */ +cuda code dim3 threads(THREADS); +cuda code dim3 grid(alignedSize/(THREADS*3)); +cuda code assert(alignedSize%(THREADS*3) == 0); +cuda code c_CopySrcToComponents<<>>(d_r, d_g, d_b, d_src, pixels); +cuda code cudaCheckAsyncError("CopySrcToComponents kernel") +cuda blank +cuda comment /* Free Memory */ +cuda code cudaFree(d_src); +cuda code cudaCheckAsyncError("Free memory") +cuda code } +cuda code template void rgbToComponents(float *d_r, float *d_g, float *d_b, unsigned char * src, int width, int height); +cuda code template void rgbToComponents(int *d_r, int *d_g, int *d_b, unsigned char * src, int width, int height); +cuda blank +cuda blank +cuda comment /* Copy a 8bit source image data into a color compoment of type T */ +cuda code template +cuda code void bwToComponent(T *d_c, unsigned char * src, int width, int height) +cuda code { +cuda code unsigned char * d_src; +cuda code int pixels = width*height; +cuda code int alignedSize = DIVANDRND(pixels, THREADS) * THREADS; //aligned to thread block size -- THREADS +cuda blank +cuda comment /* Alloc d_src buffer */ +cuda code cudaMalloc((void **)&d_src, alignedSize); +cuda code cudaCheckAsyncError("Cuda malloc") +cuda code cudaMemset(d_src, 0, alignedSize); +cuda blank +cuda comment /* Copy data to device */ +cuda code cudaMemcpy(d_src, src, pixels, cudaMemcpyHostToDevice); +cuda code cudaCheckError("Copy data to device") +cuda blank +cuda comment /* Kernel */ +cuda code dim3 threads(THREADS); +cuda code dim3 grid(alignedSize/(THREADS)); +cuda code assert(alignedSize%(THREADS) == 0); +cuda code c_CopySrcToComponent<<>>(d_c, d_src, pixels); +cuda code cudaCheckAsyncError("CopySrcToComponent kernel") +cuda blank +cuda comment /* Free Memory */ +cuda code cudaFree(d_src); +cuda code cudaCheckAsyncError("Free memory") +cuda code } +cuda blank +cuda code template void bwToComponent(float *d_c, unsigned char *src, int width, int height); +cuda code template void bwToComponent(int *d_c, unsigned char *src, int width, int height); diff --git a/test/expected_dir/coq.v b/test/expected_dir/coq.v new file mode 100644 index 0000000..d7daa1d --- /dev/null +++ b/test/expected_dir/coq.v @@ -0,0 +1,10 @@ +coq code Require Import String. +coq comment (* comment *) +coq code Check "multiline +coq code string"%string. +coq blank +coq comment (* multiline +coq comment comment *) +coq blank +coq comment (* recursion in (* a +coq comment comment *) to complicate things *) diff --git a/test/expected_dir/example.qml b/test/expected_dir/example.qml new file mode 100644 index 0000000..ab96abc --- /dev/null +++ b/test/expected_dir/example.qml @@ -0,0 +1,17 @@ +qml comment // Just an example of QML file... +qml blank +qml code import QtQuick 2.0 +qml blank +qml code Rectangle { +qml code width: 200 +qml code height: 200 +qml code color: "crimson" +qml blank +qml code MouseArea { +qml code anchors.fill: parent +qml code onClicked: { +qml comment // Was clicked +qml code Qt.quit(); +qml code } +qml code } +qml code } diff --git a/test/expected_dir/example.rkt b/test/expected_dir/example.rkt new file mode 100644 index 0000000..9c3f2e4 --- /dev/null +++ b/test/expected_dir/example.rkt @@ -0,0 +1,12 @@ +racket comment ;; language declaration commented out until someone extends the +racket comment ;; parser to support it: +racket blank +racket comment ;; #lang racket +racket blank +racket comment ;; Report each unique line from stdin +racket code (let ([saw (make-hash)]) +racket code (for ([line (in-lines)]) +racket code (unless (hash-ref saw line #f) +racket code (displayln line)) +racket code (hash-set! saw line #t))) +racket blank diff --git a/test/expected_dir/foo.coffee b/test/expected_dir/foo.coffee new file mode 100644 index 0000000..d121da7 --- /dev/null +++ b/test/expected_dir/foo.coffee @@ -0,0 +1,26 @@ +coffeescript comment # A CoffeeScript parser test file +coffeescript blank +coffeescript code simple_code = true +coffeescript blank +coffeescript comment ### +coffeescript comment A multi-line block comment +coffeescript comment begins and ends with three hash marks +coffeescript comment ### +coffeescript blank +coffeescript code multi_line_string = ''' +coffeescript code A multi-line string constant ("here doc") +coffeescript code begins and ends with three quote marks +coffeescript code ''' +coffeescript blank +coffeescript code foo = "A string can wrap across multiple lines +coffeescript code and may contain #{interpolated_values}" +coffeescript blank +coffeescript blank +coffeescript comment ### +coffeescript comment A clever parser can use Ohcount's "Polyglot" feature treat the +coffeescript comment following as embedded JavaScript. +coffeescript comment ### +javascript code embedded_js = `function() { +javascript code return [document.title, "Hello JavaScript"].join(": "); +coffeescript code }` +coffeescript blank diff --git a/test/expected_dir/foo.dtx b/test/expected_dir/foo.dtx new file mode 100644 index 0000000..1275756 --- /dev/null +++ b/test/expected_dir/foo.dtx @@ -0,0 +1,9 @@ +tex_dtx code \begin{document} +tex_dtx code \texbf Hello world +tex_dtx blank +tex_dtx blank +tex_dtx code % \acommand +tex_dtx code % \anothercommand +tex_dtx comment %% sample comment +tex_dtx blank +tex_dtx code \end{document} diff --git a/test/expected_dir/foo.nsh b/test/expected_dir/foo.nsh new file mode 100644 index 0000000..0eddb8b --- /dev/null +++ b/test/expected_dir/foo.nsh @@ -0,0 +1,17 @@ +nsis comment ; NSIS "header" libraries can be in .nsh files. +nsis comment /* Copyright some time +nsis comment * never +nsis comment * and not much of that either +nsis comment "still a comment" +nsis comment */ +nsis blank +nsis code !macro SillyMacro Param1 +nsis comment ; ... Because we can ;-) +nsis code !error "Why did you call this macro, ${Param1}? That was silly." +nsis code !macroend +nsis blank +nsis code Function Die +nsis comment # Likewise, because we can. +nsis code DetailPrint "Aarrrrggghh! I died." +nsis code Quit +nsis code FunctionEnd diff --git a/test/expected_dir/foo.nsi b/test/expected_dir/foo.nsi new file mode 100644 index 0000000..243329e --- /dev/null +++ b/test/expected_dir/foo.nsi @@ -0,0 +1,15 @@ +nsis comment ; some nsis code +nsis comment /* +nsis comment * lorem +nsis comment ipsum +nsis comment dolor sit amet etcetera +nsis comment */ +nsis blank +nsis code !include LogicLib.nsh +nsis code OutFile foo.exe +nsis blank +nsis code Section +nsis code IfFileExists ${__FILE__} 0 +2 ; comments can be inline +nsis comment # Use of ; in a string on the next line +nsis code MessageBox MB_OK "You moved this installer file; you shouldn't do that ;-)" +nsis code SectionEnd diff --git a/test/expected_dir/forth.4th b/test/expected_dir/forth.4th new file mode 100644 index 0000000..e7f5ab5 --- /dev/null +++ b/test/expected_dir/forth.4th @@ -0,0 +1,7 @@ +forth comment \ Sample Forth code +forth blank +forth comment ( This is a comment +forth comment spanning multiple lines ) +forth blank +forth code : somedefinition ; +forth blank diff --git a/test/expected_dir/grace.grace b/test/expected_dir/grace.grace new file mode 100644 index 0000000..2cc0a16 --- /dev/null +++ b/test/expected_dir/grace.grace @@ -0,0 +1,46 @@ +grace comment ////////////////////////////////////////////////// +grace comment // Sample Grace code +grace blank +grace code import "parsers-test" as parsers +grace blank +grace code class exports { +grace code inherit parsers.exports +grace comment //BEGINGRAMMAR +grace comment // top level +grace code def program = rule {codeSequence ~ rep(ws) ~ end} +grace code def codeSequence = rule { repdel((declaration | statement | empty), semicolon) } +grace code def hashLine = rule { (symbol "#") ~ rep(anyChar | space) ~ (newLine | end) } +grace blank +grace comment // def comment = +grace blank +grace comment //def oldClassDeclaration = rule { classId ~ identifier ~ lBrace ~ +grace comment // opt(genericFormals ~ blockFormals ~ arrow) ~ codeSequence ~ rBrace } +grace blank +grace code def typeOpExpression = rule { rep1sep(basicTypeExpression, typeOp) } +grace blank +grace code def typeOpExpression = rule { +grace code var otherOperator +grace code basicTypeExpression ~ opt(ws) ~ +grace code opt( guard(typeOp, { s -> otherOperator:= s; +grace code true }) ~ rep1sep(basicTypeExpression ~ opt(ws), +grace code guard(typeOp, { s -> s == otherOperator }) +grace code ) +grace code ) +grace code } +grace blank +grace comment // "literals" +grace code def literal = rule { stringLiteral | selfLiteral | blockLiteral | numberLiteral | objectLiteral | lineupLiteral | typeLiteral } +grace blank +grace comment // terminals +grace code def backslash = token "\\" // doesn't belong here, doesn't work if left below! +grace blank +grace code def colon = rule {both(symbol ":", not(assign))} +grace code def newLine = symbol "\n" +grace code def lParen = symbol "(" +grace code def rParen = symbol ")" +grace blank +grace code def reservedOp = rule {assign | equals | dot | arrow | colon | semicolon} // this is not quite right +grace blank +grace comment //ENDGRAMMAR +grace code } +grace blank diff --git a/test/expected_dir/logtalk.lgt b/test/expected_dir/logtalk.lgt new file mode 100644 index 0000000..9f30fe1 --- /dev/null +++ b/test/expected_dir/logtalk.lgt @@ -0,0 +1,11 @@ +logtalk comment /* test file for Logtalk parsing */ +logtalk blank +logtalk comment % this is a Logtalk source file +logtalk blank +logtalk code :- object(hello_world). +logtalk blank +logtalk comment % the initialization/1 directive argument is automatically executed +logtalk comment % when the object is loaded into memory: +logtalk code :- initialization((nl, write('********** Hello World! **********'), nl)). +logtalk blank +logtalk code :- end_object. diff --git a/test/expected_dir/mathematica1.m b/test/expected_dir/mathematica1.m new file mode 100644 index 0000000..ea293c3 --- /dev/null +++ b/test/expected_dir/mathematica1.m @@ -0,0 +1,1480 @@ +mathematica blank +mathematica code SetEnhancedTimes[False]; +mathematica code SetSourceLanguage["C"]; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Options *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code createCode[derivOrder_, useJacobian_, splitUpwindDerivs_, useVectors_, useOpenCL_, evolutionTimelevels_, addMatter_, formulation_] := +mathematica code Module[{prefix, suffix, thorn}, +mathematica blank +mathematica code prefix = "ML_"; +mathematica code suffix = +mathematica code "" +mathematica code <> If [useJacobian, "_MP", ""] +mathematica code <> If [derivOrder!=4, "_O" <> ToString[derivOrder], ""] +mathematica code <> If [splitUpwindDerivs, "", "_UPW"] +mathematica code <> If [useVectors, "", "_NV"] +mathematica code <> If [useOpenCL, "_CL", ""] +mathematica comment (* <> If [evolutionTimelevels!=3, "_TL" <> ToString[evolutionTimelevels], ""] *) +mathematica comment (* <> If [addMatter==1, "_M", ""] *) +mathematica code ; +mathematica blank +mathematica code thorn = prefix <> formulation <> suffix; +mathematica blank +mathematica code SetAttributes[IfCCZ4, HoldAll]; +mathematica code IfCCZ4[expr_, else_:Sequence[]] := If[formulation === "CCZ4", expr, Unevaluated[else]]; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Derivatives *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code KD = KroneckerDelta; +mathematica blank +mathematica code derivatives = +mathematica code { +mathematica code PDstandardNth[i_] -> StandardCenteredDifferenceOperator[1,fdOrder/2,i], +mathematica code PDstandardNth[i_,i_] -> StandardCenteredDifferenceOperator[2,fdOrder/2,i], +mathematica code PDstandardNth[i_,j_] -> StandardCenteredDifferenceOperator[1,fdOrder/2,i] * +mathematica code StandardCenteredDifferenceOperator[1,fdOrder/2,j], +mathematica code PDdissipationNth[i_] -> +mathematica code (-1)^(fdOrder/2) * +mathematica code spacing[i]^(fdOrder+1) / 2^(fdOrder+2) * +mathematica code StandardCenteredDifferenceOperator[fdOrder+2,fdOrder/2+1,i], +mathematica blank +mathematica comment (* PD: These come from my mathematica notebook +mathematica comment "Upwind-Kranc-Convert.nb" that converts upwinding finite +mathematica comment differencing operators generated by +mathematica comment StandardUpwindDifferenceOperator into this form *) +mathematica blank +mathematica code Sequence@@Flatten[Table[ +mathematica code {PDupwindNth[i] -> Switch[fdOrder, +mathematica code 2, (dir[i]*(-3 + 4*shift[i]^dir[i] - shift[i]^(2*dir[i])))/(2*spacing[i]), +mathematica code 4, (dir[i]*(-10 - 3/shift[i]^dir[i] + 18*shift[i]^dir[i] - +mathematica code 6*shift[i]^(2*dir[i]) + shift[i]^(3*dir[i])))/(12*spacing[i]), +mathematica code 6, (dir[i]*(-35 + 2/shift[i]^(2*dir[i]) - 24/shift[i]^dir[i] + 80*shift[i]^dir[i] - +mathematica code 30*shift[i]^(2*dir[i]) + 8*shift[i]^(3*dir[i]) - shift[i]^(4*dir[i])))/(60*spacing[i]), +mathematica code 8, (dir[i]*(-378 - 5/shift[i]^(3*dir[i]) + 60/shift[i]^(2*dir[i]) - 420/shift[i]^dir[i] + +mathematica code 1050*shift[i]^dir[i] - 420*shift[i]^(2*dir[i]) + 140*shift[i]^(3*dir[i]) - 30*shift[i]^(4*dir[i]) + +mathematica code 3*shift[i]^(5*dir[i])))/(840*spacing[i])], +mathematica blank +mathematica code PDupwindNthAnti[i] -> Switch[fdOrder, +mathematica code 2, (+1 shift[i]^(-2) -4 shift[i]^(-1) +0 shift[i]^( 0) +4 shift[i]^(+1) -1 shift[i]^(+2)) / (4 spacing[i]), +mathematica code 4, (-1 shift[i]^(-3) +6 shift[i]^(-2) -21 shift[i]^(-1 )+0 shift[i]^( 0) +21 shift[i]^(+1) +mathematica code -6 shift[i]^(+2) +1 shift[i]^(+3)) / (24 spacing[i]), +mathematica code 6, (+1 shift[i]^(-4) -8 shift[i]^(-3) +32 shift[i]^(-2) -104 shift[i]^(-1) +0 shift[i]^( 0) +mathematica code +104 shift[i]^(+1) -32 shift[i]^(+2) +8 shift[i]^(+3) -1 shift[i]^(+4)) / (120 spacing[i]), +mathematica code 8, (-3 shift[i]^(-5) +30 shift[i]^(-4) -145 shift[i]^(-3) +480 shift[i]^(-2) -1470 shift[i]^(-1) +mathematica code +0 shift[i]^( 0) +1470 shift[i]^(+1) -480 shift[i]^(+2) +145 shift[i]^(+3) -30 shift[i]^(+4) +mathematica code +3 shift[i]^(+5)) / (1680 spacing[i])], +mathematica blank +mathematica code PDupwindNthSymm[i] -> Switch[fdOrder, +mathematica code 2, (-1 shift[i]^(-2) +4 shift[i]^(-1) -6 shift[i]^( 0) +4 shift[i]^(+1) -1 shift[i]^(+2)) / (4 spacing[i]), +mathematica code 4, (+1 shift[i]^(-3) -6 shift[i]^(-2) +15 shift[i]^(-1) -20 shift[i]^( 0) +15 shift[i]^(+1) +mathematica code -6 shift[i]^(+2) +1 shift[i]^(+3)) / (24 spacing[i]), +mathematica code 6, (-1 shift[i]^(-4) +8 shift[i]^(-3) - 28 shift[i]^(-2)+56 shift[i]^(-1)-70 shift[i]^( 0) +mathematica code +56 shift[i]^(+1) -28 shift[i]^(+2) +8 shift[i]^(+3) -1 shift[i]^(+4)) / (120 spacing[i]), +mathematica code 8, (+3 shift[i]^(-5) -30 shift[i]^(-4) +135 shift[i]^(-3) -360 shift[i]^(-2) +630 shift[i]^(-1) +mathematica code -756 shift[i]^( 0) +630 shift[i]^(+1) -360 shift[i]^(+2) +135 shift[i]^(+3) -30 shift[i]^(+4) +mathematica code +3 shift[i]^(+5)) / (1680 spacing[i])], +mathematica blank +mathematica comment (* TODO: make these higher order stencils *) +mathematica code PDonesided[i] -> dir[i] (-1 + shift[i]^dir[i]) / spacing[i]} /. i->j, {j,1,3}],1] +mathematica code }; +mathematica blank +mathematica code PD = PDstandardNth; +mathematica code PDu = PDupwindNth; +mathematica code PDua = PDupwindNthAnti; +mathematica code PDus = PDupwindNthSymm; +mathematica comment (* PDo = PDonesided; *) +mathematica code PDdiss = PDdissipationNth; +mathematica blank +mathematica code If [splitUpwindDerivs, +mathematica code Upwind[dir_, var_, idx_] := dir PDua[var,idx] + Abs[dir] PDus[var,idx], +mathematica code Upwind[dir_, var_, idx_] := dir PDu[var,idx]]; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Tensors *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica comment (* Register the tensor quantities with the TensorTools package *) +mathematica code Map [DefineTensor, +mathematica code {normal, tangentA, tangentB, dir, +mathematica code nn, nu, nlen, nlen2, su, vg, +mathematica code xx, rr, th, ph, +mathematica code admg, admK, admalpha, admdtalpha, admbeta, admdtbeta, H, M, +mathematica code g, detg, gu, G, R, trR, Km, trK, cdphi, cdphi2, +mathematica code phi, gt, At, Xt, Xtn, Theta, Z, +mathematica code alpha, A, beta, B, Atm, Atu, trA, Ats, trAts, +mathematica code dottrK, dotXt, +mathematica code cXt, cS, cA, +mathematica code e4phi, em4phi, ddetg, detgt, gtu, ddetgt, dgtu, ddgtu, Gtl, Gtlu, Gt, +mathematica code Rt, Rphi, gK, +mathematica code T00, T0, T, rho, S, +mathematica code x, y, z, r, +mathematica code epsdiss}]; +mathematica blank +mathematica comment (* NOTE: It seems as if Lie[.,.] did not take these tensor weights +mathematica comment into account. Presumably, CD[.,.] and CDt[.,.] don't do this either. *) +mathematica code SetTensorAttribute[phi, TensorWeight, +1/6]; +mathematica code SetTensorAttribute[gt, TensorWeight, -2/3]; +mathematica code SetTensorAttribute[Xt, TensorWeight, +2/3]; +mathematica code SetTensorAttribute[At, TensorWeight, -2/3]; +mathematica code SetTensorAttribute[cXt, TensorWeight, +2/3]; +mathematica code SetTensorAttribute[cS, TensorWeight, +2 ]; +mathematica blank +mathematica code Map [AssertSymmetricIncreasing, +mathematica code {admg[la,lb], admK[la,lb], g[la,lb], K[la,lb], R[la,lb], cdphi2[la,lb], +mathematica code gt[la,lb], At[la,lb], Ats[la,lb], Rt[la,lb], Rphi[la,lb], T[la,lb]}]; +mathematica code AssertSymmetricIncreasing [G[ua,lb,lc], lb, lc]; +mathematica code AssertSymmetricIncreasing [Gtl[la,lb,lc], lb, lc]; +mathematica code AssertSymmetricIncreasing [Gt[ua,lb,lc], lb, lc]; +mathematica code AssertSymmetricIncreasing [gK[la,lb,lc], la, lb]; +mathematica code Map [AssertSymmetricIncreasing, +mathematica code {gu[ua,ub], gtu[ua,ub], Atu[ua,ub]}]; +mathematica code AssertSymmetricIncreasing [dgtu[ua,ub,lc], ua, ub]; +mathematica code AssertSymmetricIncreasing [ddgtu[ua,ub,lc,ld], ua, ub]; +mathematica code AssertSymmetricIncreasing [ddgtu[ua,ub,lc,ld], lc, ld]; +mathematica blank +mathematica code DefineConnection [CD, PD, G]; +mathematica code DefineConnection [CDt, PD, Gt]; +mathematica blank +mathematica comment (* Use the CartGrid3D variable names *) +mathematica code x1=x; x2=y; x3=z; +mathematica blank +mathematica comment (* Use the ADMBase variable names *) +mathematica code admg11=gxx; admg12=gxy; admg22=gyy; admg13=gxz; admg23=gyz; admg33=gzz; +mathematica code admK11=kxx; admK12=kxy; admK22=kyy; admK13=kxz; admK23=kyz; admK33=kzz; +mathematica code admalpha=alp; +mathematica code admdtalpha=dtalp; +mathematica code admbeta1=betax; admbeta2=betay; admbeta3=betaz; +mathematica code admdtbeta1=dtbetax; admdtbeta2=dtbetay; admdtbeta3=dtbetaz; +mathematica blank +mathematica comment (* Use the TmunuBase variable names *) +mathematica code T00=eTtt; +mathematica code T01=eTtx; T02=eTty; T03=eTtz; +mathematica code T11=eTxx; T12=eTxy; T22=eTyy; T13=eTxz; T23=eTyz; T33=eTzz; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Expressions *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica comment (* enum constants for conformalMethod; these must be consistent +mathematica comment with the definition of the Cactus parameter conformalMethod *) +mathematica code CMphi = 0; +mathematica code CMW = 1; +mathematica blank +mathematica code detgExpr = Det [MatrixOfComponents [g [la,lb]]]; +mathematica code ddetgExpr[la_] = +mathematica code Sum [D[Det[MatrixOfComponents[g[la, lb]]], X] PD[X, la], +mathematica code {X, Union[Flatten[MatrixOfComponents[g[la, lb]]]]}]; +mathematica blank +mathematica code detgtExpr = Det [MatrixOfComponents [gt[la,lb]]]; +mathematica code ddetgtExpr[la_] = +mathematica code Sum [D[Det[MatrixOfComponents[gt[la, lb]]], X] PD[X, la], +mathematica code {X, Union[Flatten[MatrixOfComponents[gt[la, lb]]]]}]; +mathematica blank +mathematica code etaExpr = SpatialBetaDriverRadius / Max [r, SpatialBetaDriverRadius]; +mathematica code thetaExpr = Min [Exp [1 - r / SpatialShiftGammaCoeffRadius], 1]; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Groups *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code evolvedGroups = +mathematica code {SetGroupName [CreateGroupFromTensor [phi ], prefix <> "log_confac"], +mathematica code SetGroupName [CreateGroupFromTensor [gt[la,lb]], prefix <> "metric" ], +mathematica code SetGroupName [CreateGroupFromTensor [Xt[ua] ], prefix <> "Gamma" ], +mathematica code SetGroupName [CreateGroupFromTensor [trK ], prefix <> "trace_curv"], +mathematica code SetGroupName [CreateGroupFromTensor [At[la,lb]], prefix <> "curv" ], +mathematica code SetGroupName [CreateGroupFromTensor [alpha ], prefix <> "lapse" ], +mathematica code SetGroupName [CreateGroupFromTensor [A ], prefix <> "dtlapse" ], +mathematica code SetGroupName [CreateGroupFromTensor [beta[ua] ], prefix <> "shift" ], +mathematica code SetGroupName [CreateGroupFromTensor [B[ua] ], prefix <> "dtshift" ], +mathematica code IfCCZ4[SetGroupName[CreateGroupFromTensor[Theta], prefix <> "Theta"]]}; +mathematica code evaluatedGroups = +mathematica code {SetGroupName [CreateGroupFromTensor [H ], prefix <> "Ham"], +mathematica code SetGroupName [CreateGroupFromTensor [M[la] ], prefix <> "mom"], +mathematica code SetGroupName [CreateGroupFromTensor [cS ], prefix <> "cons_detg"], +mathematica code SetGroupName [CreateGroupFromTensor [cXt[ua]], prefix <> "cons_Gamma"], +mathematica code SetGroupName [CreateGroupFromTensor [cA ], prefix <> "cons_traceA"]}; +mathematica blank +mathematica code declaredGroups = Join [evolvedGroups, evaluatedGroups]; +mathematica code declaredGroupNames = Map [First, declaredGroups]; +mathematica blank +mathematica blank +mathematica blank +mathematica code extraGroups = +mathematica code {{"grid::coordinates", {x, y, z, r}}, +mathematica code {"ADMBase::metric", {gxx, gxy, gxz, gyy, gyz, gzz}}, +mathematica code {"ADMBase::curv", {kxx, kxy, kxz, kyy, kyz, kzz}}, +mathematica code {"ADMBase::lapse", {alp}}, +mathematica code {"ADMBase::dtlapse", {dtalp}}, +mathematica code {"ADMBase::shift", {betax, betay, betaz}}, +mathematica code {"ADMBase::dtshift", {dtbetax, dtbetay, dtbetaz}}, +mathematica code {"TmunuBase::stress_energy_scalar", {eTtt}}, +mathematica code {"TmunuBase::stress_energy_vector", {eTtx, eTty, eTtz}}, +mathematica code {"TmunuBase::stress_energy_tensor", {eTxx, eTxy, eTxz, eTyy, eTyz, eTzz}} +mathematica code }; +mathematica blank +mathematica code groups = Join [declaredGroups, extraGroups]; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Initial data *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code initialCalc = +mathematica code { +mathematica code Name -> thorn <> "_Minkowski", +mathematica code Schedule -> {"IN ADMBase_InitialData"}, +mathematica code ConditionalOnKeyword -> {"my_initial_data", "Minkowski"}, +mathematica code Equations -> +mathematica code { +mathematica code phi -> IfThen[conformalMethod==CMW, 1, 0], +mathematica code gt[la,lb] -> KD[la,lb], +mathematica code trK -> 0, +mathematica code At[la,lb] -> 0, +mathematica code Xt[ua] -> 0, +mathematica code alpha -> 1, +mathematica code A -> 0, +mathematica code beta[ua] -> 0, +mathematica code B[ua] -> 0, +mathematica code IfCCZ4[Theta -> 0] +mathematica code } +mathematica code }; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Split a calculation *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code PartialCalculation[calc_, suffix_, updates_, evolVars_] := +mathematica code Module[ +mathematica code {name, calc1, replaces, calc2, vars, patterns, eqs, calc3}, +mathematica comment (* Add suffix to name *) +mathematica code name = lookup[calc, Name] <> suffix; +mathematica code calc1 = mapReplace[calc, Name, name]; +mathematica comment (* Replace some entries in the calculation *) +mathematica comment (* replaces = Map[Function[rule, mapReplace[#, rule[[1]], rule[[2]]]&], updates]; *) +mathematica code replaces = updates //. (lhs_ -> rhs_) -> (mapReplace[#, lhs, rhs]&); +mathematica code calc2 = Apply[Composition, replaces][calc1]; +mathematica comment (* Remove unnecessary equations *) +mathematica code vars = Join[evolVars, lookup[calc2, Shorthands]]; +mathematica code patterns = Replace[vars, { Tensor[n_,__] -> Tensor[n,__] , +mathematica code dot[Tensor[n_,__]] -> dot[Tensor[n,__]]}, 1]; +mathematica code eqs = FilterRules[lookup[calc, Equations], patterns]; +mathematica code calc3 = mapReplace[calc2, Equations, eqs]; +mathematica code calc3 +mathematica code ]; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Convert from ADMBase *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code convertFromADMBaseCalc = +mathematica code { +mathematica code Name -> thorn <> "_convertFromADMBase", +mathematica code Schedule -> {"AT initial AFTER ADMBase_PostInitial"}, +mathematica code ConditionalOnKeyword -> {"my_initial_data", "ADMBase"}, +mathematica code Shorthands -> {g[la,lb], detg, gu[ua,ub], em4phi}, +mathematica code Equations -> +mathematica code { +mathematica code g[la,lb] -> admg[la,lb], +mathematica code detg -> detgExpr, +mathematica code gu[ua,ub] -> 1/detg detgExpr MatrixInverse [g[ua,ub]], +mathematica blank +mathematica code phi -> IfThen[conformalMethod==CMW, detg^(-1/6), Log[detg]/12], +mathematica code em4phi -> IfThen[conformalMethod==CMW, phi^2, Exp[-4 phi]], +mathematica code gt[la,lb] -> em4phi g[la,lb], +mathematica blank +mathematica code trK -> gu[ua,ub] admK[la,lb], +mathematica code At[la,lb] -> em4phi (admK[la,lb] - (1/3) g[la,lb] trK), +mathematica blank +mathematica code alpha -> admalpha, +mathematica blank +mathematica code beta[ua] -> admbeta[ua], +mathematica blank +mathematica code IfCCZ4[Theta -> 0] +mathematica code } +mathematica code }; +mathematica blank +mathematica code convertFromADMBaseGammaCalc = +mathematica code { +mathematica code Name -> thorn <> "_convertFromADMBaseGamma", +mathematica code Schedule -> {"AT initial AFTER " <> thorn <> "_convertFromADMBase"}, +mathematica code ConditionalOnKeyword -> {"my_initial_data", "ADMBase"}, +mathematica comment (* +mathematica comment Where -> InteriorNoSync, +mathematica comment *) +mathematica comment (* Do not synchronise right after this routine; instead, synchronise +mathematica comment after extrapolating *) +mathematica code Where -> Interior, +mathematica comment (* Synchronise after this routine, so that the refinement boundaries +mathematica comment are set correctly before extrapolating. (We will need to +mathematica comment synchronise again after extrapolating because extrapolation does +mathematica comment not fill ghost zones, but this is irrelevant here.) *) +mathematica code Shorthands -> {dir[ua], +mathematica code detgt, gtu[ua,ub], Gt[ua,lb,lc], theta}, +mathematica code Equations -> +mathematica code { +mathematica code dir[ua] -> Sign[beta[ua]], +mathematica blank +mathematica code detgt -> 1 (* detgtExpr *), +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica code Gt[ua,lb,lc] -> 1/2 gtu[ua,ud] +mathematica code (PD[gt[lb,ld],lc] + PD[gt[lc,ld],lb] - PD[gt[lb,lc],ld]), +mathematica code Xt[ua] -> gtu[ub,uc] Gt[ua,lb,lc], +mathematica blank +mathematica comment (* +mathematica comment A -> - admdtalpha / (harmonicF alpha^harmonicN) (LapseAdvectionCoeff - 1), +mathematica comment *) +mathematica comment (* If LapseACoeff=0, then A is not evolved, in the sense that it +mathematica comment does not influence the time evolution of other variables. *) +mathematica code A -> IfThen [LapseACoeff != 0, +mathematica code 1 / (- harmonicF alpha^harmonicN) +mathematica code (+ admdtalpha +mathematica code - LapseAdvectionCoeff Upwind[beta[ua], alpha, la]), +mathematica code 0], +mathematica blank +mathematica code theta -> thetaExpr, +mathematica blank +mathematica comment (* If ShiftBCoeff=0 or theta ShiftGammaCoeff=0, then B^i is not +mathematica comment evolved, in the sense that it does not influence the time +mathematica comment evolution of other variables. *) +mathematica code B[ua] -> IfThen [ShiftGammaCoeff ShiftBCoeff != 0, +mathematica code 1 / (theta ShiftGammaCoeff) +mathematica code (+ admdtbeta[ua] +mathematica code - ShiftAdvectionCoeff Upwind[beta[ub], beta[ua], lb]), +mathematica code 0] +mathematica code } +mathematica code }; +mathematica blank +mathematica comment (* Initialise the Gamma variables to 0. This is necessary with +mathematica comment multipatch because convertFromADMBaseGamma does not perform the +mathematica comment conversion in the boundary points, and the order in which symmetry +mathematica comment (interpatch) and outer boundary conditions is applied means that +mathematica comment points which are both interpatch and symmetry points are never +mathematica comment initialised. *) +mathematica code initGammaCalc = +mathematica code { +mathematica code Name -> thorn <> "_InitGamma", +mathematica code Schedule -> {"AT initial BEFORE " <> thorn <> "_convertFromADMBaseGamma"}, +mathematica code ConditionalOnKeyword -> {"my_initial_data", "ADMBase"}, +mathematica code Where -> Everywhere, +mathematica code Equations -> +mathematica code { +mathematica code Xt[ua] -> 0, +mathematica code A -> 0, +mathematica code B[ua] -> 0 +mathematica code } +mathematica code }; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Convert to ADMBase *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code convertToADMBaseCalc = +mathematica code { +mathematica code Name -> thorn <> "_convertToADMBase", +mathematica code Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, +mathematica code Where -> Everywhere, +mathematica code Shorthands -> {e4phi}, +mathematica code Equations -> +mathematica code { +mathematica code e4phi -> IfThen[conformalMethod==CMW, 1/phi^2, Exp[4 phi]], +mathematica code admg[la,lb] -> e4phi gt[la,lb], +mathematica code admK[la,lb] -> e4phi At[la,lb] + (1/3) admg[la,lb] trK, +mathematica code admalpha -> alpha, +mathematica code admbeta[ua] -> beta[ua] +mathematica code } +mathematica code }; +mathematica blank +mathematica code convertToADMBaseDtLapseShiftCalc = +mathematica code { +mathematica code Name -> thorn <> "_convertToADMBaseDtLapseShift", +mathematica code Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, +mathematica code ConditionalOnKeyword -> {"dt_lapse_shift_method", "correct"}, +mathematica code Where -> Interior, +mathematica code Shorthands -> {dir[ua], detgt, gtu[ua,ub], eta, theta}, +mathematica code Equations -> +mathematica code { +mathematica code dir[ua] -> Sign[beta[ua]], +mathematica blank +mathematica code detgt -> 1 (* detgtExpr *), +mathematica comment (* This leads to simpler code... *) +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica blank +mathematica code eta -> etaExpr, +mathematica code theta -> thetaExpr, +mathematica blank +mathematica comment (* see RHS *) +mathematica comment (* +mathematica comment admdtalpha -> - harmonicF alpha^harmonicN +mathematica comment ((1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK) +mathematica comment + LapseAdvectionCoeff beta[ua] PDu[alpha,la], +mathematica comment *) +mathematica code admdtalpha -> - harmonicF alpha^harmonicN +mathematica code (+ LapseACoeff A +mathematica code + ((1 - LapseACoeff) +mathematica code (trK - IfCCZ4[2 Theta, 0]))) +mathematica code + LapseAdvectionCoeff Upwind[beta[ua], alpha, la], +mathematica code admdtbeta[ua] -> IfThen[harmonicShift, +mathematica code - 1/2 gtu[ua,uj] phi alpha +mathematica code (- 2 alpha PD[phi,lj] +mathematica code + 2 phi PD[alpha,lj] +mathematica code + gtu[uk,ul] phi alpha +mathematica code (PD[gt[lk,ll],lj] - 2 PD[gt[lj,lk],ll])), +mathematica comment (* else *) +mathematica code + theta ShiftGammaCoeff +mathematica code (+ ShiftBCoeff B[ua] +mathematica code + (1 - ShiftBCoeff) +mathematica code (Xt[ua] - eta BetaDriver beta[ua]))] +mathematica code + ShiftAdvectionCoeff Upwind[beta[ub], beta[ua], lb] +mathematica code } +mathematica code }; +mathematica blank +mathematica code convertToADMBaseDtLapseShiftBoundaryCalc = +mathematica code { +mathematica code Name -> thorn <> "_convertToADMBaseDtLapseShiftBoundary", +mathematica code Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, +mathematica code ConditionalOnKeyword -> {"dt_lapse_shift_method", "correct"}, +mathematica code Where -> BoundaryWithGhosts, +mathematica code Shorthands -> {detgt, gtu[ua,ub], eta, theta}, +mathematica code Equations -> +mathematica code { +mathematica code detgt -> 1 (* detgtExpr *), +mathematica comment (* This leads to simpler code... *) +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica blank +mathematica code eta -> etaExpr, +mathematica code theta -> thetaExpr, +mathematica blank +mathematica comment (* see RHS, but omit derivatives near the boundary *) +mathematica comment (* +mathematica comment admdtalpha -> - harmonicF alpha^harmonicN +mathematica comment ((1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK), +mathematica comment *) +mathematica code admdtalpha -> - harmonicF alpha^harmonicN +mathematica code (+ LapseACoeff A +mathematica code + ((1 - LapseACoeff) +mathematica code (trK - IfCCZ4[2 Theta, 0]))), +mathematica code admdtbeta[ua] -> IfThen[harmonicShift, +mathematica code 0, +mathematica comment (* else *) +mathematica code + theta ShiftGammaCoeff +mathematica code (+ ShiftBCoeff B[ua] +mathematica code + (1 - ShiftBCoeff) +mathematica code (Xt[ua] - eta BetaDriver beta[ua]))] +mathematica code } +mathematica code }; +mathematica blank +mathematica code convertToADMBaseFakeDtLapseShiftCalc = +mathematica code { +mathematica code Name -> thorn <> "_convertToADMBaseFakeDtLapseShift", +mathematica code Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, +mathematica code ConditionalOnKeyword -> {"dt_lapse_shift_method", "noLapseShiftAdvection"}, +mathematica code Where -> Everywhere, +mathematica code Shorthands -> {detgt, gtu[ua,ub], eta, theta}, +mathematica code Equations -> +mathematica code { +mathematica code detgt -> 1 (* detgtExpr *), +mathematica comment (* This leads to simpler code... *) +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica blank +mathematica code eta -> etaExpr, +mathematica code theta -> thetaExpr, +mathematica blank +mathematica comment (* see RHS, but omit derivatives everywhere (which is wrong, but +mathematica comment faster, since it does not require synchronisation or boundary +mathematica comment conditions) *) +mathematica comment (* +mathematica comment admdtalpha -> - harmonicF alpha^harmonicN +mathematica comment ((1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK), +mathematica comment *) +mathematica code admdtalpha -> - harmonicF alpha^harmonicN +mathematica code (+ LapseACoeff A +mathematica code + ((1 - LapseACoeff) +mathematica code (trK - IfCCZ4[2 Theta, 0]))), +mathematica code admdtbeta[ua] -> IfThen[harmonicShift, +mathematica code 0, +mathematica comment (* else *) +mathematica code + theta ShiftGammaCoeff +mathematica code (+ ShiftBCoeff B[ua] +mathematica code + (1 - ShiftBCoeff) +mathematica code (Xt[ua] - eta BetaDriver beta[ua]))] +mathematica code } +mathematica code }; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Evolution equations *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code evolCalc = +mathematica code { +mathematica code Name -> thorn <> "_RHS", +mathematica code Schedule -> {"IN " <> thorn <> "_evolCalcGroup"}, +mathematica comment (* +mathematica comment Where -> Interior, +mathematica comment *) +mathematica comment (* Synchronise the RHS grid functions after this routine, so that +mathematica comment the refinement boundaries are set correctly before applying the +mathematica comment radiative boundary conditions. *) +mathematica code Where -> InteriorNoSync, +mathematica code ConditionalOnKeyword -> {"RHS_split", "combined"}, +mathematica code Shorthands -> {dir[ua], +mathematica code detgt, gtu[ua,ub], +mathematica code Gt[ua,lb,lc], Gtl[la,lb,lc], Gtlu[la,lb,uc], Xtn[ua], +mathematica code Rt[la,lb], Rphi[la,lb], R[la,lb], +mathematica code Atm[ua,lb], Atu[ua,ub], +mathematica code e4phi, em4phi, cdphi[la], cdphi2[la,lb], g[la,lb], detg, +mathematica code gu[ua,ub], Ats[la,lb], trAts, eta, theta, +mathematica code rho, S[la], trS, fac1, fac2, dottrK, dotXt[ua], +mathematica code epsdiss[ua], IfCCZ4[Z[ua]], IfCCZ4[dotTheta]}, +mathematica code Equations -> +mathematica code { +mathematica code dir[ua] -> Sign[beta[ua]], +mathematica blank +mathematica code detgt -> 1 (* detgtExpr *), +mathematica blank +mathematica comment (* This leads to simpler code... *) +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica code Gtl[la,lb,lc] -> 1/2 +mathematica code (PD[gt[lb,la],lc] + PD[gt[lc,la],lb] - PD[gt[lb,lc],la]), +mathematica code Gtlu[la,lb,uc] -> gtu[uc,ud] Gtl[la,lb,ld], +mathematica code Gt[ua,lb,lc] -> gtu[ua,ud] Gtl[ld,lb,lc], +mathematica blank +mathematica comment (* The conformal connection functions calculated from the conformal metric, +mathematica comment used instead of Xt where no derivatives of Xt are taken *) +mathematica code Xtn[ui] -> gtu[uj,uk] Gt[ui,lj,lk], +mathematica blank +mathematica code e4phi -> IfThen[conformalMethod==CMW, 1/phi^2, Exp[4 phi]], +mathematica code em4phi -> 1 / e4phi, +mathematica code g[la,lb] -> e4phi gt[la,lb], +mathematica code detg -> detgExpr, +mathematica code gu[ua,ub] -> em4phi gtu[ua,ub], +mathematica blank +mathematica comment (* The Z quantities *) +mathematica comment (* gr-qc:1106.2254 (2011), eqn. (23) *) +mathematica code IfCCZ4[ +mathematica code Z[ud] -> (1/2) gu[ua,ud] (- PD[gt[la,lb],lc] gtu[ub,uc] + gt[la,lc] Xt[uc]) +mathematica code ], +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (18) *) +mathematica comment (* Adding Z term by changing Xtn to Xt *) +mathematica code Rt[li,lj] -> - (1/2) gtu[ul,um] PD[gt[li,lj],ll,lm] +mathematica code + (1/2) gt[lk,li] PD[Xt[uk],lj] +mathematica code + (1/2) gt[lk,lj] PD[Xt[uk],li] +mathematica code + (1/2) Xtn[uk] Gtl[li,lj,lk] +mathematica code + (1/2) Xtn[uk] Gtl[lj,li,lk] +mathematica code + (+ Gt[uk,li,ll] Gtlu[lj,lk,ul] +mathematica code + Gt[uk,lj,ll] Gtlu[li,lk,ul] +mathematica code + Gt[uk,li,ll] Gtlu[lk,lj,ul]), +mathematica blank +mathematica code fac1 -> IfThen[conformalMethod==CMW, -1/(2 phi), 1], +mathematica code cdphi[la] -> fac1 CDt[phi,la], +mathematica code fac2 -> IfThen[conformalMethod==CMW, 1/(2 phi^2), 0], +mathematica code cdphi2[la,lb] -> fac1 CDt[phi,la,lb] + fac2 CDt[phi,la] CDt[phi,lb], +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (15) *) +mathematica code Rphi[li,lj] -> - 2 cdphi2[lj,li] +mathematica code - 2 gt[li,lj] gtu[ul,un] cdphi2[ll,ln] +mathematica code + 4 cdphi[li] cdphi[lj] +mathematica code - 4 gt[li,lj] gtu[ul,un] cdphi[ln] cdphi[ll], +mathematica blank +mathematica code Atm[ua,lb] -> gtu[ua,uc] At[lc,lb], +mathematica code Atu[ua,ub] -> Atm[ua,lc] gtu[ub,uc], +mathematica blank +mathematica code R[la,lb] -> Rt[la,lb] + Rphi[la,lb], +mathematica code IfCCZ4[ +mathematica code R[la,lb] -> R[la,lb] + (2/phi) (+ g[la,lc] Z[uc] PD[phi,lb] +mathematica code + g[lb,lc] Z[uc] PD[phi,la] - g[la,lb] Z[uc] PD[phi,lc]) +mathematica code + e4phi Z[uc] PD[gt[la,lb],lc] +mathematica code ], +mathematica blank +mathematica comment (* Matter terms *) +mathematica blank +mathematica comment (* rho = n^a n^b T_ab *) +mathematica code rho -> addMatter +mathematica code (1/alpha^2 (T00 - 2 beta[ui] T0[li] + beta[ui] beta[uj] T[li,lj])), +mathematica blank +mathematica comment (* S_i = -p^a_i n^b T_ab, where p^a_i = delta^a_i + n^a n_i *) +mathematica code S[li] -> addMatter (-1/alpha (T0[li] - beta[uj] T[li,lj])), +mathematica blank +mathematica comment (* trS = gamma^ij T_ij *) +mathematica code trS -> addMatter (em4phi gtu[ui,uj] T[li,lj]), +mathematica blank +mathematica comment (* RHS terms *) +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (10) *) +mathematica comment (* PRD 67 084023 (2003), eqn. (16) and (23) *) +mathematica code dot[phi] -> IfThen[conformalMethod==CMW, 1/3 phi, -1/6] +mathematica code (alpha trK - PD[beta[ua],la]), +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (9) *) +mathematica comment (* gr-qc:1106.2254 (2011), eqn. (14) *) +mathematica comment (* removing trA from Aij ensures that detg = 1 *) +mathematica code dot[gt[la,lb]] -> - 2 alpha (At[la,lb] - IfCCZ4[(1/3) At[lc,ld] gtu[uc,ud] gt[la,lb], 0]) +mathematica code + gt[la,lc] PD[beta[uc],lb] + gt[lb,lc] PD[beta[uc],la] +mathematica code - (2/3) gt[la,lb] PD[beta[uc],lc], +mathematica comment (* PRD 62, 044034 (2000), eqn. (20) *) +mathematica comment (* PRD 67 084023 (2003), eqn (26) *) +mathematica comment (* gr-qc:1106.2254 (2011), eqn. (19) *) +mathematica comment (* Adding Z terms by changing Xtn to Xt, +mathematica comment also adding extra Z and Theta terms *) +mathematica code dotXt[ui] -> - 2 Atu[ui,uj] PD[alpha,lj] +mathematica code + 2 alpha (+ Gt[ui,lj,lk] Atu[uk,uj] +mathematica code - (2/3) gtu[ui,uj] PD[trK,lj] +mathematica code + 6 Atu[ui,uj] cdphi[lj]) +mathematica code + gtu[uj,ul] PD[beta[ui],lj,ll] +mathematica code + (1/3) gtu[ui,uj] PD[beta[ul],lj,ll] +mathematica code - Xtn[uj] PD[beta[ui],lj] +mathematica code + (2/3) Xtn[ui] PD[beta[uj],lj] +mathematica code + IfCCZ4[ +mathematica code + GammaShift 2 e4phi (- Z[uj] PD[beta[ui],lj] +mathematica code + (2/3) Z[ui] PD[beta[uj],lj]) +mathematica code - (4/3) alpha e4phi Z[ui] trK +mathematica code + 2 gtu[ui,uj] (+ alpha PD[Theta,lj] +mathematica code - Theta PD[alpha,lj]) +mathematica code - 2 alpha e4phi dampk1 Z[ui], +mathematica code 0] +mathematica comment (* Equation (4.28) in Baumgarte & Shapiro (Phys. Rept. 376 (2003) 41-131) *) +mathematica code + addMatter (- 16 Pi alpha gtu[ui,uj] S[lj]), +mathematica code dot[Xt[ui]] -> dotXt[ui], +mathematica blank +mathematica comment (* gr-qc:1106.2254 (2011), eqn. (18) *) +mathematica code IfCCZ4[ +mathematica code dotTheta -> +mathematica code - PD[alpha,la] Z[ua] - dampk1 (2 + dampk2) alpha Theta +mathematica code + (1/2) alpha (gu[ua,ub] R[la,lb] - Atm[ua,lb] Atm[ub,la] + (2/3) trK^2 - 2 trK Theta) +mathematica code + addMatter (- 8 Pi alpha rho) +mathematica code ], +mathematica blank +mathematica code IfCCZ4[ +mathematica code dot[Theta] -> dotTheta +mathematica code ], +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (11) *) +mathematica comment (* gr-qc:1106.2254 (2011), eqn. (17) *) +mathematica comment (* Adding the RHS of Theta to K, because K_Z4 = K_BSSN + 2 Theta *) +mathematica comment (* Also adding the Z term, as it has to cancel with the one in Theta *) +mathematica code dottrK -> - em4phi ( gtu[ua,ub] ( PD[alpha,la,lb] +mathematica code + 2 cdphi[la] PD[alpha,lb] ) +mathematica code - Xtn[ua] PD[alpha,la] ) +mathematica code + alpha (Atm[ua,lb] Atm[ub,la] + (1/3) trK^2) +mathematica code + IfCCZ4[ +mathematica code + 2 dotTheta + 2 PD[alpha,la] Z[ua] +mathematica code + dampk1 (1 - dampk2) alpha Theta, +mathematica code 0] +mathematica comment (* Equation (4.21) in Baumgarte & Shapiro (Phys. Rept. 376 (2003) 41-131) *) +mathematica code + addMatter (4 Pi alpha (rho + trS)), +mathematica code dot[trK] -> dottrK, +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (12) *) +mathematica comment (* TODO: Should we use the Hamiltonian constraint to make Rij tracefree? *) +mathematica comment (* gr-qc:1106.2254 (2011), eqn. (15) *) +mathematica comment (* Adding Z terms in the Ricci and Theta terms *) +mathematica code Ats[la,lb] -> - CDt[alpha,la,lb] + +mathematica code + 2 (PD[alpha,la] cdphi[lb] + PD[alpha,lb] cdphi[la] ) +mathematica code + alpha R[la,lb], +mathematica code trAts -> gu[ua,ub] Ats[la,lb], +mathematica code dot[At[la,lb]] -> + em4phi (+ Ats[la,lb] - (1/3) g[la,lb] trAts ) +mathematica code + alpha (+ ((trK - IfCCZ4[2 Theta, 0]) +mathematica code At[la,lb]) +mathematica code - 2 At[la,lc] Atm[uc,lb]) +mathematica code + At[la,lc] PD[beta[uc],lb] + At[lb,lc] PD[beta[uc],la] +mathematica code - (2/3) At[la,lb] PD[beta[uc],lc] +mathematica comment (* Equation (4.23) in Baumgarte & Shapiro (Phys. Rept. 376 (2003) 41-131) *) +mathematica code + addMatter (- em4phi alpha 8 Pi +mathematica code (T[la,lb] - (1/3) g[la,lb] trS)), +mathematica blank +mathematica comment (* dot[alpha] -> - harmonicF alpha^harmonicN trK, *) +mathematica comment (* dot[alpha] -> - harmonicF alpha^harmonicN A + Lie[alpha, beta], *) +mathematica comment (* +mathematica comment dot[alpha] -> - harmonicF alpha^harmonicN ( +mathematica comment (1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK) +mathematica comment + LapseAdvectionCoeff beta[ua] PDu[alpha,la], +mathematica comment dot[A] -> (1 - LapseAdvectionCoeff) (dottrK - AlphaDriver A), +mathematica comment *) +mathematica code dot[alpha] -> - harmonicF alpha^harmonicN +mathematica code (+ LapseACoeff A +mathematica code + ((1 - LapseACoeff) +mathematica code (+ trK - IfCCZ4[2 Theta, 0] +mathematica code + AlphaDriver (alpha - 1)))), +mathematica blank +mathematica code dot[A] -> + (LapseACoeff +mathematica code (+ dottrK - IfCCZ4[2 dotTheta, 0] +mathematica code - AlphaDriver A)), +mathematica blank +mathematica code eta -> etaExpr, +mathematica code theta -> thetaExpr, +mathematica blank +mathematica comment (* dot[beta[ua]] -> eta Xt[ua], *) +mathematica comment (* dot[beta[ua]] -> ShiftGammaCoeff alpha^ShiftAlphaPower B[ua], *) +mathematica code dot[beta[ua]] -> IfThen[harmonicShift, +mathematica code - 1/2 gtu[ua,uj] phi alpha +mathematica code (- 2 alpha PD[phi,lj] +mathematica code + 2 phi PD[alpha,lj] +mathematica code + gtu[uk,ul] phi alpha +mathematica code (PD[gt[lk,ll],lj] - 2 PD[gt[lj,lk],ll])), +mathematica comment (* else *) +mathematica code + theta ShiftGammaCoeff +mathematica code (+ ShiftBCoeff B[ua] +mathematica code + (1 - ShiftBCoeff) +mathematica code (Xt[ua] - eta BetaDriver beta[ua]))], +mathematica blank +mathematica code dot[B[ua]] -> + ShiftBCoeff (dotXt[ua] - eta BetaDriver B[ua]) +mathematica comment (* Note that this dotXt[ua] is not yet \partial_t \tilde \Gamma^i, because the +mathematica comment advection term has not yet been added. It is actually +mathematica comment \partial_t \tilde \Gamma^i - \beta^j \partial_j \tilde \Gamma^i *) +mathematica code } +mathematica code }; +mathematica blank +mathematica code advectCalc = +mathematica code { +mathematica code Name -> thorn <> "_Advect", +mathematica code Schedule -> {"IN " <> thorn <> "_evolCalcGroup " <> +mathematica code "AFTER (" <> thorn <> "_RHS " <> thorn <> "_RHS1 " <> thorn <> "_RHS2)"}, +mathematica comment (* +mathematica comment Where -> Interior, +mathematica comment *) +mathematica comment (* Synchronise the RHS grid functions after this routine, so that +mathematica comment the refinement boundaries are set correctly before applying the +mathematica comment radiative boundary conditions. *) +mathematica code Where -> InteriorNoSync, +mathematica code ConditionalOnKeyword -> {"advection_split", "combined"}, +mathematica code Shorthands -> {dir[ua]}, +mathematica code Equations -> +mathematica code { +mathematica code dir[ua] -> Sign[beta[ua]], +mathematica blank +mathematica code dot[phi] -> dot[phi] + Upwind[beta[ua], phi, la], +mathematica blank +mathematica code dot[gt[la,lb]] -> dot[gt[la,lb]] + Upwind[beta[uc], gt[la,lb], lc], +mathematica blank +mathematica code dot[Xt[ui]] -> dot[Xt[ui]] + Upwind[beta[uj], Xt[ui], lj], +mathematica blank +mathematica code IfCCZ4[ +mathematica code dot[Theta] -> dot[Theta] + Upwind[beta[ua], Theta, la] +mathematica code ], +mathematica blank +mathematica code dot[trK] -> dot[trK] + Upwind[beta[ua], trK, la], +mathematica blank +mathematica code dot[At[la,lb]] -> dot[At[la,lb]] + Upwind[beta[uc], At[la,lb], lc], +mathematica blank +mathematica code dot[alpha] -> dot[alpha] +mathematica code + LapseAdvectionCoeff Upwind[beta[ua], alpha, la], +mathematica blank +mathematica code dot[A] -> dot[A] +mathematica code + LapseACoeff ( +mathematica code + LapseAdvectionCoeff Upwind[beta[ua], A, la] +mathematica code + (1 - LapseAdvectionCoeff) Upwind[beta[ua], trK, la]), +mathematica blank +mathematica code dot[beta[ua]] -> dot[beta[ua]] +mathematica code + ShiftAdvectionCoeff Upwind[beta[ub], beta[ua], lb], +mathematica blank +mathematica code dot[B[ua]] -> dot[B[ua]] +mathematica code + ShiftBCoeff ( +mathematica code + ShiftAdvectionCoeff Upwind[beta[ub], B[ua], lb] +mathematica code + ((1 - ShiftAdvectionCoeff) +mathematica code Upwind[beta[ub], Xt[ua], lb])) +mathematica comment (* Note that the advection term \beta^j \partial_j \tilde \Gamma^i is not +mathematica comment subtracted here when ShiftAdvectionCoefficient == 1 because it was +mathematica comment implicitly subtracted before (see comment in previous calculation of +mathematica comment dot[B[ua]]. *) +mathematica code } +mathematica code }; +mathematica blank +mathematica code varsNames = { +mathematica code {"phi", dot[phi]}, +mathematica code {"gt", dot[gt[la,lb]]}, +mathematica code {"Xt", dot[Xt[ui]]}, +mathematica code {"trK", dot[trK]}, +mathematica code {"At", dot[At[la,lb]]}, +mathematica code {"alpha", dot[alpha]}, +mathematica code {"A", dot[A]}, +mathematica code {"beta", dot[beta[ua]]}, +mathematica code {"B", dot[B[ua]]}, +mathematica code IfCCZ4[{"Theta", dot[Theta]}] +mathematica code }; +mathematica blank +mathematica code advectCalcs = Map[ +mathematica code PartialCalculation[advectCalc, "_"<>ToString[First[#]], +mathematica code {ConditionalOnKeyword -> {"advection_split", +mathematica code "per variable"}}, +mathematica code {Last[#]}]&, +mathematica code varsNames]; +mathematica blank +mathematica code evolCalc1 = PartialCalculation[evolCalc, "1", +mathematica code { +mathematica code ConditionalOnKeyword -> {"RHS_split", "split At"} +mathematica code }, +mathematica code { +mathematica code dot[phi], +mathematica code dot[gt[la,lb]], +mathematica code dot[Xt[ui]], +mathematica code dot[trK], +mathematica code dot[alpha], +mathematica code dot[A], +mathematica code dot[beta[ua]], +mathematica code dot[B[ua]], +mathematica code IfCCZ4[dot[Theta]] +mathematica code }]; +mathematica blank +mathematica code evolCalc2 = PartialCalculation[evolCalc, "2", +mathematica code { +mathematica code ConditionalOnKeyword -> {"RHS_split", "split At"} +mathematica code }, +mathematica code { +mathematica code dot[At[la,lb]] +mathematica code }]; +mathematica blank +mathematica code dissCalc = +mathematica code { +mathematica code Name -> thorn <> "_Dissipation", +mathematica code Schedule -> {"IN " <> thorn <> "_evolCalcGroup " <> +mathematica code "AFTER (" <> thorn <> "_RHS1 " <> thorn <> "_RHS2)"}, +mathematica code ConditionalOnKeyword -> {"apply_dissipation", "always"}, +mathematica code Where -> InteriorNoSync, +mathematica code Shorthands -> {epsdiss[ua]}, +mathematica code Equations -> +mathematica code { +mathematica code epsdiss[ua] -> EpsDiss, +mathematica code Sequence@@Table[ +mathematica code dot[var] -> dot[var] + epsdiss[ux] PDdiss[var,lx], +mathematica code {var, {phi, gt[la,lb], Xt[ui], IfCCZ4[Theta], trK, At[la,lb], +mathematica code alpha, A, beta[ua], B[ua]}}] +mathematica code } +mathematica code }; +mathematica blank +mathematica code dissCalcs = +mathematica code Table[ +mathematica code { +mathematica code Name -> thorn <> "_Dissipation_" <> ToString[var /. {Tensor[n_,__] -> n}], +mathematica code Schedule -> {"IN " <> thorn <> "_evolCalcGroup " <> +mathematica code "AFTER (" <> thorn <> "_RHS1 " <> thorn <> "_RHS2)"}, +mathematica code ConditionalOnKeyword -> {"apply_dissipation", "always"}, +mathematica code Where -> InteriorNoSync, +mathematica code Shorthands -> {epsdiss[ua]}, +mathematica code Equations -> +mathematica code { +mathematica code epsdiss[ua] -> EpsDiss, +mathematica code dot[var] -> dot[var] + epsdiss[ux] PDdiss[var,lx] +mathematica code } +mathematica code }, +mathematica code {var, {phi, gt[la,lb], Xt[ui], IfCCZ4[Theta], trK, At[la,lb], +mathematica code alpha, A, beta[ua], B[ua]}} +mathematica code ]; +mathematica blank +mathematica code RHSStaticBoundaryCalc = +mathematica code { +mathematica code Name -> thorn <> "_RHSStaticBoundary", +mathematica code Schedule -> {"IN MoL_CalcRHS"}, +mathematica code ConditionalOnKeyword -> {"my_rhs_boundary_condition", "static"}, +mathematica code Where -> Boundary, +mathematica code Equations -> +mathematica code { +mathematica code dot[phi] -> 0, +mathematica code dot[gt[la,lb]] -> 0, +mathematica code dot[trK] -> 0, +mathematica code dot[At[la,lb]] -> 0, +mathematica code dot[Xt[ua]] -> 0, +mathematica code dot[alpha] -> 0, +mathematica code dot[A] -> 0, +mathematica code dot[beta[ua]] -> 0, +mathematica code dot[B[ua]] -> 0, +mathematica code IfCCZ4[dot[Theta] -> 0] +mathematica code } +mathematica code }; +mathematica blank +mathematica comment (* Initialise the RHS variables in analysis in case they are going to +mathematica comment be output - the noninterior points cannot be filled, so we define +mathematica comment them to be zero *) +mathematica code initRHSCalc = +mathematica code { +mathematica code Name -> thorn <> "_InitRHS", +mathematica code Schedule -> {"AT analysis BEFORE " <> thorn <> "_evolCalcGroup"}, +mathematica code Where -> Everywhere, +mathematica code Equations -> +mathematica code { +mathematica code dot[phi] -> 0, +mathematica code dot[gt[la,lb]] -> 0, +mathematica code dot[trK] -> 0, +mathematica code dot[At[la,lb]] -> 0, +mathematica code dot[Xt[ua]] -> 0, +mathematica code dot[alpha] -> 0, +mathematica code dot[A] -> 0, +mathematica code dot[beta[ua]] -> 0, +mathematica code dot[B[ua]] -> 0, +mathematica code IfCCZ4[dot[Theta] -> 0] +mathematica code } +mathematica code }; +mathematica blank +mathematica code RHSRadiativeBoundaryCalc = +mathematica code { +mathematica code Name -> thorn <> "_RHSRadiativeBoundary", +mathematica code Schedule -> {"IN MoL_CalcRHS"}, +mathematica code ConditionalOnKeyword -> {"my_rhs_boundary_condition", "radiative"}, +mathematica code Where -> Boundary, +mathematica code Shorthands -> {dir[ua], +mathematica code detgt, gtu[ua,ub], em4phi, gu[ua,ub], +mathematica code nn[la], nu[ua], nlen, nlen2, su[ua], +mathematica code vg}, +mathematica code Equations -> +mathematica code { +mathematica code dir[ua] -> Sign[normal[ua]], +mathematica blank +mathematica code detgt -> 1 (* detgtExpr *), +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica code em4phi -> IfThen[conformalMethod==CMW, phi^2, Exp[-4 phi]], +mathematica code gu[ua,ub] -> em4phi gtu[ua,ub], +mathematica blank +mathematica code nn[la] -> Euc[la,lb] normal[ub], +mathematica code nu[ua] -> gu[ua,ub] nn[lb], +mathematica code nlen2 -> nu[ua] nn[la], +mathematica code nlen -> Sqrt[nlen2], +mathematica code su[ua] -> nu[ua] / nlen, +mathematica blank +mathematica code vg -> Sqrt[harmonicF], +mathematica blank +mathematica code dot[phi] -> - vg su[uc] PDo[phi ,lc], +mathematica code dot[gt[la,lb]] -> - su[uc] PDo[gt[la,lb],lc], +mathematica code dot[trK] -> - vg su[uc] PDo[trK ,lc], +mathematica code dot[At[la,lb]] -> - su[uc] PDo[At[la,lb],lc], +mathematica code dot[Xt[ua]] -> - su[uc] PDo[Xt[ua] ,lc], +mathematica code dot[alpha] -> - vg su[uc] PDo[alpha ,lc], +mathematica code dot[A] -> - vg su[uc] PDo[A ,lc], +mathematica code dot[beta[ua]] -> - su[uc] PDo[beta[ua] ,lc], +mathematica code dot[B[ua]] -> - su[uc] PDo[B[ua] ,lc], +mathematica code IfCCZ4[ +mathematica code dot[Theta] -> - vg su[uc] PDo[Theta ,lc] +mathematica code ] +mathematica code } +mathematica code }; +mathematica blank +mathematica code enforceCalc = +mathematica code { +mathematica code Name -> thorn <> "_enforce", +mathematica code Schedule -> {"IN MoL_PostStepModify"}, +mathematica code Shorthands -> {detgt, gtu[ua,ub], trAt}, +mathematica code Equations -> +mathematica code { +mathematica comment (* The following comment is still interesting, but is not correct +mathematica comment any more since it is now scheduled in MoL_PostStepModify instead: +mathematica blank +mathematica comment Enforcing the constraints needs to be a projection, because it +mathematica comment is applied in MoL_PostStep and may thus be applied multiple +mathematica comment times, not only during time evolution. Therefore detgt has to +mathematica comment be calculated correctly, without assuming that det gt_ij = 1, +mathematica comment which is not always the case (since we don't enforce it). On +mathematica comment the other hand, this may not be so important... *) +mathematica code detgt -> 1 (* detgtExpr *), +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica blank +mathematica code trAt -> gtu[ua,ub] At[la,lb], +mathematica blank +mathematica code At[la,lb] -> At[la,lb] - (1/3) gt[la,lb] trAt, +mathematica blank +mathematica code alpha -> Max[alpha, MinimumLapse] +mathematica code } +mathematica code }; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Boundary conditions *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code boundaryCalc = +mathematica code { +mathematica code Name -> thorn <> "_boundary", +mathematica code Schedule -> {"IN MoL_PostStep"}, +mathematica code ConditionalOnKeyword -> {"my_boundary_condition", "Minkowski"}, +mathematica code Where -> BoundaryWithGhosts, +mathematica code Equations -> +mathematica code { +mathematica code phi -> IfThen[conformalMethod==CMW, 1, 0], +mathematica code gt[la,lb] -> KD[la,lb], +mathematica code trK -> 0, +mathematica code At[la,lb] -> 0, +mathematica code Xt[ua] -> 0, +mathematica code alpha -> 1, +mathematica code A -> 0, +mathematica code beta[ua] -> 0, +mathematica code B[ua] -> 0, +mathematica code IfCCZ4[Theta -> 0] +mathematica code } +mathematica code }; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Constraint equations *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code constraintsCalc = +mathematica code { +mathematica code Name -> thorn <> "_constraints", +mathematica code Schedule -> Automatic, +mathematica code After -> "MoL_PostStep", +mathematica code Where -> Interior, +mathematica code Shorthands -> {detgt, ddetgt[la], gtu[ua,ub], Z[ua], +mathematica code Gt[ua,lb,lc], Gtl[la,lb,lc], Gtlu[la,lb,uc], Xtn[ua], +mathematica code e4phi, em4phi, +mathematica code g[la,lb], detg, gu[ua,ub], ddetg[la], G[ua,lb,lc], +mathematica code Rt[la,lb], Rphi[la,lb], R[la,lb], trR, Atm[ua,lb], +mathematica code gK[la,lb,lc], cdphi[la], cdphi2[la,lb], +mathematica code rho, S[la], fac1, fac2}, +mathematica code Equations -> +mathematica code { +mathematica code detgt -> 1 (* detgtExpr *), +mathematica code ddetgt[la] -> 0 (* ddetgtExpr[la] *), +mathematica blank +mathematica comment (* This leads to simpler code... *) +mathematica code gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], +mathematica code Gtl[la,lb,lc] -> 1/2 +mathematica code (PD[gt[lb,la],lc] + PD[gt[lc,la],lb] - PD[gt[lb,lc],la]), +mathematica code Gtlu[la,lb,uc] -> gtu[uc,ud] Gtl[la,lb,ld], +mathematica code Gt[ua,lb,lc] -> gtu[ua,ud] Gtl[ld,lb,lc], +mathematica blank +mathematica comment (* The conformal connection functions calculated from the conformal metric, +mathematica comment used instead of Xt where no derivatives of Xt are taken *) +mathematica code Xtn[ui] -> gtu[uj,uk] Gt[ui,lj,lk], +mathematica blank +mathematica code e4phi -> IfThen[conformalMethod==CMW, 1/phi^2, Exp[4 phi]], +mathematica code em4phi -> 1 / e4phi, +mathematica code g[la,lb] -> e4phi gt[la,lb], +mathematica code detg -> e4phi^3, +mathematica code gu[ua,ub] -> em4phi gtu[ua,ub], +mathematica blank +mathematica comment (* The Z quantities *) +mathematica code IfCCZ4[ +mathematica code Z[ud] -> (1/2) gu[ua,ud] (- PD[gt[la,lb],lc] gtu[ub,uc] + gt[la,lc] Xt[uc]) +mathematica code ], +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (18) *) +mathematica code Rt[li,lj] -> - (1/2) gtu[ul,um] PD[gt[li,lj],ll,lm] +mathematica code + (1/2) gt[lk,li] PD[Xt[uk],lj] +mathematica code + (1/2) gt[lk,lj] PD[Xt[uk],li] +mathematica code + (1/2) Xtn[uk] Gtl[li,lj,lk] +mathematica code + (1/2) Xtn[uk] Gtl[lj,li,lk] +mathematica code + (+ Gt[uk,li,ll] Gtlu[lj,lk,ul] +mathematica code + Gt[uk,lj,ll] Gtlu[li,lk,ul] +mathematica code + Gt[uk,li,ll] Gtlu[lk,lj,ul]), +mathematica blank +mathematica comment (* From the long turducken paper. +mathematica comment This expression seems to give the same result as the one from 044034. *) +mathematica comment (* TODO: symmetrise correctly: (ij) = (1/2) [i+j] *) +mathematica comment (* +mathematica comment Rt[li,lj] -> - (1/2) gtu[uk,ul] PD[gt[li,lj],lk,ll] +mathematica comment + gt[lk,li] PD[Xt[uk],lj] + gt[lk,lj] PD[Xt[uk],li] +mathematica comment + gt[li,ln] Gt[un,lj,lk] gtu[um,ua] gtu[uk,ub] PD[gt[la,lb],lm] +mathematica comment + gt[lj,ln] Gt[un,li,lk] gtu[um,ua] gtu[uk,ub] PD[gt[la,lb],lm] +mathematica comment + gtu[ul,us] (+ 2 Gt[uk,ll,li] gt[lj,ln] Gt[un,lk,ls] +mathematica comment + 2 Gt[uk,ll,lj] gt[li,ln] Gt[un,lk,ls] +mathematica comment + Gt[uk,li,ls] gt[lk,ln] Gt[un,ll,lj]), +mathematica comment *) +mathematica blank +mathematica comment (* Below would be a straightforward calculation, +mathematica comment without taking any Gamma^i into account. +mathematica comment This expression gives a different answer! *) +mathematica comment (* +mathematica comment Rt[la,lb] -> + Gt[u1,l2,la] Gt[l1,lb,u2] - Gt[u1,la,lb] Gt[l1,l2,u2] +mathematica comment + 1/2 gtu[u1,u2] (- PD[gt[l1,l2],la,lb] + PD[gt[l1,la],l2,lb] +mathematica comment - PD[gt[la,lb],l1,l2] + PD[gt[l2,lb],l1,la]), +mathematica comment *) +mathematica blank +mathematica code fac1 -> IfThen[conformalMethod==CMW, -1/(2 phi), 1], +mathematica code cdphi[la] -> fac1 CDt[phi,la], +mathematica code fac2 -> IfThen[conformalMethod==CMW, 1/(2 phi^2), 0], +mathematica code cdphi2[la,lb] -> fac1 CDt[phi,la,lb] + fac2 CDt[phi,la] CDt[phi,lb], +mathematica blank +mathematica comment (* PRD 62, 044034 (2000), eqn. (15) *) +mathematica code Rphi[li,lj] -> - 2 cdphi2[lj,li] +mathematica code - 2 gt[li,lj] gtu[ul,un] cdphi2[ll,ln] +mathematica code + 4 cdphi[li] cdphi[lj] +mathematica code - 4 gt[li,lj] gtu[ul,un] cdphi[ln] cdphi[ll], +mathematica blank +mathematica comment (* ddetg[la] -> PD[e4phi detg,la], *) +mathematica code ddetg[la] -> e4phi ddetgt[la] + 4 detgt e4phi PD[phi,la], +mathematica comment (* TODO: check this equation, maybe simplify it by omitting ddetg *) +mathematica code G[ua,lb,lc] -> Gt[ua,lb,lc] +mathematica code + 1/(2 detg) (+ KD[ua,lb] ddetg[lc] + KD[ua,lc] ddetg[lb] +mathematica code - (1/3) g[lb,lc] gu[ua,ud] ddetg[ld]), +mathematica blank +mathematica code R[la,lb] -> + Rt[la,lb] + Rphi[la,lb], +mathematica blank +mathematica code IfCCZ4[ +mathematica code R[la,lb] -> R[la, lb] + (2/phi) (+ g[la,lc] Z[uc] PD[phi,lb] +mathematica code + g[lb,lc] Z[uc] PD[phi,la] - g[la,lb] Z[uc] PD[phi,lc]) +mathematica code + e4phi Z[uc] PD[gt[la,lb],lc] +mathematica code ], +mathematica blank +mathematica code trR -> gu[ua,ub] R[la,lb], +mathematica blank +mathematica comment (* K[la,lb] -> e4phi At[la,lb] + (1/3) g[la,lb] trK, *) +mathematica comment (* Km[ua,lb] -> gu[ua,uc] K[lc,lb], *) +mathematica code Atm[ua,lb] -> gtu[ua,uc] At[lc,lb], +mathematica blank +mathematica comment (* Matter terms *) +mathematica blank +mathematica comment (* rho = n^a n^b T_ab *) +mathematica code rho -> 1/alpha^2 (T00 - 2 beta[ui] T0[li] + beta[ui] beta[uj] T[li,lj]), +mathematica blank +mathematica comment (* S_i = -p^a_i n^b T_ab, where p^a_i = delta^a_i + n^a n_i *) +mathematica code S[li] -> -1/alpha (T0[li] - beta[uj] T[li,lj]), +mathematica blank +mathematica comment (* Constraints *) +mathematica blank +mathematica comment (* H -> trR - Km[ua,lb] Km[ub,la] + trK^2, *) +mathematica comment (* PRD 67, 084023 (2003), eqn. (19) *) +mathematica code H -> trR - Atm[ua,lb] Atm[ub,la] + (2/3) trK^2 - addMatter 16 Pi rho, +mathematica blank +mathematica comment (* gK[la,lb,lc] -> CD[K[la,lb],lc], *) +mathematica comment (* gK[la,lb,lc] -> + 4 e4phi PD[phi,lc] At[la,lb] + e4phi CD[At[la,lb],lc] +mathematica comment + (1/3) g[la,lb] PD[trK,lc], +mathematica comment M[la] -> gu[ub,uc] (gK[lc,la,lb] - gK[lc,lb,la]), *) +mathematica blank +mathematica code M[li] -> + gtu[uj,uk] (CDt[At[li,lj],lk] + 6 At[li,lj] cdphi[lk]) +mathematica code - (2/3) PD[trK,li] +mathematica code - addMatter 8 Pi S[li], +mathematica comment (* TODO: use PRD 67, 084023 (2003), eqn. (20) *) +mathematica blank +mathematica comment (* det gamma-tilde *) +mathematica code cS -> Log[detgt], +mathematica blank +mathematica comment (* Gamma constraint *) +mathematica code cXt[ua] -> gtu[ub,uc] Gt[ua,lb,lc] - Xt[ua], +mathematica blank +mathematica comment (* trace A-tilde *) +mathematica code cA -> gtu[ua,ub] At[la,lb] +mathematica code } +mathematica code }; +mathematica blank +mathematica code constraintsCalc1 = PartialCalculation[constraintsCalc, "1", +mathematica code {}, +mathematica code { +mathematica code H +mathematica code }]; +mathematica blank +mathematica code constraintsCalc2 = PartialCalculation[constraintsCalc, "2", +mathematica code {}, +mathematica code { +mathematica code M[li], +mathematica code cS, +mathematica code cXt[ua], +mathematica code cA +mathematica code }]; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Implementations *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code inheritedImplementations = +mathematica code Join[{"ADMBase"}, +mathematica code If [addMatter!=0, {"TmunuBase"}, {}]]; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Parameters *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code inheritedKeywordParameters = {}; +mathematica blank +mathematica code extendedKeywordParameters = +mathematica code { +mathematica code { +mathematica code Name -> "ADMBase::evolution_method", +mathematica code AllowedValues -> {thorn} +mathematica code }, +mathematica code { +mathematica code Name -> "ADMBase::lapse_evolution_method", +mathematica code AllowedValues -> {thorn} +mathematica code }, +mathematica code { +mathematica code Name -> "ADMBase::shift_evolution_method", +mathematica code AllowedValues -> {thorn} +mathematica code }, +mathematica code { +mathematica code Name -> "ADMBase::dtlapse_evolution_method", +mathematica code AllowedValues -> {thorn} +mathematica code }, +mathematica code { +mathematica code Name -> "ADMBase::dtshift_evolution_method", +mathematica code AllowedValues -> {thorn} +mathematica code } +mathematica code }; +mathematica blank +mathematica code keywordParameters = +mathematica code { +mathematica code { +mathematica code Name -> "my_initial_data", +mathematica comment (* Visibility -> "restricted", *) +mathematica comment (* Description -> "ddd", *) +mathematica code AllowedValues -> {"ADMBase", "Minkowski"}, +mathematica code Default -> "ADMBase" +mathematica code }, +mathematica code { +mathematica code Name -> "my_initial_boundary_condition", +mathematica code Visibility -> "restricted", +mathematica comment (* Description -> "ddd", *) +mathematica code AllowedValues -> {"none"}, +mathematica code Default -> "none" +mathematica code }, +mathematica code { +mathematica code Name -> "my_rhs_boundary_condition", +mathematica code Visibility -> "restricted", +mathematica comment (* Description -> "ddd", *) +mathematica code AllowedValues -> {"none", "static", "radiative"}, +mathematica code Default -> "none" +mathematica code }, +mathematica code { +mathematica code Name -> "my_boundary_condition", +mathematica comment (* Visibility -> "restricted", *) +mathematica comment (* Description -> "ddd", *) +mathematica code AllowedValues -> {"none", "Minkowski"}, +mathematica code Default -> "none" +mathematica code }, +mathematica code { +mathematica code Name -> "calculate_ADMBase_variables_at", +mathematica code Visibility -> "restricted", +mathematica comment (* Description -> "ddd", *) +mathematica code AllowedValues -> {"MoL_PostStep", "CCTK_EVOL", "CCTK_ANALYSIS"}, +mathematica code Default -> "MoL_PostStep" +mathematica code }, +mathematica code { +mathematica code Name -> "UseSpatialBetaDriver_UNUSED", +mathematica code Visibility -> "restricted", +mathematica comment (* Description -> "ddd", *) +mathematica code AllowedValues -> {"no", "yes"}, +mathematica code Default -> "no" +mathematica code }, +mathematica code { +mathematica code Name -> "dt_lapse_shift_method", +mathematica code Description -> "Treatment of ADMBase dtlapse and dtshift", +mathematica code AllowedValues -> {"correct", +mathematica code "noLapseShiftAdvection" (* omit lapse and shift advection terms (faster) *) +mathematica code }, +mathematica code Default -> "correct" +mathematica code }, +mathematica code { +mathematica code Name -> "apply_dissipation", +mathematica code Description -> "Whether to apply dissipation to the RHSs", +mathematica code AllowedValues -> {"always", +mathematica code "never" (* yes and no keyword values confuse Cactus, and Kranc +mathematica comment doesn't support boolean parameters *) +mathematica code }, +mathematica code Default -> "never" +mathematica code }, +mathematica code { +mathematica code Name -> "RHS_split", +mathematica code Description -> "How to split RHS calculation", +mathematica code AllowedValues -> {"combined", +mathematica code "split At"}, +mathematica code Default -> "split At" +mathematica code }, +mathematica code { +mathematica code Name -> "advection_split", +mathematica code Description -> "How to split advection calculation", +mathematica code AllowedValues -> {"combined", +mathematica code "per variable"}, +mathematica code Default -> "combined" +mathematica code } +mathematica code }; +mathematica blank +mathematica code intParameters = +mathematica code { +mathematica code { +mathematica code Name -> harmonicN, +mathematica code Description -> "d/dt alpha = - f alpha^n K (harmonic=2, 1+log=1)", +mathematica code Default -> 2 +mathematica code }, +mathematica code { +mathematica code Name -> ShiftAlphaPower, +mathematica code Default -> 0 +mathematica code }, +mathematica code { +mathematica code Name -> conformalMethod, +mathematica code Description -> "Treatment of conformal factor", +mathematica code AllowedValues -> {{Value -> "0", Description -> "phi method"}, +mathematica code {Value -> "1", Description -> "W method"}}, +mathematica code Default -> 0 +mathematica code }, +mathematica code { +mathematica code Name -> fdOrder, +mathematica code Default -> derivOrder, +mathematica code AllowedValues -> {2,4,6,8} +mathematica code }, +mathematica code { +mathematica code Name -> harmonicShift, +mathematica code Description -> "Whether to use the harmonic shift", +mathematica code AllowedValues -> {{Value -> "0", Description -> "Gamma driver shift"}, +mathematica code {Value -> "1", Description -> "Harmonic shift"}}, +mathematica code Default -> 0 +mathematica code } +mathematica code }; +mathematica blank +mathematica code realParameters = +mathematica code { +mathematica code IfCCZ4[{ +mathematica code Name -> GammaShift, +mathematica code Description -> "Covariant shift term in Gamma", +mathematica code Default -> 0.5 +mathematica code }], +mathematica code IfCCZ4[{ +mathematica code Name -> dampk1, +mathematica code Description -> "CCZ4 damping term 1 for Theta and Z", +mathematica code Default -> 0 +mathematica code }], +mathematica code IfCCZ4[{ +mathematica code Name -> dampk2, +mathematica code Description -> "CCZ4 damping term 2 for Theta and Z", +mathematica code Default -> 0 +mathematica code }], +mathematica code { +mathematica code Name -> LapseACoeff, +mathematica code Description -> "Whether to evolve A in time", +mathematica code Default -> 0 +mathematica code }, +mathematica code { +mathematica code Name -> harmonicF, +mathematica code Description -> "d/dt alpha = - f alpha^n K (harmonic=1, 1+log=2)", +mathematica code Default -> 1 +mathematica code }, +mathematica code { +mathematica code Name -> AlphaDriver, +mathematica code Default -> 0 +mathematica code }, +mathematica code { +mathematica code Name -> ShiftBCoeff, +mathematica code Description -> "Whether to evolve B^i in time", +mathematica code Default -> 1 +mathematica code }, +mathematica code { +mathematica code Name -> ShiftGammaCoeff, +mathematica code Default -> 0 +mathematica code }, +mathematica code { +mathematica code Name -> BetaDriver, +mathematica code Default -> 0 +mathematica code }, +mathematica code { +mathematica code Name -> LapseAdvectionCoeff, +mathematica code Description -> "Factor in front of the lapse advection terms in 1+log", +mathematica code Default -> 1 +mathematica code }, +mathematica code { +mathematica code Name -> ShiftAdvectionCoeff, +mathematica code Description -> "Factor in front of the shift advection terms in gamma driver", +mathematica code Default -> 1 +mathematica code }, +mathematica code { +mathematica code Name -> MinimumLapse, +mathematica code Description -> "Minimum value of the lapse function", +mathematica code Default -> -1 +mathematica code }, +mathematica code { +mathematica code Name -> SpatialBetaDriverRadius, +mathematica code Description -> "Radius at which the BetaDriver starts to be reduced", +mathematica code AllowedValues -> {{Value -> "(0:*", Description -> "Positive"}}, +mathematica code Default -> 10^12 +mathematica code }, +mathematica code { +mathematica code Name -> SpatialShiftGammaCoeffRadius, +mathematica code Description -> "Radius at which the ShiftGammaCoefficient starts to be reduced", +mathematica code AllowedValues -> {{Value -> "(0:*", Description -> "Positive"}}, +mathematica code Default -> 10^12 +mathematica code }, +mathematica code { +mathematica code Name -> EpsDiss, +mathematica code Description -> "Dissipation strength", +mathematica code AllowedValues -> {{Value -> "(0:*", Description -> "Positive"}}, +mathematica code Default -> 0 +mathematica code } +mathematica code }; +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Construct the thorns *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica code calculations = +mathematica code Join[ +mathematica code { +mathematica code initialCalc, +mathematica code convertFromADMBaseCalc, +mathematica code initGammaCalc, +mathematica code convertFromADMBaseGammaCalc, +mathematica code evolCalc, +mathematica code evolCalc1, evolCalc2, +mathematica code dissCalc, +mathematica code advectCalc, +mathematica comment (*advectCalcs,*) +mathematica code initRHSCalc, +mathematica code RHSStaticBoundaryCalc, +mathematica comment (* RHSRadiativeBoundaryCalc, *) +mathematica code enforceCalc, +mathematica code boundaryCalc, +mathematica code convertToADMBaseCalc, +mathematica code convertToADMBaseDtLapseShiftCalc, +mathematica code convertToADMBaseDtLapseShiftBoundaryCalc, +mathematica code convertToADMBaseFakeDtLapseShiftCalc, +mathematica comment (* constraintsCalc, *) +mathematica code constraintsCalc1, constraintsCalc2 +mathematica code }, +mathematica code advectCalcs +mathematica comment (*dissCalcs*) +mathematica code ]; +mathematica blank +mathematica code CreateKrancThornTT [groups, ".", thorn, +mathematica code Calculations -> calculations, +mathematica code DeclaredGroups -> declaredGroupNames, +mathematica code PartialDerivatives -> derivatives, +mathematica code EvolutionTimelevels -> evolutionTimelevels, +mathematica code DefaultEvolutionTimelevels -> 3, +mathematica code UseJacobian -> True, +mathematica code UseLoopControl -> True, +mathematica code UseVectors -> useVectors, +mathematica code UseOpenCL -> useOpenCL, +mathematica code InheritedImplementations -> inheritedImplementations, +mathematica code InheritedKeywordParameters -> inheritedKeywordParameters, +mathematica code ExtendedKeywordParameters -> extendedKeywordParameters, +mathematica code KeywordParameters -> keywordParameters, +mathematica code IntParameters -> intParameters, +mathematica code RealParameters -> realParameters +mathematica code ]; +mathematica blank +mathematica code ]; +mathematica blank +mathematica blank +mathematica blank +mathematica comment (******************************************************************************) +mathematica comment (* Options *) +mathematica comment (******************************************************************************) +mathematica blank +mathematica comment (* These are the arguments to createComment: +mathematica comment - derivative order: 2, 4, 6, 8, ... +mathematica comment - useJacobian: False or True +mathematica comment - split upwind derivatives: False or True +mathematica comment - use vectorisation: False or True +mathematica comment - use OpenCL: False or True +mathematica comment - timelevels: 2 or 3 +mathematica comment ## (keep this at 3; this is better chosen with a run-time parameter) +mathematica comment - matter: 0 or 1 +mathematica comment ## (matter seems cheap; it should be always enabled) +mathematica comment - thorn base name +mathematica comment *) +mathematica blank +mathematica code createCode[4, False, True, True , False, 3, 1, "BSSN"]; +mathematica code createCode[4, False, True, False, False, 3, 1, "BSSN"]; +mathematica code createCode[4, False, True, True , True , 3, 1, "BSSN"]; +mathematica blank +mathematica code createCode[4, False, True, True , False, 3, 1, "CCZ4"]; +mathematica blank diff --git a/test/expected_dir/octave1.m b/test/expected_dir/octave1.m index 311ca33..73977b0 100644 --- a/test/expected_dir/octave1.m +++ b/test/expected_dir/octave1.m @@ -4,7 +4,7 @@ octave comment ## 3-clause BSD license appended to this file. octave blank octave code function varargout = toledolu(LU) -octave comment ## -*- texinfo -*- +octave comment ## (*- texinfo -*) octave comment ## @deftypefn{Function File} {[@var{L}, @var{U}, @var{P}]} = toledolu(@var{A}) octave comment ## @deftypefnx{Function File} {[@var{L}, @var{U}]} = toledolu(@var{A}) octave comment ## @deftypefnx{Function File} {@var{LUP}} = toledolu(@var{A}) @@ -20,8 +20,8 @@ octave comment ## See the help for lu for details about the other calling forms. octave comment ## octave comment ## For the algorithm, see -octave comment ## @itemize -octave comment ## @item +octave comment ## (* @itemize *) +octave comment ## (* @item *) octave comment ## Toledo, Sivan. "Locality of reference in LU decomposition with octave comment ## partial pivoting," SIAM J. of Matrix Analysis and Applications, octave comment ## v18, n4, 1997. DOI: 10.1137/S0895479896297744 diff --git a/test/expected_dir/pascal2.pp b/test/expected_dir/pascal2.pp index 1ca997c..e114703 100644 --- a/test/expected_dir/pascal2.pp +++ b/test/expected_dir/pascal2.pp @@ -110,3 +110,7 @@ pascal code end; pascal blank pascal code end. +pascal blank +pascal code class function Test.Run: Boolean; +pascal blank +pascal code #include diff --git a/test/expected_dir/prolog.pl b/test/expected_dir/prolog.pl new file mode 100644 index 0000000..f009dba --- /dev/null +++ b/test/expected_dir/prolog.pl @@ -0,0 +1,9 @@ +prolog comment /* test file for Prolog parsing */ +prolog blank +prolog comment % this is a Prolog source file +prolog blank +prolog comment % select(Element, List, Remaining) +prolog blank +prolog code select(H, [H| T], T). +prolog code select(H, [X| R], [X| T]) :- +prolog code select(H, R, T). diff --git a/test/expected_dir/puppet1.pp b/test/expected_dir/puppet1.pp new file mode 100644 index 0000000..cbb3d94 --- /dev/null +++ b/test/expected_dir/puppet1.pp @@ -0,0 +1,145 @@ +puppet code class bob::open_ldap { +puppet blank +puppet code define foo::server ( +puppet code $argsfile = undef, +puppet code $bdb_cachesize = '', +puppet code $bdb_checkpoint = '', +puppet code $bdb_directory = undef, +puppet code $bdb_idlcachesize = '', +puppet code $bdb_rootdn, +puppet code $bdb_rootpw, +puppet code $bdb_shm_key = '', +puppet code $bdb_suffix, +puppet code $conf_path = undef, +puppet code $conf_dir = undef, +puppet code $enable = false, +puppet code $include = [], +puppet code $includepath = undef, +puppet code $modulepath = '', +puppet code $modules = [], +puppet code $package = undef, +puppet code $pidfile = undef, +puppet code $sysconf_path = undef +puppet code ) { +puppet blank +puppet code $resource_name = "bob_openldap_server" +puppet blank +puppet code if($name != "params") { +puppet code fail("${resource_name}: This function is a singleton. Make sure the resource name is 'params'.") +puppet code } +puppet blank +puppet code case $operatingsystem { +puppet code Fedora: { +puppet code case $operatingsystemrelease { +puppet code /^(12|13)$/: { +puppet code if(!$argsfile) { $_argsfile = "/var/run/openldap/slapd.args" } +puppet code if(!$bdb_directory) { $_bdb_directory = "/var/lib/ldap" } +puppet code if(!$conf_path) { $_conf_path = "/etc/openldap/slapd.conf" } +puppet code if(!$conf_dir) { $_conf_dir = "/etc/openldap/slapd.d" } +puppet code if(!$package) { $_package = ["openldap-servers"] } +puppet code if(!$pidfile) { $_pidfile = "/var/run/openldap/slapd.pid" } +puppet code if(!$service) { $_service = "slapd" } +puppet code if(!$sysconf_path) { $_sysconf_path = "/etc/sysconfig/ldap" } +puppet code } +puppet code } +puppet code } +puppet code } +puppet blank +puppet comment # Presume the OS did not match and because these args are necessary, just +puppet comment # bail with an error. +puppet code if(!($_argsfile and $_bdb_directory and $_pidfile and $_conf_path and +puppet code $_package and $_service and $_sysconf_path and $_conf_dir)) { +puppet code fail("${resource_name}: Unsupported operating system: ${operatingsystem} version ${operatingsystemrelease} and you have not setup the args for: argsfile, bdb_directory, conf_dir, conf_path, package, pidfile, sysconf_path and service.") +puppet code } +puppet blank +puppet comment # Fix paths - add forward slashes at the end of strings without them +puppet code $_includepath = regsubst($includepath, '([^/])$', '\1/') +puppet code $_dbconf_path = "${_bdb_directory}/DB_CONFIG" +puppet blank +puppet comment # ... +puppet code file { +puppet code $_conf_path: +puppet code content => template("bob_openldap/slapd.conf"), +puppet code require => Package[$_package], +puppet code owner => "ldap", +puppet code group => "root", +puppet code mode => "0440", +puppet code notify => Service[$_service]; +puppet code $_sysconf_path: +puppet code content => template("bob_openldap/ldap.sysconf"), +puppet code require => Package[$_package], +puppet code owner => "root", +puppet code group => "root", +puppet code mode => "0644"; +puppet code $_conf_dir: +puppet code force => true, +puppet code ensure => absent, +puppet code before => Service[$_service]; +puppet code $_dbconf_path: +puppet code content => "", +puppet code notify => Service[$_service]; +puppet code } +puppet code package { +puppet code $_package: +puppet code ensure => installed; +puppet code } +puppet code service { +puppet code $_service: +puppet code ensure => $enable ? { +puppet code true => "running", +puppet code false => "stopped" +puppet code }, +puppet code enable => $enable, +puppet code hasstatus => true, +puppet code require => [ Package[$_package], File[$_conf_path] ]; +puppet code } +puppet code } +puppet blank +puppet code define client ( +puppet code $base, +puppet code $network_timeout = '', +puppet code $path = undef, +puppet code $timeout = '', +puppet code $binddn = '', +puppet code $tls_cacertdir = undef, +puppet code $uri +puppet code ) { +puppet blank +puppet code $resource_name = "bob_openldap_client" +puppet blank +puppet code if($name != "params") { +puppet code fail("${resource_name}: This function is a singleton. Make sure the resource name is 'params'.") +puppet code } +puppet blank +puppet code case $operatingsystem { +puppet code Fedora: { +puppet code case $operatingsystemrelease { +puppet code /^(12|13)$/: { +puppet code if(!$tls_cacertdir) { $_tls_cacertdir = "/etc/openldap/cacerts" } +puppet code if(!$path) { $_path = "/etc/openldap/ldap.conf" } +puppet code } +puppet code } +puppet code } +puppet code } +puppet blank +puppet comment # Presume the OS did not match and because these args are necessary, just +puppet comment # bail with an error. +puppet code if(!($_tls_cacertdir and $_path)) { +puppet code fail("${resource_name}: Unsupported operating system: ${operatingsystem} version ${operatingsystemrelease} and you have not setup the args for: tls_cacertdir, path.") +puppet code } +puppet blank +puppet comment # Fix some vars, ready for templating +puppet code $_base = $base +puppet code $_binddn = $binddn +puppet code $_network_timeout = $network_timeout +puppet code $_timeout = $timeout +puppet code $_uri = $uri +puppet blank +puppet code file { +puppet code $_path: +puppet code content => template("bob_openldap/ldap.conf") +puppet code } +puppet blank +puppet code } +puppet blank +puppet code } diff --git a/test/expected_dir/puppet_empty_class_1.pp b/test/expected_dir/puppet_empty_class_1.pp new file mode 100644 index 0000000..823be53 --- /dev/null +++ b/test/expected_dir/puppet_empty_class_1.pp @@ -0,0 +1,4 @@ +puppet code class tester ( +puppet code ) { +puppet code "Some Content" +puppet code } diff --git a/test/expected_dir/puppet_empty_class_2.pp b/test/expected_dir/puppet_empty_class_2.pp new file mode 100644 index 0000000..4aab1a2 --- /dev/null +++ b/test/expected_dir/puppet_empty_class_2.pp @@ -0,0 +1,3 @@ +puppet code class test::files { +puppet code "Some Content" +puppet code } diff --git a/test/expected_dir/puppet_with_include_only.pp b/test/expected_dir/puppet_with_include_only.pp new file mode 100644 index 0000000..fc04b7e --- /dev/null +++ b/test/expected_dir/puppet_with_include_only.pp @@ -0,0 +1 @@ +puppet code include ::postfix diff --git a/test/expected_dir/rebol.r b/test/expected_dir/rebol.r new file mode 100644 index 0000000..17baf19 --- /dev/null +++ b/test/expected_dir/rebol.r @@ -0,0 +1,59 @@ +rebol comment ;; ================================================= +rebol comment ;; Script: new-suffix.r +rebol comment ;; downloaded from: www.REBOL.org +rebol comment ;; on: 1-Jun-2011 +rebol comment ;; at: 21:19:08.38986 UTC +rebol comment ;; owner: carl [script library member who can update +rebol comment ;; this script] +rebol comment ;; ================================================= +rebol code REBOL [ +rebol code Title: "Change File Extensions (Suffix)" +rebol code File: %new-suffix.r +rebol code Author: "Carl Sassenrath" +rebol code Date: 25-Jan-2005 +rebol code Purpose: { +rebol code Change the file extension (suffix) for files with a specific extension. +rebol code For example, change all .txt files to .r files in the current directory. +rebol code Displays a list of changes before it makes them. +rebol code } +rebol code Warning: "Back up your files first, just in case!" +rebol code License: "BSD - Use at your own risk." +rebol code Library: [ +rebol code level: 'beginner +rebol code platform: 'all +rebol code type: [tool] +rebol code domain: [files] +rebol code tested-under: none +rebol code support: none +rebol code license: 'bsd +rebol code see-also: none +rebol code ] +rebol code ] +rebol blank +rebol code from-suffix: %.txt +rebol code to-suffix: %.r +rebol blank +rebol code bulk-rename: func [confirmed] [ +rebol code foreach file load %./ [ +rebol code if all [ +rebol code not find file #"/" ; (ignore directories) +rebol code from-suffix = find/last file #"." +rebol code ][ +rebol code new-file: copy file +rebol code append clear find/last new-file #"." to-suffix +rebol code either confirmed [ +rebol code print ["Renaming" file "to" new-file] +rebol code rename file new-file +rebol code ][ +rebol code print ["Will rename" file "to" new-file] +rebol code ] +rebol code ] +rebol code ] +rebol code ] +rebol blank +rebol code bulk-rename false +rebol code if not confirm "Are you sure you want to rename all those files?" [ +rebol code quit +rebol code ] +rebol code bulk-rename true +rebol code ask "Done. Press enter." diff --git a/test/expected_dir/rust.rs b/test/expected_dir/rust.rs new file mode 100644 index 0000000..1c6b0e0 --- /dev/null +++ b/test/expected_dir/rust.rs @@ -0,0 +1,16 @@ +rust comment /* +rust comment * This is the example given by www.rust-lang.org +rust comment */ +rust comment // Line comments work too +rust code fn main() { +rust code let nums = [1, 2]; +rust code let noms = ["Tim", "Eston", "Aaron", "Ben"]; +rust blank +rust code let mut odds = nums.iter().map(|&x| x * 2 - 1); +rust blank +rust code for num in odds { +rust code do spawn { +rust code println!("{:s} says hello from a lightweight thread!", noms[num]); +rust code } +rust code } +rust code } diff --git a/test/expected_dir/sample.i3 b/test/expected_dir/sample.i3 new file mode 100644 index 0000000..43b051b --- /dev/null +++ b/test/expected_dir/sample.i3 @@ -0,0 +1,12 @@ +modula3 code (* Modula-3 *) INTERFACE M3Sample; (* file extension ".i3" *) +modula3 blank +modula3 comment (* This is a comment *) +modula3 blank +modula3 comment (* This is a comment ... +modula3 comment ... spanning more than one line *) +modula3 blank +modula3 code CONST +modula3 code sqString = 'this is a string within "a string" ...\n'; +modula3 code dqString = "this is a string within 'a string' ...\n"; +modula3 blank +modula3 code END M3Sample. diff --git a/test/expected_dir/sample.m3 b/test/expected_dir/sample.m3 new file mode 100644 index 0000000..f525d0b --- /dev/null +++ b/test/expected_dir/sample.m3 @@ -0,0 +1,12 @@ +modula3 code (* Modula-3 *) MODULE M3Sample; (* file extension ".m3" *) +modula3 blank +modula3 comment (* This is a comment *) +modula3 blank +modula3 comment (* This is a comment ... +modula3 comment ... spanning more than one line *) +modula3 blank +modula3 code CONST +modula3 code sqString = 'this is a string within "a string" ...\n'; +modula3 code dqString = "this is a string within 'a string' ...\n"; +modula3 blank +modula3 code END M3Sample. diff --git a/test/expected_dir/sample.mod b/test/expected_dir/sample.mod new file mode 100644 index 0000000..cd40648 --- /dev/null +++ b/test/expected_dir/sample.mod @@ -0,0 +1,12 @@ +modula2 code MODULE Sample; (* in Modula-2 *) +modula2 blank +modula2 comment (* This is a comment *) +modula2 blank +modula2 comment (* This is a comment ... +modula2 comment ... spanning more than one line *) +modula2 blank +modula2 code CONST +modula2 code sqString = 'this is a string within "a string" ...'; +modula2 code dqString = "this is a string within 'a string' ..."; +modula2 blank +modula2 code END Sample. diff --git a/test/expected_dir/sample.ob2 b/test/expected_dir/sample.ob2 new file mode 100644 index 0000000..4561fee --- /dev/null +++ b/test/expected_dir/sample.ob2 @@ -0,0 +1,12 @@ +oberon code (* Oberon-2 *) MODULE OberonSample; (* file extension ".ob2" *) +oberon blank +oberon comment (* This is a comment *) +oberon blank +oberon comment (* This is a comment ... +oberon comment ... spanning more than one line *) +oberon blank +oberon code CONST +oberon code sqString* = 'this is a string within "a string" ...'; +oberon code dqString* = "this is a string within 'a string' ..."; +oberon blank +oberon code END OberonSample. diff --git a/test/expected_dir/sample.obn b/test/expected_dir/sample.obn new file mode 100644 index 0000000..faa5ca7 --- /dev/null +++ b/test/expected_dir/sample.obn @@ -0,0 +1,12 @@ +oberon code (* Oberon *) MODULE OberonSample; (* file extension ".obn" *) +oberon blank +oberon comment (* This is a comment *) +oberon blank +oberon comment (* This is a comment ... +oberon comment ... spanning more than one line *) +oberon blank +oberon code CONST +oberon code sqString* = 'this is a string within "a string" ...'; +oberon code dqString* = "this is a string within 'a string' ..."; +oberon blank +oberon code END OberonSample. diff --git a/test/expected_dir/sampleDef.def b/test/expected_dir/sampleDef.def new file mode 100644 index 0000000..11842b4 --- /dev/null +++ b/test/expected_dir/sampleDef.def @@ -0,0 +1,12 @@ +modula2 code DEFINITION MODULE Sample; (* in Modula-2 *) +modula2 blank +modula2 comment (* This is a comment *) +modula2 blank +modula2 comment (* This is a comment ... +modula2 comment ... spanning more than one line *) +modula2 blank +modula2 code CONST +modula2 code sqString = 'this is a string within "a string" ...'; +modula2 code dqString = "this is a string within 'a string' ..."; +modula2 blank +modula2 code END Sample. diff --git a/test/expected_dir/sampleImp.mod b/test/expected_dir/sampleImp.mod new file mode 100644 index 0000000..04f19ce --- /dev/null +++ b/test/expected_dir/sampleImp.mod @@ -0,0 +1,12 @@ +modula2 code IMPLEMENTATION MODULE Sample; (* in Modula-2 *) +modula2 blank +modula2 comment (* This is a comment *) +modula2 blank +modula2 comment (* This is a comment ... +modula2 comment ... spanning more than one line *) +modula2 blank +modula2 code CONST +modula2 code sqString = 'this is a string within "a string" ...'; +modula2 code dqString = "this is a string within 'a string' ..."; +modula2 blank +modula2 code END Sample. diff --git a/test/expected_dir/sh2.sh b/test/expected_dir/sh2.sh new file mode 100644 index 0000000..af6a968 --- /dev/null +++ b/test/expected_dir/sh2.sh @@ -0,0 +1,5 @@ +shell code var="\ +shell code Some string" +shell blank +shell comment # Now a comment +shell code var="some new string" diff --git a/test/expected_dir/ts1.ts b/test/expected_dir/ts1.ts new file mode 100644 index 0000000..17a023c --- /dev/null +++ b/test/expected_dir/ts1.ts @@ -0,0 +1,14 @@ +typescript comment /* +typescript comment * This is a TypeScript File +typescript comment */ +typescript blank +typescript comment // And a regular comment +typescript blank +typescript code export class SomeClass { +typescript code public text: string; +typescript blank +typescript code public sayHello(name: string): string { +typescript code return `Hello, ${name}`; +typescript code } +typescript code } +typescript blank \ No newline at end of file diff --git a/test/expected_licenses/wtfpl b/test/expected_licenses/wtfpl new file mode 100644 index 0000000..c0f1ca9 --- /dev/null +++ b/test/expected_licenses/wtfpl @@ -0,0 +1 @@ +wtfpl_2 diff --git a/test/gestalt_files/netbeans/nbplatform/foo b/test/gestalt_files/netbeans/nbplatform/foo new file mode 100644 index 0000000..e69de29 diff --git a/test/src_dir/ampl.mod b/test/src_dir/ampl.mod new file mode 100644 index 0000000..24ac1b5 --- /dev/null +++ b/test/src_dir/ampl.mod @@ -0,0 +1,7 @@ +/* This is a test file for AMPL + * This is a multiline comment + */ + +# An AMPL model +var x >= 42; # variable definition. +minimize o: x; diff --git a/test/src_dir/assembler6502.as8 b/test/src_dir/assembler6502.as8 new file mode 100644 index 0000000..09846ae --- /dev/null +++ b/test/src_dir/assembler6502.as8 @@ -0,0 +1,21 @@ +; "Hello world" in 6502 assembly language for 8-bit Atari. +; Assembler: http://xasm.atari.org/ or http://mads.atari8.info/ + + org $3000 +main lda #$21 + sta $22f + lda #
dl + sta $231 + jmp * + +text dta d' HELLO, ',d'WORLD! '* + +; Display List +dl dta b($70),b($70),b($70),b($47),a(text),b($41),a(dl) + + org $2e0 + dta a(main) + + end diff --git a/test/src_dir/assembler6502.asx b/test/src_dir/assembler6502.asx new file mode 100644 index 0000000..09846ae --- /dev/null +++ b/test/src_dir/assembler6502.asx @@ -0,0 +1,21 @@ +; "Hello world" in 6502 assembly language for 8-bit Atari. +; Assembler: http://xasm.atari.org/ or http://mads.atari8.info/ + + org $3000 +main lda #$21 + sta $22f + lda #
dl + sta $231 + jmp * + +text dta d' HELLO, ',d'WORLD! '* + +; Display List +dl dta b($70),b($70),b($70),b($47),a(text),b($41),a(dl) + + org $2e0 + dta a(main) + + end diff --git a/test/src_dir/augeas.aug b/test/src_dir/augeas.aug new file mode 100644 index 0000000..a4e3b2d --- /dev/null +++ b/test/src_dir/augeas.aug @@ -0,0 +1,14 @@ +(** documentation *) +module Augeas = +autoload xfm +(**/**) +(* extra comment *) + +(* multiline + comment*) +let lns = Shellvars.lns + +(* recursion in (* a + comment *) to complicate things *) +let filter = incl "/foo/bar" +let xfm = transform lns filter diff --git a/test/src_dir/b.bfpp b/test/src_dir/b.bfpp new file mode 100644 index 0000000..90d2653 --- /dev/null +++ b/test/src_dir/b.bfpp @@ -0,0 +1,54 @@ + += comment +>++++++[>+++[<<++++>>-]<-]<. +>+++++[<++++++>-]<-. ++++++++. +. ++++. +>>++++[<++++++>-]<++[<--->-]<-. +>>++[<+++++>-]<+[<+++++>-]<. +>++++[<++++++>-]<. ++++. +------. +>++[<---->-]<. +>>++++[<++++>-]<+[<---->-]<. +>+++++++[<++++++>-]<-. +>++++++[<++++++>-]<+. +>>++++[<++++++>-]<++[<--->-]<. +>+++++[<+++++++>-]<-. +>++++[>++++[<<+++>>-]<-]<. +>++++[<---->-]<-. +>++[<++++>-]<. ++++++. +>++[<---->-]<. +>+++[<+++++>-]<. +>+++[<------>-]<. +>++[<++++>-]<. +>++++[>++++[<<---->>-]<-]<. +. +>++[<----->-]<. +. +. +. +. +[-] + = [-] is used to clear a cell + += Try to open b file +>+++++++[>+++++++[<<++>>-]<-]<. +#[ + >>++++[<++++>-]<+[<++++++>-]<. + +++. + +++. + -------. + >>++++[<++++++>-]<-[<--->-]<. + >>++[<+++++>-]<+[<++++++>-]<. + >>++[<+++++>-]<+[<------>-]<. + >>++++[<++++++>-]<++[<+++>-]<+. + +. + >++[<----->-]<-. + >+++[<+++>-]<. + >+++[<--->-]<. + -. +#] +@include(nothing.bfpp) diff --git a/test/src_dir/bat1.bat b/test/src_dir/bat1.bat index d04519b..acb3486 100644 --- a/test/src_dir/bat1.bat +++ b/test/src_dir/bat1.bat @@ -1,6 +1,11 @@ REM comment 1 rem comment 2 rEm comment 3 +rEm.comment 4 +Rem=comment 5 +@Rem comment 6 +@reM=comment 7 +::comment 8 echo not a rem comment! diff --git a/test/src_dir/brainfuck.bf b/test/src_dir/brainfuck.bf new file mode 100644 index 0000000..0eb2911 --- /dev/null +++ b/test/src_dir/brainfuck.bf @@ -0,0 +1,19 @@ +Print "Hello World!!!!!" + +Line that does nothing: >< +>++++++[>+++[<<++++>>-]<-]<. +>+++++[<++++++>-]<-. ++++++++. +. ++++. +>>++++[<++++++>-]<++[<--->-]<-. +>>++[<+++++>-]<+[<+++++>-]<. +>++++[<++++++>-]<. ++++. +------. +>++[<---->-]<. +>>++[<+++++>-]<+[<------>-]<-. +. +. +. +. diff --git a/test/src_dir/chaiscript.chai b/test/src_dir/chaiscript.chai new file mode 100644 index 0000000..208a933 --- /dev/null +++ b/test/src_dir/chaiscript.chai @@ -0,0 +1,17 @@ +/* +Random Comments +Foo Foo Foo +*/ +var submenu=1; +// comment +// another comment +submenu += 10 +var f = fun() { 5 }; +def myFun(i) : i > 0 { + return i + 10; +} + + +// some comment +var delay_hide=500 +b=0 diff --git a/test/src_dir/clj1.clj b/test/src_dir/clj1.clj new file mode 100644 index 0000000..4e6a9af --- /dev/null +++ b/test/src_dir/clj1.clj @@ -0,0 +1,16 @@ +;;; Copyright (C) 2009 Brendan Ribera. All rights reserved. +;;; Distributed under the MIT License; see the file LICENSE +;;; at the root of this distribution. +(ns kdtree) + +(defn dist-squared [a b] + "Compute the K-dimensional distance between two points" + (reduce + (for [i (range (count a))] + (let [v (- (nth a i) + (nth b i))] + (* v v))))) + +;;; Simple accessors +(defn- node-value [n] (first n)) +(defn- node-left [n] (first (rest n))) +(defn- node-right [n] (first (rest (rest n)))) diff --git a/test/src_dir/components.cu b/test/src_dir/components.cu new file mode 100644 index 0000000..e357e82 --- /dev/null +++ b/test/src_dir/components.cu @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include + +#include "components.h" +#include "common.h" + +#define THREADS 256 + +/* Store 3 RGB float components */ +__device__ void storeComponents(float *d_r, float *d_g, float *d_b, float r, float g, float b, int pos) +{ + d_r[pos] = (r/255.0f) - 0.5f; + d_g[pos] = (g/255.0f) - 0.5f; + d_b[pos] = (b/255.0f) - 0.5f; +} + +/* Store 3 RGB intege components */ +__device__ void storeComponents(int *d_r, int *d_g, int *d_b, int r, int g, int b, int pos) +{ + d_r[pos] = r - 128; + d_g[pos] = g - 128; + d_b[pos] = b - 128; +} diff --git a/test/src_dir/coq.v b/test/src_dir/coq.v new file mode 100644 index 0000000..37ae74c --- /dev/null +++ b/test/src_dir/coq.v @@ -0,0 +1,10 @@ +Require Import String. +(* comment *) +Check "multiline +string"%string. + +(* multiline + comment *) + +(* recursion in (* a + comment *) to complicate things *) diff --git a/test/src_dir/example.qml b/test/src_dir/example.qml new file mode 100644 index 0000000..b92a82d --- /dev/null +++ b/test/src_dir/example.qml @@ -0,0 +1,17 @@ +// Just an example of QML file... + +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + color: "crimson" + + MouseArea { + anchors.fill: parent + onClicked: { + // Was clicked + Qt.quit(); + } + } +} diff --git a/test/src_dir/example.rkt b/test/src_dir/example.rkt new file mode 100644 index 0000000..502b961 --- /dev/null +++ b/test/src_dir/example.rkt @@ -0,0 +1,12 @@ +;; language declaration commented out until someone extends the +;; parser to support it: + +;; #lang racket + +;; Report each unique line from stdin +(let ([saw (make-hash)]) + (for ([line (in-lines)]) + (unless (hash-ref saw line #f) + (displayln line)) + (hash-set! saw line #t))) + diff --git a/test/src_dir/foo.coffee b/test/src_dir/foo.coffee new file mode 100644 index 0000000..aa0f216 --- /dev/null +++ b/test/src_dir/foo.coffee @@ -0,0 +1,26 @@ +# A CoffeeScript parser test file + +simple_code = true + +### +A multi-line block comment +begins and ends with three hash marks +### + +multi_line_string = ''' + A multi-line string constant ("here doc") + begins and ends with three quote marks + ''' + +foo = "A string can wrap across multiple lines + and may contain #{interpolated_values}" + + +### +A clever parser can use Ohcount's "Polyglot" feature treat the +following as embedded JavaScript. +### +embedded_js = `function() { + return [document.title, "Hello JavaScript"].join(": "); +}` + diff --git a/test/src_dir/foo.dtx b/test/src_dir/foo.dtx new file mode 100644 index 0000000..d8cb14d --- /dev/null +++ b/test/src_dir/foo.dtx @@ -0,0 +1,9 @@ +\begin{document} +\texbf Hello world + + +% \acommand +% \anothercommand +%% sample comment + +\end{document} diff --git a/test/src_dir/foo.nsh b/test/src_dir/foo.nsh new file mode 100644 index 0000000..8638e86 --- /dev/null +++ b/test/src_dir/foo.nsh @@ -0,0 +1,17 @@ +; NSIS "header" libraries can be in .nsh files. +/* Copyright some time + * never + * and not much of that either +"still a comment" +*/ + +!macro SillyMacro Param1 + ; ... Because we can ;-) + !error "Why did you call this macro, ${Param1}? That was silly." +!macroend + +Function Die + # Likewise, because we can. + DetailPrint "Aarrrrggghh! I died." + Quit +FunctionEnd diff --git a/test/src_dir/foo.nsi b/test/src_dir/foo.nsi new file mode 100644 index 0000000..84ebfd8 --- /dev/null +++ b/test/src_dir/foo.nsi @@ -0,0 +1,15 @@ +; some nsis code +/* + * lorem +ipsum +dolor sit amet etcetera +*/ + +!include LogicLib.nsh +OutFile foo.exe + +Section + IfFileExists ${__FILE__} 0 +2 ; comments can be inline + # Use of ; in a string on the next line + MessageBox MB_OK "You moved this installer file; you shouldn't do that ;-)" +SectionEnd diff --git a/test/src_dir/forth.4th b/test/src_dir/forth.4th new file mode 100644 index 0000000..75ce18d --- /dev/null +++ b/test/src_dir/forth.4th @@ -0,0 +1,7 @@ +\ Sample Forth code + +( This is a comment + spanning multiple lines ) + +: somedefinition ; + diff --git a/test/src_dir/grace.grace b/test/src_dir/grace.grace new file mode 100644 index 0000000..3343b9a --- /dev/null +++ b/test/src_dir/grace.grace @@ -0,0 +1,46 @@ +////////////////////////////////////////////////// +// Sample Grace code + +import "parsers-test" as parsers + +class exports { + inherit parsers.exports + //BEGINGRAMMAR + // top level + def program = rule {codeSequence ~ rep(ws) ~ end} + def codeSequence = rule { repdel((declaration | statement | empty), semicolon) } + def hashLine = rule { (symbol "#") ~ rep(anyChar | space) ~ (newLine | end) } + + // def comment = + + //def oldClassDeclaration = rule { classId ~ identifier ~ lBrace ~ + // opt(genericFormals ~ blockFormals ~ arrow) ~ codeSequence ~ rBrace } + + def typeOpExpression = rule { rep1sep(basicTypeExpression, typeOp) } + + def typeOpExpression = rule { + var otherOperator + basicTypeExpression ~ opt(ws) ~ + opt( guard(typeOp, { s -> otherOperator:= s; + true }) ~ rep1sep(basicTypeExpression ~ opt(ws), + guard(typeOp, { s -> s == otherOperator }) + ) + ) + } + + // "literals" + def literal = rule { stringLiteral | selfLiteral | blockLiteral | numberLiteral | objectLiteral | lineupLiteral | typeLiteral } + + // terminals + def backslash = token "\\" // doesn't belong here, doesn't work if left below! + + def colon = rule {both(symbol ":", not(assign))} + def newLine = symbol "\n" + def lParen = symbol "(" + def rParen = symbol ")" + + def reservedOp = rule {assign | equals | dot | arrow | colon | semicolon} // this is not quite right + + //ENDGRAMMAR +} + diff --git a/test/src_dir/html.cgi b/test/src_dir/html.cgi new file mode 100755 index 0000000..1ac7811 --- /dev/null +++ b/test/src_dir/html.cgi @@ -0,0 +1,66 @@ +#!/usr/bin/perl -w + +# ajaxCheckbox.pl - a script to test Ajax functionality + +use strict; +use CGI qw/:standard/; +use CGI::Ajax; +use DBI; + +# --- database authenication +my $dbh = do 'db.inc'; + +my $query = q{ SELECT project.project_id, project.name, project.phase, prio.prio, + HEX((255 - prio.prio)) AS hex, begun, tags + FROM project JOIN prio + ON (project.project_id = prio.project_id) + WHERE completed < 1 + ORDER BY prio.prio DESC LIMIT 3}; + +my $sth = $dbh->prepare($query); +$sth->execute(); +my $result = $dbh->selectall_arrayref($sth); + +my $cgi = new CGI; +my $pjx = new CGI::Ajax( 'toStruck' => \&perl_func ); +print $pjx->build_html( $cgi, \&Show_HTML); + +sub Show_HTML { + + use CGI qw/:standard/; + + my $html = < + + + This is the lastest source version + + + +

Carrot Queue

Priority List  |   + Add a listing  |  

Project listing

+HEAD + +foreach my $row (@$result) { + $html .= ""; + $html .= "
" . @$row[1] . "

"; +} + +# you can append stuff to the HTML this way +$html .= ""; + +return $html; +} + +sub perl_func { + my $input=shift; + + # if onClick the change the style + if ($input eq "ON") { + $input=""; + } else { + $input =""; + } +} diff --git a/test/src_dir/logtalk.lgt b/test/src_dir/logtalk.lgt new file mode 100644 index 0000000..e65124b --- /dev/null +++ b/test/src_dir/logtalk.lgt @@ -0,0 +1,11 @@ +/* test file for Logtalk parsing */ + +% this is a Logtalk source file + +:- object(hello_world). + + % the initialization/1 directive argument is automatically executed + % when the object is loaded into memory: + :- initialization((nl, write('********** Hello World! **********'), nl)). + +:- end_object. diff --git a/test/src_dir/mathematica1.m b/test/src_dir/mathematica1.m new file mode 100644 index 0000000..6cccde6 --- /dev/null +++ b/test/src_dir/mathematica1.m @@ -0,0 +1,1480 @@ + +SetEnhancedTimes[False]; +SetSourceLanguage["C"]; + +(******************************************************************************) +(* Options *) +(******************************************************************************) + +createCode[derivOrder_, useJacobian_, splitUpwindDerivs_, useVectors_, useOpenCL_, evolutionTimelevels_, addMatter_, formulation_] := +Module[{prefix, suffix, thorn}, + +prefix = "ML_"; +suffix = + "" + <> If [useJacobian, "_MP", ""] + <> If [derivOrder!=4, "_O" <> ToString[derivOrder], ""] + <> If [splitUpwindDerivs, "", "_UPW"] + <> If [useVectors, "", "_NV"] + <> If [useOpenCL, "_CL", ""] + (* <> If [evolutionTimelevels!=3, "_TL" <> ToString[evolutionTimelevels], ""] *) + (* <> If [addMatter==1, "_M", ""] *) + ; + +thorn = prefix <> formulation <> suffix; + +SetAttributes[IfCCZ4, HoldAll]; +IfCCZ4[expr_, else_:Sequence[]] := If[formulation === "CCZ4", expr, Unevaluated[else]]; + +(******************************************************************************) +(* Derivatives *) +(******************************************************************************) + +KD = KroneckerDelta; + +derivatives = +{ + PDstandardNth[i_] -> StandardCenteredDifferenceOperator[1,fdOrder/2,i], + PDstandardNth[i_,i_] -> StandardCenteredDifferenceOperator[2,fdOrder/2,i], + PDstandardNth[i_,j_] -> StandardCenteredDifferenceOperator[1,fdOrder/2,i] * + StandardCenteredDifferenceOperator[1,fdOrder/2,j], + PDdissipationNth[i_] -> + (-1)^(fdOrder/2) * + spacing[i]^(fdOrder+1) / 2^(fdOrder+2) * + StandardCenteredDifferenceOperator[fdOrder+2,fdOrder/2+1,i], + +(* PD: These come from my mathematica notebook + "Upwind-Kranc-Convert.nb" that converts upwinding finite + differencing operators generated by + StandardUpwindDifferenceOperator into this form *) + + Sequence@@Flatten[Table[ + {PDupwindNth[i] -> Switch[fdOrder, + 2, (dir[i]*(-3 + 4*shift[i]^dir[i] - shift[i]^(2*dir[i])))/(2*spacing[i]), + 4, (dir[i]*(-10 - 3/shift[i]^dir[i] + 18*shift[i]^dir[i] - + 6*shift[i]^(2*dir[i]) + shift[i]^(3*dir[i])))/(12*spacing[i]), + 6, (dir[i]*(-35 + 2/shift[i]^(2*dir[i]) - 24/shift[i]^dir[i] + 80*shift[i]^dir[i] - + 30*shift[i]^(2*dir[i]) + 8*shift[i]^(3*dir[i]) - shift[i]^(4*dir[i])))/(60*spacing[i]), + 8, (dir[i]*(-378 - 5/shift[i]^(3*dir[i]) + 60/shift[i]^(2*dir[i]) - 420/shift[i]^dir[i] + + 1050*shift[i]^dir[i] - 420*shift[i]^(2*dir[i]) + 140*shift[i]^(3*dir[i]) - 30*shift[i]^(4*dir[i]) + + 3*shift[i]^(5*dir[i])))/(840*spacing[i])], + + PDupwindNthAnti[i] -> Switch[fdOrder, + 2, (+1 shift[i]^(-2) -4 shift[i]^(-1) +0 shift[i]^( 0) +4 shift[i]^(+1) -1 shift[i]^(+2)) / (4 spacing[i]), + 4, (-1 shift[i]^(-3) +6 shift[i]^(-2) -21 shift[i]^(-1 )+0 shift[i]^( 0) +21 shift[i]^(+1) + -6 shift[i]^(+2) +1 shift[i]^(+3)) / (24 spacing[i]), + 6, (+1 shift[i]^(-4) -8 shift[i]^(-3) +32 shift[i]^(-2) -104 shift[i]^(-1) +0 shift[i]^( 0) + +104 shift[i]^(+1) -32 shift[i]^(+2) +8 shift[i]^(+3) -1 shift[i]^(+4)) / (120 spacing[i]), + 8, (-3 shift[i]^(-5) +30 shift[i]^(-4) -145 shift[i]^(-3) +480 shift[i]^(-2) -1470 shift[i]^(-1) + +0 shift[i]^( 0) +1470 shift[i]^(+1) -480 shift[i]^(+2) +145 shift[i]^(+3) -30 shift[i]^(+4) + +3 shift[i]^(+5)) / (1680 spacing[i])], + + PDupwindNthSymm[i] -> Switch[fdOrder, + 2, (-1 shift[i]^(-2) +4 shift[i]^(-1) -6 shift[i]^( 0) +4 shift[i]^(+1) -1 shift[i]^(+2)) / (4 spacing[i]), + 4, (+1 shift[i]^(-3) -6 shift[i]^(-2) +15 shift[i]^(-1) -20 shift[i]^( 0) +15 shift[i]^(+1) + -6 shift[i]^(+2) +1 shift[i]^(+3)) / (24 spacing[i]), + 6, (-1 shift[i]^(-4) +8 shift[i]^(-3) - 28 shift[i]^(-2)+56 shift[i]^(-1)-70 shift[i]^( 0) + +56 shift[i]^(+1) -28 shift[i]^(+2) +8 shift[i]^(+3) -1 shift[i]^(+4)) / (120 spacing[i]), + 8, (+3 shift[i]^(-5) -30 shift[i]^(-4) +135 shift[i]^(-3) -360 shift[i]^(-2) +630 shift[i]^(-1) + -756 shift[i]^( 0) +630 shift[i]^(+1) -360 shift[i]^(+2) +135 shift[i]^(+3) -30 shift[i]^(+4) + +3 shift[i]^(+5)) / (1680 spacing[i])], + + (* TODO: make these higher order stencils *) + PDonesided[i] -> dir[i] (-1 + shift[i]^dir[i]) / spacing[i]} /. i->j, {j,1,3}],1] +}; + +PD = PDstandardNth; +PDu = PDupwindNth; +PDua = PDupwindNthAnti; +PDus = PDupwindNthSymm; +(* PDo = PDonesided; *) +PDdiss = PDdissipationNth; + +If [splitUpwindDerivs, + Upwind[dir_, var_, idx_] := dir PDua[var,idx] + Abs[dir] PDus[var,idx], + Upwind[dir_, var_, idx_] := dir PDu[var,idx]]; + + + +(******************************************************************************) +(* Tensors *) +(******************************************************************************) + +(* Register the tensor quantities with the TensorTools package *) +Map [DefineTensor, + {normal, tangentA, tangentB, dir, + nn, nu, nlen, nlen2, su, vg, + xx, rr, th, ph, + admg, admK, admalpha, admdtalpha, admbeta, admdtbeta, H, M, + g, detg, gu, G, R, trR, Km, trK, cdphi, cdphi2, + phi, gt, At, Xt, Xtn, Theta, Z, + alpha, A, beta, B, Atm, Atu, trA, Ats, trAts, + dottrK, dotXt, + cXt, cS, cA, + e4phi, em4phi, ddetg, detgt, gtu, ddetgt, dgtu, ddgtu, Gtl, Gtlu, Gt, + Rt, Rphi, gK, + T00, T0, T, rho, S, + x, y, z, r, + epsdiss}]; + +(* NOTE: It seems as if Lie[.,.] did not take these tensor weights + into account. Presumably, CD[.,.] and CDt[.,.] don't do this either. *) +SetTensorAttribute[phi, TensorWeight, +1/6]; +SetTensorAttribute[gt, TensorWeight, -2/3]; +SetTensorAttribute[Xt, TensorWeight, +2/3]; +SetTensorAttribute[At, TensorWeight, -2/3]; +SetTensorAttribute[cXt, TensorWeight, +2/3]; +SetTensorAttribute[cS, TensorWeight, +2 ]; + +Map [AssertSymmetricIncreasing, + {admg[la,lb], admK[la,lb], g[la,lb], K[la,lb], R[la,lb], cdphi2[la,lb], + gt[la,lb], At[la,lb], Ats[la,lb], Rt[la,lb], Rphi[la,lb], T[la,lb]}]; +AssertSymmetricIncreasing [G[ua,lb,lc], lb, lc]; +AssertSymmetricIncreasing [Gtl[la,lb,lc], lb, lc]; +AssertSymmetricIncreasing [Gt[ua,lb,lc], lb, lc]; +AssertSymmetricIncreasing [gK[la,lb,lc], la, lb]; +Map [AssertSymmetricIncreasing, + {gu[ua,ub], gtu[ua,ub], Atu[ua,ub]}]; +AssertSymmetricIncreasing [dgtu[ua,ub,lc], ua, ub]; +AssertSymmetricIncreasing [ddgtu[ua,ub,lc,ld], ua, ub]; +AssertSymmetricIncreasing [ddgtu[ua,ub,lc,ld], lc, ld]; + +DefineConnection [CD, PD, G]; +DefineConnection [CDt, PD, Gt]; + +(* Use the CartGrid3D variable names *) +x1=x; x2=y; x3=z; + +(* Use the ADMBase variable names *) +admg11=gxx; admg12=gxy; admg22=gyy; admg13=gxz; admg23=gyz; admg33=gzz; +admK11=kxx; admK12=kxy; admK22=kyy; admK13=kxz; admK23=kyz; admK33=kzz; +admalpha=alp; +admdtalpha=dtalp; +admbeta1=betax; admbeta2=betay; admbeta3=betaz; +admdtbeta1=dtbetax; admdtbeta2=dtbetay; admdtbeta3=dtbetaz; + +(* Use the TmunuBase variable names *) +T00=eTtt; +T01=eTtx; T02=eTty; T03=eTtz; +T11=eTxx; T12=eTxy; T22=eTyy; T13=eTxz; T23=eTyz; T33=eTzz; + + + +(******************************************************************************) +(* Expressions *) +(******************************************************************************) + +(* enum constants for conformalMethod; these must be consistent + with the definition of the Cactus parameter conformalMethod *) +CMphi = 0; +CMW = 1; + +detgExpr = Det [MatrixOfComponents [g [la,lb]]]; +ddetgExpr[la_] = + Sum [D[Det[MatrixOfComponents[g[la, lb]]], X] PD[X, la], + {X, Union[Flatten[MatrixOfComponents[g[la, lb]]]]}]; + +detgtExpr = Det [MatrixOfComponents [gt[la,lb]]]; +ddetgtExpr[la_] = + Sum [D[Det[MatrixOfComponents[gt[la, lb]]], X] PD[X, la], + {X, Union[Flatten[MatrixOfComponents[gt[la, lb]]]]}]; + +etaExpr = SpatialBetaDriverRadius / Max [r, SpatialBetaDriverRadius]; +thetaExpr = Min [Exp [1 - r / SpatialShiftGammaCoeffRadius], 1]; + + + +(******************************************************************************) +(* Groups *) +(******************************************************************************) + +evolvedGroups = + {SetGroupName [CreateGroupFromTensor [phi ], prefix <> "log_confac"], + SetGroupName [CreateGroupFromTensor [gt[la,lb]], prefix <> "metric" ], + SetGroupName [CreateGroupFromTensor [Xt[ua] ], prefix <> "Gamma" ], + SetGroupName [CreateGroupFromTensor [trK ], prefix <> "trace_curv"], + SetGroupName [CreateGroupFromTensor [At[la,lb]], prefix <> "curv" ], + SetGroupName [CreateGroupFromTensor [alpha ], prefix <> "lapse" ], + SetGroupName [CreateGroupFromTensor [A ], prefix <> "dtlapse" ], + SetGroupName [CreateGroupFromTensor [beta[ua] ], prefix <> "shift" ], + SetGroupName [CreateGroupFromTensor [B[ua] ], prefix <> "dtshift" ], + IfCCZ4[SetGroupName[CreateGroupFromTensor[Theta], prefix <> "Theta"]]}; +evaluatedGroups = + {SetGroupName [CreateGroupFromTensor [H ], prefix <> "Ham"], + SetGroupName [CreateGroupFromTensor [M[la] ], prefix <> "mom"], + SetGroupName [CreateGroupFromTensor [cS ], prefix <> "cons_detg"], + SetGroupName [CreateGroupFromTensor [cXt[ua]], prefix <> "cons_Gamma"], + SetGroupName [CreateGroupFromTensor [cA ], prefix <> "cons_traceA"]}; + +declaredGroups = Join [evolvedGroups, evaluatedGroups]; +declaredGroupNames = Map [First, declaredGroups]; + + + +extraGroups = + {{"grid::coordinates", {x, y, z, r}}, + {"ADMBase::metric", {gxx, gxy, gxz, gyy, gyz, gzz}}, + {"ADMBase::curv", {kxx, kxy, kxz, kyy, kyz, kzz}}, + {"ADMBase::lapse", {alp}}, + {"ADMBase::dtlapse", {dtalp}}, + {"ADMBase::shift", {betax, betay, betaz}}, + {"ADMBase::dtshift", {dtbetax, dtbetay, dtbetaz}}, + {"TmunuBase::stress_energy_scalar", {eTtt}}, + {"TmunuBase::stress_energy_vector", {eTtx, eTty, eTtz}}, + {"TmunuBase::stress_energy_tensor", {eTxx, eTxy, eTxz, eTyy, eTyz, eTzz}} +}; + +groups = Join [declaredGroups, extraGroups]; + + + +(******************************************************************************) +(* Initial data *) +(******************************************************************************) + +initialCalc = +{ + Name -> thorn <> "_Minkowski", + Schedule -> {"IN ADMBase_InitialData"}, + ConditionalOnKeyword -> {"my_initial_data", "Minkowski"}, + Equations -> + { + phi -> IfThen[conformalMethod==CMW, 1, 0], + gt[la,lb] -> KD[la,lb], + trK -> 0, + At[la,lb] -> 0, + Xt[ua] -> 0, + alpha -> 1, + A -> 0, + beta[ua] -> 0, + B[ua] -> 0, + IfCCZ4[Theta -> 0] + } +}; + + + +(******************************************************************************) +(* Split a calculation *) +(******************************************************************************) + +PartialCalculation[calc_, suffix_, updates_, evolVars_] := +Module[ + {name, calc1, replaces, calc2, vars, patterns, eqs, calc3}, + (* Add suffix to name *) + name = lookup[calc, Name] <> suffix; + calc1 = mapReplace[calc, Name, name]; + (* Replace some entries in the calculation *) + (* replaces = Map[Function[rule, mapReplace[#, rule[[1]], rule[[2]]]&], updates]; *) + replaces = updates //. (lhs_ -> rhs_) -> (mapReplace[#, lhs, rhs]&); + calc2 = Apply[Composition, replaces][calc1]; + (* Remove unnecessary equations *) + vars = Join[evolVars, lookup[calc2, Shorthands]]; + patterns = Replace[vars, { Tensor[n_,__] -> Tensor[n,__] , + dot[Tensor[n_,__]] -> dot[Tensor[n,__]]}, 1]; + eqs = FilterRules[lookup[calc, Equations], patterns]; + calc3 = mapReplace[calc2, Equations, eqs]; + calc3 +]; + + + +(******************************************************************************) +(* Convert from ADMBase *) +(******************************************************************************) + +convertFromADMBaseCalc = +{ + Name -> thorn <> "_convertFromADMBase", + Schedule -> {"AT initial AFTER ADMBase_PostInitial"}, + ConditionalOnKeyword -> {"my_initial_data", "ADMBase"}, + Shorthands -> {g[la,lb], detg, gu[ua,ub], em4phi}, + Equations -> + { + g[la,lb] -> admg[la,lb], + detg -> detgExpr, + gu[ua,ub] -> 1/detg detgExpr MatrixInverse [g[ua,ub]], + + phi -> IfThen[conformalMethod==CMW, detg^(-1/6), Log[detg]/12], + em4phi -> IfThen[conformalMethod==CMW, phi^2, Exp[-4 phi]], + gt[la,lb] -> em4phi g[la,lb], + + trK -> gu[ua,ub] admK[la,lb], + At[la,lb] -> em4phi (admK[la,lb] - (1/3) g[la,lb] trK), + + alpha -> admalpha, + + beta[ua] -> admbeta[ua], + + IfCCZ4[Theta -> 0] + } +}; + +convertFromADMBaseGammaCalc = +{ + Name -> thorn <> "_convertFromADMBaseGamma", + Schedule -> {"AT initial AFTER " <> thorn <> "_convertFromADMBase"}, + ConditionalOnKeyword -> {"my_initial_data", "ADMBase"}, + (* + Where -> InteriorNoSync, + *) + (* Do not synchronise right after this routine; instead, synchronise + after extrapolating *) + Where -> Interior, + (* Synchronise after this routine, so that the refinement boundaries + are set correctly before extrapolating. (We will need to + synchronise again after extrapolating because extrapolation does + not fill ghost zones, but this is irrelevant here.) *) + Shorthands -> {dir[ua], + detgt, gtu[ua,ub], Gt[ua,lb,lc], theta}, + Equations -> + { + dir[ua] -> Sign[beta[ua]], + + detgt -> 1 (* detgtExpr *), + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + Gt[ua,lb,lc] -> 1/2 gtu[ua,ud] + (PD[gt[lb,ld],lc] + PD[gt[lc,ld],lb] - PD[gt[lb,lc],ld]), + Xt[ua] -> gtu[ub,uc] Gt[ua,lb,lc], + +(* + A -> - admdtalpha / (harmonicF alpha^harmonicN) (LapseAdvectionCoeff - 1), +*) + (* If LapseACoeff=0, then A is not evolved, in the sense that it + does not influence the time evolution of other variables. *) + A -> IfThen [LapseACoeff != 0, + 1 / (- harmonicF alpha^harmonicN) + (+ admdtalpha + - LapseAdvectionCoeff Upwind[beta[ua], alpha, la]), + 0], + + theta -> thetaExpr, + + (* If ShiftBCoeff=0 or theta ShiftGammaCoeff=0, then B^i is not + evolved, in the sense that it does not influence the time + evolution of other variables. *) + B[ua] -> IfThen [ShiftGammaCoeff ShiftBCoeff != 0, + 1 / (theta ShiftGammaCoeff) + (+ admdtbeta[ua] + - ShiftAdvectionCoeff Upwind[beta[ub], beta[ua], lb]), + 0] + } +}; + +(* Initialise the Gamma variables to 0. This is necessary with + multipatch because convertFromADMBaseGamma does not perform the + conversion in the boundary points, and the order in which symmetry + (interpatch) and outer boundary conditions is applied means that + points which are both interpatch and symmetry points are never + initialised. *) +initGammaCalc = +{ + Name -> thorn <> "_InitGamma", + Schedule -> {"AT initial BEFORE " <> thorn <> "_convertFromADMBaseGamma"}, + ConditionalOnKeyword -> {"my_initial_data", "ADMBase"}, + Where -> Everywhere, + Equations -> + { + Xt[ua] -> 0, + A -> 0, + B[ua] -> 0 + } +}; + + + +(******************************************************************************) +(* Convert to ADMBase *) +(******************************************************************************) + +convertToADMBaseCalc = +{ + Name -> thorn <> "_convertToADMBase", + Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, + Where -> Everywhere, + Shorthands -> {e4phi}, + Equations -> + { + e4phi -> IfThen[conformalMethod==CMW, 1/phi^2, Exp[4 phi]], + admg[la,lb] -> e4phi gt[la,lb], + admK[la,lb] -> e4phi At[la,lb] + (1/3) admg[la,lb] trK, + admalpha -> alpha, + admbeta[ua] -> beta[ua] + } +}; + +convertToADMBaseDtLapseShiftCalc = +{ + Name -> thorn <> "_convertToADMBaseDtLapseShift", + Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, + ConditionalOnKeyword -> {"dt_lapse_shift_method", "correct"}, + Where -> Interior, + Shorthands -> {dir[ua], detgt, gtu[ua,ub], eta, theta}, + Equations -> + { + dir[ua] -> Sign[beta[ua]], + + detgt -> 1 (* detgtExpr *), + (* This leads to simpler code... *) + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + + eta -> etaExpr, + theta -> thetaExpr, + + (* see RHS *) +(* + admdtalpha -> - harmonicF alpha^harmonicN + ((1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK) + + LapseAdvectionCoeff beta[ua] PDu[alpha,la], +*) + admdtalpha -> - harmonicF alpha^harmonicN + (+ LapseACoeff A + + ((1 - LapseACoeff) + (trK - IfCCZ4[2 Theta, 0]))) + + LapseAdvectionCoeff Upwind[beta[ua], alpha, la], + admdtbeta[ua] -> IfThen[harmonicShift, + - 1/2 gtu[ua,uj] phi alpha + (- 2 alpha PD[phi,lj] + + 2 phi PD[alpha,lj] + + gtu[uk,ul] phi alpha + (PD[gt[lk,ll],lj] - 2 PD[gt[lj,lk],ll])), + (* else *) + + theta ShiftGammaCoeff + (+ ShiftBCoeff B[ua] + + (1 - ShiftBCoeff) + (Xt[ua] - eta BetaDriver beta[ua]))] + + ShiftAdvectionCoeff Upwind[beta[ub], beta[ua], lb] + } +}; + +convertToADMBaseDtLapseShiftBoundaryCalc = +{ + Name -> thorn <> "_convertToADMBaseDtLapseShiftBoundary", + Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, + ConditionalOnKeyword -> {"dt_lapse_shift_method", "correct"}, + Where -> BoundaryWithGhosts, + Shorthands -> {detgt, gtu[ua,ub], eta, theta}, + Equations -> + { + detgt -> 1 (* detgtExpr *), + (* This leads to simpler code... *) + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + + eta -> etaExpr, + theta -> thetaExpr, + + (* see RHS, but omit derivatives near the boundary *) +(* + admdtalpha -> - harmonicF alpha^harmonicN + ((1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK), +*) + admdtalpha -> - harmonicF alpha^harmonicN + (+ LapseACoeff A + + ((1 - LapseACoeff) + (trK - IfCCZ4[2 Theta, 0]))), + admdtbeta[ua] -> IfThen[harmonicShift, + 0, + (* else *) + + theta ShiftGammaCoeff + (+ ShiftBCoeff B[ua] + + (1 - ShiftBCoeff) + (Xt[ua] - eta BetaDriver beta[ua]))] + } +}; + +convertToADMBaseFakeDtLapseShiftCalc = +{ + Name -> thorn <> "_convertToADMBaseFakeDtLapseShift", + Schedule -> {"IN " <> thorn <> "_convertToADMBaseGroup"}, + ConditionalOnKeyword -> {"dt_lapse_shift_method", "noLapseShiftAdvection"}, + Where -> Everywhere, + Shorthands -> {detgt, gtu[ua,ub], eta, theta}, + Equations -> + { + detgt -> 1 (* detgtExpr *), + (* This leads to simpler code... *) + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + + eta -> etaExpr, + theta -> thetaExpr, + + (* see RHS, but omit derivatives everywhere (which is wrong, but + faster, since it does not require synchronisation or boundary + conditions) *) +(* + admdtalpha -> - harmonicF alpha^harmonicN + ((1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK), +*) + admdtalpha -> - harmonicF alpha^harmonicN + (+ LapseACoeff A + + ((1 - LapseACoeff) + (trK - IfCCZ4[2 Theta, 0]))), + admdtbeta[ua] -> IfThen[harmonicShift, + 0, + (* else *) + + theta ShiftGammaCoeff + (+ ShiftBCoeff B[ua] + + (1 - ShiftBCoeff) + (Xt[ua] - eta BetaDriver beta[ua]))] + } +}; + +(******************************************************************************) +(* Evolution equations *) +(******************************************************************************) + +evolCalc = +{ + Name -> thorn <> "_RHS", + Schedule -> {"IN " <> thorn <> "_evolCalcGroup"}, + (* + Where -> Interior, + *) + (* Synchronise the RHS grid functions after this routine, so that + the refinement boundaries are set correctly before applying the + radiative boundary conditions. *) + Where -> InteriorNoSync, + ConditionalOnKeyword -> {"RHS_split", "combined"}, + Shorthands -> {dir[ua], + detgt, gtu[ua,ub], + Gt[ua,lb,lc], Gtl[la,lb,lc], Gtlu[la,lb,uc], Xtn[ua], + Rt[la,lb], Rphi[la,lb], R[la,lb], + Atm[ua,lb], Atu[ua,ub], + e4phi, em4phi, cdphi[la], cdphi2[la,lb], g[la,lb], detg, + gu[ua,ub], Ats[la,lb], trAts, eta, theta, + rho, S[la], trS, fac1, fac2, dottrK, dotXt[ua], + epsdiss[ua], IfCCZ4[Z[ua]], IfCCZ4[dotTheta]}, + Equations -> + { + dir[ua] -> Sign[beta[ua]], + + detgt -> 1 (* detgtExpr *), + + (* This leads to simpler code... *) + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + Gtl[la,lb,lc] -> 1/2 + (PD[gt[lb,la],lc] + PD[gt[lc,la],lb] - PD[gt[lb,lc],la]), + Gtlu[la,lb,uc] -> gtu[uc,ud] Gtl[la,lb,ld], + Gt[ua,lb,lc] -> gtu[ua,ud] Gtl[ld,lb,lc], + + (* The conformal connection functions calculated from the conformal metric, + used instead of Xt where no derivatives of Xt are taken *) + Xtn[ui] -> gtu[uj,uk] Gt[ui,lj,lk], + + e4phi -> IfThen[conformalMethod==CMW, 1/phi^2, Exp[4 phi]], + em4phi -> 1 / e4phi, + g[la,lb] -> e4phi gt[la,lb], + detg -> detgExpr, + gu[ua,ub] -> em4phi gtu[ua,ub], + + (* The Z quantities *) + (* gr-qc:1106.2254 (2011), eqn. (23) *) + IfCCZ4[ + Z[ud] -> (1/2) gu[ua,ud] (- PD[gt[la,lb],lc] gtu[ub,uc] + gt[la,lc] Xt[uc]) + ], + + (* PRD 62, 044034 (2000), eqn. (18) *) + (* Adding Z term by changing Xtn to Xt *) + Rt[li,lj] -> - (1/2) gtu[ul,um] PD[gt[li,lj],ll,lm] + + (1/2) gt[lk,li] PD[Xt[uk],lj] + + (1/2) gt[lk,lj] PD[Xt[uk],li] + + (1/2) Xtn[uk] Gtl[li,lj,lk] + + (1/2) Xtn[uk] Gtl[lj,li,lk] + + (+ Gt[uk,li,ll] Gtlu[lj,lk,ul] + + Gt[uk,lj,ll] Gtlu[li,lk,ul] + + Gt[uk,li,ll] Gtlu[lk,lj,ul]), + + fac1 -> IfThen[conformalMethod==CMW, -1/(2 phi), 1], + cdphi[la] -> fac1 CDt[phi,la], + fac2 -> IfThen[conformalMethod==CMW, 1/(2 phi^2), 0], + cdphi2[la,lb] -> fac1 CDt[phi,la,lb] + fac2 CDt[phi,la] CDt[phi,lb], + + (* PRD 62, 044034 (2000), eqn. (15) *) + Rphi[li,lj] -> - 2 cdphi2[lj,li] + - 2 gt[li,lj] gtu[ul,un] cdphi2[ll,ln] + + 4 cdphi[li] cdphi[lj] + - 4 gt[li,lj] gtu[ul,un] cdphi[ln] cdphi[ll], + + Atm[ua,lb] -> gtu[ua,uc] At[lc,lb], + Atu[ua,ub] -> Atm[ua,lc] gtu[ub,uc], + + R[la,lb] -> Rt[la,lb] + Rphi[la,lb], + IfCCZ4[ + R[la,lb] -> R[la,lb] + (2/phi) (+ g[la,lc] Z[uc] PD[phi,lb] + + g[lb,lc] Z[uc] PD[phi,la] - g[la,lb] Z[uc] PD[phi,lc]) + + e4phi Z[uc] PD[gt[la,lb],lc] + ], + + (* Matter terms *) + + (* rho = n^a n^b T_ab *) + rho -> addMatter + (1/alpha^2 (T00 - 2 beta[ui] T0[li] + beta[ui] beta[uj] T[li,lj])), + + (* S_i = -p^a_i n^b T_ab, where p^a_i = delta^a_i + n^a n_i *) + S[li] -> addMatter (-1/alpha (T0[li] - beta[uj] T[li,lj])), + + (* trS = gamma^ij T_ij *) + trS -> addMatter (em4phi gtu[ui,uj] T[li,lj]), + + (* RHS terms *) + + (* PRD 62, 044034 (2000), eqn. (10) *) + (* PRD 67 084023 (2003), eqn. (16) and (23) *) + dot[phi] -> IfThen[conformalMethod==CMW, 1/3 phi, -1/6] + (alpha trK - PD[beta[ua],la]), + + (* PRD 62, 044034 (2000), eqn. (9) *) + (* gr-qc:1106.2254 (2011), eqn. (14) *) + (* removing trA from Aij ensures that detg = 1 *) + dot[gt[la,lb]] -> - 2 alpha (At[la,lb] - IfCCZ4[(1/3) At[lc,ld] gtu[uc,ud] gt[la,lb], 0]) + + gt[la,lc] PD[beta[uc],lb] + gt[lb,lc] PD[beta[uc],la] + - (2/3) gt[la,lb] PD[beta[uc],lc], + (* PRD 62, 044034 (2000), eqn. (20) *) + (* PRD 67 084023 (2003), eqn (26) *) + (* gr-qc:1106.2254 (2011), eqn. (19) *) + (* Adding Z terms by changing Xtn to Xt, + also adding extra Z and Theta terms *) + dotXt[ui] -> - 2 Atu[ui,uj] PD[alpha,lj] + + 2 alpha (+ Gt[ui,lj,lk] Atu[uk,uj] + - (2/3) gtu[ui,uj] PD[trK,lj] + + 6 Atu[ui,uj] cdphi[lj]) + + gtu[uj,ul] PD[beta[ui],lj,ll] + + (1/3) gtu[ui,uj] PD[beta[ul],lj,ll] + - Xtn[uj] PD[beta[ui],lj] + + (2/3) Xtn[ui] PD[beta[uj],lj] + + IfCCZ4[ + + GammaShift 2 e4phi (- Z[uj] PD[beta[ui],lj] + + (2/3) Z[ui] PD[beta[uj],lj]) + - (4/3) alpha e4phi Z[ui] trK + + 2 gtu[ui,uj] (+ alpha PD[Theta,lj] + - Theta PD[alpha,lj]) + - 2 alpha e4phi dampk1 Z[ui], + 0] + (* Equation (4.28) in Baumgarte & Shapiro (Phys. Rept. 376 (2003) 41-131) *) + + addMatter (- 16 Pi alpha gtu[ui,uj] S[lj]), + dot[Xt[ui]] -> dotXt[ui], + + (* gr-qc:1106.2254 (2011), eqn. (18) *) + IfCCZ4[ + dotTheta -> + - PD[alpha,la] Z[ua] - dampk1 (2 + dampk2) alpha Theta + + (1/2) alpha (gu[ua,ub] R[la,lb] - Atm[ua,lb] Atm[ub,la] + (2/3) trK^2 - 2 trK Theta) + + addMatter (- 8 Pi alpha rho) + ], + + IfCCZ4[ + dot[Theta] -> dotTheta + ], + + (* PRD 62, 044034 (2000), eqn. (11) *) + (* gr-qc:1106.2254 (2011), eqn. (17) *) + (* Adding the RHS of Theta to K, because K_Z4 = K_BSSN + 2 Theta *) + (* Also adding the Z term, as it has to cancel with the one in Theta *) + dottrK -> - em4phi ( gtu[ua,ub] ( PD[alpha,la,lb] + + 2 cdphi[la] PD[alpha,lb] ) + - Xtn[ua] PD[alpha,la] ) + + alpha (Atm[ua,lb] Atm[ub,la] + (1/3) trK^2) + + IfCCZ4[ + + 2 dotTheta + 2 PD[alpha,la] Z[ua] + + dampk1 (1 - dampk2) alpha Theta, + 0] + (* Equation (4.21) in Baumgarte & Shapiro (Phys. Rept. 376 (2003) 41-131) *) + + addMatter (4 Pi alpha (rho + trS)), + dot[trK] -> dottrK, + + (* PRD 62, 044034 (2000), eqn. (12) *) + (* TODO: Should we use the Hamiltonian constraint to make Rij tracefree? *) + (* gr-qc:1106.2254 (2011), eqn. (15) *) + (* Adding Z terms in the Ricci and Theta terms *) + Ats[la,lb] -> - CDt[alpha,la,lb] + + + 2 (PD[alpha,la] cdphi[lb] + PD[alpha,lb] cdphi[la] ) + + alpha R[la,lb], + trAts -> gu[ua,ub] Ats[la,lb], + dot[At[la,lb]] -> + em4phi (+ Ats[la,lb] - (1/3) g[la,lb] trAts ) + + alpha (+ ((trK - IfCCZ4[2 Theta, 0]) + At[la,lb]) + - 2 At[la,lc] Atm[uc,lb]) + + At[la,lc] PD[beta[uc],lb] + At[lb,lc] PD[beta[uc],la] + - (2/3) At[la,lb] PD[beta[uc],lc] + (* Equation (4.23) in Baumgarte & Shapiro (Phys. Rept. 376 (2003) 41-131) *) + + addMatter (- em4phi alpha 8 Pi + (T[la,lb] - (1/3) g[la,lb] trS)), + + (* dot[alpha] -> - harmonicF alpha^harmonicN trK, *) + (* dot[alpha] -> - harmonicF alpha^harmonicN A + Lie[alpha, beta], *) +(* + dot[alpha] -> - harmonicF alpha^harmonicN ( + (1 - LapseAdvectionCoeff) A + LapseAdvectionCoeff trK) + + LapseAdvectionCoeff beta[ua] PDu[alpha,la], + dot[A] -> (1 - LapseAdvectionCoeff) (dottrK - AlphaDriver A), +*) + dot[alpha] -> - harmonicF alpha^harmonicN + (+ LapseACoeff A + + ((1 - LapseACoeff) + (+ trK - IfCCZ4[2 Theta, 0] + + AlphaDriver (alpha - 1)))), + + dot[A] -> + (LapseACoeff + (+ dottrK - IfCCZ4[2 dotTheta, 0] + - AlphaDriver A)), + + eta -> etaExpr, + theta -> thetaExpr, + + (* dot[beta[ua]] -> eta Xt[ua], *) + (* dot[beta[ua]] -> ShiftGammaCoeff alpha^ShiftAlphaPower B[ua], *) + dot[beta[ua]] -> IfThen[harmonicShift, + - 1/2 gtu[ua,uj] phi alpha + (- 2 alpha PD[phi,lj] + + 2 phi PD[alpha,lj] + + gtu[uk,ul] phi alpha + (PD[gt[lk,ll],lj] - 2 PD[gt[lj,lk],ll])), + (* else *) + + theta ShiftGammaCoeff + (+ ShiftBCoeff B[ua] + + (1 - ShiftBCoeff) + (Xt[ua] - eta BetaDriver beta[ua]))], + + dot[B[ua]] -> + ShiftBCoeff (dotXt[ua] - eta BetaDriver B[ua]) + (* Note that this dotXt[ua] is not yet \partial_t \tilde \Gamma^i, because the + advection term has not yet been added. It is actually + \partial_t \tilde \Gamma^i - \beta^j \partial_j \tilde \Gamma^i *) + } +}; + +advectCalc = +{ + Name -> thorn <> "_Advect", + Schedule -> {"IN " <> thorn <> "_evolCalcGroup " <> + "AFTER (" <> thorn <> "_RHS " <> thorn <> "_RHS1 " <> thorn <> "_RHS2)"}, + (* + Where -> Interior, + *) + (* Synchronise the RHS grid functions after this routine, so that + the refinement boundaries are set correctly before applying the + radiative boundary conditions. *) + Where -> InteriorNoSync, + ConditionalOnKeyword -> {"advection_split", "combined"}, + Shorthands -> {dir[ua]}, + Equations -> + { + dir[ua] -> Sign[beta[ua]], + + dot[phi] -> dot[phi] + Upwind[beta[ua], phi, la], + + dot[gt[la,lb]] -> dot[gt[la,lb]] + Upwind[beta[uc], gt[la,lb], lc], + + dot[Xt[ui]] -> dot[Xt[ui]] + Upwind[beta[uj], Xt[ui], lj], + + IfCCZ4[ + dot[Theta] -> dot[Theta] + Upwind[beta[ua], Theta, la] + ], + + dot[trK] -> dot[trK] + Upwind[beta[ua], trK, la], + + dot[At[la,lb]] -> dot[At[la,lb]] + Upwind[beta[uc], At[la,lb], lc], + + dot[alpha] -> dot[alpha] + + LapseAdvectionCoeff Upwind[beta[ua], alpha, la], + + dot[A] -> dot[A] + + LapseACoeff ( + + LapseAdvectionCoeff Upwind[beta[ua], A, la] + + (1 - LapseAdvectionCoeff) Upwind[beta[ua], trK, la]), + + dot[beta[ua]] -> dot[beta[ua]] + + ShiftAdvectionCoeff Upwind[beta[ub], beta[ua], lb], + + dot[B[ua]] -> dot[B[ua]] + + ShiftBCoeff ( + + ShiftAdvectionCoeff Upwind[beta[ub], B[ua], lb] + + ((1 - ShiftAdvectionCoeff) + Upwind[beta[ub], Xt[ua], lb])) + (* Note that the advection term \beta^j \partial_j \tilde \Gamma^i is not + subtracted here when ShiftAdvectionCoefficient == 1 because it was + implicitly subtracted before (see comment in previous calculation of + dot[B[ua]]. *) + } +}; + +varsNames = { + {"phi", dot[phi]}, + {"gt", dot[gt[la,lb]]}, + {"Xt", dot[Xt[ui]]}, + {"trK", dot[trK]}, + {"At", dot[At[la,lb]]}, + {"alpha", dot[alpha]}, + {"A", dot[A]}, + {"beta", dot[beta[ua]]}, + {"B", dot[B[ua]]}, + IfCCZ4[{"Theta", dot[Theta]}] + }; + +advectCalcs = Map[ + PartialCalculation[advectCalc, "_"<>ToString[First[#]], + {ConditionalOnKeyword -> {"advection_split", + "per variable"}}, + {Last[#]}]&, + varsNames]; + +evolCalc1 = PartialCalculation[evolCalc, "1", + { + ConditionalOnKeyword -> {"RHS_split", "split At"} + }, + { + dot[phi], + dot[gt[la,lb]], + dot[Xt[ui]], + dot[trK], + dot[alpha], + dot[A], + dot[beta[ua]], + dot[B[ua]], + IfCCZ4[dot[Theta]] + }]; + +evolCalc2 = PartialCalculation[evolCalc, "2", + { + ConditionalOnKeyword -> {"RHS_split", "split At"} + }, + { + dot[At[la,lb]] + }]; + +dissCalc = +{ + Name -> thorn <> "_Dissipation", + Schedule -> {"IN " <> thorn <> "_evolCalcGroup " <> + "AFTER (" <> thorn <> "_RHS1 " <> thorn <> "_RHS2)"}, + ConditionalOnKeyword -> {"apply_dissipation", "always"}, + Where -> InteriorNoSync, + Shorthands -> {epsdiss[ua]}, + Equations -> + { + epsdiss[ua] -> EpsDiss, + Sequence@@Table[ + dot[var] -> dot[var] + epsdiss[ux] PDdiss[var,lx], + {var, {phi, gt[la,lb], Xt[ui], IfCCZ4[Theta], trK, At[la,lb], + alpha, A, beta[ua], B[ua]}}] + } +}; + +dissCalcs = +Table[ +{ + Name -> thorn <> "_Dissipation_" <> ToString[var /. {Tensor[n_,__] -> n}], + Schedule -> {"IN " <> thorn <> "_evolCalcGroup " <> + "AFTER (" <> thorn <> "_RHS1 " <> thorn <> "_RHS2)"}, + ConditionalOnKeyword -> {"apply_dissipation", "always"}, + Where -> InteriorNoSync, + Shorthands -> {epsdiss[ua]}, + Equations -> + { + epsdiss[ua] -> EpsDiss, + dot[var] -> dot[var] + epsdiss[ux] PDdiss[var,lx] + } +}, + {var, {phi, gt[la,lb], Xt[ui], IfCCZ4[Theta], trK, At[la,lb], + alpha, A, beta[ua], B[ua]}} +]; + +RHSStaticBoundaryCalc = +{ + Name -> thorn <> "_RHSStaticBoundary", + Schedule -> {"IN MoL_CalcRHS"}, + ConditionalOnKeyword -> {"my_rhs_boundary_condition", "static"}, + Where -> Boundary, + Equations -> + { + dot[phi] -> 0, + dot[gt[la,lb]] -> 0, + dot[trK] -> 0, + dot[At[la,lb]] -> 0, + dot[Xt[ua]] -> 0, + dot[alpha] -> 0, + dot[A] -> 0, + dot[beta[ua]] -> 0, + dot[B[ua]] -> 0, + IfCCZ4[dot[Theta] -> 0] + } +}; + +(* Initialise the RHS variables in analysis in case they are going to + be output - the noninterior points cannot be filled, so we define + them to be zero *) +initRHSCalc = +{ + Name -> thorn <> "_InitRHS", + Schedule -> {"AT analysis BEFORE " <> thorn <> "_evolCalcGroup"}, + Where -> Everywhere, + Equations -> + { + dot[phi] -> 0, + dot[gt[la,lb]] -> 0, + dot[trK] -> 0, + dot[At[la,lb]] -> 0, + dot[Xt[ua]] -> 0, + dot[alpha] -> 0, + dot[A] -> 0, + dot[beta[ua]] -> 0, + dot[B[ua]] -> 0, + IfCCZ4[dot[Theta] -> 0] + } +}; + +RHSRadiativeBoundaryCalc = +{ + Name -> thorn <> "_RHSRadiativeBoundary", + Schedule -> {"IN MoL_CalcRHS"}, + ConditionalOnKeyword -> {"my_rhs_boundary_condition", "radiative"}, + Where -> Boundary, + Shorthands -> {dir[ua], + detgt, gtu[ua,ub], em4phi, gu[ua,ub], + nn[la], nu[ua], nlen, nlen2, su[ua], + vg}, + Equations -> + { + dir[ua] -> Sign[normal[ua]], + + detgt -> 1 (* detgtExpr *), + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + em4phi -> IfThen[conformalMethod==CMW, phi^2, Exp[-4 phi]], + gu[ua,ub] -> em4phi gtu[ua,ub], + + nn[la] -> Euc[la,lb] normal[ub], + nu[ua] -> gu[ua,ub] nn[lb], + nlen2 -> nu[ua] nn[la], + nlen -> Sqrt[nlen2], + su[ua] -> nu[ua] / nlen, + + vg -> Sqrt[harmonicF], + + dot[phi] -> - vg su[uc] PDo[phi ,lc], + dot[gt[la,lb]] -> - su[uc] PDo[gt[la,lb],lc], + dot[trK] -> - vg su[uc] PDo[trK ,lc], + dot[At[la,lb]] -> - su[uc] PDo[At[la,lb],lc], + dot[Xt[ua]] -> - su[uc] PDo[Xt[ua] ,lc], + dot[alpha] -> - vg su[uc] PDo[alpha ,lc], + dot[A] -> - vg su[uc] PDo[A ,lc], + dot[beta[ua]] -> - su[uc] PDo[beta[ua] ,lc], + dot[B[ua]] -> - su[uc] PDo[B[ua] ,lc], + IfCCZ4[ + dot[Theta] -> - vg su[uc] PDo[Theta ,lc] + ] + } +}; + +enforceCalc = +{ + Name -> thorn <> "_enforce", + Schedule -> {"IN MoL_PostStepModify"}, + Shorthands -> {detgt, gtu[ua,ub], trAt}, + Equations -> + { + (* The following comment is still interesting, but is not correct + any more since it is now scheduled in MoL_PostStepModify instead: + + Enforcing the constraints needs to be a projection, because it + is applied in MoL_PostStep and may thus be applied multiple + times, not only during time evolution. Therefore detgt has to + be calculated correctly, without assuming that det gt_ij = 1, + which is not always the case (since we don't enforce it). On + the other hand, this may not be so important... *) + detgt -> 1 (* detgtExpr *), + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + + trAt -> gtu[ua,ub] At[la,lb], + + At[la,lb] -> At[la,lb] - (1/3) gt[la,lb] trAt, + + alpha -> Max[alpha, MinimumLapse] + } +}; + +(******************************************************************************) +(* Boundary conditions *) +(******************************************************************************) + +boundaryCalc = +{ + Name -> thorn <> "_boundary", + Schedule -> {"IN MoL_PostStep"}, + ConditionalOnKeyword -> {"my_boundary_condition", "Minkowski"}, + Where -> BoundaryWithGhosts, + Equations -> + { + phi -> IfThen[conformalMethod==CMW, 1, 0], + gt[la,lb] -> KD[la,lb], + trK -> 0, + At[la,lb] -> 0, + Xt[ua] -> 0, + alpha -> 1, + A -> 0, + beta[ua] -> 0, + B[ua] -> 0, + IfCCZ4[Theta -> 0] + } +}; + +(******************************************************************************) +(* Constraint equations *) +(******************************************************************************) + +constraintsCalc = +{ + Name -> thorn <> "_constraints", + Schedule -> Automatic, + After -> "MoL_PostStep", + Where -> Interior, + Shorthands -> {detgt, ddetgt[la], gtu[ua,ub], Z[ua], + Gt[ua,lb,lc], Gtl[la,lb,lc], Gtlu[la,lb,uc], Xtn[ua], + e4phi, em4phi, + g[la,lb], detg, gu[ua,ub], ddetg[la], G[ua,lb,lc], + Rt[la,lb], Rphi[la,lb], R[la,lb], trR, Atm[ua,lb], + gK[la,lb,lc], cdphi[la], cdphi2[la,lb], + rho, S[la], fac1, fac2}, + Equations -> + { + detgt -> 1 (* detgtExpr *), + ddetgt[la] -> 0 (* ddetgtExpr[la] *), + + (* This leads to simpler code... *) + gtu[ua,ub] -> 1/detgt detgtExpr MatrixInverse [gt[ua,ub]], + Gtl[la,lb,lc] -> 1/2 + (PD[gt[lb,la],lc] + PD[gt[lc,la],lb] - PD[gt[lb,lc],la]), + Gtlu[la,lb,uc] -> gtu[uc,ud] Gtl[la,lb,ld], + Gt[ua,lb,lc] -> gtu[ua,ud] Gtl[ld,lb,lc], + + (* The conformal connection functions calculated from the conformal metric, + used instead of Xt where no derivatives of Xt are taken *) + Xtn[ui] -> gtu[uj,uk] Gt[ui,lj,lk], + + e4phi -> IfThen[conformalMethod==CMW, 1/phi^2, Exp[4 phi]], + em4phi -> 1 / e4phi, + g[la,lb] -> e4phi gt[la,lb], + detg -> e4phi^3, + gu[ua,ub] -> em4phi gtu[ua,ub], + + (* The Z quantities *) + IfCCZ4[ + Z[ud] -> (1/2) gu[ua,ud] (- PD[gt[la,lb],lc] gtu[ub,uc] + gt[la,lc] Xt[uc]) + ], + + (* PRD 62, 044034 (2000), eqn. (18) *) + Rt[li,lj] -> - (1/2) gtu[ul,um] PD[gt[li,lj],ll,lm] + + (1/2) gt[lk,li] PD[Xt[uk],lj] + + (1/2) gt[lk,lj] PD[Xt[uk],li] + + (1/2) Xtn[uk] Gtl[li,lj,lk] + + (1/2) Xtn[uk] Gtl[lj,li,lk] + + (+ Gt[uk,li,ll] Gtlu[lj,lk,ul] + + Gt[uk,lj,ll] Gtlu[li,lk,ul] + + Gt[uk,li,ll] Gtlu[lk,lj,ul]), + + (* From the long turducken paper. + This expression seems to give the same result as the one from 044034. *) + (* TODO: symmetrise correctly: (ij) = (1/2) [i+j] *) +(* + Rt[li,lj] -> - (1/2) gtu[uk,ul] PD[gt[li,lj],lk,ll] + + gt[lk,li] PD[Xt[uk],lj] + gt[lk,lj] PD[Xt[uk],li] + + gt[li,ln] Gt[un,lj,lk] gtu[um,ua] gtu[uk,ub] PD[gt[la,lb],lm] + + gt[lj,ln] Gt[un,li,lk] gtu[um,ua] gtu[uk,ub] PD[gt[la,lb],lm] + + gtu[ul,us] (+ 2 Gt[uk,ll,li] gt[lj,ln] Gt[un,lk,ls] + + 2 Gt[uk,ll,lj] gt[li,ln] Gt[un,lk,ls] + + Gt[uk,li,ls] gt[lk,ln] Gt[un,ll,lj]), +*) + + (* Below would be a straightforward calculation, + without taking any Gamma^i into account. + This expression gives a different answer! *) +(* + Rt[la,lb] -> + Gt[u1,l2,la] Gt[l1,lb,u2] - Gt[u1,la,lb] Gt[l1,l2,u2] + + 1/2 gtu[u1,u2] (- PD[gt[l1,l2],la,lb] + PD[gt[l1,la],l2,lb] + - PD[gt[la,lb],l1,l2] + PD[gt[l2,lb],l1,la]), +*) + + fac1 -> IfThen[conformalMethod==CMW, -1/(2 phi), 1], + cdphi[la] -> fac1 CDt[phi,la], + fac2 -> IfThen[conformalMethod==CMW, 1/(2 phi^2), 0], + cdphi2[la,lb] -> fac1 CDt[phi,la,lb] + fac2 CDt[phi,la] CDt[phi,lb], + + (* PRD 62, 044034 (2000), eqn. (15) *) + Rphi[li,lj] -> - 2 cdphi2[lj,li] + - 2 gt[li,lj] gtu[ul,un] cdphi2[ll,ln] + + 4 cdphi[li] cdphi[lj] + - 4 gt[li,lj] gtu[ul,un] cdphi[ln] cdphi[ll], + + (* ddetg[la] -> PD[e4phi detg,la], *) + ddetg[la] -> e4phi ddetgt[la] + 4 detgt e4phi PD[phi,la], + (* TODO: check this equation, maybe simplify it by omitting ddetg *) + G[ua,lb,lc] -> Gt[ua,lb,lc] + + 1/(2 detg) (+ KD[ua,lb] ddetg[lc] + KD[ua,lc] ddetg[lb] + - (1/3) g[lb,lc] gu[ua,ud] ddetg[ld]), + + R[la,lb] -> + Rt[la,lb] + Rphi[la,lb], + + IfCCZ4[ + R[la,lb] -> R[la, lb] + (2/phi) (+ g[la,lc] Z[uc] PD[phi,lb] + + g[lb,lc] Z[uc] PD[phi,la] - g[la,lb] Z[uc] PD[phi,lc]) + + e4phi Z[uc] PD[gt[la,lb],lc] + ], + + trR -> gu[ua,ub] R[la,lb], + + (* K[la,lb] -> e4phi At[la,lb] + (1/3) g[la,lb] trK, *) + (* Km[ua,lb] -> gu[ua,uc] K[lc,lb], *) + Atm[ua,lb] -> gtu[ua,uc] At[lc,lb], + + (* Matter terms *) + + (* rho = n^a n^b T_ab *) + rho -> 1/alpha^2 (T00 - 2 beta[ui] T0[li] + beta[ui] beta[uj] T[li,lj]), + + (* S_i = -p^a_i n^b T_ab, where p^a_i = delta^a_i + n^a n_i *) + S[li] -> -1/alpha (T0[li] - beta[uj] T[li,lj]), + + (* Constraints *) + + (* H -> trR - Km[ua,lb] Km[ub,la] + trK^2, *) + (* PRD 67, 084023 (2003), eqn. (19) *) + H -> trR - Atm[ua,lb] Atm[ub,la] + (2/3) trK^2 - addMatter 16 Pi rho, + + (* gK[la,lb,lc] -> CD[K[la,lb],lc], *) +(* gK[la,lb,lc] -> + 4 e4phi PD[phi,lc] At[la,lb] + e4phi CD[At[la,lb],lc] + + (1/3) g[la,lb] PD[trK,lc], + M[la] -> gu[ub,uc] (gK[lc,la,lb] - gK[lc,lb,la]), *) + + M[li] -> + gtu[uj,uk] (CDt[At[li,lj],lk] + 6 At[li,lj] cdphi[lk]) + - (2/3) PD[trK,li] + - addMatter 8 Pi S[li], + (* TODO: use PRD 67, 084023 (2003), eqn. (20) *) + + (* det gamma-tilde *) + cS -> Log[detgt], + + (* Gamma constraint *) + cXt[ua] -> gtu[ub,uc] Gt[ua,lb,lc] - Xt[ua], + + (* trace A-tilde *) + cA -> gtu[ua,ub] At[la,lb] + } +}; + +constraintsCalc1 = PartialCalculation[constraintsCalc, "1", + {}, + { + H + }]; + +constraintsCalc2 = PartialCalculation[constraintsCalc, "2", + {}, + { + M[li], + cS, + cXt[ua], + cA + }]; + +(******************************************************************************) +(* Implementations *) +(******************************************************************************) + +inheritedImplementations = + Join[{"ADMBase"}, + If [addMatter!=0, {"TmunuBase"}, {}]]; + +(******************************************************************************) +(* Parameters *) +(******************************************************************************) + +inheritedKeywordParameters = {}; + +extendedKeywordParameters = +{ + { + Name -> "ADMBase::evolution_method", + AllowedValues -> {thorn} + }, + { + Name -> "ADMBase::lapse_evolution_method", + AllowedValues -> {thorn} + }, + { + Name -> "ADMBase::shift_evolution_method", + AllowedValues -> {thorn} + }, + { + Name -> "ADMBase::dtlapse_evolution_method", + AllowedValues -> {thorn} + }, + { + Name -> "ADMBase::dtshift_evolution_method", + AllowedValues -> {thorn} + } +}; + +keywordParameters = +{ + { + Name -> "my_initial_data", + (* Visibility -> "restricted", *) + (* Description -> "ddd", *) + AllowedValues -> {"ADMBase", "Minkowski"}, + Default -> "ADMBase" + }, + { + Name -> "my_initial_boundary_condition", + Visibility -> "restricted", + (* Description -> "ddd", *) + AllowedValues -> {"none"}, + Default -> "none" + }, + { + Name -> "my_rhs_boundary_condition", + Visibility -> "restricted", + (* Description -> "ddd", *) + AllowedValues -> {"none", "static", "radiative"}, + Default -> "none" + }, + { + Name -> "my_boundary_condition", + (* Visibility -> "restricted", *) + (* Description -> "ddd", *) + AllowedValues -> {"none", "Minkowski"}, + Default -> "none" + }, + { + Name -> "calculate_ADMBase_variables_at", + Visibility -> "restricted", + (* Description -> "ddd", *) + AllowedValues -> {"MoL_PostStep", "CCTK_EVOL", "CCTK_ANALYSIS"}, + Default -> "MoL_PostStep" + }, + { + Name -> "UseSpatialBetaDriver_UNUSED", + Visibility -> "restricted", + (* Description -> "ddd", *) + AllowedValues -> {"no", "yes"}, + Default -> "no" + }, + { + Name -> "dt_lapse_shift_method", + Description -> "Treatment of ADMBase dtlapse and dtshift", + AllowedValues -> {"correct", + "noLapseShiftAdvection" (* omit lapse and shift advection terms (faster) *) + }, + Default -> "correct" + }, + { + Name -> "apply_dissipation", + Description -> "Whether to apply dissipation to the RHSs", + AllowedValues -> {"always", + "never" (* yes and no keyword values confuse Cactus, and Kranc + doesn't support boolean parameters *) + }, + Default -> "never" + }, + { + Name -> "RHS_split", + Description -> "How to split RHS calculation", + AllowedValues -> {"combined", + "split At"}, + Default -> "split At" + }, + { + Name -> "advection_split", + Description -> "How to split advection calculation", + AllowedValues -> {"combined", + "per variable"}, + Default -> "combined" + } +}; + +intParameters = +{ + { + Name -> harmonicN, + Description -> "d/dt alpha = - f alpha^n K (harmonic=2, 1+log=1)", + Default -> 2 + }, + { + Name -> ShiftAlphaPower, + Default -> 0 + }, + { + Name -> conformalMethod, + Description -> "Treatment of conformal factor", + AllowedValues -> {{Value -> "0", Description -> "phi method"}, + {Value -> "1", Description -> "W method"}}, + Default -> 0 + }, + { + Name -> fdOrder, + Default -> derivOrder, + AllowedValues -> {2,4,6,8} + }, + { + Name -> harmonicShift, + Description -> "Whether to use the harmonic shift", + AllowedValues -> {{Value -> "0", Description -> "Gamma driver shift"}, + {Value -> "1", Description -> "Harmonic shift"}}, + Default -> 0 + } +}; + +realParameters = +{ + IfCCZ4[{ + Name -> GammaShift, + Description -> "Covariant shift term in Gamma", + Default -> 0.5 + }], + IfCCZ4[{ + Name -> dampk1, + Description -> "CCZ4 damping term 1 for Theta and Z", + Default -> 0 + }], + IfCCZ4[{ + Name -> dampk2, + Description -> "CCZ4 damping term 2 for Theta and Z", + Default -> 0 + }], + { + Name -> LapseACoeff, + Description -> "Whether to evolve A in time", + Default -> 0 + }, + { + Name -> harmonicF, + Description -> "d/dt alpha = - f alpha^n K (harmonic=1, 1+log=2)", + Default -> 1 + }, + { + Name -> AlphaDriver, + Default -> 0 + }, + { + Name -> ShiftBCoeff, + Description -> "Whether to evolve B^i in time", + Default -> 1 + }, + { + Name -> ShiftGammaCoeff, + Default -> 0 + }, + { + Name -> BetaDriver, + Default -> 0 + }, + { + Name -> LapseAdvectionCoeff, + Description -> "Factor in front of the lapse advection terms in 1+log", + Default -> 1 + }, + { + Name -> ShiftAdvectionCoeff, + Description -> "Factor in front of the shift advection terms in gamma driver", + Default -> 1 + }, + { + Name -> MinimumLapse, + Description -> "Minimum value of the lapse function", + Default -> -1 + }, + { + Name -> SpatialBetaDriverRadius, + Description -> "Radius at which the BetaDriver starts to be reduced", + AllowedValues -> {{Value -> "(0:*", Description -> "Positive"}}, + Default -> 10^12 + }, + { + Name -> SpatialShiftGammaCoeffRadius, + Description -> "Radius at which the ShiftGammaCoefficient starts to be reduced", + AllowedValues -> {{Value -> "(0:*", Description -> "Positive"}}, + Default -> 10^12 + }, + { + Name -> EpsDiss, + Description -> "Dissipation strength", + AllowedValues -> {{Value -> "(0:*", Description -> "Positive"}}, + Default -> 0 + } +}; + +(******************************************************************************) +(* Construct the thorns *) +(******************************************************************************) + +calculations = +Join[ +{ + initialCalc, + convertFromADMBaseCalc, + initGammaCalc, + convertFromADMBaseGammaCalc, + evolCalc, + evolCalc1, evolCalc2, + dissCalc, + advectCalc, + (*advectCalcs,*) + initRHSCalc, + RHSStaticBoundaryCalc, + (* RHSRadiativeBoundaryCalc, *) + enforceCalc, + boundaryCalc, + convertToADMBaseCalc, + convertToADMBaseDtLapseShiftCalc, + convertToADMBaseDtLapseShiftBoundaryCalc, + convertToADMBaseFakeDtLapseShiftCalc, + (* constraintsCalc, *) + constraintsCalc1, constraintsCalc2 +}, + advectCalcs + (*dissCalcs*) +]; + +CreateKrancThornTT [groups, ".", thorn, + Calculations -> calculations, + DeclaredGroups -> declaredGroupNames, + PartialDerivatives -> derivatives, + EvolutionTimelevels -> evolutionTimelevels, + DefaultEvolutionTimelevels -> 3, + UseJacobian -> True, + UseLoopControl -> True, + UseVectors -> useVectors, + UseOpenCL -> useOpenCL, + InheritedImplementations -> inheritedImplementations, + InheritedKeywordParameters -> inheritedKeywordParameters, + ExtendedKeywordParameters -> extendedKeywordParameters, + KeywordParameters -> keywordParameters, + IntParameters -> intParameters, + RealParameters -> realParameters +]; + +]; + + + +(******************************************************************************) +(* Options *) +(******************************************************************************) + +(* These are the arguments to createComment: + - derivative order: 2, 4, 6, 8, ... + - useJacobian: False or True + - split upwind derivatives: False or True + - use vectorisation: False or True + - use OpenCL: False or True + - timelevels: 2 or 3 + ## (keep this at 3; this is better chosen with a run-time parameter) + - matter: 0 or 1 + ## (matter seems cheap; it should be always enabled) + - thorn base name +*) + +createCode[4, False, True, True , False, 3, 1, "BSSN"]; +createCode[4, False, True, False, False, 3, 1, "BSSN"]; +createCode[4, False, True, True , True , 3, 1, "BSSN"]; + +createCode[4, False, True, True , False, 3, 1, "CCZ4"]; + diff --git a/test/src_dir/octave1.m b/test/src_dir/octave1.m index d72372d..4c795fb 100644 --- a/test/src_dir/octave1.m +++ b/test/src_dir/octave1.m @@ -4,7 +4,7 @@ ## 3-clause BSD license appended to this file. function varargout = toledolu(LU) - ## -*- texinfo -*- + ## (*- texinfo -*) ## @deftypefn{Function File} {[@var{L}, @var{U}, @var{P}]} = toledolu(@var{A}) ## @deftypefnx{Function File} {[@var{L}, @var{U}]} = toledolu(@var{A}) ## @deftypefnx{Function File} {@var{LUP}} = toledolu(@var{A}) @@ -20,8 +20,8 @@ ## See the help for lu for details about the other calling forms. ## ## For the algorithm, see - ## @itemize - ## @item + ## (* @itemize *) + ## (* @item *) ## Toledo, Sivan. "Locality of reference in LU decomposition with ## partial pivoting," SIAM J. of Matrix Analysis and Applications, ## v18, n4, 1997. DOI: 10.1137/S0895479896297744 diff --git a/test/src_dir/pascal2.pp b/test/src_dir/pascal2.pp index a820b9a..3e00b4e 100644 --- a/test/src_dir/pascal2.pp +++ b/test/src_dir/pascal2.pp @@ -110,3 +110,7 @@ end; end. + +class function Test.Run: Boolean; + +#include diff --git a/test/src_dir/perl.cgi b/test/src_dir/perl.cgi deleted file mode 100755 index 1ac7811..0000000 --- a/test/src_dir/perl.cgi +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/perl -w - -# ajaxCheckbox.pl - a script to test Ajax functionality - -use strict; -use CGI qw/:standard/; -use CGI::Ajax; -use DBI; - -# --- database authenication -my $dbh = do 'db.inc'; - -my $query = q{ SELECT project.project_id, project.name, project.phase, prio.prio, - HEX((255 - prio.prio)) AS hex, begun, tags - FROM project JOIN prio - ON (project.project_id = prio.project_id) - WHERE completed < 1 - ORDER BY prio.prio DESC LIMIT 3}; - -my $sth = $dbh->prepare($query); -$sth->execute(); -my $result = $dbh->selectall_arrayref($sth); - -my $cgi = new CGI; -my $pjx = new CGI::Ajax( 'toStruck' => \&perl_func ); -print $pjx->build_html( $cgi, \&Show_HTML); - -sub Show_HTML { - - use CGI qw/:standard/; - - my $html = < - - - This is the lastest source version - - - -

Carrot Queue

Priority List  |   - Add a listing  |  

Project listing

-HEAD - -foreach my $row (@$result) { - $html .= ""; - $html .= "
" . @$row[1] . "

"; -} - -# you can append stuff to the HTML this way -$html .= ""; - -return $html; -} - -sub perl_func { - my $input=shift; - - # if onClick the change the style - if ($input eq "ON") { - $input=""; - } else { - $input =""; - } -} diff --git a/test/src_dir/prolog.pl b/test/src_dir/prolog.pl new file mode 100644 index 0000000..5a82d23 --- /dev/null +++ b/test/src_dir/prolog.pl @@ -0,0 +1,9 @@ +/* test file for Prolog parsing */ + +% this is a Prolog source file + +% select(Element, List, Remaining) + +select(H, [H| T], T). +select(H, [X| R], [X| T]) :- + select(H, R, T). diff --git a/test/src_dir/puppet1.pp b/test/src_dir/puppet1.pp new file mode 100644 index 0000000..dea2fd8 --- /dev/null +++ b/test/src_dir/puppet1.pp @@ -0,0 +1,145 @@ +class bob::open_ldap { + + define foo::server ( + $argsfile = undef, + $bdb_cachesize = '', + $bdb_checkpoint = '', + $bdb_directory = undef, + $bdb_idlcachesize = '', + $bdb_rootdn, + $bdb_rootpw, + $bdb_shm_key = '', + $bdb_suffix, + $conf_path = undef, + $conf_dir = undef, + $enable = false, + $include = [], + $includepath = undef, + $modulepath = '', + $modules = [], + $package = undef, + $pidfile = undef, + $sysconf_path = undef + ) { + + $resource_name = "bob_openldap_server" + + if($name != "params") { + fail("${resource_name}: This function is a singleton. Make sure the resource name is 'params'.") + } + + case $operatingsystem { + Fedora: { + case $operatingsystemrelease { + /^(12|13)$/: { + if(!$argsfile) { $_argsfile = "/var/run/openldap/slapd.args" } + if(!$bdb_directory) { $_bdb_directory = "/var/lib/ldap" } + if(!$conf_path) { $_conf_path = "/etc/openldap/slapd.conf" } + if(!$conf_dir) { $_conf_dir = "/etc/openldap/slapd.d" } + if(!$package) { $_package = ["openldap-servers"] } + if(!$pidfile) { $_pidfile = "/var/run/openldap/slapd.pid" } + if(!$service) { $_service = "slapd" } + if(!$sysconf_path) { $_sysconf_path = "/etc/sysconfig/ldap" } + } + } + } + } + + # Presume the OS did not match and because these args are necessary, just + # bail with an error. + if(!($_argsfile and $_bdb_directory and $_pidfile and $_conf_path and + $_package and $_service and $_sysconf_path and $_conf_dir)) { + fail("${resource_name}: Unsupported operating system: ${operatingsystem} version ${operatingsystemrelease} and you have not setup the args for: argsfile, bdb_directory, conf_dir, conf_path, package, pidfile, sysconf_path and service.") + } + + # Fix paths - add forward slashes at the end of strings without them + $_includepath = regsubst($includepath, '([^/])$', '\1/') + $_dbconf_path = "${_bdb_directory}/DB_CONFIG" + + # ... + file { + $_conf_path: + content => template("bob_openldap/slapd.conf"), + require => Package[$_package], + owner => "ldap", + group => "root", + mode => "0440", + notify => Service[$_service]; + $_sysconf_path: + content => template("bob_openldap/ldap.sysconf"), + require => Package[$_package], + owner => "root", + group => "root", + mode => "0644"; + $_conf_dir: + force => true, + ensure => absent, + before => Service[$_service]; + $_dbconf_path: + content => "", + notify => Service[$_service]; + } + package { + $_package: + ensure => installed; + } + service { + $_service: + ensure => $enable ? { + true => "running", + false => "stopped" + }, + enable => $enable, + hasstatus => true, + require => [ Package[$_package], File[$_conf_path] ]; + } + } + + define client ( + $base, + $network_timeout = '', + $path = undef, + $timeout = '', + $binddn = '', + $tls_cacertdir = undef, + $uri + ) { + + $resource_name = "bob_openldap_client" + + if($name != "params") { + fail("${resource_name}: This function is a singleton. Make sure the resource name is 'params'.") + } + + case $operatingsystem { + Fedora: { + case $operatingsystemrelease { + /^(12|13)$/: { + if(!$tls_cacertdir) { $_tls_cacertdir = "/etc/openldap/cacerts" } + if(!$path) { $_path = "/etc/openldap/ldap.conf" } + } + } + } + } + + # Presume the OS did not match and because these args are necessary, just + # bail with an error. + if(!($_tls_cacertdir and $_path)) { + fail("${resource_name}: Unsupported operating system: ${operatingsystem} version ${operatingsystemrelease} and you have not setup the args for: tls_cacertdir, path.") + } + + # Fix some vars, ready for templating + $_base = $base + $_binddn = $binddn + $_network_timeout = $network_timeout + $_timeout = $timeout + $_uri = $uri + + file { + $_path: + content => template("bob_openldap/ldap.conf") + } + + } + +} diff --git a/test/src_dir/puppet_empty_class_1.pp b/test/src_dir/puppet_empty_class_1.pp new file mode 100644 index 0000000..f38c3b7 --- /dev/null +++ b/test/src_dir/puppet_empty_class_1.pp @@ -0,0 +1,4 @@ +class tester ( +) { + "Some Content" +} diff --git a/test/src_dir/puppet_empty_class_2.pp b/test/src_dir/puppet_empty_class_2.pp new file mode 100644 index 0000000..d1e8dc2 --- /dev/null +++ b/test/src_dir/puppet_empty_class_2.pp @@ -0,0 +1,3 @@ +class test::files { + "Some Content" +} diff --git a/test/src_dir/puppet_with_include_only.pp b/test/src_dir/puppet_with_include_only.pp new file mode 100644 index 0000000..38679c2 --- /dev/null +++ b/test/src_dir/puppet_with_include_only.pp @@ -0,0 +1 @@ +include ::postfix diff --git a/test/src_dir/rebol.r b/test/src_dir/rebol.r new file mode 100644 index 0000000..8e0b6ff --- /dev/null +++ b/test/src_dir/rebol.r @@ -0,0 +1,59 @@ +;; ================================================= +;; Script: new-suffix.r +;; downloaded from: www.REBOL.org +;; on: 1-Jun-2011 +;; at: 21:19:08.38986 UTC +;; owner: carl [script library member who can update +;; this script] +;; ================================================= +REBOL [ + Title: "Change File Extensions (Suffix)" + File: %new-suffix.r + Author: "Carl Sassenrath" + Date: 25-Jan-2005 + Purpose: { + Change the file extension (suffix) for files with a specific extension. + For example, change all .txt files to .r files in the current directory. + Displays a list of changes before it makes them. + } + Warning: "Back up your files first, just in case!" + License: "BSD - Use at your own risk." + Library: [ + level: 'beginner + platform: 'all + type: [tool] + domain: [files] + tested-under: none + support: none + license: 'bsd + see-also: none + ] +] + +from-suffix: %.txt +to-suffix: %.r + +bulk-rename: func [confirmed] [ + foreach file load %./ [ + if all [ + not find file #"/" ; (ignore directories) + from-suffix = find/last file #"." + ][ + new-file: copy file + append clear find/last new-file #"." to-suffix + either confirmed [ + print ["Renaming" file "to" new-file] + rename file new-file + ][ + print ["Will rename" file "to" new-file] + ] + ] + ] +] + +bulk-rename false +if not confirm "Are you sure you want to rename all those files?" [ + quit +] +bulk-rename true +ask "Done. Press enter." diff --git a/test/src_dir/rust.rs b/test/src_dir/rust.rs new file mode 100644 index 0000000..03906b0 --- /dev/null +++ b/test/src_dir/rust.rs @@ -0,0 +1,16 @@ +/* + * This is the example given by www.rust-lang.org + */ +// Line comments work too +fn main() { + let nums = [1, 2]; + let noms = ["Tim", "Eston", "Aaron", "Ben"]; + + let mut odds = nums.iter().map(|&x| x * 2 - 1); + + for num in odds { + do spawn { + println!("{:s} says hello from a lightweight thread!", noms[num]); + } + } +} diff --git a/test/src_dir/sample.i3 b/test/src_dir/sample.i3 new file mode 100644 index 0000000..8a0b394 --- /dev/null +++ b/test/src_dir/sample.i3 @@ -0,0 +1,12 @@ +(* Modula-3 *) INTERFACE M3Sample; (* file extension ".i3" *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString = 'this is a string within "a string" ...\n'; + dqString = "this is a string within 'a string' ...\n"; + +END M3Sample. diff --git a/test/src_dir/sample.m3 b/test/src_dir/sample.m3 new file mode 100644 index 0000000..7640dea --- /dev/null +++ b/test/src_dir/sample.m3 @@ -0,0 +1,12 @@ +(* Modula-3 *) MODULE M3Sample; (* file extension ".m3" *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString = 'this is a string within "a string" ...\n'; + dqString = "this is a string within 'a string' ...\n"; + +END M3Sample. diff --git a/test/src_dir/sample.mod b/test/src_dir/sample.mod new file mode 100644 index 0000000..4f8debe --- /dev/null +++ b/test/src_dir/sample.mod @@ -0,0 +1,12 @@ +MODULE Sample; (* in Modula-2 *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString = 'this is a string within "a string" ...'; + dqString = "this is a string within 'a string' ..."; + +END Sample. diff --git a/test/src_dir/sample.ob2 b/test/src_dir/sample.ob2 new file mode 100644 index 0000000..6355698 --- /dev/null +++ b/test/src_dir/sample.ob2 @@ -0,0 +1,12 @@ +(* Oberon-2 *) MODULE OberonSample; (* file extension ".ob2" *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString* = 'this is a string within "a string" ...'; + dqString* = "this is a string within 'a string' ..."; + +END OberonSample. diff --git a/test/src_dir/sample.obn b/test/src_dir/sample.obn new file mode 100644 index 0000000..9ad1e2b --- /dev/null +++ b/test/src_dir/sample.obn @@ -0,0 +1,12 @@ +(* Oberon *) MODULE OberonSample; (* file extension ".obn" *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString* = 'this is a string within "a string" ...'; + dqString* = "this is a string within 'a string' ..."; + +END OberonSample. diff --git a/test/src_dir/sampleDef.def b/test/src_dir/sampleDef.def new file mode 100644 index 0000000..cd7c9ed --- /dev/null +++ b/test/src_dir/sampleDef.def @@ -0,0 +1,12 @@ +DEFINITION MODULE Sample; (* in Modula-2 *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString = 'this is a string within "a string" ...'; + dqString = "this is a string within 'a string' ..."; + +END Sample. diff --git a/test/src_dir/sampleImp.mod b/test/src_dir/sampleImp.mod new file mode 100644 index 0000000..cd5189e --- /dev/null +++ b/test/src_dir/sampleImp.mod @@ -0,0 +1,12 @@ +IMPLEMENTATION MODULE Sample; (* in Modula-2 *) + +(* This is a comment *) + +(* This is a comment ... + ... spanning more than one line *) + +CONST + sqString = 'this is a string within "a string" ...'; + dqString = "this is a string within 'a string' ..."; + +END Sample. diff --git a/test/src_dir/sh2.sh b/test/src_dir/sh2.sh new file mode 100644 index 0000000..2e03cdb --- /dev/null +++ b/test/src_dir/sh2.sh @@ -0,0 +1,5 @@ +var="\ +Some string" + +# Now a comment +var="some new string" diff --git a/test/src_dir/ts1.ts b/test/src_dir/ts1.ts new file mode 100644 index 0000000..85de989 --- /dev/null +++ b/test/src_dir/ts1.ts @@ -0,0 +1,13 @@ +/* + * This is a TypeScript File + */ + +// And a regular comment + +export class SomeClass { + public text: string; + + public sayHello(name: string): string { + return `Hello, ${name}`; + } +} diff --git a/test/src_licenses/wtfpl.c b/test/src_licenses/wtfpl.c new file mode 100644 index 0000000..443cfe6 --- /dev/null +++ b/test/src_licenses/wtfpl.c @@ -0,0 +1 @@ +// Do What The Fuck you Want to Public License 2 (WTFPL) diff --git a/test/symlink_test_dir/symlink_test_dir_target b/test/symlink_test_dir/symlink_test_dir_target new file mode 120000 index 0000000..733a6fa --- /dev/null +++ b/test/symlink_test_dir/symlink_test_dir_target @@ -0,0 +1 @@ +../symlink_test_dir_target/ \ No newline at end of file diff --git a/test/symlink_test_dir_target/from_symlink_foo.c b/test/symlink_test_dir_target/from_symlink_foo.c new file mode 100644 index 0000000..5c2fd48 --- /dev/null +++ b/test/symlink_test_dir_target/from_symlink_foo.c @@ -0,0 +1,4 @@ +// c file +int function_a(void) { + int x; +} diff --git a/test/unit/detector_test.h b/test/unit/detector_test.h old file mode 100644 new file mode 100755 index a26adaa..f320aac 100755 --- a/test/unit/detector_test.h +++ b/test/unit/detector_test.h @@ -2,6 +2,7 @@ // See COPYING for license information. #include +#include #include #include @@ -9,8 +10,38 @@ #include "../../src/languages.h" #include "../../src/sourcefile.h" +char **get_filenames(SourceFile *sourcefile) { + if (sourcefile->filenames == NULL) { + char dirpath[FILENAME_MAX]; + strncpy(dirpath, sourcefile->filepath, sourcefile->dirpath); + dirpath[sourcefile->dirpath] = '\0'; + struct dirent *file; + DIR *d = opendir((const char *)dirpath); + if (d) { + int length = 0; + while ((file = readdir(d))) length++; + closedir(d); + + char **filenames = calloc(length + 1, sizeof(char *)); + int i = 0; + d = opendir((const char *)dirpath); + while ((file = readdir(d))) { + int len = strlen(file->d_name); + char *filename = malloc(len + 1); + strncpy(filename, file->d_name, len); + filename[len] = '\0'; + filenames[i++] = filename; + } + closedir(d); + sourcefile->filenames = filenames; + } + } + return sourcefile->filenames; +} + #define ASSERT_DETECT(x, y) { \ SourceFile *sf = ohcount_sourcefile_new("../detect_files/" y); \ + get_filenames(sf); \ const char *lang = ohcount_detect_language(sf); \ assert(lang); \ assert(strcmp(x, lang) == 0); \ @@ -18,6 +49,7 @@ } #define ASSERT_NODETECT(x) { \ SourceFile *sf = ohcount_sourcefile_new("../detect_files/" x); \ + get_filenames(sf); \ assert(ohcount_detect_language(sf) == NULL); \ ohcount_sourcefile_free(sf); \ } @@ -25,6 +57,16 @@ void test_detector_smalltalk() { ASSERT_DETECT(LANG_SMALLTALK, "example.st"); ASSERT_NODETECT("english.st"); +} + +void test_detector_disambiguate_asx() { + ASSERT_DETECT(LANG_ASSEMBLER, "assembler6502.asx"); + ASSERT_NODETECT("AdvancedStreamRedirector.asx"); +} + +void test_detector_disambiguate_def() { + ASSERT_DETECT(LANG_MODULA2, "sampleDef.def"); + ASSERT_NODETECT("module-definition.def"); } void test_detector_disambiguate_m() { @@ -32,16 +74,43 @@ ASSERT_DETECT(LANG_OBJECTIVE_C, "t2.m"); ASSERT_DETECT(LANG_OBJECTIVE_C, "TCPSocket.m"); ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.m"); + ASSERT_DETECT(LANG_MATHEMATICA, "foo_mathematica.m"); ASSERT_DETECT(LANG_MATLAB, "foo_matlab.m"); ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m"); } void test_detector_disambiguate_in() { ASSERT_NODETECT("empty.in"); -} + ASSERT_NODETECT("foo.in.in"); +} + +void test_detector_disambiguate_pl() { + ASSERT_DETECT(LANG_PERL, "foo_perl1.pl"); + ASSERT_DETECT(LANG_PERL, "foo_perl2.pl"); + ASSERT_DETECT(LANG_PROLOG, "foo_prolog1.pl"); + ASSERT_DETECT(LANG_PERL, "perl_with_smiley.pl"); + ASSERT_DETECT(LANG_PERL, "perl_shebang_prolog_body.pl"); +} + void test_detector_disambiguate_pro() { ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); ASSERT_DETECT(LANG_MAKE, "qmake.pro"); +} + +void test_detector_disambiguate_r() { + ASSERT_DETECT(LANG_R, "foo_r.R"); + ASSERT_DETECT(LANG_REBOL, "foo_rebol_lower.r"); + ASSERT_DETECT(LANG_REBOL, "foo_rebol_upper.r"); +} + +void test_detector_disambiguate_mod() { + ASSERT_DETECT(LANG_AMPL, "ampl.mod"); + ASSERT_DETECT(LANG_MODULA2, "modula2.mod"); +} + +void test_detector_disambiguate_dat() { + ASSERT_DETECT(LANG_AMPL, "ampl.dat"); + ASSERT_DETECT("\1", "binary.dat"); } void test_detector_fortran_fixedfree() { @@ -57,31 +126,51 @@ ASSERT_DETECT(LANG_CPP, "uses_cpp_keywords.h"); ASSERT_DETECT(LANG_RUBY, "foo.rb"); ASSERT_DETECT(LANG_MAKE, "foo.mk"); + ASSERT_DETECT(LANG_MATHEMATICA, "foo.mt"); + ASSERT_DETECT(LANG_MATHEMATICA, "foo.wl"); + ASSERT_DETECT(LANG_MATHEMATICA, "foo.wlt"); ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.h"); ASSERT_DETECT(LANG_PHP, "upper_case_php"); ASSERT_DETECT(LANG_SMALLTALK, "example.st"); ASSERT_DETECT(LANG_VALA, "foo.vala"); + ASSERT_DETECT(LANG_TEX_DTX, "foo.dtx"); ASSERT_DETECT(LANG_TEX, "foo.tex"); + ASSERT_DETECT(LANG_TYPESCRIPT, "foo.ts"); + ASSERT_DETECT(LANG_TYPESCRIPT, "foo.tsx"); ASSERT_DETECT(LANG_XSLT, "example.xsl"); + ASSERT_DETECT(LANG_LOGTALK, "foo.lgt"); ASSERT_DETECT(LANG_LISP, "core.lisp"); ASSERT_DETECT(LANG_DMD, "foo.d"); ASSERT_DETECT(LANG_VIM, "foo.vim"); + ASSERT_DETECT(LANG_EC, "foo.ec"); + ASSERT_DETECT(LANG_EC, "foo.eh"); ASSERT_DETECT(LANG_EBUILD, "foo.ebuild"); ASSERT_DETECT(LANG_EBUILD, "foo.eclass"); ASSERT_DETECT(LANG_EXHERES, "foo.exheres-0"); ASSERT_DETECT(LANG_EXHERES, "foo.exlib"); ASSERT_DETECT(LANG_EIFFEL, "eiffel.e"); ASSERT_DETECT(LANG_OCAML, "ocaml.ml"); + ASSERT_DETECT(LANG_AUGEAS, "augeas.aug"); ASSERT_DETECT(LANG_STRATEGO, "stratego.str"); - ASSERT_DETECT(LANG_R, "foo.R"); ASSERT_DETECT(LANG_GLSL, "foo.glsl"); ASSERT_DETECT(LANG_GLSL, "foo_glsl.vert"); ASSERT_DETECT(LANG_GLSL, "foo_glsl.frag"); - ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); + ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro"); ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80"); ASSERT_DETECT(LANG_PHP, "php.inc"); + ASSERT_DETECT(LANG_FORTH, "forth.4th"); + ASSERT_DETECT(LANG_FORTH, "forth.fr"); + ASSERT_DETECT(LANG_FSHARP, "fs1.fs"); + ASSERT_DETECT(LANG_GRACE, "grace1.grace"); + ASSERT_DETECT(LANG_GRACE, "grace2.grc"); + ASSERT_DETECT(LANG_AUTOCONF, "m4.m4"); + ASSERT_DETECT(LANG_NSIS, "foo.nsi"); + ASSERT_DETECT(LANG_NSIS, "foo.nsh"); + ASSERT_DETECT(LANG_COFFEESCRIPT, "foo.coffee"); + ASSERT_DETECT(LANG_QML, "foo.qml"); + ASSERT_DETECT(LANG_COQ, "coq.v"); + ASSERT_DETECT(LANG_AMPL, "foo.run"); ASSERT_NODETECT("empty.inc"); - ASSERT_DETECT(LANG_FSHARP, "fs1.fs"); } void test_detector_upper_case_extensions() { @@ -99,6 +188,7 @@ ASSERT_DETECT(LANG_TCL, "tcl_script"); ASSERT_DETECT(LANG_PYTHON, "python.data"); ASSERT_DETECT(LANG_PYTHON, "python2.data"); + ASSERT_DETECT(LANG_CPP, "uses_cpp_modeline"); } void test_detector_csharp_or_clearsilver() { @@ -109,21 +199,64 @@ void test_detector_basic() { ASSERT_DETECT(LANG_VISUALBASIC, "visual_basic.bas"); ASSERT_DETECT(LANG_CLASSIC_BASIC, "classic_basic.b"); - system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2"); + assert(system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2") == 0); ASSERT_DETECT(LANG_STRUCTURED_BASIC, "visual_basic.bas"); ASSERT_DETECT(LANG_STRUCTURED_BASIC, "structured_basic.b"); - system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx"); + assert(system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx") == 0); } void test_detector_xml_with_custom_extension() { ASSERT_DETECT(LANG_XML, "xml.custom_ext"); } +void test_detector_brainfuck() { + ASSERT_DETECT(LANG_BRAINFUCK, "foo.bf"); + ASSERT_DETECT(LANG_BFPP, "foo.bfpp"); +} + +void test_detector_emacs_mode() { + ASSERT_DETECT(LANG_C, "emacs_mode_c"); +} + +void test_detector_emacs_with_extension() { + ASSERT_DETECT(LANG_RUBY, "java_emac.rb"); + ASSERT_DETECT(LANG_JAVASCRIPT, "javascript_emac.js"); +} + +void test_detector_puppet(){ + ASSERT_DETECT(LANG_PUPPET, "puppet_import.pp"); + ASSERT_DETECT(LANG_PUPPET, "puppet_test.pp"); +} + +void test_detector_genie(){ + ASSERT_DETECT(LANG_GENIE, "client-osx.gs"); +} + +void test_detector_rust(){ + ASSERT_DETECT(LANG_RUST, "rust.rs"); + // When RenderScript is implemented, this will, of course, need to be removed. + ASSERT_NODETECT("renderscript.rs"); +} + +void test_detector_ampl(){ + ASSERT_DETECT(LANG_AMPL, "foo.run"); +} + +void test_non_existent_file(){ + ASSERT_NODETECT("xxx_non_exists_xxxi.pp"); +} + void all_detector_tests() { test_detector_smalltalk(); + test_detector_disambiguate_asx(); + test_detector_disambiguate_def(); test_detector_disambiguate_m(); test_detector_disambiguate_in(); + test_detector_disambiguate_pl(); test_detector_disambiguate_pro(); + test_detector_disambiguate_r(); + test_detector_disambiguate_mod(); + test_detector_disambiguate_dat(); test_detector_fortran_fixedfree(); test_detector_detect_polyglot(); test_detector_upper_case_extensions(); @@ -131,4 +264,12 @@ test_detector_csharp_or_clearsilver(); test_detector_basic(); test_detector_xml_with_custom_extension(); -} + test_detector_brainfuck(); + test_detector_emacs_mode(); + test_detector_emacs_with_extension(); + test_detector_puppet(); + test_detector_genie(); + test_detector_rust(); + test_detector_ampl(); + test_non_existent_file(); +} diff --git a/test/unit/license_test.h b/test/unit/license_test.h index b804f37..8977e8f 100644 --- a/test/unit/license_test.h +++ b/test/unit/license_test.h @@ -37,7 +37,7 @@ length = p - file->d_name; strncpy(e_p, (const char *)file->d_name, length); *(e_p + length) = '\0'; - FILE *f = fopen((const char *)expected, "r"); + FILE *f = fopen((const char *)expected, "rb"); if (f) { SourceFile *sf = ohcount_sourcefile_new((const char *)src); LicenseList *iter = ohcount_sourcefile_get_license_list(sf)->head; diff --git a/test/unit/parser_test.h b/test/unit/parser_test.h index 23291de..6a622ac 100644 --- a/test/unit/parser_test.h +++ b/test/unit/parser_test.h @@ -75,7 +75,9 @@ #include "parsers/test_actionscript.h" #include "parsers/test_ada.h" +#include "parsers/test_ampl.h" #include "parsers/test_assembler.h" +#include "parsers/test_augeas.h" #include "parsers/test_autoconf.h" #include "parsers/test_automake.h" #include "parsers/test_awk.h" @@ -83,9 +85,14 @@ #include "parsers/test_bat.h" #include "parsers/test_blitzmax.h" #include "parsers/test_boo.h" +#include "parsers/test_brainfuck.h" +#include "parsers/test_bfpp.h" #include "parsers/test_c.h" +#include "parsers/test_chaiscript.h" #include "parsers/test_clearsilvertemplate.h" #include "parsers/test_clearsilver.h" +#include "parsers/test_clojure.h" +#include "parsers/test_coq.h" #include "parsers/test_cs_aspx.h" #include "parsers/test_csharp.h" #include "parsers/test_css.h" @@ -98,34 +105,44 @@ #include "parsers/test_erlang.h" #include "parsers/test_exheres.h" #include "parsers/test_factor.h" +#include "parsers/test_forth.h" #include "parsers/test_fortran.h" #include "parsers/test_fsharp.h" #include "parsers/test_glsl.h" +#include "parsers/test_golang.h" #include "parsers/test_groovy.h" #include "parsers/test_haml.h" #include "parsers/test_haskell.h" #include "parsers/test_haxe.h" #include "parsers/test_html.h" #include "parsers/test_idl_pvwave.h" +#include "parsers/test_jam.h" #include "parsers/test_java.h" #include "parsers/test_javascript.h" #include "parsers/test_jsp.h" #include "parsers/test_lisp.h" +#include "parsers/test_logtalk.h" #include "parsers/test_lua.h" #include "parsers/test_make.h" +#include "parsers/test_mathematica.h" #include "parsers/test_matlab.h" #include "parsers/test_metafont.h" #include "parsers/test_metapost.h" #include "parsers/test_mxml.h" #include "parsers/test_nix.h" +#include "parsers/test_nsis.h" #include "parsers/test_objective_j.h" #include "parsers/test_ocaml.h" #include "parsers/test_octave.h" #include "parsers/test_pascal.h" #include "parsers/test_perl.h" #include "parsers/test_pike.h" +#include "parsers/test_puppet.h" #include "parsers/test_python.h" +#include "parsers/test_qml.h" #include "parsers/test_r.h" +#include "parsers/test_racket.h" +#include "parsers/test_rebol.h" #include "parsers/test_rexx.h" #include "parsers/test_rhtml.h" #include "parsers/test_ruby.h" @@ -138,6 +155,7 @@ #include "parsers/test_stratego.h" #include "parsers/test_tcl.h" #include "parsers/test_tex.h" +#include "parsers/test_typescript.h" #include "parsers/test_vala.h" #include "parsers/test_vb_aspx.h" #include "parsers/test_vhdl.h" @@ -169,11 +187,8 @@ end - start); line2[strlen(language) + strlen(entity) + 2 + (end - start)] = '\0'; if (strcmp(line, line2) != 0) { - fprintf(stderr, "lines didn't match:\n1: '%s'\n2: '%s'\n", line, line2); - if (strcmp(line, line2) != 0) { - fprintf(stderr, "lines didn't match:\n1: '%s'\n2: '%s'\n", line, line2); - assert(strcmp(line, line2) == 0); - } + fprintf(stderr, "FAIL: Parser test failure in %s:\nExpected: %sGot: %s", udata->sf->filename, line, line2); + assert(strcmp(line, line2) == 0); } } @@ -202,7 +217,7 @@ strncpy(e_p, (const char *)file->d_name, length); *(e_p + length) = '\0'; - FILE *f = fopen((const char *)expected, "r"); + FILE *f = fopen((const char *)expected, "rb"); if (f) { SourceFile *sf = ohcount_sourcefile_new((const char *)src); @@ -213,9 +228,9 @@ if (strcmp(s_p, "visual_basic.bas") == 0) // This file needs frx1.frx in the directory contents to be // detected as Visual Basic. - ohcount_sourcefile_set_filenames(sf, test_basic_vb_filenames); + sf->filenames = test_basic_vb_filenames; else - ohcount_sourcefile_set_filenames(sf, test_parser_filenames); + sf->filenames = test_parser_filenames; TestParserUData *udata = malloc(sizeof(TestParserUData)); udata->sf = sf; @@ -247,7 +262,9 @@ test_parser_verify_parses(); all_actionscript_tests(); all_ada_tests(); + all_ampl_tests(); all_assembler_tests(); + all_augeas_tests(); all_autoconf_tests(); all_automake_tests(); all_awk_tests(); @@ -255,9 +272,14 @@ all_bat_tests(); all_blitzmax_tests(); all_boo_tests(); + all_brainfuck_tests(); + all_bfpp_tests(); all_c_tests(); + all_chaiscript_tests(); all_clearsilver_template_tests(); all_clearsilver_tests(); + all_clojure_tests(); + all_coq_tests(); all_cs_aspx_tests(); all_csharp_tests(); all_css_tests(); @@ -270,6 +292,7 @@ all_erlang_tests(); all_exheres_tests(); all_factor_tests(); + all_forth_tests(); all_fortran_tests(); all_fsharp_tests(); all_glsl_tests(); @@ -279,17 +302,21 @@ all_haxe_tests(); all_html_tests(); all_idl_pvwave_tests(); + all_jam_tests(); all_java_tests(); all_javascript_tests(); all_jsp_tests(); all_lisp_tests(); + all_logtalk_tests(); all_lua_tests(); all_make_tests(); + all_mathematica_tests(); all_matlab_tests(); all_metafont_tests(); all_metapost_tests(); all_mxml_tests(); all_nix_tests(); + all_nsis_tests(); all_objective_j_tests(); all_ocaml_tests(); all_octave_tests(); @@ -298,6 +325,8 @@ all_pike_tests(); all_python_tests(); all_r_tests(); + all_racket_tests(); + all_rebol_tests(); all_rexx_tests(); all_rhtml_tests(); all_ruby_tests(); diff --git a/test/unit/parsers/test_ampl.h b/test/unit/parsers/test_ampl.h new file mode 100644 index 0000000..bcd028f --- /dev/null +++ b/test/unit/parsers/test_ampl.h @@ -0,0 +1,19 @@ + +void test_ampl_comments() { + test_parser_verify_parse( + test_parser_sourcefile("ampl", " #comment"), + "ampl", "", "#comment", 0 + ); +} + +void test_ampl_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("ampl", " #comment"), + "comment", "#comment" + ); +} + +void all_ampl_tests() { + test_ampl_comments(); + test_ampl_comment_entities(); +} diff --git a/test/unit/parsers/test_augeas.h b/test/unit/parsers/test_augeas.h new file mode 100644 index 0000000..2e2e60a --- /dev/null +++ b/test/unit/parsers/test_augeas.h @@ -0,0 +1,19 @@ + +void test_augeas_comments() { + test_parser_verify_parse( + test_parser_sourcefile("augeas", " (* comment *)"), + "augeas", "", "(* comment *)", 0 + ); +} + +void test_augeas_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("augeas", " (*comment*)"), + "comment", "(*comment*)" + ); +} + +void all_augeas_tests() { + test_augeas_comments(); + test_augeas_comment_entities(); +} diff --git a/test/unit/parsers/test_bfpp.h b/test/unit/parsers/test_bfpp.h new file mode 100644 index 0000000..cef3077 --- /dev/null +++ b/test/unit/parsers/test_bfpp.h @@ -0,0 +1,19 @@ +void test_bfpp_comment() { + test_parser_verify_parse( + test_parser_sourcefile("bfpp", " = comment"), + "bfpp", "", "= comment", 0 + ); +} + +void test_bfpp_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("bfpp", " = comment"), + " comment", "= comment" + ); +} + +void all_bfpp_tests() { + test_bfpp_comment(); + test_bfpp_comment_entities(); +} + diff --git a/test/unit/parsers/test_brainfuck.h b/test/unit/parsers/test_brainfuck.h new file mode 100644 index 0000000..a13f452 --- /dev/null +++ b/test/unit/parsers/test_brainfuck.h @@ -0,0 +1,18 @@ +void test_brainfuck_comment() { + test_parser_verify_parse( + test_parser_sourcefile("brainfuck", " #comment"), + "brainfuck", "", "#comment", 0 + ); +} + +void test_brainfuck_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("brainfuck", " #comment"), + "#comment", "#comment" + ); +} + +void all_brainfuck_tests() { + test_brainfuck_comment(); + test_brainfuck_comment_entities(); +} diff --git a/test/unit/parsers/test_chaiscript.h b/test/unit/parsers/test_chaiscript.h new file mode 100644 index 0000000..6688011 --- /dev/null +++ b/test/unit/parsers/test_chaiscript.h @@ -0,0 +1,23 @@ + +void test_chaiscript_comments() { + test_parser_verify_parse( + test_parser_sourcefile("chaiscript", " //comment"), + "chaiscript", "", "//comment", 0 + ); +} + +void test_chaiscript_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("chaiscript", " //comment"), + "comment", "//comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("chaiscript", " /*comment*/"), + "comment", "/*comment*/" + ); +} + +void all_chaiscript_tests() { + test_chaiscript_comments(); + test_chaiscript_comment_entities(); +} diff --git a/test/unit/parsers/test_clojure.h b/test/unit/parsers/test_clojure.h new file mode 100644 index 0000000..bcb75f2 --- /dev/null +++ b/test/unit/parsers/test_clojure.h @@ -0,0 +1,19 @@ + +void test_clojure_comments() { + test_parser_verify_parse( + test_parser_sourcefile("clojure", " ;;; comment"), + "clojure", "", ";;; comment", 0 + ); +} + +void test_clojure_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("clojure", " ;comment"), + "comment", ";comment" + ); +} + +void all_clojure_tests() { + test_clojure_comments(); + test_clojure_comment_entities(); +} diff --git a/test/unit/parsers/test_coq.h b/test/unit/parsers/test_coq.h new file mode 100644 index 0000000..d3f97c7 --- /dev/null +++ b/test/unit/parsers/test_coq.h @@ -0,0 +1,19 @@ + +void test_coq_comments() { + test_parser_verify_parse( + test_parser_sourcefile("coq", " (* comment *)"), + "coq", "", "(* comment *)", 0 + ); +} + +void test_coq_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("coq", " (*comment*)"), + "comment", "(*comment*)" + ); +} + +void all_coq_tests() { + test_coq_comments(); + test_coq_comment_entities(); +} diff --git a/test/unit/parsers/test_forth.h b/test/unit/parsers/test_forth.h new file mode 100644 index 0000000..9f93497 --- /dev/null +++ b/test/unit/parsers/test_forth.h @@ -0,0 +1,15 @@ + +void test_forth_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("forth", " \\comment"), + "comment", "\\comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("forth", " (comment)"), + "comment", "(comment)" + ); +} + +void all_forth_tests() { + test_forth_comment_entities(); +} diff --git a/test/unit/parsers/test_golang.h b/test/unit/parsers/test_golang.h new file mode 100644 index 0000000..7463d4b --- /dev/null +++ b/test/unit/parsers/test_golang.h @@ -0,0 +1,39 @@ + +void test_golang_comments() { + test_parser_verify_parse( + test_parser_sourcefile("go", " //comment"), + "go", "", "//comment", 0 + ); +} + +void test_golang_empty_comments() { + test_parser_verify_parse( + test_parser_sourcefile("go", " //\n"), + "go", "", "//\n", 0 + ); +} + +void test_golang_block_comment() { + test_parser_verify_parse( + test_parser_sourcefile("go", "/*c*/"), + "go", "", "/*c*/", 0 + ); +} + +void test_golang_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("go", " //comment"), + "comment", "//comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("go", " /*comment*/"), + "comment", "/*comment*/" + ); +} + +void all_golang_tests() { + test_golang_comments(); + test_golang_empty_comments(); + test_golang_block_comment(); + test_golang_comment_entities(); +} diff --git a/test/unit/parsers/test_jam.h b/test/unit/parsers/test_jam.h new file mode 100644 index 0000000..373a6be --- /dev/null +++ b/test/unit/parsers/test_jam.h @@ -0,0 +1,19 @@ + +void test_jam_comments() { + test_parser_verify_parse( + test_parser_sourcefile("jam", " #comment"), + "jam", "", "#comment", 0 + ); +} + +void test_jam_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("jam", " #comment"), + "comment", "#comment" + ); +} + +void all_jam_tests() { + test_jam_comments(); + test_jam_comment_entities(); +} diff --git a/test/unit/parsers/test_logtalk.h b/test/unit/parsers/test_logtalk.h new file mode 100644 index 0000000..8b83ffb --- /dev/null +++ b/test/unit/parsers/test_logtalk.h @@ -0,0 +1,27 @@ + +void test_logtalk_comments() { + test_parser_verify_parse( + test_parser_sourcefile("logtalk", " %comment"), + "logtalk", "", "%comment", 0 + ); +} + +void test_logtalk_empty_comments() { + test_parser_verify_parse( + test_parser_sourcefile("logtalk", " %\n"), + "logtalk", "", "%\n", 0 + ); +} + +void test_logtalk_block_comment() { + test_parser_verify_parse( + test_parser_sourcefile("logtalk", " /*d*/"), + "logtalk", "", "/*d*/", 0 + ); +} + +void all_logtalk_tests() { + test_logtalk_comments(); + test_logtalk_empty_comments(); + test_logtalk_block_comment(); +} diff --git a/test/unit/parsers/test_mathematica.h b/test/unit/parsers/test_mathematica.h new file mode 100644 index 0000000..855bd36 --- /dev/null +++ b/test/unit/parsers/test_mathematica.h @@ -0,0 +1,11 @@ + +void test_mathematica_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("mathematica", " (*comment*)"), + "comment", "(*comment*)" + ); +} + +void all_mathematica_tests() { + test_mathematica_comment_entities(); +} diff --git a/test/unit/parsers/test_nsis.h b/test/unit/parsers/test_nsis.h new file mode 100644 index 0000000..027ee5f --- /dev/null +++ b/test/unit/parsers/test_nsis.h @@ -0,0 +1,51 @@ + +void test_nsis_comments() { + test_parser_verify_parse( + test_parser_sourcefile("nsis", " ;comment"), + "nsis", "", ";comment", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("nsis", " #comment"), + "nsis", "", "#comment", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("nsis", " /*comment*/"), + "nsis", "", "/*comment*/", 0 + ); +} + +void test_nsis_strings() { + test_parser_verify_parse( + test_parser_sourcefile("nsis", "\"abc;not a 'comment\""), + "nsis", "\"abc;not a 'comment\"", "", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("nsis", "'abc;not a \"comment'"), + "nsis", "'abc;not a \"comment'", "", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("nsis", "`abc;not a 'comment`"), + "nsis", "`abc;not a 'comment`", "", 0 + ); +} + +void test_nsis_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("nsis", " ;comment"), + "comment", ";comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("nsis", " #comment"), + "comment", "#comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("nsis", " /*comment*/"), + "comment", "/*comment*/" + ); +} + +void all_nsis_tests() { + test_nsis_comments(); + test_nsis_strings(); + test_nsis_comment_entities(); +} diff --git a/test/unit/parsers/test_puppet.h b/test/unit/parsers/test_puppet.h new file mode 100644 index 0000000..8d55b09 --- /dev/null +++ b/test/unit/parsers/test_puppet.h @@ -0,0 +1,23 @@ + +void test_puppet_comments() { + test_parser_verify_parse( + test_parser_sourcefile("puppet", " #comment"), + "puppet", "", "#comment", 0 + ); +} + +void test_puppet_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("puppet", " #comment"), + "comment", "#comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("puppet", " /*comment*/"), + "comment", "/*comment*/" + ); +} + +void all_puppet_tests() { + test_puppet_comments(); + test_puppet_comment_entities(); +} diff --git a/test/unit/parsers/test_qml.h b/test/unit/parsers/test_qml.h new file mode 100644 index 0000000..d4ba843 --- /dev/null +++ b/test/unit/parsers/test_qml.h @@ -0,0 +1,23 @@ + +void test_qml_comments() { + test_parser_verify_parse( + test_parser_sourcefile("qml", " //comment"), + "qml", "", "//comment", 0 + ); +} + +void test_qml_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("qml", " //comment"), + "comment", "//comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("qml", " /*comment*/"), + "comment", "/*comment*/" + ); +} + +void all_qml_tests() { + test_qml_comments(); + test_qml_comment_entities(); +} diff --git a/test/unit/parsers/test_racket.h b/test/unit/parsers/test_racket.h new file mode 100644 index 0000000..9267a8f --- /dev/null +++ b/test/unit/parsers/test_racket.h @@ -0,0 +1,54 @@ +/* renamed from lisp unit tests... + * lots more possible here. + */ + +void test_racket_comment() { + test_parser_verify_parse( + test_parser_sourcefile("racket", " ;;; comment"), + "racket", "", ";;; comment", 0 + ); +} + +void test_racket_doc_string() { + test_parser_verify_parse( + test_parser_sourcefile("racket", " \"\"\" comment \"\"\""), + "racket", "", "\"\"\" comment \"\"\"", 0 + ); +} + +void test_racket_doc_string_blank() { + test_parser_verify_parse( + test_parser_sourcefile("racket", " \"\"\"\"\"\""), + "racket", "", "\"\"\"\"\"\"", 0 + ); +} + +void test_racket_empty_string() { + test_parser_verify_parse( + test_parser_sourcefile("racket", "\"\""), + "racket", "\"\"", "", 0 + ); +} + +void test_racket_char_string() { + test_parser_verify_parse( + test_parser_sourcefile("racket", " \"a\""), + "racket", "\"a\"", "", 0 + ); +} + +void test_racket_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("racket", " ;comment"), + "comment", ";comment" + ); +} + +void all_racket_tests() { + test_racket_comment(); + test_racket_doc_string(); + test_racket_doc_string_blank(); + test_racket_empty_string(); + test_racket_char_string(); + test_racket_comment_entities(); +} diff --git a/test/unit/parsers/test_rebol.h b/test/unit/parsers/test_rebol.h new file mode 100644 index 0000000..95bace9 --- /dev/null +++ b/test/unit/parsers/test_rebol.h @@ -0,0 +1,43 @@ + +void test_rebol_comments() { + test_parser_verify_parse( + test_parser_sourcefile("rebol", "REBOL []\n;comment"), + "rebol", "REBOL []\n", ";comment", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("rebol", "{}"), + "rebol", "{}", "", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("rebol", "{{}}"), + "rebol", "{{}}", "", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("rebol", "{{\n}}"), + "rebol", "{{\n}}", "", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("rebol", "{\n;inside string\n}"), + "rebol", "{\n;inside string\n}", "", 0 + ); + test_parser_verify_parse( + test_parser_sourcefile("rebol", "{}\n;comment"), + "rebol", "{}\n", ";comment", 0 + ); +} + +void test_rebol_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("rebol", " ;comment"), + "comment", ";comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("rebol", " \";no comment\""), + "string", "\";no comment\"" + ); +} + +void all_rebol_tests() { + test_rebol_comments(); + test_rebol_comment_entities(); +} diff --git a/test/unit/parsers/test_typescript.h b/test/unit/parsers/test_typescript.h new file mode 100644 index 0000000..13dbd02 --- /dev/null +++ b/test/unit/parsers/test_typescript.h @@ -0,0 +1,23 @@ + +void test_typescript_comments() { + test_parser_verify_parse( + test_parser_sourcefile("typescript", " //comment"), + "typescript", "", "//comment", 0 + ); +} + +void test_typescript_comment_entities() { + test_parser_verify_entity( + test_parser_sourcefile("typescript", " //comment"), + "comment", "//comment" + ); + test_parser_verify_entity( + test_parser_sourcefile("typescript", " /*comment*/"), + "comment", "/*comment*/" + ); +} + +void all_typescript_tests() { + test_typescript_comments(); + test_typescript_comment_entities(); +} diff --git a/test/unit/python/python_test.py b/test/unit/python/python_test.py new file mode 100644 index 0000000..6fbe254 --- /dev/null +++ b/test/unit/python/python_test.py @@ -0,0 +1,68 @@ +import unittest +import ohcount + +class TestSourceFileList(unittest.TestCase): + + def setUp(self): + # must not raise + self.sf_list = ohcount.SourceFileList(paths=['../../gestalt_files']) + + def assertStrOp(self, obj, not_equals): + s = str(obj) + if not_equals: + for v in not_equals: + self.assertTrue(s is not v) + + def assertHasAttr(self, obj, name, not_equals=None): + self.assertTrue(hasattr(obj, name)) + if not_equals: + val = getattr(obj, name) + for v in not_equals: + self.assertTrue(val is not v) + + def assertHasItem(self, obj, name, not_equals=None): + self.assertTrue(name in obj) + if not_equals: + val = obj[name] + for v in not_equals: + self.assertTrue(val is not v) + + def assertHasItemAttr(self, obj, name, not_equals=None): + self.assertHasAttr(obj, name, not_equals) + self.assertHasItem(obj, name, not_equals) + + def assertHasKeys(self, obj, keylist): + for k in keylist: + self.assertTrue(k in obj) + + def assertListIsInstance(self, list, type): + for o in list: + self.assertTrue(isinstance(o, type)) + + def assertHasItemAttrs(self, obj, list, not_equals=None): + for name in list: + self.assertHasItemAttr(obj, name, not_equals) + + def testList(self): + self.assertTrue(len(self.sf_list) > 0) + self.assertListIsInstance(self.sf_list, ohcount.SourceFile) + + def testStr(self): + self.assertStrOp(self.sf_list, [None, ""]) + + def testAnalyzeLanguages(self): + locs = self.sf_list.analyze_languages() + self.assertTrue(isinstance(locs, ohcount.LocList)) + names = ['code','comments','blanks','filecount','total'] + self.assertHasKeys(locs, names) + self.assertHasItemAttrs(locs, names, [None, 0]) + self.assertListIsInstance(locs, ohcount.Loc) + + def testAddDirectory(self): + self.sf_list.add_directory('../../detect_files') # must not raise + + def testAddFile(self): + self.sf_list.add_file('../../src_licenses/academic_t1.c') # must not raise + +if __name__ == '__main__': + unittest.main() diff --git a/test/unit/ruby/gestalt/definitions_test.rb b/test/unit/ruby/gestalt/definitions_test.rb index 7d8de42..ab78748 100644 --- a/test/unit/ruby/gestalt/definitions_test.rb +++ b/test/unit/ruby/gestalt/definitions_test.rb @@ -31,10 +31,7 @@ def test_eclipse_platform assert_gestalts 'eclipse_platform', [ Base.new(:platform,'java'), - Base.new(:platform,'eclipseplatform'), - Base.new(:java_import,"java.text.SimpleDateFormat"), - Base.new(:java_import,"java.util.Map"), - Base.new(:java_import,"org.eclipse.core") + Base.new(:platform,'eclipseplatform') ] end @@ -48,18 +45,6 @@ assert_gestalts 'win32_enough', [ Base.new(:platform, 'win32'), Base.new(:platform, 'native_code') - ] - end - - def test_wpf - assert_gestalts 'wpf', [ - Base.new(:platform, 'wpf') - ] - end - - def test_asp_net - assert_gestalts 'asp_net', [ - Base.new(:platform, 'asp_net') ] end @@ -100,8 +85,7 @@ def test_spring_framework assert_gestalts 'spring_framework', [ Base.new(:platform, 'java'), - Base.new(:platform, 'springframework'), - Base.new(:java_jar, 'spring.jar'), + Base.new(:platform, 'springframework') ] end @@ -173,24 +157,6 @@ assert_tool('netbeans', :netbeans) end - def test_java_imports_from_java_file - java = SourceFile.new("foo.java", :contents => <<-INLINE_C - import com.foo; - import net.ohloh; - import com.foo; - // import dont.import.this; - INLINE_C - ) - - expected_gestalts = [ - Base.new(:java_import, 'com.foo', 2), - Base.new(:java_import, 'net.ohloh'), - Base.new(:platform, 'java'), - ] - - assert_equal expected_gestalts.sort, java.gestalts.sort - end - def test_arm asm = SourceFile.new("foo.S", :contents => <<-INLINE_ASM orrs 3, eax @@ -228,16 +194,6 @@ ] assert_equal expected_gestalts.sort, asm.gestalts.sort - end - - def test_imports_from_java_file - jar = SourceFile.new("foo/foo.jar", :contents => '') - - expected_gestalts = [ - Base.new(:java_jar, 'foo.jar'), - ] - - assert_equal expected_gestalts.sort, jar.gestalts.sort end def test_moblin_clutter @@ -308,14 +264,10 @@ INLINE_C ) - expected_gestalts = [ - Base.new(:java_import, 'android.app.Activity'), - Base.new(:platform, 'java'), - Base.new(:platform, 'android'), - Base.new(:platform, 'mid_combined') - ] - - assert_equal expected_gestalts.sort, java.gestalts.sort + names = java.gestalts.map { |g| g.name if g.type == :platform }.compact + assert names.include?('java') + assert names.include?('android') + assert names.include?('mid_combined') end def test_iphone @@ -418,13 +370,9 @@ import com.sun.identity.authentication; INLINE_JAVA ) - expected_gestalts = [ - Base.new(:platform, 'java'), - Base.new(:platform, 'opensso'), - Base.new(:java_import, 'com.sun.identity') - ] - - assert_equal expected_gestalts.sort, java.gestalts.sort + platforms = java.gestalts.map { |g| g.name if g.type == :platform }.compact + assert platforms.include?('java') + assert platforms.include?('opensso') end def test_windows_ce diff --git a/test/unit/ruby/gestalt/dot_net_definitions_test.rb b/test/unit/ruby/gestalt/dot_net_definitions_test.rb index ac1e630..c54f955 100644 --- a/test/unit/ruby/gestalt/dot_net_definitions_test.rb +++ b/test/unit/ruby/gestalt/dot_net_definitions_test.rb @@ -3,63 +3,20 @@ include Ohcount include Ohcount::Gestalt -class DotNetDefinitionsTest < Test::Unit::TestCase +class DotNetDefinitionsTest < Ohcount::Test - def test_nunit - sf = SourceFile.new('foo.cs', :contents => <<-CONTENTS -using NUnit.Framework; -CONTENTS - ) - assert_equal [ - Gestalt::Base.new(:platform, 'dot_net'), - Gestalt::Base.new(:platform, 'nunit') - ], sf.gestalts.sort - end + def test_wpf + platforms = get_gestalts('wpf').map { |g| g.name if g.type == :platform }.compact + assert platforms.include?("dot_net") + assert platforms.include?("wpf") + end - def test_nhibernate - sf = SourceFile.new('foo.cs', :contents => <<-CONTENTS -using NHibernate.Connection.DriverConnectionProvider; -CONTENTS - ) - assert_equal [ - Gestalt::Base.new(:platform, 'dot_net'), - Gestalt::Base.new(:platform, 'nhibernate') - ], sf.gestalts.sort - end + def test_asp_net + platforms = get_gestalts('asp_net').map { |g| g.name if g.type == :platform }.compact + assert platforms.include?("dot_net") + assert platforms.include?("asp_net") + end - def test_remoting_implies_enterprise - sf = SourceFile.new('foo.cs', :contents => <<-CONTENTS -using System.Runtime.Remoting; -CONTENTS - ) - assert_equal [ - Gestalt::Base.new(:platform, 'dot_net'), - Gestalt::Base.new(:platform, 'dot_net_enterprise') - ], sf.gestalts.sort - end - - def test_biztalk_implies_enterprise - sf = SourceFile.new('foo.cs', :contents => <<-CONTENTS -using Microsoft.BizTalk; -CONTENTS - ) - assert_equal [ - Gestalt::Base.new(:platform, 'dot_net'), - Gestalt::Base.new(:platform, 'dot_net_biztalk'), - Gestalt::Base.new(:platform, 'dot_net_enterprise') - ], sf.gestalts.sort - end - - def test_linq_implies_enterprise - sf = SourceFile.new('foo.cs', :contents => <<-CONTENTS -using System.Data.Linq; -CONTENTS - ) - assert_equal [ - Gestalt::Base.new(:platform, 'dot_net'), - Gestalt::Base.new(:platform, 'dot_net_enterprise') - ], sf.gestalts.sort - end def test_silverlight_via_asp_keyword sf = SourceFile.new('foo.aspx', :contents => <<-CONTENTS @@ -68,10 +25,10 @@ CONTENTS ) - assert_equal [ - Gestalt::Base.new(:platform, 'asp_net'), - Gestalt::Base.new(:platform, 'silverlight') - ], sf.gestalts.sort + platforms = sf.gestalts.map { |g| g.name if g.type == :platform }.compact + assert platforms.include?('dot_net') + assert platforms.include?('asp_net') + assert platforms.include?('silverlight') end def test_silverlight_via_csproj_import @@ -81,9 +38,11 @@ CONTENTS ) - assert_equal([ - Gestalt::Base.new(:platform, 'silverlight'), - Gestalt::Base.new(:tool, 'visualstudio') - ], sf.gestalts.sort) + platforms = sf.gestalts.map { |g| g.name if g.type == :platform }.compact + assert platforms.include?('dot_net') + assert platforms.include?('silverlight') + + tools = sf.gestalts.map { |g| g.name if g.type == :tool }.compact + assert tools.include?('visualstudio') end end diff --git a/test/unit/ruby/gestalt/find_java_imports_rule_test.rb b/test/unit/ruby/gestalt/find_java_imports_rule_test.rb deleted file mode 100644 index 932d787..0000000 --- a/test/unit/ruby/gestalt/find_java_imports_rule_test.rb +++ /dev/null @@ -1,32 +0,0 @@ -require File.dirname(__FILE__) + '/../../test_helper' - -class FindJavaImportsRuleTest < Test::Unit::TestCase - include Ohcount::Gestalt - - def test_truncate_name - assert_equal "", FindJavaImportsRule.truncate_name(nil, 3) - assert_equal "", FindJavaImportsRule.truncate_name("", 3) - assert_equal "", FindJavaImportsRule.truncate_name("net.ohloh.ohcount.test", 0) - assert_equal "net", FindJavaImportsRule.truncate_name("net.ohloh.ohcount.test", 1) - assert_equal "net.ohloh", FindJavaImportsRule.truncate_name("net.ohloh.ohcount.test", 2) - assert_equal "net.ohloh.ohcount", FindJavaImportsRule.truncate_name("net.ohloh.ohcount.test", 3) - assert_equal "net.ohloh.ohcount.test", FindJavaImportsRule.truncate_name("net.ohloh.ohcount.test", 4) - assert_equal "net.ohloh.ohcount.test", FindJavaImportsRule.truncate_name("net.ohloh.ohcount.test", 5) - end - - def test_arm_from_java_import - java = SourceFile.new("foo.java", :contents => <<-INLINE_C - import org.opengroup.arm40.transaction.ArmConstants; - // import dont.import.this; - INLINE_C - ) - - expected_gestalts = [ - Base.new(:java_import, 'org.opengroup.arm40'), - Base.new(:platform, 'Java'), - Base.new(:platform, 'arm'), - ] - - assert_equal expected_gestalts.sort, java.gestalts.sort - end -end diff --git a/test/unit/ruby/source_file_test.rb b/test/unit/ruby/source_file_test.rb index 807b614..83a1af1 100644 --- a/test/unit/ruby/source_file_test.rb +++ b/test/unit/ruby/source_file_test.rb @@ -1,12 +1,12 @@ require 'test/unit' -require File.dirname(__FILE__) + '/../../../ruby/gestalt' +require_relative '../../../ruby/gestalt' class SourceFileTest < Test::Unit::TestCase def test_diff - c = File.open(File.dirname(__FILE__) + "/../../src_dir/optimer").read - new = Ohcount::SourceFile.new("optimer", :contents => c, :filenames => nil, :filenames => ["optimer"]) + optimer = File.open(File.dirname(__FILE__) + "/../../src_dir/optimer").read + new = Ohcount::SourceFile.new("optimer", :contents => optimer, :filenames => nil, :filenames => ["optimer"]) old = Ohcount::SourceFile.new("optimer", :contents => "", :filenames => ["optimer"]) - assert_equal c, new.contents + assert_equal optimer, new.contents deltas = old.diff(new).loc_deltas assert_not_nil deltas assert_equal "shell", deltas.first.language diff --git a/test/unit/ruby/test_helper.rb b/test/unit/ruby/test_helper.rb index 93bd79b..a43a4d2 100644 --- a/test/unit/ruby/test_helper.rb +++ b/test/unit/ruby/test_helper.rb @@ -47,11 +47,15 @@ end def assert_gestalts(path, expected_gestalts) + assert_equal expected_gestalts.sort, get_gestalts(path) + end + + def get_gestalts(path) sfl = SourceFileList.new(:paths => [test_dir(path)]) assert sfl.size > 0 sfl.analyze(:gestalt) - assert_equal expected_gestalts.sort, sfl.gestalts.sort - end + sfl.gestalts.sort + end def test_dir(d) File.expand_path(File.dirname(__FILE__) + "/../../gestalt_files/#{ d }") diff --git a/test/unit/sourcefile_test.h b/test/unit/sourcefile_test.h index 1c03d07..f780675 100644 --- a/test/unit/sourcefile_test.h +++ b/test/unit/sourcefile_test.h @@ -203,7 +203,7 @@ void test_sourcefile_list_language_facts() { SourceFileList *sfl = ohcount_sourcefile_list_new(); - ohcount_sourcefile_list_add_directory(sfl, "../gestalt_files/win32_enough/"); + ohcount_sourcefile_list_add_directory(sfl, "../gestalt_files/win32_enough"); LocList *list = ohcount_sourcefile_list_analyze_languages(sfl); assert(ohcount_loc_list_filecount(list) == 2); Loc *loc = ohcount_loc_list_get_loc(list, "c"); @@ -214,6 +214,38 @@ ohcount_loc_list_free(list); } +void test_sourcefile_list_no_symlink_dir() { + SourceFileList *sfl = ohcount_sourcefile_list_new(); + ohcount_sourcefile_list_add_directory(sfl, "../symlink_test_dir"); + LocList *list = ohcount_sourcefile_list_analyze_languages(sfl); + assert(ohcount_loc_list_filecount(list) == 0); + ohcount_sourcefile_list_free(sfl); + ohcount_loc_list_free(list); +} + +#define FALSE 0 +#define TRUE 1 +char *tmp_file_from_buf(const char *buf); + +void test_tmp_dir() { + char buf[] = "This is just some bogus text."; + char *tmp_path = tmp_file_from_buf(buf); + + SourceFileList *list = ohcount_sourcefile_list_new(); + ohcount_sourcefile_list_add_directory(list, "/tmp"); + int has_tmp = FALSE; + SourceFileList *iter = list->head; + + for (; iter != NULL; iter = iter->next) { + if (strcmp(iter->sf->filepath, tmp_path) == 0) { + has_tmp = TRUE; + break; + } + } + assert(has_tmp); +} + + void all_sourcefile_tests() { test_sourcefile_initialize(); test_sourcefile_language_breakdowns(); @@ -224,4 +256,6 @@ test_sourcefile_calc_diff(); test_sourcefile_list_language_facts(); -} + test_sourcefile_list_no_symlink_dir(); + test_tmp_dir(); +}