Codebase list ohcount / 8e3aae6
New upstream version 3.1.0 Sylvestre Ledru 5 years ago
262 changed file(s) with 10810 addition(s) and 3655 deletion(s). Raw diff Collapse all Expand all
1212 ruby/ohcount.so
1313 ruby/ohcount_wrap.c
1414 test/unit/run_tests.dSYM/
15 build-python/
16 python/ohcount.py
17 .rvmrc
18 .ruby-version
+0
-1
.pc/.quilt_patches less more
0 debian/patches
+0
-1
.pc/.quilt_series less more
0 series
+0
-1
.pc/.version less more
0 2
+0
-5
.pc/applied-patches less more
0 fix_null_dereference_2.patch
1 fix_null_dereference.patch
2 txx_support.patch
3 disabled_test_suite.patch
4 rbconfig.patch
+0
-162
.pc/disabled_test_suite.patch/build less more
0 #!/usr/bin/env bash
1 # Build script for Ohcount.
2 # Written by Mitchell Foral. mitchell<att>caladbolg.net.
3
4 # Options
5 # Change these for your system configuration.
6 if [ `uname` != "Darwin" ]
7 then
8 # Linux
9 INC_DIR=
10 LIB_DIR=
11
12 if [ `uname` == "FreeBSD" ]
13 then
14 INC_DIR=/usr/local/include
15 LIB_DIR=/usr/local/lib
16 fi
17
18 # You shouldn't have to change the following.
19 CFLAGS=-O3
20 CFLAGS="$CFLAGS -DTMP_FILES_ARE_DT_UNKNOWN" # workaround bug on centos/SF servers
21 WARN="-Wall -Wno-pointer-to-int-cast -Wno-parentheses"
22 SHARED=-shared
23 SHARED_NAME=libohcount.so
24 RB_SHARED=-shared
25 RB_SHARED_NAME=ohcount.so
26 else
27 # Mac OSX
28 INC_DIR=/opt/local/include
29 LIB_DIR=/opt/local/lib
30 # You shouldn't have to change the following.
31 CFLAGS="-fno-common -g"
32 WARN="-Wall -Wno-parentheses"
33 SHARED="-dynamiclib -L$LIB_DIR -lpcre"
34 SHARED_NAME=libohcount.dylib
35 RB_SHARED="-dynamic -bundle -lruby"
36 RB_SHARED_NAME=ohcount.bundle
37 fi
38
39 # C compiler and flags
40 cc="gcc -fPIC -g $CFLAGS $WARN -I$INC_DIR -L$LIB_DIR"
41
42 # Ohcount source files
43 files="src/sourcefile.c \
44 src/detector.c \
45 src/licenses.c \
46 src/parser.o \
47 src/loc.c \
48 src/log.c \
49 src/diff.c \
50 src/parsed_language.c \
51 src/hash/language_hash.c"
52
53 # If any src/hash/*.gperf file is newer than the header files (which were
54 # presumably generated together), regenerate the headers.
55 build_hash_headers()
56 {
57 if [[ -z `ls src/hash/ | grep "_hash.h$"` ||
58 ! -z `find src/hash/*.gperf -newer src/hash/parser_hash.h` ]]
59 then
60 echo "Generating hash headers"
61 sh -c "cd src/hash/ && ./generate_headers" || exit 1
62 fi
63 }
64
65 # If src/parser.o does not exist, or if there are Ragel parsers or parser
66 # header files newer than the existing parser.o, recompile parser.o.
67 build_parser_o()
68 {
69 if [[ ! -f src/parser.o ||
70 ! -z `find src/parsers/*.{h,rl} -newer src/parser.o` ]]
71 then
72 bash -c "cd src/parsers/ && bash ./compile" || exit 1
73 echo "Building src/parser.c (will take a while)"
74 bash -c "$cc -c src/parser.c -o src/parser.o" || exit 1
75 fi
76 }
77
78 build_shared()
79 {
80 build_hash_headers
81 build_parser_o
82 if [[ ! -f src/$SHARED_NAME ||
83 ! -z `find src/*.{h,c} -newer src/$SHARED_NAME` ]]
84 then
85 echo "Building shared library"
86 sh -c "$cc $SHARED $files -o src/$SHARED_NAME" || exit 1
87 fi
88 }
89
90 build_ohcount()
91 {
92 build_hash_headers
93 build_parser_o
94 echo "Building Ohcount"
95 mkdir -p bin/
96 sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre" || exit 1
97 }
98
99 build_test_suite()
100 {
101 build_hash_headers
102 build_parser_o
103 echo "Building test suite"
104 sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre" \
105 || exit 1
106 }
107
108 run_test_suite()
109 {
110 echo "Running test suite"
111 sh -c "cd test/unit/ && ./run_tests"
112 }
113
114 build_ruby_bindings()
115 {
116 arch=`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`
117 echo "Generating Ruby bindings for $arch"
118 sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1
119 mkdir -p ruby/$arch
120 sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \
121 -I`ruby -rmkmf -e 'print Config::expand(CONFIG["archdir"])'` \
122 -lpcre" || exit 1
123 sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1
124 }
125
126 if [ $# -eq 0 ] || [ $1 == "all" ]
127 then
128 build_ohcount
129 build_test_suite
130 run_test_suite
131 echo $success
132 elif [ $1 == "shared" ]
133 then
134 build_shared
135 echo "Build successful; $SHARED_NAME is in src/"
136 elif [ $1 == "ohcount" ]
137 then
138 build_ohcount
139 echo "Build successful; ohcount is in bin/"
140 elif [ $1 == "tests" ]
141 then
142 build_test_suite
143 run_test_suite
144 elif [ $1 == "ruby" ]
145 then
146 build_ruby_bindings
147 echo "Build successful; $RB_SHARED_NAME is in ruby/$arch"
148 elif [ $1 == "clean" ]
149 then
150 rm -f bin/ohcount
151 rm -f test/unit/run_tests
152 rm -f src/parser.o
153 rm -f src/parsers/*.h
154 rm -f src/hash/*.h
155 rm -f src/hash/*.c
156 rm -f src/$SHARED_NAME
157 rm -f ruby/$RB_SHARED_NAME
158 rm -rf ruby/`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`/*
159 else
160 echo "Usage: build [all|ohcount|shared|tests|ruby|clean]"
161 fi
+0
-693
.pc/fix_null_dereference.patch/src/detector.c less more
0 // detector.c written by Mitchell Foral. mitchell<att>caladbolg.net.
1 // See COPYING for license information.
2
3 #include <ctype.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8
9 #include "detector.h"
10 #include "languages.h"
11 #include "log.h"
12
13 #include "hash/cppheader_hash.h"
14 #include "hash/disambiguatefunc_hash.h"
15 #include "hash/extension_hash.h"
16 #include "hash/filename_hash.h"
17
18 #define ISBINARY(x) (x[0] == '\1')
19 #define ISAMBIGUOUS(x) (x[0] == '\2')
20 #define DISAMBIGUATEWHAT(x) &x[1]
21
22 const char *ohcount_detect_language(SourceFile *sourcefile) {
23 const char *language = NULL;
24 char *p, *pe;
25 int length;
26
27 // Attempt to detect based on file extension.
28 length = strlen(sourcefile->ext);
29 struct ExtensionMap *re = ohcount_hash_language_from_ext(sourcefile->ext,
30 length);
31 if (re) language = re->value;
32 if (language == NULL) {
33 // Try the lower-case version of this extension.
34 char lowerext[length + 1];
35 strncpy(lowerext, sourcefile->ext, length);
36 lowerext[length] = '\0';
37 for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p);
38 struct ExtensionMap *re = ohcount_hash_language_from_ext(lowerext, length);
39 if (re) return re->value;
40 }
41 if (language) {
42 if (ISAMBIGUOUS(language)) {
43 // Call the appropriate function for disambiguation.
44 length = strlen(DISAMBIGUATEWHAT(language));
45 struct DisambiguateFuncsMap *rd =
46 ohcount_hash_disambiguate_func_from_id(DISAMBIGUATEWHAT(language),
47 length);
48 if (rd) return rd->value(sourcefile);
49 } else return ISBINARY(language) ? NULL : language;
50 }
51
52 // Attempt to detect based on filename.
53 length = strlen(sourcefile->filename);
54 struct FilenameMap *rf =
55 ohcount_hash_language_from_filename(sourcefile->filename, length);
56 if (rf) return rf->value;
57
58 char line[81] = { '\0' }, buf[81];
59
60 // Attempt to detect using Emacs mode line (/^-\*-\s*mode[\s:]*\w/i).
61 p = ohcount_sourcefile_get_contents(sourcefile);
62 pe = p;
63 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
64 while (pe < eof) {
65 // Get the contents of the first line.
66 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
67 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
68 strncpy(line, p, length);
69 line[length] = '\0';
70 if (*line == '#' && *(line + 1) == '!') {
71 // First line was sh-bang; loop to get contents of second line.
72 while (*pe == '\r' || *pe == '\n') pe++;
73 p = pe;
74 } else break;
75 }
76 char *eol = line + strlen(line);
77 for (p = line; p < eol; p++) *p = tolower(*p);
78 p = strstr(line, "-*-");
79 if (p) {
80 p += 3;
81 while (*p == ' ' || *p == '\t') p++;
82 if (strncmp(p, "mode", 4) == 0) {
83 p += 4;
84 while (*p == ' ' || *p == '\t' || *p == ':') p++;
85 }
86 pe = p;
87 while (isalnum(*pe)) pe++;
88 length = pe - p;
89 strncpy(buf, p, length);
90 buf[length] = '\0';
91 struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length);
92 if (rl) return rl->name;
93 }
94
95 // Attempt to detect based on Unix 'file' command.
96 int tmpfile = 0;
97 char *path = sourcefile->filepath;
98 if (sourcefile->diskpath)
99 path = sourcefile->diskpath;
100 if (access(path, F_OK) != 0) { // create temporary file
101 path = malloc(21);
102 strncpy(path, "/tmp/ohcount_XXXXXXX", 20);
103 *(path + 21) = '\0';
104 int fd = mkstemp(path);
105 char *contents = ohcount_sourcefile_get_contents(sourcefile);
106 log_it("contents:");
107 log_it(contents);
108 length = contents ? strlen(contents) : 0;
109 write(fd, contents, length);
110 close(fd);
111 tmpfile = 1;
112 }
113 char command[strlen(path) + 11];
114 sprintf(command, "file -b '%s'", path);
115 FILE *f = popen(command, "r");
116 if (f) {
117 fgets(line, sizeof(line), f);
118 char *eol = line + strlen(line);
119 for (p = line; p < eol; p++) *p = tolower(*p);
120 p = strstr(line, "script text");
121 if (p && p == line) { // /^script text(?: executable)? for \w/
122 p = strstr(line, "for ");
123 if (p) {
124 p += 4;
125 pe = p;
126 while (isalnum(*pe)) pe++;
127 length = pe - p;
128 strncpy(buf, p, length);
129 buf[length] = '\0';
130 struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length);
131 if (rl) language = rl->name;
132 }
133 } else if (p) { // /(\w+)(?: -\w+)* script text/
134 do {
135 p--;
136 pe = p;
137 while (*p == ' ') p--;
138 while (p != line && isalnum(*(p - 1))) p--;
139 if (p != line && *(p - 1) == '-') p--;
140 } while (*p == '-'); // Skip over any switches.
141 length = pe - p;
142 strncpy(buf, p, length);
143 buf[length] = '\0';
144 struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length);
145 if (rl) language = rl->name;
146 } else if (strstr(line, "xml")) language = LANG_XML;
147 pclose(f);
148 if (tmpfile) {
149 remove(path);
150 free(path);
151 }
152 if (language) return language;
153 }
154
155 return NULL;
156 }
157
158 const char *disambiguate_aspx(SourceFile *sourcefile) {
159 char *p = ohcount_sourcefile_get_contents(sourcefile);
160 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
161 for (; p < eof; p++) {
162 // /<%@\s*Page[^>]+Language="VB"[^>]+%>/
163 p = strstr(p, "<%@");
164 if (!p)
165 break;
166 char *pe = strstr(p, "%>");
167 if (p && pe) {
168 p += 3;
169 const int length = pe - p;
170 char buf[length];
171 strncpy(buf, p, length);
172 buf[length] = '\0';
173 char *eol = buf + strlen(buf);
174 for (p = buf; p < eol; p++) *p = tolower(*p);
175 p = buf;
176 while (*p == ' ' || *p == '\t') p++;
177 if (strncmp(p, "page", 4) == 0) {
178 p += 4;
179 if (strstr(p, "language=\"vb\""))
180 return LANG_VB_ASPX;
181 }
182 }
183 }
184 return LANG_CS_ASPX;
185 }
186
187 const char *disambiguate_b(SourceFile *sourcefile) {
188 char *p = ohcount_sourcefile_get_contents(sourcefile);
189 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
190 while (p < eof) {
191 // /(implement[ \t])|(include[ \t]+"[^"]*";)|
192 // ((return|break|continue).*;|(pick|case).*\{)/
193 if (strncmp(p, "implement", 9) == 0 &&
194 (*(p + 9) == ' ' || *(p + 9) == '\t'))
195 return LANG_LIMBO;
196 else if (strncmp(p, "include", 7) == 0 &&
197 (*(p + 7) == ' ' || *(p + 7) == '\t')) {
198 p += 7;
199 while (*p == ' ' || *p == '\t') p++;
200 if (*p == '"') {
201 while (*p != '"' && p < eof) p++;
202 if (*p == '"' && *(p + 1) == ';')
203 return LANG_LIMBO;
204 }
205 } else if (strncmp(p, "return", 6) == 0 ||
206 strncmp(p, "break", 5) == 0 ||
207 strncmp(p, "continue", 8) == 0) {
208 if (strstr(p, ";"))
209 return LANG_LIMBO;
210 } else if (strncmp(p, "pick", 4) == 0 ||
211 strncmp(p, "case", 4) == 0) {
212 if (strstr(p, "{"))
213 return LANG_LIMBO;
214 }
215 p++;
216 }
217 return disambiguate_basic(sourcefile);
218 }
219
220 const char *disambiguate_basic(SourceFile *sourcefile) {
221 char *p, *pe;
222 int length;
223
224 // Attempt to detect based on file contents.
225 char line[81];
226 p = ohcount_sourcefile_get_contents(sourcefile);
227 pe = p;
228 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
229 while (pe < eof) {
230 // Get a line at a time.
231 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
232 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
233 strncpy(line, p, length);
234 line[length] = '\0';
235 char *line_end = pe;
236
237 p = line;
238 if (isdigit(*p)) {
239 // /^\d+\s+\w/
240 p++;
241 while (isdigit(*p)) p++;
242 if (*p == ' ' || *p == '\t') {
243 p++;
244 while (*p == ' ' || *p == '\t') p++;
245 if (isalnum(*p))
246 return LANG_CLASSIC_BASIC;
247 }
248 }
249
250 // Next line.
251 pe = line_end;
252 while (*pe == '\r' || *pe == '\n') pe++;
253 p = pe;
254 }
255
256 // Attempt to detect from associated VB files in file context.
257 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
258 if (filenames) {
259 int i;
260 for (i = 0; filenames[i] != NULL; i++) {
261 pe = filenames[i] + strlen(filenames[i]);
262 p = pe;
263 while (p > filenames[i] && *(p - 1) != '.') p--;
264 length = pe - p;
265 if (length == 3 &&
266 (strncmp(p, "frm", length) == 0 ||
267 strncmp(p, "frx", length) == 0 ||
268 strncmp(p, "vba", length) == 0 ||
269 strncmp(p, "vbp", length) == 0 ||
270 strncmp(p, "vbs", length) == 0)) {
271 return LANG_VISUALBASIC;
272 }
273 }
274 }
275
276 return LANG_STRUCTURED_BASIC;
277 }
278
279 const char *disambiguate_cs(SourceFile *sourcefile) {
280 // Attempt to detect based on file contents.
281 char *contents = ohcount_sourcefile_get_contents(sourcefile);
282 if (contents && strstr(contents, "<?cs"))
283 return LANG_CLEARSILVER_TEMPLATE;
284 else
285 return LANG_CSHARP;
286 }
287
288 const char *disambiguate_fortran(SourceFile *sourcefile) {
289 char *p, *pe;
290
291 p = ohcount_sourcefile_get_contents(sourcefile);
292 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
293 while (p < eof) {
294 if (*p == ' ' && p + 5 < eof) {
295 int i;
296 for (i = 1; i <= 5; i++)
297 if (!isdigit(*(p + i)) && *(p + i) != ' ')
298 return LANG_FORTRANFIXED; // definately not f77
299 // Possibly fixed (doesn't match /^\s*\d+\s*$/).
300 pe = p;
301 while (*pe == ' ' || *pe == '\t') pe++;
302 if (pe - p <= 5) {
303 if (!isdigit(*pe))
304 return LANG_FORTRANFIXED;
305 while (isdigit(*pe)) pe++;
306 while (*pe == ' ' || *pe == '\t') pe++;
307 if (*pe != '\r' && *pe != '\n' && pe - p == 5)
308 return LANG_FORTRANFIXED;
309 }
310 }
311 while (*p != '\r' && *p != '\n' && *p != '&' && p < eof) p++;
312 if (*p == '&') {
313 p++;
314 // Look for free-form continuation.
315 while (*p == ' ' || *p == '\t') p++;
316 if (*p == '\r' || *p == '\n') {
317 pe = p;
318 while (*pe == '\r' || *pe == '\n' || *pe == ' ' || *pe == '\t') pe++;
319 if (*pe == '&')
320 return LANG_FORTRANFREE;
321 }
322 }
323 while (*p == '\r' || *p == '\n') p++;
324 }
325 return LANG_FORTRANFREE; // might as well be free-form
326 }
327
328 const char *disambiguate_h(SourceFile *sourcefile) {
329 char *p, *pe;
330 int length;
331
332 // If the directory contains a matching *.m file, likely Objective C.
333 length = strlen(sourcefile->filename);
334 if (strcmp(sourcefile->ext, "h") == 0) {
335 char path[length];
336 strncpy(path, sourcefile->filename, length);
337 path[length] = '\0';
338 *(path + length - 1) = 'm';
339 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
340 if (filenames) {
341 int i;
342 for (i = 0; filenames[i] != NULL; i++)
343 if (strcmp(path, filenames[i]) == 0)
344 return LANG_OBJECTIVE_C;
345 }
346 }
347
348 // Attempt to detect based on file contents.
349 char line[81], buf[81];
350 p = ohcount_sourcefile_get_contents(sourcefile);
351 pe = p;
352 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
353 while (pe < eof) {
354 // Get a line at a time.
355 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
356 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
357 strncpy(line, p, length);
358 line[length] = '\0';
359 char *eol = line + strlen(line);
360 char *line_end = pe;
361
362 // Look for C++ headers.
363 if (*line == '#') {
364 p = line + 1;
365 while (*p == ' ' || *p == '\t') p++;
366 if (strncmp(p, "include", 7) == 0 &&
367 (*(p + 7) == ' ' || *(p + 7) == '\t')) {
368 // /^#\s*include\s+[<"][^>"]+[>"]/
369 p += 8;
370 while (*p == ' ' || *p == '\t') p++;
371 if (*p == '<' || *p == '"') {
372 // Is the header file a C++ header file?
373 p++;
374 pe = p;
375 while (pe < eol && *pe != '>' && *pe != '"') pe++;
376 length = pe - p;
377 strncpy(buf, p, length);
378 buf[length] = '\0';
379 if (ohcount_hash_is_cppheader(buf, length))
380 return LANG_CPP;
381 // Is the extension for the header file a C++ file?
382 p = pe;
383 while (p > line && *(p - 1) != '.') p--;
384 length = pe - p;
385 strncpy(buf, p, length);
386 buf[length] = '\0';
387 struct ExtensionMap *re = ohcount_hash_language_from_ext(buf, length);
388 if (re && strcmp(re->value, LANG_CPP) == 0)
389 return LANG_CPP;
390 }
391 }
392 }
393
394 // Look for C++ keywords.
395 p = line;
396 while (p < eol) {
397 if (islower(*p) && p != line && !isalnum(*(p - 1)) && *(p - 1) != '_') {
398 pe = p;
399 while (islower(*pe)) pe++;
400 if (!isalnum(*pe) && *pe != '_') {
401 length = pe - p;
402 strncpy(buf, p, length);
403 buf[length] = '\0';
404 if (strcmp(buf, "class") == 0 ||
405 strcmp(buf, "namespace") == 0 ||
406 strcmp(buf, "template") == 0 ||
407 strcmp(buf, "typename") == 0)
408 return LANG_CPP;
409 }
410 p = pe + 1;
411 } else p++;
412 }
413
414 // Next line.
415 pe = line_end;
416 while (*pe == '\r' || *pe == '\n') pe++;
417 p = pe;
418 }
419
420 // Nothing to suggest C++.
421 return LANG_C;
422 }
423
424 const char *disambiguate_in(SourceFile *sourcefile) {
425 char *p, *pe;
426 int length;
427 const char *language = NULL;
428
429 p = sourcefile->filepath;
430 pe = p + strlen(p) - 3;
431 if (strstr(p, ".") <= pe) {
432 // Only if the filename has an extension prior to the .in
433 length = pe - p;
434 char buf[length];
435 strncpy(buf, p, length);
436 buf[length] = '\0';
437 SourceFile *undecorated = ohcount_sourcefile_new(buf);
438 p = ohcount_sourcefile_get_contents(sourcefile);
439 if (!p) {
440 return NULL;
441 }
442 // The filepath without the '.in' extension does not exist on disk. The
443 // sourcefile->diskpath field must be set incase the detector needs to run
444 // 'file -b' on the file.
445 ohcount_sourcefile_set_diskpath(undecorated, sourcefile->filepath);
446 ohcount_sourcefile_set_contents(undecorated, p);
447 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
448 ohcount_sourcefile_set_filenames(undecorated, filenames);
449 language = ohcount_sourcefile_get_language(undecorated);
450 ohcount_sourcefile_free(undecorated);
451 }
452 return language;
453 }
454
455 const char *disambiguate_inc(SourceFile *sourcefile) {
456 char *p = ohcount_sourcefile_get_contents(sourcefile);
457 char *eof = p + strlen(p);
458 while (p < eof) {
459 if (*p == '\0')
460 return BINARY;
461 else if (*p == '?' && strncmp(p + 1, "php", 3) == 0)
462 return LANG_PHP;
463 p++;
464 }
465 return NULL;
466 }
467
468 const char *disambiguate_m(SourceFile *sourcefile) {
469 char *p, *pe;
470 int length;
471
472 // Attempt to detect based on a weighted heuristic of file contents.
473 int matlab_score = 0;
474 int objective_c_score = 0;
475 int limbo_score = 0;
476 int octave_syntax_detected = 0;
477
478 int i, has_h_headers = 0, has_c_files = 0;
479 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
480 if (filenames) {
481 for (i = 0; filenames[i] != NULL; i++) {
482 p = filenames[i];
483 pe = p + strlen(p);
484 if (pe - p >= 4) {
485 if (*(pe - 4) == '.' && *(pe - 3) == 'c' &&
486 ((*(pe - 2) == 'p' && *(pe - 1) == 'p') ||
487 (*(pe - 2) == '+' && *(pe - 1) == '+') ||
488 (*(pe - 2) == 'x' && *(pe - 1) == 'x'))) {
489 has_c_files = 1;
490 break; // short circuit
491 }
492 } else if (pe - p >= 3) {
493 if (*(pe - 3) == '.' && *(pe - 2) == 'c' && *(pe - 1) == 'c') {
494 has_c_files = 1;
495 break; // short circuit
496 }
497 } else if (pe - p >= 2) {
498 if (*(pe - 2) == '.') {
499 if (*(pe - 1) == 'h')
500 has_h_headers = 1;
501 else if (*(pe - 1) == 'c' || *(pe - 1) == 'C') {
502 has_c_files = 1;
503 break; // short circuit
504 }
505 }
506 }
507 }
508 }
509 if (has_h_headers && !has_c_files)
510 objective_c_score += 5;
511
512 char line[81], buf[81];
513 p = ohcount_sourcefile_get_contents(sourcefile);
514 pe = p;
515 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
516 while (pe < eof) {
517 // Get a line at a time.
518 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
519 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
520 strncpy(line, p, length);
521 line[length] = '\0';
522 char *eol = line + strlen(line);
523 char *line_end = pe;
524
525 // Look for tell-tale lines.
526 p = line;
527 while (*p == ' ' || *p == '\t') p++;
528 if (*p == '%') { // Matlab comment
529 matlab_score++;
530 } else if (*p == '#' && strncmp(p, "#import", 7) == 0) { // Objective C
531 objective_c_score++;
532 } else if (*p == '#') { // Limbo or Octave comment
533 while (*p == '#') p++;
534 if (*p == ' ' || *p == '\t') {
535 limbo_score++;
536 matlab_score++;
537 octave_syntax_detected = 1;
538 }
539 } else if (*p == '/' && *(p + 1) == '/' || *(p + 1) == '*') {
540 objective_c_score++; // Objective C comment
541 } else if (*p == '+' || *p == '-') { // Objective C method signature
542 objective_c_score++;
543 } else if (*p == '@' || *p == '#') { // Objective C method signature
544 if (strncmp(p, "@implementation", 15) == 0 ||
545 strncmp(p, "@interface", 10) == 0)
546 objective_c_score++;
547 } else if (strncmp(p, "function", 8) == 0) { // Matlab or Octave function
548 p += 8;
549 while (*p == ' ' || *p == '\t') p++;
550 if (*p == '(')
551 matlab_score++;
552 } else if (strncmp(p, "include", 7) == 0) { // Limbo include
553 // /^include[ \t]+"[^"]+\.m";/
554 p += 7;
555 if (*p == ' ' || *p == '\t') {
556 while (*p == ' ' || *p == '\t') p++;
557 if (*p == '"') {
558 while (*p != '"' && p < eol) p++;
559 if (*p == '"' && *(p - 2) == '.' && *(p - 1) == 'm')
560 limbo_score++;
561 }
562 }
563 }
564
565 // Look for Octave keywords.
566 p = line;
567 while (p < eol) {
568 if (islower(*p) && p != line && !isalnum(*(p - 1))) {
569 pe = p;
570 while (islower(*pe) || *pe == '_') pe++;
571 if (!isalnum(*pe)) {
572 length = pe - p;
573 strncpy(buf, p, length);
574 buf[length] = '\0';
575 if (strcmp(buf, "end_try_catch") == 0 ||
576 strcmp(buf, "end_unwind_protect") == 0 ||
577 strcmp(buf, "endfunction") == 0 ||
578 strcmp(buf, "endwhile") == 0)
579 octave_syntax_detected = 1;
580 }
581 p = pe + 1;
582 } else p++;
583 }
584
585 // Look for Limbo declarations
586 p = line;
587 while (p < eol) {
588 if (*p == ':' && (*(p + 1) == ' ' || *(p + 1) == '\t')) {
589 // /:[ \t]+(module|adt|fn ?\(|con[ \t])/
590 p += 2;
591 if (strncmp(p, "module", 6) == 0 && !isalnum(*(p + 6)) ||
592 strncmp(p, "adt", 3) == 0 && !isalnum(*(p + 3)) ||
593 strncmp(p, "fn", 2) == 0 &&
594 (*(p + 2) == ' ' && *(p + 3) == '(' || *(p + 2) == '(') ||
595 strncmp(p, "con", 3) == 0 &&
596 (*(p + 3) == ' ' || *(p + 3) == '\t'))
597 limbo_score++;
598 } else p++;
599 }
600
601 // Next line.
602 pe = line_end;
603 while (*pe == '\r' || *pe == '\n') pe++;
604 p = pe;
605 }
606
607 if (limbo_score > objective_c_score && limbo_score > matlab_score)
608 return LANG_LIMBO;
609 else if (objective_c_score > matlab_score)
610 return LANG_OBJECTIVE_C;
611 else
612 return octave_syntax_detected ? LANG_OCTAVE : LANG_MATLAB;
613 }
614
615 #define QMAKE_SOURCES_SPACE "SOURCES +="
616 #define QMAKE_SOURCES "SOURCES+="
617 #define QMAKE_CONFIG_SPACE "CONFIG +="
618 #define QMAKE_CONFIG "CONFIG+="
619
620 const char *disambiguate_pro(SourceFile *sourcefile) {
621 char *p = ohcount_sourcefile_get_contents(sourcefile);
622 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
623 for (; p < eof; p++) {
624 if (strncmp(p, QMAKE_SOURCES_SPACE, strlen(QMAKE_SOURCES_SPACE)) == 0 ||
625 strncmp(p, QMAKE_SOURCES, strlen(QMAKE_SOURCES)) == 0 ||
626 strncmp(p, QMAKE_CONFIG_SPACE, strlen(QMAKE_CONFIG_SPACE)) == 0 ||
627 strncmp(p, QMAKE_CONFIG, strlen(QMAKE_CONFIG)) == 0)
628 return LANG_MAKE; // really QMAKE
629 }
630 return LANG_IDL_PVWAVE;
631 }
632
633 const char *disambiguate_st(SourceFile *sourcefile) {
634 char *p, *pe;
635 int length;
636
637 // Attempt to detect based on file contents.
638 int found_assignment = 0, found_block_start = 0, found_block_end = 0;
639
640 char line[81];
641 p = ohcount_sourcefile_get_contents(sourcefile);
642 pe = p;
643 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
644 while (pe < eof) {
645 // Get a line at a time.
646 while (p < eof && *pe != '\r' && *pe != '\n') pe++;
647 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
648 strncpy(line, p, length);
649 line[length] = '\0';
650 char *eol = line + strlen(line);
651 char *line_end = pe;
652
653 for (p = line; p < eol; p++) {
654 if (*p == ':') {
655 p++;
656 while (p < eol && (*p == ' ' || *p == '\t')) p++;
657 if (*p == '=')
658 found_assignment = 1;
659 else if (*p == '[')
660 found_block_start = 1;
661 } else if (*p == ']' && *(p + 1) == '.') found_block_end = 1;
662 if (found_assignment && found_block_start && found_block_end)
663 return LANG_SMALLTALK;
664 }
665
666 // Next line.
667 pe = line_end;
668 while (*pe == '\r' || *pe == '\n') pe++;
669 p = pe;
670 }
671
672 return NULL;
673 }
674
675 int ohcount_is_binary_filename(const char *filename) {
676 char *p = (char *)filename + strlen(filename);
677 while (p > filename && *(p - 1) != '.') p--;
678 if (p > filename) {
679 struct ExtensionMap *re;
680 int length = strlen(p);
681 re = ohcount_hash_language_from_ext(p, length);
682 if (re) return ISBINARY(re->value);
683 // Try the lower-case version of this extension.
684 char lowerext[length];
685 strncpy(lowerext, p, length);
686 lowerext[length] = '\0';
687 for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p);
688 re = ohcount_hash_language_from_ext(lowerext, length);
689 if (re) return ISBINARY(re->value);
690 }
691 return 0;
692 }
+0
-0
.pc/fix_null_dereference.patch/test/detect_files/empty.inc less more
(Empty file)
+0
-133
.pc/fix_null_dereference.patch/test/unit/detector_test.h less more
0 // detector_test.h written by Mitchell Foral. mitchell<att>caladbolg.net.
1 // See COPYING for license information.
2
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "../../src/detector.h"
8 #include "../../src/languages.h"
9 #include "../../src/sourcefile.h"
10
11 #define ASSERT_DETECT(x, y) { \
12 SourceFile *sf = ohcount_sourcefile_new("../detect_files/" y); \
13 const char *lang = ohcount_detect_language(sf); \
14 assert(lang); \
15 assert(strcmp(x, lang) == 0); \
16 ohcount_sourcefile_free(sf); \
17 }
18 #define ASSERT_NODETECT(x) { \
19 SourceFile *sf = ohcount_sourcefile_new("../detect_files/" x); \
20 assert(ohcount_detect_language(sf) == NULL); \
21 ohcount_sourcefile_free(sf); \
22 }
23
24 void test_detector_smalltalk() {
25 ASSERT_DETECT(LANG_SMALLTALK, "example.st");
26 ASSERT_NODETECT("english.st");
27 }
28
29 void test_detector_disambiguate_m() {
30 ASSERT_DETECT(LANG_OBJECTIVE_C, "t1.m");
31 ASSERT_DETECT(LANG_OBJECTIVE_C, "t2.m");
32 ASSERT_DETECT(LANG_OBJECTIVE_C, "TCPSocket.m");
33 ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.m");
34 ASSERT_DETECT(LANG_MATLAB, "foo_matlab.m");
35 ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m");
36 }
37
38 void test_detector_disambiguate_in() {
39 ASSERT_NODETECT("empty.in");
40 }
41 void test_detector_disambiguate_pro() {
42 ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
43 ASSERT_DETECT(LANG_MAKE, "qmake.pro");
44 }
45
46 void test_detector_fortran_fixedfree() {
47 ASSERT_DETECT(LANG_FORTRANFIXED, "fortranfixed.f");
48 ASSERT_DETECT(LANG_FORTRANFREE, "fortranfree.f");
49 }
50
51 void test_detector_detect_polyglot() {
52 ASSERT_DETECT(LANG_C, "foo.c");
53 ASSERT_DETECT(LANG_C, "uses_no_cpp.h");
54 ASSERT_DETECT(LANG_CPP, "uses_cpp_headers.h");
55 ASSERT_DETECT(LANG_CPP, "uses_cpp_stdlib_headers.h");
56 ASSERT_DETECT(LANG_CPP, "uses_cpp_keywords.h");
57 ASSERT_DETECT(LANG_RUBY, "foo.rb");
58 ASSERT_DETECT(LANG_MAKE, "foo.mk");
59 ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.h");
60 ASSERT_DETECT(LANG_PHP, "upper_case_php");
61 ASSERT_DETECT(LANG_SMALLTALK, "example.st");
62 ASSERT_DETECT(LANG_VALA, "foo.vala");
63 ASSERT_DETECT(LANG_TEX, "foo.tex");
64 ASSERT_DETECT(LANG_XSLT, "example.xsl");
65 ASSERT_DETECT(LANG_LISP, "core.lisp");
66 ASSERT_DETECT(LANG_DMD, "foo.d");
67 ASSERT_DETECT(LANG_VIM, "foo.vim");
68 ASSERT_DETECT(LANG_EBUILD, "foo.ebuild");
69 ASSERT_DETECT(LANG_EBUILD, "foo.eclass");
70 ASSERT_DETECT(LANG_EXHERES, "foo.exheres-0");
71 ASSERT_DETECT(LANG_EXHERES, "foo.exlib");
72 ASSERT_DETECT(LANG_EIFFEL, "eiffel.e");
73 ASSERT_DETECT(LANG_OCAML, "ocaml.ml");
74 ASSERT_DETECT(LANG_STRATEGO, "stratego.str");
75 ASSERT_DETECT(LANG_R, "foo.R");
76 ASSERT_DETECT(LANG_GLSL, "foo.glsl");
77 ASSERT_DETECT(LANG_GLSL, "foo_glsl.vert");
78 ASSERT_DETECT(LANG_GLSL, "foo_glsl.frag");
79 ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
80 ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80");
81 ASSERT_DETECT(LANG_PHP, "php.inc");
82 ASSERT_DETECT(LANG_FSHARP, "fs1.fs");
83 }
84
85 void test_detector_upper_case_extensions() {
86 ASSERT_DETECT(LANG_CPP, "foo_upper_case.C");
87 ASSERT_DETECT(LANG_RUBY, "foo_upper_case.RB");
88 }
89
90 void test_detector_no_extensions() {
91 ASSERT_DETECT(LANG_PYTHON, "py_script");
92 ASSERT_DETECT(LANG_RUBY, "ruby_script");
93 ASSERT_DETECT(LANG_SHELL, "bourne_again_script");
94 ASSERT_DETECT(LANG_SHELL, "bash_script");
95 ASSERT_DETECT(LANG_PERL, "perl_w");
96 ASSERT_DETECT(LANG_DMD, "d_script");
97 ASSERT_DETECT(LANG_TCL, "tcl_script");
98 ASSERT_DETECT(LANG_PYTHON, "python.data");
99 ASSERT_DETECT(LANG_PYTHON, "python2.data");
100 }
101
102 void test_detector_csharp_or_clearsilver() {
103 ASSERT_DETECT(LANG_CSHARP, "cs1.cs");
104 ASSERT_DETECT(LANG_CLEARSILVER_TEMPLATE, "clearsilver_template1.cs");
105 }
106
107 void test_detector_basic() {
108 ASSERT_DETECT(LANG_VISUALBASIC, "visual_basic.bas");
109 ASSERT_DETECT(LANG_CLASSIC_BASIC, "classic_basic.b");
110 system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2");
111 ASSERT_DETECT(LANG_STRUCTURED_BASIC, "visual_basic.bas");
112 ASSERT_DETECT(LANG_STRUCTURED_BASIC, "structured_basic.b");
113 system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx");
114 }
115
116 void test_detector_xml_with_custom_extension() {
117 ASSERT_DETECT(LANG_XML, "xml.custom_ext");
118 }
119
120 void all_detector_tests() {
121 test_detector_smalltalk();
122 test_detector_disambiguate_m();
123 test_detector_disambiguate_in();
124 test_detector_disambiguate_pro();
125 test_detector_fortran_fixedfree();
126 test_detector_detect_polyglot();
127 test_detector_upper_case_extensions();
128 test_detector_no_extensions();
129 test_detector_csharp_or_clearsilver();
130 test_detector_basic();
131 test_detector_xml_with_custom_extension();
132 }
+0
-690
.pc/fix_null_dereference_2.patch/src/detector.c less more
0 // detector.c written by Mitchell Foral. mitchell<att>caladbolg.net.
1 // See COPYING for license information.
2
3 #include <ctype.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8
9 #include "detector.h"
10 #include "languages.h"
11 #include "log.h"
12
13 #include "hash/cppheader_hash.h"
14 #include "hash/disambiguatefunc_hash.h"
15 #include "hash/extension_hash.h"
16 #include "hash/filename_hash.h"
17
18 #define ISBINARY(x) (x[0] == '\1')
19 #define ISAMBIGUOUS(x) (x[0] == '\2')
20 #define DISAMBIGUATEWHAT(x) &x[1]
21
22 const char *ohcount_detect_language(SourceFile *sourcefile) {
23 const char *language = NULL;
24 char *p, *pe;
25 int length;
26
27 // Attempt to detect based on file extension.
28 length = strlen(sourcefile->ext);
29 struct ExtensionMap *re = ohcount_hash_language_from_ext(sourcefile->ext,
30 length);
31 if (re) language = re->value;
32 if (language == NULL) {
33 // Try the lower-case version of this extension.
34 char lowerext[length + 1];
35 strncpy(lowerext, sourcefile->ext, length);
36 lowerext[length] = '\0';
37 for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p);
38 struct ExtensionMap *re = ohcount_hash_language_from_ext(lowerext, length);
39 if (re) return re->value;
40 }
41 if (language) {
42 if (ISAMBIGUOUS(language)) {
43 // Call the appropriate function for disambiguation.
44 length = strlen(DISAMBIGUATEWHAT(language));
45 struct DisambiguateFuncsMap *rd =
46 ohcount_hash_disambiguate_func_from_id(DISAMBIGUATEWHAT(language),
47 length);
48 if (rd) return rd->value(sourcefile);
49 } else return ISBINARY(language) ? NULL : language;
50 }
51
52 // Attempt to detect based on filename.
53 length = strlen(sourcefile->filename);
54 struct FilenameMap *rf =
55 ohcount_hash_language_from_filename(sourcefile->filename, length);
56 if (rf) return rf->value;
57
58 char line[81] = { '\0' }, buf[81];
59
60 // Attempt to detect using Emacs mode line (/^-\*-\s*mode[\s:]*\w/i).
61 p = ohcount_sourcefile_get_contents(sourcefile);
62 pe = p;
63 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
64 while (pe < eof) {
65 // Get the contents of the first line.
66 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
67 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
68 strncpy(line, p, length);
69 line[length] = '\0';
70 if (*line == '#' && *(line + 1) == '!') {
71 // First line was sh-bang; loop to get contents of second line.
72 while (*pe == '\r' || *pe == '\n') pe++;
73 p = pe;
74 } else break;
75 }
76 char *eol = line + strlen(line);
77 for (p = line; p < eol; p++) *p = tolower(*p);
78 p = strstr(line, "-*-");
79 if (p) {
80 p += 3;
81 while (*p == ' ' || *p == '\t') p++;
82 if (strncmp(p, "mode", 4) == 0) {
83 p += 4;
84 while (*p == ' ' || *p == '\t' || *p == ':') p++;
85 }
86 pe = p;
87 while (isalnum(*pe)) pe++;
88 length = pe - p;
89 strncpy(buf, p, length);
90 buf[length] = '\0';
91 struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length);
92 if (rl) return rl->name;
93 }
94
95 // Attempt to detect based on Unix 'file' command.
96 int tmpfile = 0;
97 char *path = sourcefile->filepath;
98 if (sourcefile->diskpath)
99 path = sourcefile->diskpath;
100 if (access(path, F_OK) != 0) { // create temporary file
101 path = malloc(21);
102 strncpy(path, "/tmp/ohcount_XXXXXXX", 20);
103 *(path + 21) = '\0';
104 int fd = mkstemp(path);
105 char *contents = ohcount_sourcefile_get_contents(sourcefile);
106 log_it("contents:");
107 log_it(contents);
108 length = contents ? strlen(contents) : 0;
109 write(fd, contents, length);
110 close(fd);
111 tmpfile = 1;
112 }
113 char command[strlen(path) + 11];
114 sprintf(command, "file -b '%s'", path);
115 FILE *f = popen(command, "r");
116 if (f) {
117 fgets(line, sizeof(line), f);
118 char *eol = line + strlen(line);
119 for (p = line; p < eol; p++) *p = tolower(*p);
120 p = strstr(line, "script text");
121 if (p && p == line) { // /^script text(?: executable)? for \w/
122 p = strstr(line, "for ");
123 if (p) {
124 p += 4;
125 pe = p;
126 while (isalnum(*pe)) pe++;
127 length = pe - p;
128 strncpy(buf, p, length);
129 buf[length] = '\0';
130 struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length);
131 if (rl) language = rl->name;
132 }
133 } else if (p) { // /(\w+)(?: -\w+)* script text/
134 do {
135 p--;
136 pe = p;
137 while (*p == ' ') p--;
138 while (p != line && isalnum(*(p - 1))) p--;
139 if (p != line && *(p - 1) == '-') p--;
140 } while (*p == '-'); // Skip over any switches.
141 length = pe - p;
142 strncpy(buf, p, length);
143 buf[length] = '\0';
144 struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length);
145 if (rl) language = rl->name;
146 } else if (strstr(line, "xml")) language = LANG_XML;
147 pclose(f);
148 if (tmpfile) {
149 remove(path);
150 free(path);
151 }
152 if (language) return language;
153 }
154
155 return NULL;
156 }
157
158 const char *disambiguate_aspx(SourceFile *sourcefile) {
159 char *p = ohcount_sourcefile_get_contents(sourcefile);
160 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
161 for (; p < eof; p++) {
162 // /<%@\s*Page[^>]+Language="VB"[^>]+%>/
163 p = strstr(p, "<%@");
164 if (!p)
165 break;
166 char *pe = strstr(p, "%>");
167 if (p && pe) {
168 p += 3;
169 const int length = pe - p;
170 char buf[length];
171 strncpy(buf, p, length);
172 buf[length] = '\0';
173 char *eol = buf + strlen(buf);
174 for (p = buf; p < eol; p++) *p = tolower(*p);
175 p = buf;
176 while (*p == ' ' || *p == '\t') p++;
177 if (strncmp(p, "page", 4) == 0) {
178 p += 4;
179 if (strstr(p, "language=\"vb\""))
180 return LANG_VB_ASPX;
181 }
182 }
183 }
184 return LANG_CS_ASPX;
185 }
186
187 const char *disambiguate_b(SourceFile *sourcefile) {
188 char *p = ohcount_sourcefile_get_contents(sourcefile);
189 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
190 while (p < eof) {
191 // /(implement[ \t])|(include[ \t]+"[^"]*";)|
192 // ((return|break|continue).*;|(pick|case).*\{)/
193 if (strncmp(p, "implement", 9) == 0 &&
194 (*(p + 9) == ' ' || *(p + 9) == '\t'))
195 return LANG_LIMBO;
196 else if (strncmp(p, "include", 7) == 0 &&
197 (*(p + 7) == ' ' || *(p + 7) == '\t')) {
198 p += 7;
199 while (*p == ' ' || *p == '\t') p++;
200 if (*p == '"') {
201 while (*p != '"' && p < eof) p++;
202 if (*p == '"' && *(p + 1) == ';')
203 return LANG_LIMBO;
204 }
205 } else if (strncmp(p, "return", 6) == 0 ||
206 strncmp(p, "break", 5) == 0 ||
207 strncmp(p, "continue", 8) == 0) {
208 if (strstr(p, ";"))
209 return LANG_LIMBO;
210 } else if (strncmp(p, "pick", 4) == 0 ||
211 strncmp(p, "case", 4) == 0) {
212 if (strstr(p, "{"))
213 return LANG_LIMBO;
214 }
215 p++;
216 }
217 return disambiguate_basic(sourcefile);
218 }
219
220 const char *disambiguate_basic(SourceFile *sourcefile) {
221 char *p, *pe;
222 int length;
223
224 // Attempt to detect based on file contents.
225 char line[81];
226 p = ohcount_sourcefile_get_contents(sourcefile);
227 pe = p;
228 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
229 while (pe < eof) {
230 // Get a line at a time.
231 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
232 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
233 strncpy(line, p, length);
234 line[length] = '\0';
235 char *line_end = pe;
236
237 p = line;
238 if (isdigit(*p)) {
239 // /^\d+\s+\w/
240 p++;
241 while (isdigit(*p)) p++;
242 if (*p == ' ' || *p == '\t') {
243 p++;
244 while (*p == ' ' || *p == '\t') p++;
245 if (isalnum(*p))
246 return LANG_CLASSIC_BASIC;
247 }
248 }
249
250 // Next line.
251 pe = line_end;
252 while (*pe == '\r' || *pe == '\n') pe++;
253 p = pe;
254 }
255
256 // Attempt to detect from associated VB files in file context.
257 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
258 if (filenames) {
259 int i;
260 for (i = 0; filenames[i] != NULL; i++) {
261 pe = filenames[i] + strlen(filenames[i]);
262 p = pe;
263 while (p > filenames[i] && *(p - 1) != '.') p--;
264 length = pe - p;
265 if (length == 3 &&
266 (strncmp(p, "frm", length) == 0 ||
267 strncmp(p, "frx", length) == 0 ||
268 strncmp(p, "vba", length) == 0 ||
269 strncmp(p, "vbp", length) == 0 ||
270 strncmp(p, "vbs", length) == 0)) {
271 return LANG_VISUALBASIC;
272 }
273 }
274 }
275
276 return LANG_STRUCTURED_BASIC;
277 }
278
279 const char *disambiguate_cs(SourceFile *sourcefile) {
280 // Attempt to detect based on file contents.
281 char *contents = ohcount_sourcefile_get_contents(sourcefile);
282 if (contents && strstr(contents, "<?cs"))
283 return LANG_CLEARSILVER_TEMPLATE;
284 else
285 return LANG_CSHARP;
286 }
287
288 const char *disambiguate_fortran(SourceFile *sourcefile) {
289 char *p, *pe;
290
291 p = ohcount_sourcefile_get_contents(sourcefile);
292 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
293 while (p < eof) {
294 if (*p == ' ' && p + 5 < eof) {
295 int i;
296 for (i = 1; i <= 5; i++)
297 if (!isdigit(*(p + i)) && *(p + i) != ' ')
298 return LANG_FORTRANFIXED; // definately not f77
299 // Possibly fixed (doesn't match /^\s*\d+\s*$/).
300 pe = p;
301 while (*pe == ' ' || *pe == '\t') pe++;
302 if (pe - p <= 5) {
303 if (!isdigit(*pe))
304 return LANG_FORTRANFIXED;
305 while (isdigit(*pe)) pe++;
306 while (*pe == ' ' || *pe == '\t') pe++;
307 if (*pe != '\r' && *pe != '\n' && pe - p == 5)
308 return LANG_FORTRANFIXED;
309 }
310 }
311 while (*p != '\r' && *p != '\n' && *p != '&' && p < eof) p++;
312 if (*p == '&') {
313 p++;
314 // Look for free-form continuation.
315 while (*p == ' ' || *p == '\t') p++;
316 if (*p == '\r' || *p == '\n') {
317 pe = p;
318 while (*pe == '\r' || *pe == '\n' || *pe == ' ' || *pe == '\t') pe++;
319 if (*pe == '&')
320 return LANG_FORTRANFREE;
321 }
322 }
323 while (*p == '\r' || *p == '\n') p++;
324 }
325 return LANG_FORTRANFREE; // might as well be free-form
326 }
327
328 const char *disambiguate_h(SourceFile *sourcefile) {
329 char *p, *pe;
330 int length;
331
332 // If the directory contains a matching *.m file, likely Objective C.
333 length = strlen(sourcefile->filename);
334 if (strcmp(sourcefile->ext, "h") == 0) {
335 char path[length];
336 strncpy(path, sourcefile->filename, length);
337 path[length] = '\0';
338 *(path + length - 1) = 'm';
339 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
340 if (filenames) {
341 int i;
342 for (i = 0; filenames[i] != NULL; i++)
343 if (strcmp(path, filenames[i]) == 0)
344 return LANG_OBJECTIVE_C;
345 }
346 }
347
348 // Attempt to detect based on file contents.
349 char line[81], buf[81];
350 p = ohcount_sourcefile_get_contents(sourcefile);
351 pe = p;
352 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
353 while (pe < eof) {
354 // Get a line at a time.
355 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
356 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
357 strncpy(line, p, length);
358 line[length] = '\0';
359 char *eol = line + strlen(line);
360 char *line_end = pe;
361
362 // Look for C++ headers.
363 if (*line == '#') {
364 p = line + 1;
365 while (*p == ' ' || *p == '\t') p++;
366 if (strncmp(p, "include", 7) == 0 &&
367 (*(p + 7) == ' ' || *(p + 7) == '\t')) {
368 // /^#\s*include\s+[<"][^>"]+[>"]/
369 p += 8;
370 while (*p == ' ' || *p == '\t') p++;
371 if (*p == '<' || *p == '"') {
372 // Is the header file a C++ header file?
373 p++;
374 pe = p;
375 while (pe < eol && *pe != '>' && *pe != '"') pe++;
376 length = pe - p;
377 strncpy(buf, p, length);
378 buf[length] = '\0';
379 if (ohcount_hash_is_cppheader(buf, length))
380 return LANG_CPP;
381 // Is the extension for the header file a C++ file?
382 p = pe;
383 while (p > line && *(p - 1) != '.') p--;
384 length = pe - p;
385 strncpy(buf, p, length);
386 buf[length] = '\0';
387 struct ExtensionMap *re = ohcount_hash_language_from_ext(buf, length);
388 if (re && strcmp(re->value, LANG_CPP) == 0)
389 return LANG_CPP;
390 }
391 }
392 }
393
394 // Look for C++ keywords.
395 p = line;
396 while (p < eol) {
397 if (islower(*p) && p != line && !isalnum(*(p - 1)) && *(p - 1) != '_') {
398 pe = p;
399 while (islower(*pe)) pe++;
400 if (!isalnum(*pe) && *pe != '_') {
401 length = pe - p;
402 strncpy(buf, p, length);
403 buf[length] = '\0';
404 if (strcmp(buf, "class") == 0 ||
405 strcmp(buf, "namespace") == 0 ||
406 strcmp(buf, "template") == 0 ||
407 strcmp(buf, "typename") == 0)
408 return LANG_CPP;
409 }
410 p = pe + 1;
411 } else p++;
412 }
413
414 // Next line.
415 pe = line_end;
416 while (*pe == '\r' || *pe == '\n') pe++;
417 p = pe;
418 }
419
420 // Nothing to suggest C++.
421 return LANG_C;
422 }
423
424 const char *disambiguate_in(SourceFile *sourcefile) {
425 char *p, *pe;
426 int length;
427 const char *language = NULL;
428
429 p = sourcefile->filepath;
430 pe = p + strlen(p) - 3;
431 if (strstr(p, ".") <= pe) {
432 // Only if the filename has an extension prior to the .in
433 length = pe - p;
434 char buf[length];
435 strncpy(buf, p, length);
436 buf[length] = '\0';
437 SourceFile *undecorated = ohcount_sourcefile_new(buf);
438 p = ohcount_sourcefile_get_contents(sourcefile);
439 // The filepath without the '.in' extension does not exist on disk. The
440 // sourcefile->diskpath field must be set incase the detector needs to run
441 // 'file -b' on the file.
442 ohcount_sourcefile_set_diskpath(undecorated, sourcefile->filepath);
443 ohcount_sourcefile_set_contents(undecorated, p);
444 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
445 ohcount_sourcefile_set_filenames(undecorated, filenames);
446 language = ohcount_sourcefile_get_language(undecorated);
447 ohcount_sourcefile_free(undecorated);
448 }
449 return language;
450 }
451
452 const char *disambiguate_inc(SourceFile *sourcefile) {
453 char *p = ohcount_sourcefile_get_contents(sourcefile);
454 char *eof = p + strlen(p);
455 while (p < eof) {
456 if (*p == '\0')
457 return BINARY;
458 else if (*p == '?' && strncmp(p + 1, "php", 3) == 0)
459 return LANG_PHP;
460 p++;
461 }
462 return NULL;
463 }
464
465 const char *disambiguate_m(SourceFile *sourcefile) {
466 char *p, *pe;
467 int length;
468
469 // Attempt to detect based on a weighted heuristic of file contents.
470 int matlab_score = 0;
471 int objective_c_score = 0;
472 int limbo_score = 0;
473 int octave_syntax_detected = 0;
474
475 int i, has_h_headers = 0, has_c_files = 0;
476 char **filenames = ohcount_sourcefile_get_filenames(sourcefile);
477 if (filenames) {
478 for (i = 0; filenames[i] != NULL; i++) {
479 p = filenames[i];
480 pe = p + strlen(p);
481 if (pe - p >= 4) {
482 if (*(pe - 4) == '.' && *(pe - 3) == 'c' &&
483 ((*(pe - 2) == 'p' && *(pe - 1) == 'p') ||
484 (*(pe - 2) == '+' && *(pe - 1) == '+') ||
485 (*(pe - 2) == 'x' && *(pe - 1) == 'x'))) {
486 has_c_files = 1;
487 break; // short circuit
488 }
489 } else if (pe - p >= 3) {
490 if (*(pe - 3) == '.' && *(pe - 2) == 'c' && *(pe - 1) == 'c') {
491 has_c_files = 1;
492 break; // short circuit
493 }
494 } else if (pe - p >= 2) {
495 if (*(pe - 2) == '.') {
496 if (*(pe - 1) == 'h')
497 has_h_headers = 1;
498 else if (*(pe - 1) == 'c' || *(pe - 1) == 'C') {
499 has_c_files = 1;
500 break; // short circuit
501 }
502 }
503 }
504 }
505 }
506 if (has_h_headers && !has_c_files)
507 objective_c_score += 5;
508
509 char line[81], buf[81];
510 p = ohcount_sourcefile_get_contents(sourcefile);
511 pe = p;
512 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
513 while (pe < eof) {
514 // Get a line at a time.
515 while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
516 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
517 strncpy(line, p, length);
518 line[length] = '\0';
519 char *eol = line + strlen(line);
520 char *line_end = pe;
521
522 // Look for tell-tale lines.
523 p = line;
524 while (*p == ' ' || *p == '\t') p++;
525 if (*p == '%') { // Matlab comment
526 matlab_score++;
527 } else if (*p == '#' && strncmp(p, "#import", 7) == 0) { // Objective C
528 objective_c_score++;
529 } else if (*p == '#') { // Limbo or Octave comment
530 while (*p == '#') p++;
531 if (*p == ' ' || *p == '\t') {
532 limbo_score++;
533 matlab_score++;
534 octave_syntax_detected = 1;
535 }
536 } else if (*p == '/' && *(p + 1) == '/' || *(p + 1) == '*') {
537 objective_c_score++; // Objective C comment
538 } else if (*p == '+' || *p == '-') { // Objective C method signature
539 objective_c_score++;
540 } else if (*p == '@' || *p == '#') { // Objective C method signature
541 if (strncmp(p, "@implementation", 15) == 0 ||
542 strncmp(p, "@interface", 10) == 0)
543 objective_c_score++;
544 } else if (strncmp(p, "function", 8) == 0) { // Matlab or Octave function
545 p += 8;
546 while (*p == ' ' || *p == '\t') p++;
547 if (*p == '(')
548 matlab_score++;
549 } else if (strncmp(p, "include", 7) == 0) { // Limbo include
550 // /^include[ \t]+"[^"]+\.m";/
551 p += 7;
552 if (*p == ' ' || *p == '\t') {
553 while (*p == ' ' || *p == '\t') p++;
554 if (*p == '"') {
555 while (*p != '"' && p < eol) p++;
556 if (*p == '"' && *(p - 2) == '.' && *(p - 1) == 'm')
557 limbo_score++;
558 }
559 }
560 }
561
562 // Look for Octave keywords.
563 p = line;
564 while (p < eol) {
565 if (islower(*p) && p != line && !isalnum(*(p - 1))) {
566 pe = p;
567 while (islower(*pe) || *pe == '_') pe++;
568 if (!isalnum(*pe)) {
569 length = pe - p;
570 strncpy(buf, p, length);
571 buf[length] = '\0';
572 if (strcmp(buf, "end_try_catch") == 0 ||
573 strcmp(buf, "end_unwind_protect") == 0 ||
574 strcmp(buf, "endfunction") == 0 ||
575 strcmp(buf, "endwhile") == 0)
576 octave_syntax_detected = 1;
577 }
578 p = pe + 1;
579 } else p++;
580 }
581
582 // Look for Limbo declarations
583 p = line;
584 while (p < eol) {
585 if (*p == ':' && (*(p + 1) == ' ' || *(p + 1) == '\t')) {
586 // /:[ \t]+(module|adt|fn ?\(|con[ \t])/
587 p += 2;
588 if (strncmp(p, "module", 6) == 0 && !isalnum(*(p + 6)) ||
589 strncmp(p, "adt", 3) == 0 && !isalnum(*(p + 3)) ||
590 strncmp(p, "fn", 2) == 0 &&
591 (*(p + 2) == ' ' && *(p + 3) == '(' || *(p + 2) == '(') ||
592 strncmp(p, "con", 3) == 0 &&
593 (*(p + 3) == ' ' || *(p + 3) == '\t'))
594 limbo_score++;
595 } else p++;
596 }
597
598 // Next line.
599 pe = line_end;
600 while (*pe == '\r' || *pe == '\n') pe++;
601 p = pe;
602 }
603
604 if (limbo_score > objective_c_score && limbo_score > matlab_score)
605 return LANG_LIMBO;
606 else if (objective_c_score > matlab_score)
607 return LANG_OBJECTIVE_C;
608 else
609 return octave_syntax_detected ? LANG_OCTAVE : LANG_MATLAB;
610 }
611
612 #define QMAKE_SOURCES_SPACE "SOURCES +="
613 #define QMAKE_SOURCES "SOURCES+="
614 #define QMAKE_CONFIG_SPACE "CONFIG +="
615 #define QMAKE_CONFIG "CONFIG+="
616
617 const char *disambiguate_pro(SourceFile *sourcefile) {
618 char *p = ohcount_sourcefile_get_contents(sourcefile);
619 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
620 for (; p < eof; p++) {
621 if (strncmp(p, QMAKE_SOURCES_SPACE, strlen(QMAKE_SOURCES_SPACE)) == 0 ||
622 strncmp(p, QMAKE_SOURCES, strlen(QMAKE_SOURCES)) == 0 ||
623 strncmp(p, QMAKE_CONFIG_SPACE, strlen(QMAKE_CONFIG_SPACE)) == 0 ||
624 strncmp(p, QMAKE_CONFIG, strlen(QMAKE_CONFIG)) == 0)
625 return LANG_MAKE; // really QMAKE
626 }
627 return LANG_IDL_PVWAVE;
628 }
629
630 const char *disambiguate_st(SourceFile *sourcefile) {
631 char *p, *pe;
632 int length;
633
634 // Attempt to detect based on file contents.
635 int found_assignment = 0, found_block_start = 0, found_block_end = 0;
636
637 char line[81];
638 p = ohcount_sourcefile_get_contents(sourcefile);
639 pe = p;
640 char *eof = p + ohcount_sourcefile_get_contents_size(sourcefile);
641 while (pe < eof) {
642 // Get a line at a time.
643 while (p < eof && *pe != '\r' && *pe != '\n') pe++;
644 length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
645 strncpy(line, p, length);
646 line[length] = '\0';
647 char *eol = line + strlen(line);
648 char *line_end = pe;
649
650 for (p = line; p < eol; p++) {
651 if (*p == ':') {
652 p++;
653 while (p < eol && (*p == ' ' || *p == '\t')) p++;
654 if (*p == '=')
655 found_assignment = 1;
656 else if (*p == '[')
657 found_block_start = 1;
658 } else if (*p == ']' && *(p + 1) == '.') found_block_end = 1;
659 if (found_assignment && found_block_start && found_block_end)
660 return LANG_SMALLTALK;
661 }
662
663 // Next line.
664 pe = line_end;
665 while (*pe == '\r' || *pe == '\n') pe++;
666 p = pe;
667 }
668
669 return NULL;
670 }
671
672 int ohcount_is_binary_filename(const char *filename) {
673 char *p = (char *)filename + strlen(filename);
674 while (p > filename && *(p - 1) != '.') p--;
675 if (p > filename) {
676 struct ExtensionMap *re;
677 int length = strlen(p);
678 re = ohcount_hash_language_from_ext(p, length);
679 if (re) return ISBINARY(re->value);
680 // Try the lower-case version of this extension.
681 char lowerext[length];
682 strncpy(lowerext, p, length);
683 lowerext[length] = '\0';
684 for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p);
685 re = ohcount_hash_language_from_ext(lowerext, length);
686 if (re) return ISBINARY(re->value);
687 }
688 return 0;
689 }
+0
-0
.pc/fix_null_dereference_2.patch/test/detect_files/empty.in less more
(Empty file)
+0
-129
.pc/fix_null_dereference_2.patch/test/unit/detector_test.h less more
0 // detector_test.h written by Mitchell Foral. mitchell<att>caladbolg.net.
1 // See COPYING for license information.
2
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "../../src/detector.h"
8 #include "../../src/languages.h"
9 #include "../../src/sourcefile.h"
10
11 #define ASSERT_DETECT(x, y) { \
12 SourceFile *sf = ohcount_sourcefile_new("../detect_files/" y); \
13 const char *lang = ohcount_detect_language(sf); \
14 assert(lang); \
15 assert(strcmp(x, lang) == 0); \
16 ohcount_sourcefile_free(sf); \
17 }
18 #define ASSERT_NODETECT(x) { \
19 SourceFile *sf = ohcount_sourcefile_new("../detect_files/" x); \
20 assert(ohcount_detect_language(sf) == NULL); \
21 ohcount_sourcefile_free(sf); \
22 }
23
24 void test_detector_smalltalk() {
25 ASSERT_DETECT(LANG_SMALLTALK, "example.st");
26 ASSERT_NODETECT("english.st");
27 }
28
29 void test_detector_disambiguate_m() {
30 ASSERT_DETECT(LANG_OBJECTIVE_C, "t1.m");
31 ASSERT_DETECT(LANG_OBJECTIVE_C, "t2.m");
32 ASSERT_DETECT(LANG_OBJECTIVE_C, "TCPSocket.m");
33 ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.m");
34 ASSERT_DETECT(LANG_MATLAB, "foo_matlab.m");
35 ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m");
36 }
37
38 void test_detector_disambiguate_pro() {
39 ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
40 ASSERT_DETECT(LANG_MAKE, "qmake.pro");
41 }
42
43 void test_detector_fortran_fixedfree() {
44 ASSERT_DETECT(LANG_FORTRANFIXED, "fortranfixed.f");
45 ASSERT_DETECT(LANG_FORTRANFREE, "fortranfree.f");
46 }
47
48 void test_detector_detect_polyglot() {
49 ASSERT_DETECT(LANG_C, "foo.c");
50 ASSERT_DETECT(LANG_C, "uses_no_cpp.h");
51 ASSERT_DETECT(LANG_CPP, "uses_cpp_headers.h");
52 ASSERT_DETECT(LANG_CPP, "uses_cpp_stdlib_headers.h");
53 ASSERT_DETECT(LANG_CPP, "uses_cpp_keywords.h");
54 ASSERT_DETECT(LANG_RUBY, "foo.rb");
55 ASSERT_DETECT(LANG_MAKE, "foo.mk");
56 ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.h");
57 ASSERT_DETECT(LANG_PHP, "upper_case_php");
58 ASSERT_DETECT(LANG_SMALLTALK, "example.st");
59 ASSERT_DETECT(LANG_VALA, "foo.vala");
60 ASSERT_DETECT(LANG_TEX, "foo.tex");
61 ASSERT_DETECT(LANG_XSLT, "example.xsl");
62 ASSERT_DETECT(LANG_LISP, "core.lisp");
63 ASSERT_DETECT(LANG_DMD, "foo.d");
64 ASSERT_DETECT(LANG_VIM, "foo.vim");
65 ASSERT_DETECT(LANG_EBUILD, "foo.ebuild");
66 ASSERT_DETECT(LANG_EBUILD, "foo.eclass");
67 ASSERT_DETECT(LANG_EXHERES, "foo.exheres-0");
68 ASSERT_DETECT(LANG_EXHERES, "foo.exlib");
69 ASSERT_DETECT(LANG_EIFFEL, "eiffel.e");
70 ASSERT_DETECT(LANG_OCAML, "ocaml.ml");
71 ASSERT_DETECT(LANG_STRATEGO, "stratego.str");
72 ASSERT_DETECT(LANG_R, "foo.R");
73 ASSERT_DETECT(LANG_GLSL, "foo.glsl");
74 ASSERT_DETECT(LANG_GLSL, "foo_glsl.vert");
75 ASSERT_DETECT(LANG_GLSL, "foo_glsl.frag");
76 ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
77 ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80");
78 ASSERT_DETECT(LANG_PHP, "php.inc");
79 ASSERT_DETECT(LANG_FSHARP, "fs1.fs");
80 }
81
82 void test_detector_upper_case_extensions() {
83 ASSERT_DETECT(LANG_CPP, "foo_upper_case.C");
84 ASSERT_DETECT(LANG_RUBY, "foo_upper_case.RB");
85 }
86
87 void test_detector_no_extensions() {
88 ASSERT_DETECT(LANG_PYTHON, "py_script");
89 ASSERT_DETECT(LANG_RUBY, "ruby_script");
90 ASSERT_DETECT(LANG_SHELL, "bourne_again_script");
91 ASSERT_DETECT(LANG_SHELL, "bash_script");
92 ASSERT_DETECT(LANG_PERL, "perl_w");
93 ASSERT_DETECT(LANG_DMD, "d_script");
94 ASSERT_DETECT(LANG_TCL, "tcl_script");
95 ASSERT_DETECT(LANG_PYTHON, "python.data");
96 ASSERT_DETECT(LANG_PYTHON, "python2.data");
97 }
98
99 void test_detector_csharp_or_clearsilver() {
100 ASSERT_DETECT(LANG_CSHARP, "cs1.cs");
101 ASSERT_DETECT(LANG_CLEARSILVER_TEMPLATE, "clearsilver_template1.cs");
102 }
103
104 void test_detector_basic() {
105 ASSERT_DETECT(LANG_VISUALBASIC, "visual_basic.bas");
106 ASSERT_DETECT(LANG_CLASSIC_BASIC, "classic_basic.b");
107 system("mv ../detect_files/frx1.frx ../detect_files/frx1.frx2");
108 ASSERT_DETECT(LANG_STRUCTURED_BASIC, "visual_basic.bas");
109 ASSERT_DETECT(LANG_STRUCTURED_BASIC, "structured_basic.b");
110 system("mv ../detect_files/frx1.frx2 ../detect_files/frx1.frx");
111 }
112
113 void test_detector_xml_with_custom_extension() {
114 ASSERT_DETECT(LANG_XML, "xml.custom_ext");
115 }
116
117 void all_detector_tests() {
118 test_detector_smalltalk();
119 test_detector_disambiguate_m();
120 test_detector_disambiguate_pro();
121 test_detector_fortran_fixedfree();
122 test_detector_detect_polyglot();
123 test_detector_upper_case_extensions();
124 test_detector_no_extensions();
125 test_detector_csharp_or_clearsilver();
126 test_detector_basic();
127 test_detector_xml_with_custom_extension();
128 }
+0
-162
.pc/rbconfig.patch/build less more
0 #!/usr/bin/env bash
1 # Build script for Ohcount.
2 # Written by Mitchell Foral. mitchell<att>caladbolg.net.
3
4 # Options
5 # Change these for your system configuration.
6 if [ `uname` != "Darwin" ]
7 then
8 # Linux
9 INC_DIR=
10 LIB_DIR=
11
12 if [ `uname` == "FreeBSD" ]
13 then
14 INC_DIR=/usr/local/include
15 LIB_DIR=/usr/local/lib
16 fi
17
18 # You shouldn't have to change the following.
19 CFLAGS=-O3
20 CFLAGS="$CFLAGS -DTMP_FILES_ARE_DT_UNKNOWN" # workaround bug on centos/SF servers
21 WARN="-Wall -Wno-pointer-to-int-cast -Wno-parentheses"
22 SHARED=-shared
23 SHARED_NAME=libohcount.so
24 RB_SHARED=-shared
25 RB_SHARED_NAME=ohcount.so
26 else
27 # Mac OSX
28 INC_DIR=/opt/local/include
29 LIB_DIR=/opt/local/lib
30 # You shouldn't have to change the following.
31 CFLAGS="-fno-common -g"
32 WARN="-Wall -Wno-parentheses"
33 SHARED="-dynamiclib -L$LIB_DIR -lpcre"
34 SHARED_NAME=libohcount.dylib
35 RB_SHARED="-dynamic -bundle -lruby"
36 RB_SHARED_NAME=ohcount.bundle
37 fi
38
39 # C compiler and flags
40 cc="gcc -fPIC -g $CFLAGS $WARN -I$INC_DIR -L$LIB_DIR"
41
42 # Ohcount source files
43 files="src/sourcefile.c \
44 src/detector.c \
45 src/licenses.c \
46 src/parser.o \
47 src/loc.c \
48 src/log.c \
49 src/diff.c \
50 src/parsed_language.c \
51 src/hash/language_hash.c"
52
53 # If any src/hash/*.gperf file is newer than the header files (which were
54 # presumably generated together), regenerate the headers.
55 build_hash_headers()
56 {
57 if [[ -z `ls src/hash/ | grep "_hash.h$"` ||
58 ! -z `find src/hash/*.gperf -newer src/hash/parser_hash.h` ]]
59 then
60 echo "Generating hash headers"
61 sh -c "cd src/hash/ && ./generate_headers" || exit 1
62 fi
63 }
64
65 # If src/parser.o does not exist, or if there are Ragel parsers or parser
66 # header files newer than the existing parser.o, recompile parser.o.
67 build_parser_o()
68 {
69 if [[ ! -f src/parser.o ||
70 ! -z `find src/parsers/*.{h,rl} -newer src/parser.o` ]]
71 then
72 bash -c "cd src/parsers/ && bash ./compile" || exit 1
73 echo "Building src/parser.c (will take a while)"
74 bash -c "$cc -c src/parser.c -o src/parser.o" || exit 1
75 fi
76 }
77
78 build_shared()
79 {
80 build_hash_headers
81 build_parser_o
82 if [[ ! -f src/$SHARED_NAME ||
83 ! -z `find src/*.{h,c} -newer src/$SHARED_NAME` ]]
84 then
85 echo "Building shared library"
86 sh -c "$cc $SHARED $files -o src/$SHARED_NAME" || exit 1
87 fi
88 }
89
90 build_ohcount()
91 {
92 build_hash_headers
93 build_parser_o
94 echo "Building Ohcount"
95 mkdir -p bin/
96 sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre" || exit 1
97 }
98
99 build_test_suite()
100 {
101 build_hash_headers
102 build_parser_o
103 echo "Building test suite"
104 sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre" \
105 || exit 1
106 }
107
108 run_test_suite()
109 {
110 echo "Running test suite"
111 echo "disabled test suite, does not work"
112 }
113
114 build_ruby_bindings()
115 {
116 arch=`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`
117 echo "Generating Ruby bindings for $arch"
118 sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1
119 mkdir -p ruby/$arch
120 sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \
121 -I`ruby -rmkmf -e 'print Config::expand(CONFIG["archdir"])'` \
122 -lpcre" || exit 1
123 sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1
124 }
125
126 if [ $# -eq 0 ] || [ $1 == "all" ]
127 then
128 build_ohcount
129 build_test_suite
130 run_test_suite
131 echo $success
132 elif [ $1 == "shared" ]
133 then
134 build_shared
135 echo "Build successful; $SHARED_NAME is in src/"
136 elif [ $1 == "ohcount" ]
137 then
138 build_ohcount
139 echo "Build successful; ohcount is in bin/"
140 elif [ $1 == "tests" ]
141 then
142 build_test_suite
143 run_test_suite
144 elif [ $1 == "ruby" ]
145 then
146 build_ruby_bindings
147 echo "Build successful; $RB_SHARED_NAME is in ruby/$arch"
148 elif [ $1 == "clean" ]
149 then
150 rm -f bin/ohcount
151 rm -f test/unit/run_tests
152 rm -f src/parser.o
153 rm -f src/parsers/*.h
154 rm -f src/hash/*.h
155 rm -f src/hash/*.c
156 rm -f src/$SHARED_NAME
157 rm -f ruby/$RB_SHARED_NAME
158 rm -rf ruby/`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`/*
159 else
160 echo "Usage: build [all|ohcount|shared|tests|ruby|clean]"
161 fi
+0
-181
.pc/txx_support.patch/src/hash/extensions.gperf less more
0 %{
1 #include "../languages.h"
2
3 #define BINARY "\1"
4 #define DISAMBIGUATE(x) ("\2" x)
5 %}
6 struct ExtensionMap { const char *key; const char *value; };
7 %%
8 C, LANG_CPP
9 H, LANG_CPP
10 ada, LANG_ADA
11 adb, LANG_ADA
12 ads, LANG_ADA
13 aiff, BINARY
14 as, LANG_ACTIONSCRIPT
15 ascx, DISAMBIGUATE("aspx")
16 asm, LANG_ASSEMBLER
17 aspx, DISAMBIGUATE("aspx")
18 au, BINARY
19 avi, BINARY
20 awk, LANG_AWK
21 b, DISAMBIGUATE("b")
22 bas, DISAMBIGUATE("basic")
23 bat, LANG_BAT
24 bi, DISAMBIGUATE("basic")
25 bmp, BINARY
26 bmx, LANG_BLITZMAX
27 boo, LANG_BOO
28 c, LANG_C
29 c++, LANG_CPP
30 cache, BINARY
31 cc, LANG_CPP
32 cmake, LANG_CMAKE
33 com, LANG_DCL
34 cpp, LANG_CPP
35 cs, DISAMBIGUATE("cs")
36 csproj, LANG_XML
37 css, LANG_CSS
38 ctp, LANG_PHP
39 cxx, LANG_CPP
40 d, LANG_DMD
41 dat, BINARY
42 di, LANG_DMD
43 doc, BINARY
44 dylan, LANG_DYLAN
45 e, LANG_EIFFEL
46 ebuild, LANG_EBUILD
47 eclass, LANG_EBUILD
48 el, LANG_EMACSLISP
49 erl, LANG_ERLANG
50 exheres-0, LANG_EXHERES
51 exlib, LANG_EXHERES
52 f, DISAMBIGUATE("fortran")
53 f03, DISAMBIGUATE("fortran")
54 f77, DISAMBIGUATE("fortran")
55 f90, DISAMBIGUATE("fortran")
56 f95, DISAMBIGUATE("fortran")
57 factor, LANG_FACTOR
58 frag, LANG_GLSL
59 frm, LANG_VISUALBASIC
60 frx, LANG_VISUALBASIC
61 fs, LANG_FSHARP
62 ftn, DISAMBIGUATE("fortran")
63 gif, BINARY
64 glsl, LANG_GLSL
65 groovy, LANG_GROOVY
66 gz, BINARY
67 h, DISAMBIGUATE("h")
68 h++, LANG_CPP
69 haml, LANG_HAML
70 hh, LANG_CPP
71 hpp, LANG_CPP
72 hrl, LANG_ERLANG
73 hs, LANG_HASKELL
74 htm, LANG_HTML
75 html, LANG_HTML
76 hx, LANG_HAXE
77 hxx, LANG_CPP
78 icns, BINARY
79 in, DISAMBIGUATE("in")
80 inc, DISAMBIGUATE("inc")
81 j, LANG_OBJECTIVE_J
82 jar, BINARY
83 java, LANG_JAVA
84 jpeg, BINARY
85 jpg, BINARY
86 js, LANG_JAVASCRIPT
87 jsp, LANG_JSP
88 kdebuild-1, LANG_EBUILD
89 latex, LANG_TEX
90 lisp, LANG_LISP
91 lsp, LANG_LISP
92 ltx, LANG_TEX
93 lua, LANG_LUA
94 m, DISAMBIGUATE("m")
95 m4a, BINARY
96 mf, LANG_METAFONT
97 mk, LANG_MAKE
98 ml, LANG_OCAML
99 ml4, LANG_OCAML
100 mli, LANG_OCAML
101 mm, LANG_OBJECTIVE_C
102 mov, BINARY
103 mp, LANG_METAPOST_WITH_TEX
104 mp3, BINARY
105 mpg, BINARY
106 mxml, LANG_MXML
107 nix, LANG_NIX
108 nse, LANG_LUA
109 ogg, BINARY
110 p6, LANG_PERL
111 pas, LANG_PASCAL
112 perl, LANG_PERL
113 pdf, BINARY
114 ph, LANG_PERL
115 php, LANG_PHP
116 php3, LANG_PHP
117 php4, LANG_PHP
118 php5, LANG_PHP
119 pike, LANG_PIKE
120 pl, LANG_PERL
121 pm, LANG_PERL
122 pmc, LANG_C
123 pmod, LANG_PIKE
124 png, BINARY
125 pnt, BINARY
126 pod, LANG_PERL
127 pp, LANG_PASCAL
128 ppt, BINARY
129 pro, DISAMBIGUATE("pro")
130 py, LANG_PYTHON
131 qt, BINARY
132 r, LANG_R
133 ra, BINARY
134 rb, LANG_RUBY
135 rex, LANG_REXX
136 rexx, LANG_REXX
137 rhtml, LANG_RHTML
138 s, LANG_ASSEMBLER
139 sc, LANG_SCHEME
140 scala, LANG_SCALA
141 sce, LANG_SCILAB
142 sci, LANG_SCILAB
143 scm, LANG_SCHEME
144 sh, LANG_SHELL
145 sls, LANG_SCHEME
146 sps, LANG_SCHEME
147 sql, LANG_SQL
148 ss, LANG_SCHEME
149 st, DISAMBIGUATE("st")
150 str, LANG_STRATEGO
151 svg, BINARY
152 svgz, BINARY
153 svn, BINARY
154 swf, BINARY
155 t, LANG_PERL
156 tar, BINARY
157 tcl, LANG_TCL
158 tex, LANG_TEX
159 tgz, BINARY
160 tif, BINARY
161 tiff, BINARY
162 tpl, LANG_HTML
163 vala, LANG_VALA
164 vb, LANG_VISUALBASIC
165 vba, LANG_VISUALBASIC
166 vbs, LANG_VISUALBASIC
167 vert, LANG_GLSL
168 vhd, LANG_VHDL
169 vhdl, LANG_VHDL
170 vim, LANG_VIM
171 wav, BINARY
172 xaml, LANG_XAML
173 xls, BINARY
174 xlw, BINARY
175 xml, LANG_XML
176 xs, LANG_C
177 xsd, LANG_XMLSCHEMA
178 xsl, LANG_XSLT
179 z80, LANG_ASSEMBLER
180 zip, BINARY
+0
-90
README less more
0 == Ohcount
1
2 NOTE: THE PRIMARY DOCUMENTATION FOR OHCOUNT IS EXTRACTED FROM SOURCE CODE
3 BY DOXYGEN. FOR THE MOST UP-TO-DATE DOCS, PLEASE SEE BELOW FOR INFO
4 ON BUILDING AND REFERING TO THE DOXYGEN DOCS.
5
6 Ohloh/SourceForge's source code line counter.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License Version 2 as
10 published by the Free Software Foundation.
11
12 Ohcount is specifically licensed under GPL v2.0, and no later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 == Overview
23
24 Ohcount is a library for counting lines of source code.
25 It was originally developed at Ohloh, and is used to generate
26 the reports at www.ohloh.net.
27
28 Ohcount supports multiple languages within a single file: for example,
29 a complex HTML document might include regions of both CSS and JavaScript.
30
31 Ohcount has two main components: a detector which determines the primary
32 language family used by a particular source file, and a parser which
33 provides a line-by-line breakdown of the contents of a source file.
34
35 Ohcount includes a command line tool that allows you to count individual
36 files or whole directory trees. It also allows you to find source code
37 files by language family, or to create a detailed annotation of an
38 individual source file.
39
40 Ohcount includes a Ruby binding which allows you to directly access its
41 language detection features from a Ruby application.
42
43 == System Requirements
44
45 Ohcount is supported on Mac OS X 10.4 and 10.5 and Ubuntu 8.04 LTS. Other Linux
46 environments should also work, but your mileage may vary.
47
48 Ohcount does not support Windows.
49
50 Ohcount targets Ruby 1.8.6. The build script requires a bash shell. You
51 also need a C compiler to build the native extensions.
52
53 == Source Code ==
54
55 Ohcount source code is available as a Git repository:
56
57 git clone git://github.com/andyverprauskus/ohcount.git
58
59 == Doc files ==
60
61 To build the more extensive Doxygen docs, do
62 > cd doc
63 > Doxygen Doxyfile
64
65 After building the docs, view them with a browser by opening doc/html/index.html.
66 On a mac, you can install Doxygen with "sudo port install Doxygen".
67 On Debian/Ubuntu, install with "sudo apt-get instal doxygen".
68
69 == Building Ohcount ==
70
71 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:
72
73 > bash build
74 or > ./build
75
76 == Using Ohcount ==
77
78 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:
79 "ohcount" to count the current directory and source code in any child directories
80
81 == For additional docs, including how to add a new language, see the Doxygen docs ==
82
83 Particularly, for instructions on adding a new language, follow the instructions at doc/html/detector_doc.html
84 Read http://labs.ohloh.net/ohcount/wiki/HowToSubmitPatches for information about having your patch accepted.
85
86
87 DEPENDENCIES
88 ============
89 SWIG, pcre, ragel, bash
0 Ohcount
1 =======
2
3 Ohloh's source code line counter.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License Version 2 as
7 published by the Free Software Foundation.
8
9 License
10 -------
11
12 Ohcount is specifically licensed under GPL v2.0, and no later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 Overview
23 --------
24
25 Ohcount is a library for counting lines of source code.
26 It was originally developed at Ohloh, and is used to generate
27 the reports at www.openhub.net.
28
29 Ohcount supports multiple languages within a single file: for example,
30 a complex HTML document might include regions of both CSS and JavaScript.
31
32 Ohcount has two main components: a detector which determines the primary
33 language family used by a particular source file, and a parser which
34 provides a line-by-line breakdown of the contents of a source file.
35
36 Ohcount includes a command line tool that allows you to count individual
37 files or whole directory trees. It also allows you to find source code
38 files by language family, or to create a detailed annotation of an
39 individual source file.
40
41 Ohcount includes a Ruby binding which allows you to directly access its
42 language detection features from a Ruby application.
43
44 System Requirements
45 -------------------
46
47 Ohcount is supported on Ubuntu 14.04 LTS. Other Linux
48 environments should also work, but your mileage may vary.
49
50 Ohcount does not support Windows.
51
52 Ohcount targets Ruby 1.9.3. The build script requires a bash shell. You
53 also need a C compiler to build the native extensions.
54
55 Source Code
56 -----------
57
58 Ohcount source code is available as a Git repository:
59
60 git clone git://github.com/blackducksw/ohcount.git
61
62 Building Ohcount
63 ----------------
64
65 You will need ragel 6.8 or higher, bash, gperf, libpcre3-dev, libmagic-dev, gcc (version 4.8.2 or greater)
66 and SWIG (2.0.11). Once you have them, go to the top directory of ohcount and run
67
68 ```
69 ./build
70 ```
71
72 Using Ohcount
73 -------------
74
75 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:
76
77 ```
78 bin/ohcount
79 ```
80
81 Ohcount support several options. Run `ohcount --help` for more information.
82
83 Building Ruby and Python Libraries
84 ----------------------------------
85
86 To build the ruby wrapper:
87
88 ```
89 ./build ruby
90 ```
91
92 To build the python wrapper, run
93
94 ```
95 python python/setup.py build
96 python python/setup.py install
97 ```
98
99 The python wrapper is currently unsupported.
1717
1818 # You shouldn't have to change the following.
1919 CFLAGS=-O3
20 CFLAGS="$CFLAGS -DTMP_FILES_ARE_DT_UNKNOWN" # workaround bug on centos/SF servers
2120 WARN="-Wall -Wno-pointer-to-int-cast -Wno-parentheses"
2221 SHARED=-shared
2322 SHARED_NAME=libohcount.so
3837
3938 # C compiler and flags
4039 cc="gcc -fPIC -g $CFLAGS $WARN -I$INC_DIR -L$LIB_DIR"
40
41 # ARCHITECTURE
42 arch=`ruby/print_arch`
4143
4244 # Ohcount source files
4345 files="src/sourcefile.c \
9395 build_parser_o
9496 echo "Building Ohcount"
9597 mkdir -p bin/
96 sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre" || exit 1
98 sh -c "$cc src/ohcount.c $files -o bin/ohcount -lpcre -lmagic" || exit 1
9799 }
98100
99101 build_test_suite()
101103 build_hash_headers
102104 build_parser_o
103105 echo "Building test suite"
104 sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre" \
106 sh -c "$cc test/unit/all_tests.c $files -o test/unit/run_tests -lpcre -lmagic" \
105107 || exit 1
106108 }
107109
108110 run_test_suite()
109111 {
110112 echo "Running test suite"
111 echo "disabled test suite, does not work"
113 sh -c "cd test/unit/ && ./run_tests"
112114 }
115
116 RUBY_HEADER_DIR=`ruby -rmkmf -e 'print RbConfig::expand(CONFIG["rubyhdrdir"])'`
117 rbconfig_arch=`ruby -rmkmf -e 'print RbConfig::expand(CONFIG["arch"])'`
118 RUBY_CONFIG_DIR="$RUBY_HEADER_DIR/$rbconfig_arch"
113119
114120 build_ruby_bindings()
115121 {
116 arch=`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'`
117122 echo "Generating Ruby bindings for $arch"
118123 sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1
119124 mkdir -p ruby/$arch
120125 sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \
121 -I`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["archdir"])'` \
122 -lpcre" || exit 1
126 -I$RUBY_HEADER_DIR -I$RUBY_CONFIG_DIR \
127 -lpcre -lmagic" || exit 1
123128 sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1
124129 }
125130
128133 build_ohcount
129134 build_test_suite
130135 run_test_suite
136 build_ruby_bindings
131137 echo $success
132138 elif [ $1 == "shared" ]
133139 then
155161 rm -f src/hash/*.c
156162 rm -f src/$SHARED_NAME
157163 rm -f ruby/$RB_SHARED_NAME
158 rm -rf ruby/`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'`/*
164 rm -rf ruby/$arch/*
165 rm -f ruby/ohcount_wrap.c
159166 else
160167 echo "Usage: build [all|ohcount|shared|tests|ruby|clean]"
161168 fi
+0
-120
debian/changelog less more
0 ohcount (3.0.0-8.4) unstable; urgency=medium
1
2 * Standards-Version updated to 4.1.3
3 * Update of Vcs-*
4 * Update of the homepage
5 * Add a watch file
6
7 -- Sylvestre Ledru <sylvestre@debian.org> Sun, 14 Jan 2018 19:03:49 +0100
8
9 ohcount (3.0.0-8.3) unstable; urgency=medium
10
11 * Non-maintainer upload.
12 * Remove ruby files from ohcount-doc, which only get installed
13 when building for Arch: all. (Closes: #818239)
14
15 -- Christian Hofstaedtler <zeha@debian.org> Thu, 22 Dec 2016 06:54:28 +0000
16
17 ohcount (3.0.0-8.2) unstable; urgency=medium
18
19 * Non-maintainer upload.
20 * Source-ful, binary-less upload to get rid of /ruby directory.
21 Probably somehow my fault? (Closes: #818239)
22
23 -- Christian Hofstaedtler <zeha@debian.org> Sun, 17 Jul 2016 19:58:32 +0000
24
25 ohcount (3.0.0-8.1) unstable; urgency=medium
26
27 * Non-maintainer upload.
28 * Fix build system being broken by removal of deprecated "Config"
29 object in Ruby 2.2. (Closes: #805674)
30
31 -- Christian Hofstaedtler <zeha@debian.org> Tue, 01 Mar 2016 22:02:31 +0100
32
33 ohcount (3.0.0-8) unstable; urgency=low
34
35 * Remove the explicit dependency on ruby 1.8
36 Thanks to Jonas Genannt (Closes: #733724)
37 * Switch from cdbs to dh. Thanks to Jonas Genannt
38 * Standards-Version updated to 3.9.5
39
40 -- Sylvestre Ledru <sylvestre@debian.org> Thu, 16 Jan 2014 16:26:45 +0100
41
42 ohcount (3.0.0-7) unstable; urgency=low
43
44 * Standards-Version updated to 3.9.4
45 * libdifflcs-ruby dep renamed to ruby-diff-lcs (Closes: #707792)
46 * Remove Torsten from the uploaders (I have been DD for a while :)
47 * ACK NMU (thanks btw)
48
49 -- Sylvestre Ledru <sylvestre@debian.org> Sat, 11 May 2013 19:17:57 +0200
50
51 ohcount (3.0.0-6.1) unstable; urgency=low
52
53 * Non-maintainer upload.
54 * Add dependency on file (Closes: #677494).
55
56 -- Luk Claes <luk@debian.org> Wed, 04 Jul 2012 17:18:12 +0000
57
58 ohcount (3.0.0-6) unstable; urgency=low
59
60 * Update some issues with the documentation (Closes: #650685)
61
62 -- Sylvestre Ledru <sylvestre@debian.org> Sat, 10 Dec 2011 19:38:15 +0100
63
64 ohcount (3.0.0-5) unstable; urgency=low
65
66 * Oups. Plug back the patches
67 * Manpage of ohcount added
68
69 -- Sylvestre Ledru <sylvestre@debian.org> Fri, 30 Sep 2011 21:37:34 +0200
70
71 ohcount (3.0.0-4) unstable; urgency=low
72
73 * Support of the txx extension (considered as C++). Thanks to Sébastien Dinot
74 for the patch.
75 * Switch to dpkg-source 3.0 (quilt) format
76 * Standards-Version updated to version 3.9.2
77 * Fix debian-rules-uses-deprecated-makefile lintian warning
78
79 -- Sylvestre Ledru <sylvestre@debian.org> Mon, 26 Sep 2011 13:42:49 +0200
80
81 ohcount (3.0.0-3) unstable; urgency=low
82
83 * Standards-Version updated to version 3.9.1
84 * Fix a seg fault when checking lintian source code. Thanks to
85 Raphael Geissert for investigating for me. (Closes: #608837)
86 (LP: #605631)
87 * Fix lintian warning copyright-refers-to-deprecated-bsd-license-file
88
89 -- Sylvestre Ledru <sylvestre@debian.org> Sat, 15 Jan 2011 09:34:05 +0100
90
91 ohcount (3.0.0-2) unstable; urgency=low
92
93 * Missing dependency (Closes: #558491)
94
95 -- Sylvestre Ledru <sylvestre@debian.org> Sun, 29 Nov 2009 18:19:46 +0100
96
97 ohcount (3.0.0-1) unstable; urgency=low
98
99 * New upstream release
100 * New package ohcount-doc added
101 * Homepage updated
102 * Vcs-* added
103 * Many changes on the debian/rules due to a refactoring from upstream which
104 has been done (patches are now obsolete or upstream)
105 * Upstream has redeveloped ohcount with C (instead of ruby). (Closes: #542892)
106 * Update of the watch file
107 * Repack script updated (upstream has a .so)
108 * Standards-Version updated to version 3.8.3
109 * Change of my email address since I am now DD
110 * Standards-Version updated to 3.8.3
111 * DM-Upload-Allowed removed
112
113 -- Sylvestre Ledru <sylvestre@debian.org> Fri, 27 Nov 2009 11:22:21 +0100
114
115 ohcount (2.0.1-1) unstable; urgency=low
116
117 * Initial release (Closes: #523006)
118
119 -- Sylvestre Ledru <sylvestre.ledru@inria.fr> Tue, 07 Apr 2009 20:18:38 +0200
+0
-1
debian/compat less more
0 7
+0
-40
debian/control less more
0 Source: ohcount
1 Section: utils
2 Priority: optional
3 Maintainer: Sylvestre Ledru <sylvestre@debian.org>
4 Build-Depends: debhelper (>= 7), libpcre3-dev, gem2deb, rake,
5 ragel (>= 6.3), ruby-diff-lcs, doxygen, gperf, file
6 Standards-Version: 4.1.3
7 Homepage: https://github.com/blackducksoftware/ohcount
8 Vcs-Git: https://salsa.debian.org/debian/ohcount.git
9 Vcs-Browser: https://salsa.debian.org/debian/ohcount
10 XS-Ruby-Versions: all
11
12 Package: ohcount
13 XB-Ruby-Versions: ${ruby:Versions}
14 Architecture: any
15 Depends: ruby | ruby-interpreter, ${shlibs:Depends}, ${misc:Depends},
16 ruby-diff-lcs, file
17 Suggests: ohcount-doc
18 Description: Source code line counter
19 Ohcount supports over 70 popular programming languages.
20 Ohcount does more than just count lines of code. It can also detect
21 popular open source licenses such as GPL within a large directory of source
22 code. It can also detect code that targets a particular programming API,
23 such as Win32 or KDE.
24 Ohcount is the line counter which powers http://www.ohloh.net/
25 .
26
27 Package: ohcount-doc
28 Section: doc
29 Architecture: all
30 Depends: ${shlibs:Depends}, ${misc:Depends}
31 Description: Source code line counter - Documentation
32 Ohcount supports over 70 popular programming languages.
33 Ohcount does more than just count lines of code. It can also detect
34 popular open source licenses such as GPL within a large directory of source
35 code. It can also detect code that targets a particular programming API,
36 such as Win32 or KDE.
37 Ohcount is the line counter which powers http://www.ohloh.net/
38 .
39 This package contains the documentation.
+0
-132
debian/copyright less more
0 This package was debianized by Sylvestre Ledru <sylvestre.ledru@inria.fr> on
1 Tue, 07 Apr 2009 20:18:38 +0200.
2
3 It was downloaded from <http://labs.ohloh.net/ohcount/>
4
5 Upstream Author:
6
7 Ohloh <info@ohloh.net>
8
9 Copyright:
10
11 Copyright (C) 2007-2009 Ohloh
12
13 License:
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License along
26 with this program; if not, write to the Free Software Foundation, Inc.,
27 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28
29 The full text of the license can be found in
30 `/usr/share/common-licenses/GPL-2'.
31
32 The Debian packaging is (C) 2009, Sylvestre Ledru <sylvestre.ledru@inria.fr> and
33 is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
34
35 ohcount incorporates some piece of code in order to test during build time
36 its capabilities. These files are not included in the binary.
37
38
39 Files: test/expected_dir/haxe1.hx test/src_dir/haxe1.hx
40
41 Copyright:
42 Thomas Pfeiffer - kiroukou
43 Niel Drummond
44
45 License:
46 Copyright the original author or authors.
47 Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
48 you may not use this file except in compliance with the License.
49 You may obtain a copy of the License at
50 http://www.mozilla.org/MPL/MPL-1.1.html
51 Unless required by applicable law or agreed to in writing, software
52 distributed under the License is distributed on an "AS IS" BASIS,
53 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54 See the License for the specific language governing permissions and
55 limitations under the License.
56
57 Files: test/src_dir/pascal2.pp test/expected_dir/pascal2.pp
58
59 Copyright:
60 Simon Steele 1998-2000
61
62 License:
63 BSD
64 Redistribution and use in source and binary forms, with or without
65 modification, are permitted provided that the following conditions are
66 met:
67
68 * Redistributions of source code must retain the above copyright
69 notice, this list of conditions and the following disclaimer.
70 * Redistributions in binary form must reproduce the above copyright
71 notice, this list of conditions and the following disclaimer in the
72 documentation and/or other materials provided with the distribution.
73 * Neither the name of the <ORGANIZATION> nor the names of its
74 contributors may be used to endorse or promote products derived from
75 this software without specific prior written permission.
76
77 Files: test/src_dir/js1.js test/expected_dir/js1.js
78
79 Copyright:
80 2005-2008 Sam Stephenson
81
82 License:
83 MIT
84
85 Permission is hereby granted, free of charge, to any person obtaining a copy
86 of this software and associated documentation files (the "Software"), to deal
87 in the Software without restriction, including without limitation the rights
88 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
89 copies of the Software, and to permit persons to whom the Software is
90 furnished to do so, subject to the following conditions:
91
92 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
93 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
94 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
95 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
96 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
97 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
98 SOFTWARE.
99
100
101 Files: test/src_dir/foo.ebuild test/detect_files/foo.ebuild
102
103 License:
104 GPL-2
105
106 Files: test/src_dir/as1.as test/expected_dir/as1.as
107
108 Copyright:
109 Sean Chatman and Garrett Woodworth 2008
110
111 License:
112 MIT
113
114 Files: test/src_dir/perl_module.pm test/expected_dir/perl_module.pm
115
116 Copyright:
117 Audrey Tang 2003-2007
118
119 License:
120 This program is free software; you can redistribute it and/or modify it
121 under the same terms as Perl itself.
122
123 a) the GNU General Public License as published by the Free Software
124 Foundation; either version 1, or (at your option) any later
125 version, or
126
127 b) the "Artistic License" which comes with Perl.
128
129 On Debian GNU/Linux systems, the complete text of the GNU General
130 Public License can be found in `/usr/share/common-licenses/GPL' and
131 the Artistic Licence in `/usr/share/common-licenses/Artistic'.
+0
-9
debian/ohcount-doc.doc-base less more
0 Document: ohcount
1 Title: Debian ohcount Manual
2 Author: Ohloh
3 Abstract: ohcount manual
4 Section: Programming/Ruby
5
6 Format: HTML
7 Index: /usr/share/doc/ohcount-doc/index.html
8 Files: /usr/share/doc/ohcount-doc/*
+0
-1
debian/ohcount-doc.docs less more
0 README
+0
-67
debian/ohcount.1 less more
0 .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.39.4.
1 .TH OHCOUNT "1" "September 2011" "ohcount 3.0.0" "User Commands"
2 .SH NAME
3 ohcount \- manual page for ohcount 3.0.0
4 .SH SYNOPSIS
5 .B ohcount
6 [\fIoption\fR] [\fIpaths\fR...]
7 .SH DESCRIPTION
8 Ohloh source code line counter command line tool.
9 .IP
10 http://www.ohloh.net/
11 .SS "[option] can be one of the following:"
12 .HP
13 \fB\-a\fR, \fB\-\-annotate\fR
14 .HP
15 \fB\-d\fR, \fB\-\-detect\fR
16 .HP
17 \fB\-h\fR, \fB\-\-help\fR
18 .HP
19 \fB\-i\fR, \fB\-\-individual\fR
20 .HP
21 \fB\-l\fR, \fB\-\-license\fR
22 .HP
23 \fB\-re\fR
24 .HP
25 \fB\-s\fR, \fB\-\-summary\fR
26 .PP
27 \fB\-a\fR, \fB\-\-annotate\fR Show annotated source code
28 .IP
29 The contents of all source code files found within the given
30 paths will be emitted to stdout. Each line will be prefixed with
31 a tab\-delimited language name and semantic categorization (code,
32 comment, or blank).
33 .PP
34 \fB\-d\fR, \fB\-\-detect\fR Find source code files
35 .IP
36 Recursively find all source code files within the given paths.
37 For each source code file found, the file name will be emitted to
38 stdout prefixed with a tab\-delimited language name.
39 .PP
40 \fB\-h\fR, \fB\-\-help\fR Display this message
41 .PP
42 \fB\-i\fR, \fB\-\-individual\fR Count lines of code per file
43 .IP
44 Count lines in all source code files within the given paths, and
45 emit a report of the lines of code, comments, and blanks in each
46 language per file.
47 .PP
48 \fB\-l\fR, \fB\-\-license\fR
49 .IP
50 Displays detected licensing information contained in each source
51 code file.
52 .PP
53 \fB\-re\fR
54 .IP
55 Prints raw entity information to the screen (mainly for debugging).
56 .PP
57 \fB\-s\fR, \fB\-\-summary\fR Count lines of code (default)
58 .IP
59 Count lines in all source code files within the given paths, and
60 emit a report of the total number of lines of code, comments,
61 and blanks in each language. This is the default action.
62 .PP
63 [paths] can refer to any number of individual files or directories.
64 .IP
65 Directories will be probed recursively. If no path is given,
66 the current directory will be used.
+0
-2
debian/ohcount.manpages less more
0 debian/ohcount.1
1
+0
-1
debian/orig-tar.exclude less more
0 *.so
+0
-19
debian/orig-tar.sh less more
0 #!/bin/sh -e
1
2 # called by uscan with '--upstream-version' <version> <file>
3 DIR=ohcount-$2
4 TAR=../ohcount_$2.orig.tar.gz
5
6 # clean up the upstream tarball
7 tar zxf $3
8 # Remove vendor/ because it is including
9 tar -c -z -X debian/orig-tar.exclude -f $TAR $DIR/
10 rm -rf $DIR
11
12 # move to directory 'tarballs'
13 if [ -r .svn/deb-layout ]; then
14 . .svn/deb-layout
15 mv $TAR $origDir
16 echo "moved $TAR to $origDir"
17 fi
18
+0
-15
debian/patches/disabled_test_suite.patch less more
0 Description: disable test suite on build time, does not work
1 Author: Jonas Genannt <jonas.genannt@capi2name.de>
2 Forwarded: not-needed
3
4 --- a/build
5 +++ b/build
6 @@ -109,7 +109,7 @@ build_test_suite()
7 run_test_suite()
8 {
9 echo "Running test suite"
10 - sh -c "cd test/unit/ && ./run_tests"
11 + echo "disabled test suite, does not work"
12 }
13
14 build_ruby_bindings()
+0
-58
debian/patches/fix_null_dereference.patch less more
0 From a6783afcf61f18e9f1aef3e2655b30af7501c902 Mon Sep 17 00:00:00 2001
1 From: Robin Luckey <robin@ohloh.net>
2 Date: Thu, 1 Oct 2009 14:32:16 -0700
3 Subject: [PATCH] [FIX] Avoid null dereference in disambiguate_inc()
4
5 ---
6 src/detector.c | 18 ++++++++++--------
7 test/unit/detector_test.h | 1 +
8 2 files changed, 11 insertions(+), 8 deletions(-)
9 create mode 100644 test/detect_files/empty.inc
10
11 diff --git a/src/detector.c b/src/detector.c
12 index 4d0e1f4..9b4d8d2 100644
13 --- a/src/detector.c
14 +++ b/src/detector.c
15 @@ -452,14 +452,16 @@ const char *disambiguate_in(SourceFile *sourcefile) {
16
17 const char *disambiguate_inc(SourceFile *sourcefile) {
18 char *p = ohcount_sourcefile_get_contents(sourcefile);
19 - char *eof = p + strlen(p);
20 - while (p < eof) {
21 - if (*p == '\0')
22 - return BINARY;
23 - else if (*p == '?' && strncmp(p + 1, "php", 3) == 0)
24 - return LANG_PHP;
25 - p++;
26 - }
27 + if (p) {
28 + char *eof = p + strlen(p);
29 + while (p < eof) {
30 + if (*p == '\0')
31 + return BINARY;
32 + else if (*p == '?' && strncmp(p + 1, "php", 3) == 0)
33 + return LANG_PHP;
34 + p++;
35 + }
36 + }
37 return NULL;
38 }
39
40 diff --git a/test/detect_files/empty.inc b/test/detect_files/empty.inc
41 new file mode 100644
42 index 0000000..e69de29
43 diff --git a/test/unit/detector_test.h b/test/unit/detector_test.h
44 index cd36b6d..628b6cc 100644
45 --- a/test/unit/detector_test.h
46 +++ b/test/unit/detector_test.h
47 @@ -77,6 +77,7 @@ void test_detector_detect_polyglot() {
48 ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
49 ASSERT_DETECT(LANG_ASSEMBLER, "foo.z80");
50 ASSERT_DETECT(LANG_PHP, "php.inc");
51 + ASSERT_NODETECT("empty.inc");
52 ASSERT_DETECT(LANG_FSHARP, "fs1.fs");
53 }
54
55 --
56 1.7.0.1
57
+0
-53
debian/patches/fix_null_dereference_2.patch less more
0 From c0b28d67f27f6e954c93dabd71d098854896d679 Mon Sep 17 00:00:00 2001
1 From: Robin Luckey <robin@ohloh.net>
2 Date: Thu, 1 Oct 2009 15:43:42 -0700
3 Subject: [PATCH] [FIX] Null dereference error in disambiguate_in()
4
5 ---
6 src/detector.c | 3 +++
7 test/unit/detector_test.h | 4 ++++
8 2 files changed, 7 insertions(+), 0 deletions(-)
9 create mode 100644 test/detect_files/empty.in
10
11 diff --git a/src/detector.c b/src/detector.c
12 index 9b4d8d2..863b379 100644
13 --- a/src/detector.c
14 +++ b/src/detector.c
15 @@ -437,6 +437,9 @@ const char *disambiguate_in(SourceFile *sourcefile) {
16 buf[length] = '\0';
17 SourceFile *undecorated = ohcount_sourcefile_new(buf);
18 p = ohcount_sourcefile_get_contents(sourcefile);
19 + if (!p) {
20 + return NULL;
21 + }
22 // The filepath without the '.in' extension does not exist on disk. The
23 // sourcefile->diskpath field must be set incase the detector needs to run
24 // 'file -b' on the file.
25 diff --git a/test/detect_files/empty.in b/test/detect_files/empty.in
26 new file mode 100644
27 index 0000000..e69de29
28 diff --git a/test/unit/detector_test.h b/test/unit/detector_test.h
29 index 628b6cc..a26adaa 100644
30 --- a/test/unit/detector_test.h
31 +++ b/test/unit/detector_test.h
32 @@ -36,6 +36,9 @@ void test_detector_disambiguate_m() {
33 ASSERT_DETECT(LANG_OCTAVE, "foo_octave.m");
34 }
35
36 +void test_detector_disambiguate_in() {
37 + ASSERT_NODETECT("empty.in");
38 +}
39 void test_detector_disambiguate_pro() {
40 ASSERT_DETECT(LANG_IDL_PVWAVE, "foo.pro");
41 ASSERT_DETECT(LANG_MAKE, "qmake.pro");
42 @@ -119,6 +122,7 @@ void test_detector_xml_with_custom_extension() {
43 void all_detector_tests() {
44 test_detector_smalltalk();
45 test_detector_disambiguate_m();
46 + test_detector_disambiguate_in();
47 test_detector_disambiguate_pro();
48 test_detector_fortran_fixedfree();
49 test_detector_detect_polyglot();
50 --
51 1.7.0.1
52
+0
-28
debian/patches/rbconfig.patch less more
0 Index: ohcount-3.0.0/build
1 ===================================================================
2 --- ohcount-3.0.0.orig/build
3 +++ ohcount-3.0.0/build
4 @@ -114,12 +114,12 @@ run_test_suite()
5
6 build_ruby_bindings()
7 {
8 - arch=`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`
9 + arch=`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'`
10 echo "Generating Ruby bindings for $arch"
11 sh -c "swig -ruby -o ruby/ohcount_wrap.c ruby/ohcount.i" || exit 1
12 mkdir -p ruby/$arch
13 sh -c "$cc $RB_SHARED ruby/ohcount_wrap.c $files -o ruby/$arch/$RB_SHARED_NAME \
14 - -I`ruby -rmkmf -e 'print Config::expand(CONFIG["archdir"])'` \
15 + -I`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["archdir"])'` \
16 -lpcre" || exit 1
17 sh -c "cd test/unit/ruby && ruby ruby_test.rb" || exit 1
18 }
19 @@ -156,7 +156,7 @@ then
20 rm -f src/hash/*.c
21 rm -f src/$SHARED_NAME
22 rm -f ruby/$RB_SHARED_NAME
23 - rm -rf ruby/`ruby -rmkmf -e 'print Config::expand(CONFIG["arch"])'`/*
24 + rm -rf ruby/`ruby -rmkmf -e 'print RbConfig::expand(RbConfig::CONFIG["arch"])'`/*
25 else
26 echo "Usage: build [all|ohcount|shared|tests|ruby|clean]"
27 fi
+0
-5
debian/patches/series less more
0 fix_null_dereference_2.patch
1 fix_null_dereference.patch
2 txx_support.patch
3 disabled_test_suite.patch
4 rbconfig.patch
+0
-12
debian/patches/txx_support.patch less more
0 diff -Naur ohcount-3.0.0/src/hash/extensions.gperf ohcount-3.0.1/src/hash/extensions.gperf
1 --- ohcount-3.0.0/src/hash/extensions.gperf 2009-09-30 17:30:19.000000000 +0000
2 +++ ohcount-3.0.1/src/hash/extensions.gperf 2011-09-26 09:32:34.000000000 +0000
3 @@ -161,6 +161,7 @@
4 tif, BINARY
5 tiff, BINARY
6 tpl, LANG_HTML
7 +txx, LANG_CPP
8 vala, LANG_VALA
9 vb, LANG_VISUALBASIC
10 vba, LANG_VISUALBASIC
11
+0
-27
debian/rules less more
0 #!/usr/bin/make -f
1
2 %:
3 dh $@ --buildsystem=ruby --with ruby
4
5 override_dh_auto_clean:
6 dh_auto_clean -O--buildsystem=ruby
7 ./build clean
8 rm -rf doc_build
9
10 override_dh_install:
11 ./build all
12 dh_install --buildsystem=ruby --with ruby
13 install -d debian/ohcount/usr/lib/ruby/vendor_ruby/ohcount
14 install -d debian/ohcount/usr/bin
15 install -d debian/ohcount-doc/usr/share/doc/ohcount-doc
16 cp bin/ohcount debian/ohcount/usr/bin/
17 cp -R ruby/gestalt ruby/gestalt.rb ruby/ohcount.rb debian/ohcount/usr/lib/ruby/vendor_ruby/ohcount/
18 # build doxygen
19 mkdir doc_build
20 cp -aR doc/* doc_build/
21 (cd doc_build && doxygen Doxyfile)
22 cp -aR doc_build/html/* debian/ohcount-doc/usr/share/doc/ohcount-doc
23 rm -rf debian/ohcount/ruby debian/ohcount-doc/ruby
24
25 get-orig-source:
26 uscan --force-download
+0
-1
debian/source/format less more
0 3.0 (quilt)
+0
-6
debian/watch less more
0 version=4
1 opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%ohcount-$1.tar.gz%" \
2 https://github.com/blackducksoftware/ohcount/tags \
3 (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
4
5
00 %%{
11 machine c;
22 write data;
3 include "common.rl";
3 include common "common.rl";
44
55 ...
66 }%%
0 import os, collections
1 from abc import abstractmethod
2 import ohcount
3
4 class _OhcountBase(object):
5
6 def __init__(self, base):
7 self._base = base
8
9 def __getattr__(self, name):
10 if name == '_base':
11 return object.__getattr__(self, name)
12 raise AttributeError
13
14 def __setattr__(self, name, value):
15 if name == '_base':
16 return object.__setattr__(self, name, value)
17 raise AttributeError
18
19 class _OhcountDict(_OhcountBase, collections.Mapping, collections.KeysView):
20
21 def __init__(self, base, mapping):
22 _OhcountBase.__init__(self, base)
23 collections.KeysView.__init__(self, mapping)
24
25 def __getattr__(self, name):
26 if name == '_mapping':
27 return collections.KeysView.__getattr__(self, name)
28 try:
29 return _OhcountBase.__getattr__(self, name)
30 except AttributeError:
31 try:
32 return self.__getitem__(name)
33 except KeyError:
34 raise AttributeError
35 except:
36 raise
37
38 def __setattr__(self, name, value):
39 if name == '_mapping':
40 return collections.KeysView.__setattr__(self, name, value)
41 try:
42 return _OhcountBase.__setattr__(self, name, value)
43 except AttributeError:
44 try:
45 return self.__setitem__(name, value)
46 except KeyError:
47 raise AttributeError
48 except:
49 raise
50
51 def keys(self):
52 return self._mapping
53
54 def __setitem__(self, key, item):
55 raise KeyError
56
57 def __delitem__(self, key):
58 raise KeyError
59
60 def __str__(self):
61 return dict([(key, self[key]) for key in self.keys()]).__str__()
62
63 def iterkeys(self):
64 return iter(self.keys())
65
66 def itervalues(self):
67 for key in self.keys():
68 yield self[key]
69
70 def iteritems(self):
71 for key in self.keys():
72 yield (key, self[key])
73
74 def items(self):
75 return [(key, self[key]) for key in self.keys()]
76
77 def values(self):
78 return [self[key] for key in self.keys()]
79
80 class _OhcountList(_OhcountBase):
81
82 @abstractmethod
83 def _get_value(self, inner):
84 raise NotImplementedError
85
86 def __len__(self):
87 count = 0
88 for e in self:
89 count += 1
90 return count
91
92 def __iter__(self):
93 return self.next()
94
95 def next(self):
96 iter = self._base.head
97 while iter is not None:
98 yield self._get_value(iter)
99 iter = iter.next
100
101 def __str__(self):
102 return [v for v in self].__str__()
103
104 class License(_OhcountDict):
105
106 def __init__(self, base):
107 _OhcountDict.__init__(self, base,
108 ['name','url','nice_name'])
109
110 def __getitem__(self, key):
111 if key == 'name':
112 return self._base.name
113 if key == 'url':
114 return self._base.url
115 if key == 'nice_name':
116 return self._base.nice_name
117 raise KeyError
118
119 class Loc(_OhcountDict):
120
121 def __init__(self, base):
122 _OhcountDict.__init__(self, base,
123 ['lang','code','comments','blanks','filecount','total'])
124
125 def __getitem__(self, key):
126 if key == 'lang' or key == 'language':
127 return self._base.language
128 if key == 'code':
129 return self._base.code
130 if key == 'comments':
131 return self._base.comments
132 if key == 'blanks':
133 return self._base.blanks
134 if key == 'filecount':
135 return self._base.filecount
136 if key == 'total':
137 return self._base.total()
138 raise KeyError
139
140 class LocList(_OhcountDict, _OhcountList):
141
142 def __init__(self, base):
143 _OhcountDict.__init__(self, base,
144 ['code','comments','blanks','filecount','total'])
145
146 def _get_value(self, inner):
147 return Loc(inner.loc)
148
149 def __getitem__(self, key):
150 if key == 'code':
151 return self._base.code()
152 if key == 'comments':
153 return self._base.comments()
154 if key == 'blanks':
155 return self._base.blanks()
156 if key == 'filecount':
157 return self._base.filecount()
158 if key == 'total':
159 return self._base.total()
160 raise KeyError
161
162 def __str__(self):
163 return _OhcountDict.__str__(self)
164
165 def compact(self):
166 return LocList(self._base.compact())
167
168 class SourceFile(_OhcountDict):
169
170 def __init__(self, base):
171 _OhcountDict.__init__(self, base,
172 ['filepath','filename','ext','contents','size','language',
173 'licenses','locs'])
174
175 def _get_licenses(self):
176 result = []
177 list = self._base.get_license_list()
178 if list is not None:
179 iter = list.head
180 while iter is not None:
181 result.append(License(iter.lic))
182 iter = iter.next
183 return result
184
185 def _get_locs(self):
186 return LocList(self._base.get_loc_list())
187
188 def __getitem__(self, key):
189 if key == 'filepath':
190 return self._base.filepath
191 if key == 'filename':
192 return self._base.filename
193 if key == 'ext':
194 return self._base.ext
195 if key == 'contents':
196 return self._base.get_contents()
197 if key == 'size':
198 return self._base.contents_size()
199 if key == 'language':
200 return self._base.get_language()
201 if key == 'licenses':
202 return self._get_licenses()
203 if key == 'locs':
204 return self._get_locs()
205 raise AttributeError
206
207 def annotate(self):
208 return self._base.annotate()
209
210 def raw_entities(self):
211 return self._base.raw_entities()
212
213 class SourceFileList(_OhcountList):
214
215 def __init__(self, **kwargs):
216 _OhcountList.__init__(self, ohcount.SourceFileList(kwargs))
217
218 def _get_value(self, inner):
219 return SourceFile(inner.sf)
220
221 def analyze_languages(self):
222 return LocList( self._base.analyze_languages() )
223
224 def add_directory(self, path):
225 if not os.path.isdir(path):
226 raise SyntaxError('Input path is not a directory: %s' % path)
227 self._base.add_directory(path)
228
229 def add_file(self, filepath):
230 if not os.path.isfile(filepath):
231 raise SyntaxError('Input path is not a file: %s' % filepath)
232 self._base.add_file(filepath)
233
0 #=== mingw_setup.py by Phillip J. Eby
1 """Create pythonNN.def and libpythonNN.a in 'PythonNN/libs' directory
2
3 This script makes it possible to use the MinGW compiler tools to
4 build C extensions that work with the standard Windows Python
5 distribution.
6
7 Before running, you should have installed the MinGW compiler toolset,
8 and placed its 'bin' directory on your PATH. An easy way to do this
9 is to install Cygwin's "binutils", "gcc", and "mingw-*" packages,
10 then run this script from the Cygwin shell. (Be sure to use *Windows*
11 Python, not Cygwin python!)
12
13 Once this script has been run, you should be able to build extensions
14 using distutils in the standard way, as long as you select the
15 'mingw32' compiler, and the required tools are on your PATH. See
16 the "Installing Python Modules" manual for more information on
17 selecting a compiler.
18 """
19
20
21 from distutils.spawn import find_executable
22 from distutils.sysconfig import get_config_var
23 from distutils import __file__ as distutils_file
24 import os, re, sys
25
26 if sys.platform=='cygwin':
27 print "Please run this script using Windows python,",
28 print "not Cygwin python. E.g, try:"
29 print
30 print "/cygdrive/c/PythonNN/python", " ".join(sys.argv)
31 print
32 print "(where NN is the major/minor python version number)"
33 sys.exit()
34
35 basename = 'python%d%d' % sys.version_info[:2]
36
37 libs_dir = os.path.join(get_config_var('prefix'),'libs')
38 lib_file = os.path.join(libs_dir,basename+'.lib')
39 def_file = os.path.join(libs_dir,basename+'.def')
40 ming_lib = os.path.join(libs_dir,'lib%s.a' % basename)
41
42 distutils_cfg = os.path.join(os.path.dirname(distutils_file),'distutils.cfg')
43
44 export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match
45
46 nm = find_executable('nm')
47 dlltool = find_executable('dlltool')
48
49 if not nm or not dlltool:
50 print "'nm' and/or 'dlltool' were not found;"
51 print "Please make sure they're on your PATH."
52 sys.exit()
53
54 nm_command = '%s -Cs %s' % (nm, lib_file)
55
56 print "Building", def_file, "using", nm_command
57 f = open(def_file,'w')
58 print >>f, "LIBRARY %s.dll" % basename
59 print >>f, "EXPORTS"
60
61
62 nm_pipe = os.popen(nm_command)
63 for line in nm_pipe.readlines():
64 m = export_match(line)
65 if m:
66 print >>f, m.group(1)
67 f.close()
68
69 exit = nm_pipe.close()
70 if exit:
71 print "nm exited with status", exit
72 print "Please check that", lib_file, "exists and is valid."
73 sys.exit()
74
75
76 print "Building",ming_lib,"using",dlltool
77 dlltool_pipe = os.popen(
78 "%s --dllname %s.dll --def %s --output-lib %s" %
79 (dlltool, basename, def_file, ming_lib)
80 )
81
82 dlltool_pipe.readlines()
83 exit = dlltool_pipe.close()
84 if exit:
85 print "dlltool exited with status", exit
86 print "Unable to proceed."
87 sys.exit()
88
89 print
90 print "Installation complete. You may wish to add the following"
91 print "lines to", distutils_cfg, ':'
92 print
93 print "[build]"
94 print "compiler = mingw32"
95 print
96 print "This will make the distutils use MinGW as the default"
97 print "compiler, so that you don't need to configure this for"
98 print "every 'setup.py' you run."
99
0 #!/usr/bin/env python
1
2 import distutils.ccompiler
3 from distutils.core import setup, Extension
4 from distutils.command.build import build
5 from distutils.command.build_ext import build_ext
6 from distutils.command.install_lib import install_lib
7 import os, sys
8 from glob import glob
9
10 if not hasattr(sys, 'version_info') or sys.version_info < (2,6,0,'final'):
11 raise SystemExit("Ohcount requires Python 2.6 or later.")
12
13 class build_ohcount(build):
14 """Ohcount already have a script named 'build', from the original package,
15 so it conflicts with Python default build path. To solve this, setup.py
16 will use the directory 'build-python' instead. The original distutils
17 execute 'build_py' before 'build_ext', but we need the wrapper ohcount.py
18 created by SWIG to be installed too, so we need to invert this order.
19 """
20
21 sub_commands = [('build_ext', build.has_ext_modules), # changed
22 ('build_py', build.has_pure_modules), # changed
23 ('build_clib', build.has_c_libraries),
24 ('build_scripts', build.has_scripts),
25 ]
26
27 def initialize_options(self):
28 build.initialize_options(self)
29 self.build_base = 'build-python'
30
31 def newer_than(srclist, dstlist):
32 for left, right in zip(srclist, dstlist):
33 if not os.path.exists(right):
34 return True
35 left_stat = os.lstat(left)
36 right_stat = os.lstat(right)
37 if left_stat.st_mtime > right_stat.st_mtime:
38 return True
39 return False
40
41 class build_ohcount_ext(build_ext):
42 """This class implements extra steps needed by Ohcount build process."""
43
44 def run(self):
45 parsers = glob('src/parsers/*.rl')
46 parsers_h = [f.replace('.rl', '.h') for f in parsers]
47 if newer_than(parsers, parsers_h):
48 os.system('cd src/parsers/ && bash ./compile')
49 hash_files = glob('src/hash/*.gperf')
50 hash_srcs = []
51 for f in hash_files:
52 if not f.endswith('languages.gperf'):
53 hash_srcs.append(f.replace('s.gperf', '_hash.h'))
54 else:
55 hash_srcs.append(f.replace('s.gperf', '_hash.c'))
56 if newer_than(hash_files, hash_srcs):
57 os.system('cd src/hash/ && bash ./generate_headers')
58 return build_ext.run(self)
59
60 # Overwrite default Mingw32 compiler
61 (module_name, class_name, long_description) = \
62 distutils.ccompiler.compiler_class['mingw32']
63 module_name = "distutils." + module_name
64 __import__(module_name)
65 module = sys.modules[module_name]
66 Mingw32CCompiler = vars(module)[class_name]
67
68 class Mingw32CCompiler_ohcount(Mingw32CCompiler):
69 """Ohcount CCompiler version for Mingw32. There is a problem linking
70 against msvcrXX for Python 2.6.4: as both DLLs msvcr and msvcr90 are
71 loaded, it seems to happen some unexpected segmentation faults in
72 several function calls."""
73
74 def __init__(self, *args, **kwargs):
75 Mingw32CCompiler.__init__(self, *args, **kwargs)
76 self.dll_libraries=[] # empty link libraries list
77
78 _new_compiler = distutils.ccompiler.new_compiler
79
80 def ohcount_new_compiler(plat=None,compiler=None,verbose=0,dry_run=0,force=0):
81 if compiler == 'mingw32':
82 inst = Mingw32CCompiler_ohcount(None, dry_run, force)
83 else:
84 inst = _new_compiler(plat,compiler,verbose,dry_run,force)
85 return inst
86
87 distutils.ccompiler.new_compiler = ohcount_new_compiler
88
89 # Ohcount python extension
90 ext_modules=[
91 Extension(
92 name='ohcount._ohcount',
93 sources= [
94 'ruby/ohcount.i',
95 'src/sourcefile.c',
96 'src/detector.c',
97 'src/licenses.c',
98 'src/parser.c',
99 'src/loc.c',
100 'src/log.c',
101 'src/diff.c',
102 'src/parsed_language.c',
103 'src/hash/language_hash.c',
104 ],
105 libraries=['pcre'],
106 swig_opts=['-outdir', './python/'],
107 )
108 ]
109
110 setup(
111 name='ohcount',
112 version = '3.0.0',
113 description = 'Ohcount is the source code line counter that powers Ohloh.',
114 long_description =
115 'Ohcount supports over 70 popular programming languages, and has been '
116 'used to count over 6 billion lines of code by 300,000 developers! '
117 'Ohcount does more more than just count lines of code. It can also '
118 'detect popular open source licenses such as GPL within a large '
119 'directory of source code. It can also detect code that targets a '
120 'particular programming API, such as Win32 or KDE.',
121 author = 'Mitchell Foral',
122 author_email = 'mitchell@caladbolg.net',
123 license = 'GNU GPL',
124 platforms = ['Linux','Mac OSX'],
125 keywords = ['ohcount','ohloh','loc','source','code','line','counter'],
126 url = 'http://www.ohloh.net/p/ohcount',
127 download_url = 'http://sourceforge.net/projects/ohcount/files/',
128 packages = ['ohcount'],
129 package_dir = {'ohcount': 'python'},
130 classifiers = [
131 'Development Status :: 5 - Production/Stable',
132 'License :: OSI Approved :: GNU General Public License (GPL)'
133 'Intended Audience :: Developers',
134 'Natural Language :: English',
135 'Programming Language :: C',
136 'Programming Language :: Python',
137 'Topic :: Software Development :: Libraries :: Python Modules',
138 ],
139 ext_modules=ext_modules,
140 cmdclass={
141 'build': build_ohcount,
142 'build_ext': build_ohcount_ext,
143 },
144 )
145
1212 require 'gestalt/rules/gestalt_rule'
1313 require 'gestalt/rules/java_import_rule'
1414 require 'gestalt/rules/csharp_using_rule'
15 require 'gestalt/rules/find_java_imports_rule'
1615 require 'gestalt/rules/maven_parser'
1716 require 'gestalt/rules/maven_rule'
1817 require 'gestalt/rules/csproj_parser'
11 module Gestalt
22
33 define_platform 'dot_net' do
4 language :csharp, :min_percent => 10
4 _or do
5 language :csharp, :min_percent => 10
6 gestalt :platform, 'asp_net'
7 gestalt :platform, 'wpf'
8 gestalt :platform, 'silverlight'
9 end
510 end
611
712