#!/usr/bin/csi -script ; (declare (standard-bindings)) ; (declare (extended-bindings)) (declare (block)) (declare (uses library posix script-utils)) (require 'sqlite) (define (print-cpu-time) (call-with-values cpu-time (lambda x (print x)))) (define ifile (list-ref (command-line-arguments) 0)) (define ofile (list-ref (command-line-arguments) 1)) ; (define ident-start-regex (regexp "\\A([A-Za-z0-9_~])")) ; (define scope-regex (regexp "\\A(class|struct|enum|union|namespace):")) (define idents (make-hash-table string=?)) (define idents-len 0) (define files (make-hash-table string=?)) (define files-len 0) (define tags '()) (define (parse-ctags-line line) (let* ((tokens (string-split line "\t")) (is-symbol-line (and (not (null? tokens)) (let ((c (string-ref (car tokens) 0))) (or (char-alphabetic? c) (memq c '(#\~ #\_ #\:))))))) (when is-symbol-line ; (print line) ; (print tokens) (let* ((ident (list-ref tokens 0)) (line-x (list-ref tokens 2)) (line (substring line-x 0 (- (string-length line-x) 2))) (type (list-ref tokens 3)) (scope-x (and (> (length tokens) 4) (string-split (list-ref tokens 4) ":"))) (scope (and scope-x (member (car scope-x) '("class" "struct" "enum" "union" "namespace")) (list-ref scope-x (- (length scope-x) 1)))) (path (list-ref tokens 1)) (file (string-append (pathname-file path) "." (pathname-extension path))) (dir (pathname-directory path)) (ident-no (hash-table-ref idents ident)) (file-no (hash-table-ref files file)) (dir-no (hash-table-ref files dir)) (scope-no (and scope (hash-table-ref idents scope)))) (unless ident-no (set! ident-no idents-len) (hash-table-set! idents ident ident-no) (set! idents-len (+ idents-len 1))) (if scope (when (not scope-no) (set! scope-no idents-len) (hash-table-set! idents scope scope-no) (set! idents-len (+ idents-len 1))) (set! scope-no -1)) (unless file-no (set! file-no files-len) (hash-table-set! files file file-no) (set! files-len (+ files-len 1))) (unless dir-no (set! dir-no files-len) (hash-table-set! files dir dir-no) (set! files-len (+ files-len 1))) (set! tags (cons (list ident-no file-no dir-no line type scope-no) tags)) ; (print ident ":" scope) ; (print (list ident-no file-no dir-no line type scope-no)) ; (print ident-no "," file-no "," dir-no "," type "," scope-no) ; (print (list-ref tokens 1) "," ; file-name "," dir-name "," ; (list-ref tokens 3) "," ; (list-ref tokens 4) "," ; (list-ref tokens 7)) )) #t)) (define (read-and-print) (unless (eqv? (map parse-ctags-line (read-lines)) '()) (read-and-print))) (print-cpu-time) (with-input-from-pipe (string-append "cleartool catcr -union -element_only -name '*.[cxhs]*' -short -nxname " ifile " | ctags --filter=yes --sort=no -n --c-kinds=+p --c++-kinds=+p ") read-and-print) ;;(exit 0) (print-cpu-time) (define db (sqlite:open ofile #f)) (sqlite:execute db "PRAGMA synchronous = OFF;") (sqlite:execute db "PRAGMA default_synchronous = OFF;") (sqlite:execute db "PRAGMA count_changes = OFF;") (sqlite:execute db "begin;") (sqlite:execute db "create table idents(symname TEXT UNIQUE on conflict abort,symid INTEGER PRIMARY KEY on conflict abort);") (sqlite:execute db "create table files(fileid INTEGER PRIMARY KEY on conflict abort, filename TEXT UNIQUE on conflict abort);") (sqlite:execute db (string-append "create table tags(sym INTEGER,file INTEGER, path INTEGER, line INTEGER, syntax TEXT, scope INTEGER," "unique(sym,file,path,line,syntax,scope));")); (sqlite:execute db "insert or abort into idents values(NULL,-1);") (hash-table-for-each (lambda (key value) (sqlite:execute db (string-append "insert or abort into idents values('" key "', " (number->string value) ");"))) idents) (hash-table-for-each (lambda (key value) (sqlite:execute db (string-append "insert or abort into files values(" (number->string value) " , '" key "');"))) files) (map (lambda (tag) (sqlite:execute db (string-append "insert or ignore into tags values (" (number->string (list-ref tag 0)) "," (number->string (list-ref tag 1)) "," (number->string (list-ref tag 2)) "," (list-ref tag 3) ",'" (list-ref tag 4) "'," (number->string (list-ref tag 5)) ");"))) tags) (print-cpu-time) (sqlite:execute db "create index idents_symname on idents(symname);") (sqlite:execute db "create index files_filename on files(filename);") (sqlite:execute db "create index tags_sym on tags(sym);") (sqlite:execute db "commit;") (sqlite:close db) (print-cpu-time)