Ver código fonte

Now it's in a working condition, add a sample to show how to use it.

mingodad 10 anos atrás
pai
commit
278aa69466

+ 66 - 13
SquiLu-ext/sq_libclang.cpp

@@ -35,6 +35,7 @@ local dynamic_functions = [
     ["CXString", "clang_getCursorSpelling", "CXCursor"],
     ["CXString", "clang_getTypeSpelling", "CXType CT"],
     ["CXString", "clang_getCursorKindSpelling", "enum CXCursorKind"],
+    ["CXCursor", "clang_getCursorReferenced", "CXCursor"],
     ["const char *", "clang_getCString", "CXString string"],
     ["void", "clang_disposeString", "CXString str"],
     ["CXSourceLocation", "clang_getCursorLocation", "CXCursor"],
@@ -96,6 +97,8 @@ typedef CXString (*clang_getTypeSpelling_t)(CXType CT);
 static clang_getTypeSpelling_t dlclang_getTypeSpelling = 0;
 typedef CXString (*clang_getCursorKindSpelling_t)(enum CXCursorKind);
 static clang_getCursorKindSpelling_t dlclang_getCursorKindSpelling = 0;
+typedef CXCursor (*clang_getCursorReferenced_t)(CXCursor);
+static clang_getCursorReferenced_t dlclang_getCursorReferenced = 0;
 typedef const char * (*clang_getCString_t)(CXString string);
 static clang_getCString_t dlclang_getCString = 0;
 typedef void (*clang_disposeString_t)(CXString str);
@@ -144,6 +147,8 @@ dlclang_getTypeSpelling = (clang_getTypeSpelling_t) dynamicLib.dlsym("clang_getT
 if(!dlclang_getTypeSpelling) return false;
 dlclang_getCursorKindSpelling = (clang_getCursorKindSpelling_t) dynamicLib.dlsym("clang_getCursorKindSpelling");
 if(!dlclang_getCursorKindSpelling) return false;
+dlclang_getCursorReferenced = (clang_getCursorReferenced_t) dynamicLib.dlsym("clang_getCursorReferenced");
+if(!dlclang_getCursorReferenced) return false;
 dlclang_getCString = (clang_getCString_t) dynamicLib.dlsym("clang_getCString");
 if(!dlclang_getCString) return false;
 dlclang_disposeString = (clang_disposeString_t) dynamicLib.dlsym("clang_disposeString");
@@ -172,6 +177,8 @@ struct MyLibClang {
     int depth;
 	const char *file_name;
 	char *function_name;
+	unsigned int prev_line, prev_column;
+	unsigned int line, column;
 	HSQUIRRELVM v;
 	HSQOBJECT visitor_cb;
 	HSQOBJECT visitor_udata;
@@ -259,16 +266,18 @@ functionDeclVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
 	enum CXCursorKind kind = dlclang_getCursorKind(cursor);
 	CXType type = dlclang_getCursorType(cursor);
 	CXString type_spelling;
-	CXString type_kind_spelling;
+	//CXString type_kind_spelling;
 	CXString name;
 
 	if (kind == CXCursor_ParmDecl){
 		name = dlclang_getCursorSpelling(cursor);
 		type_spelling = dlclang_getTypeSpelling(type);
 		//db_add_funcparam(cvu->db, cvu->function_name, dlclang_getCString(name), dlclang_getCString(type_spelling), type.kind);
-		call_visitor_cb(cvu, "sssssi",
+		call_visitor_cb(cvu, "ssiisssi",
                         "FuncParam",
                         cvu->file_name,
+                        cvu->line,
+                        cvu->column,
                         cvu->function_name,
                         dlclang_getCString(name),
                         dlclang_getCString(type_spelling),
@@ -294,6 +303,8 @@ cursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
 	CXSourceLocation location = dlclang_getCursorLocation(cursor);
 	dlclang_getPresumedLocation(location, &filename, &line, &column);
     cvu->file_name = dlclang_getCString(filename);
+    cvu->line = line;
+    cvu->column = column;
 	//sqlite_int64 file_id = db_add_funcfile(cvu->db, dlclang_getCString(filename));
 	//call_visitor_cb(cvu, "ss", "FuncFile", dlclang_getCString(filename));
 	if (kind == CXCursor_FunctionDecl) {
@@ -304,13 +315,15 @@ cursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
 		CXString rtype_spelling = dlclang_getTypeSpelling(rtype);
 		free(cvu->function_name);
 		cvu->function_name = strdup(dlclang_getCString(name));
+		cvu->prev_line = line;
+		cvu->prev_column = column;
 		//db_add_funcdecl(cvu->db, cvu->function_name, dlclang_getCString(type_spelling),
         //          dlclang_getCString(rtype_spelling), lk, file_id, line, column);
-        call_visitor_cb(cvu, "ssiissi",
+        call_visitor_cb(cvu, "ssiisssi",
                         "FuncDecl",
                         cvu->file_name,
-                        line,
-                        column,
+                        cvu->line,
+                        cvu->column,
                         cvu->function_name,
                         dlclang_getCString(type_spelling),
                         dlclang_getCString(rtype_spelling),
@@ -321,13 +334,26 @@ cursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
 		//CXString type_spelling = clang_getTypeSpelling(type);
 		//printf("%s\n", type_spelling);
 		//db_add_funccall(cvu->db, cvu->function_name, dlclang_getCString(name), file_id, line, column);
-		call_visitor_cb(cvu, "ssiiss",
+
+		CXCursor to_func_file_cursor = dlclang_getCursorReferenced(cursor);
+        CXString to_func_filename;
+        unsigned int to_func_line, to_func_column;
+
+        CXSourceLocation to_func_location = dlclang_getCursorLocation(to_func_file_cursor);
+        dlclang_getPresumedLocation(to_func_location, &to_func_filename, &to_func_line, &to_func_column);
+
+		call_visitor_cb(cvu, "ssiisiisiis",
                         "CallExpr",
                         cvu->file_name,
                         line,
                         column,
-                        cvu->function_name,
-                        dlclang_getCString(name));
+                        cvu->function_name, //from function
+                        cvu->prev_line,
+                        cvu->prev_column,
+                        dlclang_getCString(to_func_filename),
+                        to_func_line,
+                        to_func_column,
+                        dlclang_getCString(name)); //to function
 
 		ret = CXChildVisit_Continue;
 	}
@@ -349,28 +375,55 @@ static SQRESULT sq_libclang_parseTranslationUnit(HSQUIRRELVM v){
 	sq_getstackobj(v, 2, &self->visitor_cb);
     sq_addref(v, &self->visitor_cb);
 
-	const char *cl_args[] = {"-I."};
+	const char *cl_argsDefault[] = {"-I."};
+	const char **cl_args = cl_argsDefault;
 	int cl_argNum = 1;
+	int rc = 0;
+	const int cl_arg_start = 4;
+	bool has_extra_params = _top_ >= cl_arg_start;
 
-	if(_top_ > 3)
+	if(has_extra_params)
     {
         //create cl_args with extra parameters
+        cl_argNum = _top_ - (cl_arg_start -1);
+        cl_args = (const char **)sq_malloc(sizeof(char*) * cl_argNum);
+        for(int i=cl_arg_start; i <= _top_; ++i)
+        {
+            const SQChar *p;
+            if(sq_gettype(v, i) == OT_STRING)
+            {
+                rc = sq_getstring(v, i, &p);
+            }
+            else
+            {
+                rc = sq_throwerror(v, _SC("not a string parameter at %d"), i);
+                goto cleanup;
+            }
+            cl_args[i-cl_arg_start] = p;
+        }
     }
 
 	CXTranslationUnit TU;
+	CXCursor rootCursor;
 
     TU = dlclang_parseTranslationUnit(self->index, fname,
                     cl_args, cl_argNum, 0, 0, CXTranslationUnit_Incomplete);
 
     if (TU == NULL) {
-        return sq_throwerror(v, _SC("clang_parseTranslationUnit for %s failed\n"), fname);
+        rc = sq_throwerror(v, _SC("clang_parseTranslationUnit for %s failed\n"), fname);
+        goto cleanup;
     }
 
-    CXCursor rootCursor = dlclang_getTranslationUnitCursor(TU);
+    rootCursor = dlclang_getTranslationUnitCursor(TU);
     dlclang_visitChildren(rootCursor, cursorVisitor, self);
     dlclang_disposeTranslationUnit(TU);
 
-	return 0;
+cleanup:
+	if(has_extra_params)
+    {
+        sq_free(cl_args, sizeof(char*) * cl_argNum);
+    }
+	return rc;
 }
 
 #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),  sq_libclang_##name,nparams,tycheck}

+ 474 - 0
SquiLu/samples/clang-parse.nut

@@ -0,0 +1,474 @@
+dofile("libclang.nut");
+
+local file_list_lib = [==[
+src/tbox/tbox.c
+src/tbox/math/math.c
+src/tbox/math/impl/random_linear.c
+src/tbox/math/int32.c
+src/tbox/math/fixed16.c
+src/tbox/math/random.c
+src/tbox/libc/libc.c
+src/tbox/libc/misc/time/mktime.c
+src/tbox/libc/misc/time/localtime.c
+src/tbox/libc/misc/time/gmmktime.c
+src/tbox/libc/misc/time/gmtime.c
+src/tbox/libc/misc/time/time.c
+src/tbox/libc/stdio/vswprintf.c
+src/tbox/libc/stdio/printf_object.c
+src/tbox/libc/stdio/swprintf.c
+src/tbox/libc/stdio/wprintf.c
+src/tbox/libc/stdio/puts.c
+src/tbox/libc/stdio/snprintf.c
+src/tbox/libc/stdio/wputs.c
+src/tbox/libc/stdio/printf.c
+src/tbox/libc/stdio/sprintf.c
+src/tbox/libc/stdio/vsnprintf.c
+src/tbox/libc/stdlib/wcstombs.c
+src/tbox/libc/stdlib/stdlib.c
+src/tbox/libc/stdlib/mbstowcs.c
+src/tbox/libc/stdlib/random.c
+src/tbox/libc/string/strrstr.c
+src/tbox/libc/string/strnrstr.c
+src/tbox/libc/string/memcpy.c
+src/tbox/libc/string/wcsndup.c
+src/tbox/libc/string/wcslen.c
+src/tbox/libc/string/wcscat.c
+src/tbox/libc/string/wcsirstr.c
+src/tbox/libc/string/strnstr.c
+src/tbox/libc/string/strcat.c
+src/tbox/libc/string/memdup.c
+src/tbox/libc/string/strnirstr.c
+src/tbox/libc/string/wcsnrchr.c
+src/tbox/libc/string/strnirchr.c
+src/tbox/libc/string/strcpy.c
+src/tbox/libc/string/strchr.c
+src/tbox/libc/string/strnlen.c
+src/tbox/libc/string/strlcpy.c
+src/tbox/libc/string/stricmp.c
+src/tbox/libc/string/strirchr.c
+src/tbox/libc/string/strncat.c
+src/tbox/libc/string/strncmp.c
+src/tbox/libc/string/strncpy.c
+src/tbox/libc/string/strdup.c
+src/tbox/libc/string/strirstr.c
+src/tbox/libc/string/wcsnicmp.c
+src/tbox/libc/string/wcsicmp.c
+src/tbox/libc/string/memmov.c
+src/tbox/libc/string/wcsncpy.c
+src/tbox/libc/string/wcsnirchr.c
+src/tbox/libc/string/wcslcpy.c
+src/tbox/libc/string/wcsnrstr.c
+src/tbox/libc/string/wcsichr.c
+src/tbox/libc/string/strndup.c
+src/tbox/libc/string/memmem.c
+src/tbox/libc/string/strstr.c
+src/tbox/libc/string/wcscmp.c
+src/tbox/libc/string/strnrchr.c
+src/tbox/libc/string/wcsirchr.c
+src/tbox/libc/string/strcmp.c
+src/tbox/libc/string/wcsrchr.c
+src/tbox/libc/string/wcschr.c
+src/tbox/libc/string/wcsrstr.c
+src/tbox/libc/string/wcsncmp.c
+src/tbox/libc/string/wcsdup.c
+src/tbox/libc/string/strrchr.c
+src/tbox/libc/string/wcsistr.c
+src/tbox/libc/string/strichr.c
+src/tbox/libc/string/wcsstr.c
+src/tbox/libc/string/stristr.c
+src/tbox/libc/string/wcsncat.c
+src/tbox/libc/string/memset.c
+src/tbox/libc/string/strlen.c
+src/tbox/libc/string/strnistr.c
+src/tbox/libc/string/wcsnlen.c
+src/tbox/libc/string/strnicmp.c
+src/tbox/libc/string/wcsnirstr.c
+src/tbox/libc/string/wcscpy.c
+src/tbox/libc/string/memcmp.c
+src/tbox/utils/crc.c
+src/tbox/utils/sha.c
+src/tbox/utils/adler32.c
+src/tbox/utils/trace.c
+src/tbox/utils/base64.c
+src/tbox/utils/singleton.c
+src/tbox/utils/used.c
+src/tbox/utils/lock_profiler.c
+src/tbox/utils/dump.c
+src/tbox/utils/base32.c
+src/tbox/utils/bits.c
+src/tbox/utils/md5.c
+src/tbox/utils/url.c
+src/tbox/prefix/state.c
+src/tbox/memory/native_allocator.c
+src/tbox/memory/default_allocator.c
+src/tbox/memory/queue_buffer.c
+src/tbox/memory/allocator.c
+src/tbox/memory/static_buffer.c
+src/tbox/memory/static_allocator.c
+src/tbox/memory/string_pool.c
+src/tbox/memory/impl/prefix.c
+src/tbox/memory/impl/static_fixed_pool.c
+src/tbox/memory/impl/static_large_allocator.c
+src/tbox/memory/impl/native_large_allocator.c
+src/tbox/memory/memory.c
+src/tbox/memory/fixed_pool.c
+src/tbox/memory/large_allocator.c
+src/tbox/memory/small_allocator.c
+src/tbox/memory/buffer.c
+src/tbox/string/static_string.c
+src/tbox/string/string.c
+src/tbox/stream/transfer.c
+src/tbox/stream/impl/filter/cache.c
+src/tbox/stream/impl/stream/filter.c
+src/tbox/stream/impl/stream/file.c
+src/tbox/stream/impl/stream/data.c
+src/tbox/stream/filter.c
+src/tbox/stream/stream.c
+src/tbox/stream/static_stream.c
+src/tbox/algorithm/heap_sort.c
+src/tbox/algorithm/count.c
+src/tbox/algorithm/predicate.c
+src/tbox/algorithm/remove_first_if.c
+src/tbox/algorithm/insert_sort.c
+src/tbox/algorithm/quick_sort.c
+src/tbox/algorithm/sort.c
+src/tbox/algorithm/count_if.c
+src/tbox/algorithm/rfind_if.c
+src/tbox/algorithm/binary_find.c
+src/tbox/algorithm/walk.c
+src/tbox/algorithm/bubble_sort.c
+src/tbox/algorithm/remove_if.c
+src/tbox/algorithm/remove.c
+src/tbox/algorithm/rwalk.c
+src/tbox/algorithm/remove_first.c
+src/tbox/algorithm/distance.c
+src/tbox/algorithm/binary_find_if.c
+src/tbox/algorithm/find_if.c
+src/tbox/algorithm/rfind.c
+src/tbox/algorithm/find.c
+src/tbox/container/list_entry.c
+src/tbox/container/heap.c
+src/tbox/container/vector.c
+src/tbox/container/bloom_filter.c
+src/tbox/container/iterator.c
+src/tbox/container/single_list.c
+src/tbox/container/queue.c
+src/tbox/container/stack.c
+src/tbox/container/hash_map.c
+src/tbox/container/list.c
+src/tbox/container/single_list_entry.c
+src/tbox/container/circle_queue.c
+src/tbox/container/element/long.c
+src/tbox/container/element/ptr.c
+src/tbox/container/element/str.c
+src/tbox/container/element/size.c
+src/tbox/container/element/true.c
+src/tbox/container/element/obj.c
+src/tbox/container/element/mem.c
+src/tbox/container/element/uint8.c
+src/tbox/container/element/uint16.c
+src/tbox/container/element/uint32.c
+src/tbox/container/element/null.c
+src/tbox/container/element/hash.c
+src/tbox/container/hash_set.c
+src/tbox/container/priority_queue.c
+src/tbox/container/iterator/long.c
+src/tbox/container/iterator/ptr.c
+src/tbox/container/iterator/str.c
+src/tbox/container/iterator/size.c
+src/tbox/container/iterator/mem.c
+src/tbox/libm/libm.c
+src/tbox/libm/idivi8.c
+src/tbox/libm/ilog2i.c
+src/tbox/libm/isqrti.c
+src/tbox/libm/isqrti64.c
+src/tbox/platform/directory.c
+src/tbox/platform/path.c
+src/tbox/platform/print.c
+src/tbox/platform/dynamic.c
+src/tbox/platform/atomic64.c
+src/tbox/platform/time.c
+src/tbox/platform/sched.c
+src/tbox/platform/processor.c
+src/tbox/platform/process.c
+src/tbox/platform/memory.c
+src/tbox/platform/backtrace.c
+src/tbox/platform/hostname.c
+src/tbox/platform/cache_time.c
+src/tbox/platform/file.c
+src/tbox/platform/page.c
+src/tbox/platform/platform.c
+src/tbox/platform/ifaddrs.c
+src/tbox/platform/environment.c
+src/tbox/libm/tan.c
+src/tbox/libm/sinf.c
+src/tbox/libm/exp1f.c
+src/tbox/libm/atanf.c
+src/tbox/libm/isfin.c
+src/tbox/libm/fmod.c
+src/tbox/libm/isinf.c
+src/tbox/libm/exp1.c
+src/tbox/libm/sqrtf.c
+src/tbox/libm/atan2.c
+src/tbox/libm/tanf.c
+src/tbox/libm/acos.c
+src/tbox/libm/pow.c
+src/tbox/libm/sincos.c
+src/tbox/libm/expf.c
+src/tbox/libm/sqrt.c
+src/tbox/libm/cosf.c
+src/tbox/libm/exp.c
+src/tbox/libm/isnan.c
+src/tbox/libm/sin.c
+src/tbox/libm/asin.c
+src/tbox/libm/isinff.c
+src/tbox/libm/isnanf.c
+src/tbox/libm/sincosf.c
+src/tbox/libm/expif.c
+src/tbox/libm/isfinf.c
+src/tbox/libm/asinf.c
+src/tbox/libm/fmodf.c
+src/tbox/libm/log2.c
+src/tbox/libm/expi.c
+src/tbox/libm/atan2f.c
+src/tbox/libm/cos.c
+src/tbox/libm/powf.c
+src/tbox/libm/atan.c
+src/tbox/libm/log2f.c
+src/tbox/libm/acosf.c
+src/tbox/xml/reader.c
+src/tbox/xml/node.c
+src/tbox/xml/writer.c
+src/tbox/regex/regex.c
+src/tbox/asio/aioo.c
+src/tbox/asio/aiop.c
+src/tbox/platform/dns.c
+src/tbox/platform/aioo.c
+src/tbox/platform/aiop.c
+src/tbox/platform/socket.c
+src/tbox/stream/impl/stream/http.c
+src/tbox/stream/impl/stream/sock.c
+src/tbox/stream/impl/filter/chunked.c
+src/tbox/network/ipv4.c
+src/tbox/network/ipv6.c
+src/tbox/network/dns/looker.c
+src/tbox/network/dns/cache.c
+src/tbox/network/dns/server.c
+src/tbox/network/cookies.c
+src/tbox/network/http.c
+src/tbox/network/hwaddr.c
+src/tbox/network/impl/http/method.c
+src/tbox/network/impl/http/option.c
+src/tbox/network/impl/http/status.c
+src/tbox/network/impl/http/date.c
+src/tbox/network/network.c
+src/tbox/network/ipaddr.c
+src/tbox/network/url.c
+src/tbox/asio/aico.c
+src/tbox/asio/aicp.c
+src/tbox/asio/http.c
+src/tbox/asio/dns.c
+src/tbox/stream/async_stream.c
+src/tbox/stream/impl/async_stream/prefix.c
+src/tbox/stream/impl/async_stream/http.c
+src/tbox/stream/impl/async_stream/sock.c
+src/tbox/stream/impl/async_stream/filter.c
+src/tbox/stream/impl/async_stream/file.c
+src/tbox/stream/impl/async_stream/data.c
+src/tbox/stream/async_transfer.c
+src/tbox/stream/transfer_pool.c
+src/tbox/platform/aicp.c
+src/tbox/asio/ssl.c
+src/tbox/platform/thread_pool.c
+src/tbox/platform/thread_store.c
+src/tbox/platform/thread.c
+src/tbox/platform/event.c
+src/tbox/platform/mutex.c
+src/tbox/platform/semaphore.c
+src/tbox/platform/timer.c
+src/tbox/platform/ltimer.c
+src/tbox/object/number.c
+src/tbox/object/boolean.c
+src/tbox/object/dictionary.c
+src/tbox/object/impl/reader/bplist.c
+src/tbox/object/impl/reader/bin.c
+src/tbox/object/impl/reader/reader.c
+src/tbox/object/impl/reader/json.c
+src/tbox/object/impl/writer/bplist.c
+src/tbox/object/impl/writer/bin.c
+src/tbox/object/impl/writer/json.c
+src/tbox/object/impl/writer/writer.c
+src/tbox/object/array.c
+src/tbox/object/null.c
+src/tbox/object/string.c
+src/tbox/object/data.c
+src/tbox/object/date.c
+src/tbox/object/object.c
+src/tbox/utils/option.c
+src/tbox/object/impl/reader/xml.c
+src/tbox/object/impl/reader/xplist.c
+src/tbox/object/impl/writer/xml.c
+src/tbox/object/impl/writer/xplist.c
+src/tbox/charset/charset.c
+src/tbox/charset/utf32.c
+src/tbox/charset/ascii.c
+src/tbox/charset/utf16.c
+src/tbox/charset/utf8.c
+src/tbox/charset/gb2312.c
+src/tbox/charset/ucs2.c
+src/tbox/charset/ucs4.c
+src/tbox/charset/iso8859.c
+src/tbox/stream/impl/filter/charset.c
+src/tbox/zip/zip.c
+src/tbox/stream/impl/filter/zip.c
+src/tbox/zip/gzip.c
+src/tbox/zip/zlib.c
+src/tbox/zip/zlibraw.c
+src/tbox/database/value.c
+src/tbox/database/sql.c
+src/tbox/database/impl/sqlite3.c
+src/tbox/network/impl/ssl/polarssl.c
+]==];
+
+local file_list_demo = [==[
+src/demo/demo.c
+src/demo/libc/stdlib.c
+src/demo/libc/wchar.c
+src/demo/libc/time.c
+src/demo/libc/string.c
+src/demo/libm/integer.c
+src/demo/math/random.c
+src/demo/utils/crc.c
+src/demo/utils/sha.c
+src/demo/utils/adler32.c
+src/demo/utils/base64.c
+src/demo/utils/dump.c
+src/demo/utils/base32.c
+src/demo/utils/bits.c
+src/demo/utils/md5.c
+src/demo/utils/url.c
+src/demo/other/test.c
+src/demo/string/static_string.c
+src/demo/string/string.c
+src/demo/memory/memops.c
+src/demo/memory/default_allocator.c
+src/demo/memory/queue_buffer.c
+src/demo/memory/static_buffer.c
+src/demo/memory/large_pool.c
+src/demo/memory/string_pool.c
+src/demo/memory/impl/static_fixed_pool.c
+src/demo/memory/fixed_pool.c
+src/demo/memory/check.c
+src/demo/memory/small_allocator.c
+src/demo/memory/buffer.c
+src/demo/platform/barrier.c
+src/demo/platform/directory.c
+src/demo/platform/path.c
+src/demo/platform/utils.c
+src/demo/platform/atomic64.c
+src/demo/platform/processor.c
+src/demo/platform/process.c
+src/demo/platform/backtrace.c
+src/demo/platform/atomic.c
+src/demo/platform/hostname.c
+src/demo/platform/cache_time.c
+src/demo/platform/file.c
+src/demo/platform/ifaddrs.c
+src/demo/platform/environment.c
+src/demo/container/list_entry.c
+src/demo/container/heap.c
+src/demo/container/vector.c
+src/demo/container/bloom_filter.c
+src/demo/container/single_list.c
+src/demo/container/queue.c
+src/demo/container/stack.c
+src/demo/container/hash_map.c
+src/demo/container/list.c
+src/demo/container/single_list_entry.c
+src/demo/container/circle_queue.c
+src/demo/container/hash_set.c
+src/demo/algorithm/sort.c
+src/demo/algorithm/find.c
+src/demo/stream/stream.c
+src/demo/stream/stream/charset.c
+src/demo/stream/stream/zip.c
+src/demo/stream/stream/cache.c
+src/demo/stream/stream/null.c
+src/demo/math/fixed.c
+src/demo/libm/float.c
+src/demo/libm/double.c
+src/demo/platform/thread_pool.c
+src/demo/platform/thread_store.c
+src/demo/platform/event.c
+src/demo/platform/lock.c
+src/demo/platform/timer.c
+src/demo/platform/ltimer.c
+src/demo/platform/exception.c
+src/demo/platform/semaphore.c
+src/demo/xml/document.c
+src/demo/xml/reader.c
+src/demo/xml/writer.c
+src/demo/regex/regex.c
+src/demo/network/ipv4.c
+src/demo/network/ipv6.c
+src/demo/network/cookies.c
+src/demo/network/http.c
+src/demo/network/hwaddr.c
+src/demo/network/impl/date.c
+src/demo/network/ipaddr.c
+src/demo/network/spider.c
+src/demo/network/whois.c
+src/demo/network/url.c
+src/demo/network/dns.c
+src/demo/asio/aicpc.c
+src/demo/asio/http.c
+src/demo/asio/aiopd.c
+src/demo/asio/httpd.c
+src/demo/asio/aicpd.c
+src/demo/asio/dns.c
+src/demo/asio/aiopc.c
+src/demo/stream/async_stream.c
+src/demo/stream/transfer_pool.c
+src/demo/stream/async_transfer.c
+src/demo/stream/async_stream/charset.c
+src/demo/stream/async_stream/zip.c
+src/demo/stream/async_stream/cache.c
+src/demo/stream/async_stream/null.c
+src/demo/utils/option.c
+src/demo/object/bplist.c
+src/demo/object/xplist.c
+src/demo/object/bin.c
+src/demo/object/jcat.c
+src/demo/object/xml.c
+src/demo/object/dump.c
+src/demo/object/json.c
+src/demo/other/charset.c
+src/demo/database/sql.c
+]==];
+
+local cflags_lib = "-c -Wno-error=deprecated-declarations -fno-strict-aliasing -g -Wall -Werror -O0 -std=c99 -Ibuild -Ibuild/tbox -D_GNU_SOURCE=1 -D_REENTRANT -D__tb_prefix__=\"tbox\" -Ipkg/zlib.pkg/inc/linux -Ipkg/zlib.pkg/inc -Ipkg/sqlite3.pkg/inc/linux -Ipkg/sqlite3.pkg/inc -Ipkg/openssl.pkg/inc/linux -Ipkg/openssl.pkg/inc -Ipkg/polarssl.pkg/inc/linux -Ipkg/polarssl.pkg/inc -Ipkg/pcre2.pkg/inc/linux -Ipkg/pcre2.pkg/inc -DPCRE2_CODE_UNIT_WIDTH=8 -Ipkg/pcre.pkg/inc/linux -Ipkg/pcre.pkg/inc -m64 -I/usr/include -I/usr/local/include"
+local cflags_demo = "-c -Wno-error=deprecated-declarations -fno-strict-aliasing -g -Wall -Werror -O0 -std=c99 -Ibuild -Ibuild/tbox -D_GNU_SOURCE=1 -D_REENTRANT -D__tb_prefix__=\"demo\" -Ipkg/zlib.pkg/inc/linux -Ipkg/zlib.pkg/inc -Ipkg/sqlite3.pkg/inc/linux -Ipkg/sqlite3.pkg/inc -Ipkg/pcre.pkg/inc/linux -Ipkg/pcre.pkg/inc -Ipkg/pcre2.pkg/inc/linux -Ipkg/pcre2.pkg/inc -DPCRE2_CODE_UNIT_WIDTH=8 -Ipkg/openssl.pkg/inc/linux -Ipkg/openssl.pkg/inc -Ipkg/polarssl.pkg/inc/linux -Ipkg/polarssl.pkg/inc -m64 -I/usr/include -I/usr/local/include"
+
+//libclangParse2sqlite("c2sqlite.db", "c2sqlite.c", "-I.", "-I/home/mingo/local/clang-3.6/include");
+
+function parseFileList(file_list, cflags)
+{
+	local call_args = cflags.split(' ');
+	call_args.insert(0, "");
+	call_args.insert(0, "tbox-clang.db");
+	call_args.insert(0, getroottable());
+
+	foreach(fn in file_list.split('\n'))
+	{
+		if(fn && fn.len())
+		{
+			print("Now parsing:", fn);
+			call_args[2] = fn;
+			libclangParse2sqlite.acall(call_args);
+		}
+	}
+}
+
+parseFileList(file_list_lib, cflags_lib);
+parseFileList(file_list_demo, cflags_demo);
+

+ 320 - 0
SquiLu/samples/libclang.nut

@@ -0,0 +1,320 @@
+function libclangParse2sqlite(dbname, source_file_name, ...)
+{
+	auto db = SQLite3(dbname);
+
+	db.exec_dml([==[
+		CREATE TABLE IF NOT EXISTS function_file (
+			id INTEGER PRIMARY KEY,
+			file_name VARCHAR UNIQUE NOT NULL
+		);
+		]==]);
+
+	db.exec_dml([==[
+		CREATE TABLE IF NOT EXISTS function_declaration (
+			id INTEGER PRIMARY KEY,
+			name VARCHAR NOT NULL,
+			ftype VARCHAR NOT NULL,
+			return_type VARCHAR NOT NULL,
+			linkage_type INTEGER,
+			file_id INTEGER NOT NULL REFERENCES function_file(id),
+			line INTEGER,
+			col INTEGER,
+			UNIQUE(file_id, name, line, col)
+		);
+		]==]);
+
+	db.exec_dml([==[
+		CREATE INDEX IF NOT EXISTS function_declaration_name_file_idx ON function_declaration(name, file_id);
+		]==]);
+
+	db.exec_dml([==[
+		CREATE TABLE IF NOT EXISTS function_param (
+			id INTEGER PRIMARY KEY,
+			function_id INTEGER NOT NULL REFERENCES function_declaration(id),
+			name VARCHAR,
+			type VARCHAR NOT NULL,
+			kind_id INTEGER,
+			UNIQUE(function_id, name)
+		);
+		]==]);
+
+	db.exec_dml([==[
+		CREATE TABLE IF NOT EXISTS function_calling (
+			id INTEGER PRIMARY KEY,
+			caller_id INTEGER NOT NULL REFERENCES function_declaration(id),
+			callee_id INTEGER NOT NULL REFERENCES function_declaration(id),
+			file_id INTEGER NOT NULL REFERENCES function_file(id),
+			line INTEGER,
+			col INTEGER,
+			UNIQUE(file_id, caller_id, callee_id, line, col)
+		);
+		]==]);
+
+	db.exec_dml([==[
+		CREATE INDEX IF NOT EXISTS function_calling_caller_idx ON function_calling(caller_id);
+		CREATE INDEX IF NOT EXISTS function_calling_callee_idx ON function_calling(callee_id);
+		]==]);
+
+	auto stmt_get_file_id = db.prepare("SELECT id  FROM function_file  WHERE file_name = ?;");
+	auto stmt_get_func_decl_id = db.prepare("SELECT id  FROM function_declaration  WHERE file_id = ? AND name=? AND line=? AND col=?;");
+	auto stmt_insert_file = db.prepare("INSERT OR IGNORE INTO function_file (file_name) VALUES (?);");
+	auto stmt_insert_function = db.prepare("INSERT OR IGNORE INTO function_declaration (name, ftype, return_type, linkage_type, file_id, line, col) VALUES (?, ?, ?, ?, ?, ?, ?);");
+	auto stmt_insert_call = db.prepare("INSERT OR IGNORE INTO function_calling (caller_id, callee_id, file_id, line, col) VALUES (?, ?, ?, ?, ?);");
+	auto stmt_insert_param = db.prepare("INSERT OR IGNORE INTO function_param (function_id, name, type, kind_id) VALUES (?, ?, ?, ?);");
+
+	local function cleanBackwardPath(path)
+	{
+		while(path.find("/../") > 0)
+		{
+			path = path.gsub("/[^/.]+/%.%.", "");
+		}
+		return path;
+	}
+
+	local function add_funcfile(file_name)
+	{
+		local id = null;
+		file_name = cleanBackwardPath(file_name);
+		
+		stmt_get_file_id.bind(1, file_name);
+
+		if (stmt_get_file_id.next_row()) {
+			id = stmt_get_file_id.col(0);
+		}
+		stmt_get_file_id.reset();
+		if(id) {
+			return id;
+		}
+
+		stmt_insert_file.bind(1, file_name);
+
+		local rc = stmt_insert_file.step();
+		if (rc != db.SQLITE_DONE) {
+			print("Can't insert: %d : %s\n", rc, db.errmsg());
+			os.exit(-1);
+		}
+
+		stmt_insert_file.reset();
+		return db.last_row_id();
+	}
+
+	local function add_funcdecl(file_name, line, col, func_name, func_type, return_type, linkage_type)
+	{
+		local file_id = add_funcfile(file_name);
+		stmt_insert_function.bind(1, func_name);
+		stmt_insert_function.bind(2, func_type);
+		stmt_insert_function.bind(3, return_type);
+		stmt_insert_function.bind(4, linkage_type);
+		stmt_insert_function.bind(5, file_id);
+		stmt_insert_function.bind(6, line);
+		stmt_insert_function.bind(7, col);
+
+		local rc = stmt_insert_function.step();
+		if (rc != db.SQLITE_DONE) {
+			print("Can't insert: %d : %s\n", rc, db.errmsg());
+			os.exit(-1);
+		}
+
+		stmt_insert_function.reset();
+	}
+
+	local function get_func_decl_id(file_id, func_name, line, col)
+	{
+		local id = null;
+		stmt_get_func_decl_id.bind(1, file_id);
+		stmt_get_func_decl_id.bind(2, func_name);
+		stmt_get_func_decl_id.bind(3, line);
+		stmt_get_func_decl_id.bind(4, col);
+
+		if (stmt_get_func_decl_id.next_row()) {
+			id = stmt_get_func_decl_id.col(0);
+		}
+		stmt_get_func_decl_id.reset();
+		return id;
+	}
+
+	local function add_funcparam(file_name, line, col, func_name, param_name, param_type, type_kind)
+	{
+		local file_id = add_funcfile(file_name);
+		local func_id = get_func_decl_id(file_id, func_name, line, col);
+		stmt_insert_param.bind(1, func_id);
+		stmt_insert_param.bind(2, param_name);
+		stmt_insert_param.bind(3, param_type);
+		stmt_insert_param.bind(4, type_kind);
+
+		local rc = stmt_insert_param.step();
+		if (rc != db.SQLITE_DONE) {
+			print("Can't insert: %d : %s\n", rc, db.errmsg());
+			os.exit(-1);
+		}
+
+		stmt_insert_param.reset();
+	}
+
+	local function add_funccall(file_name, line, col, from_func, from_line, from_col, to_func_file, to_func_line, to_func_col, to_func)
+	{
+		local file_id = add_funcfile(file_name);
+		local from_func_id = get_func_decl_id(file_id, from_func, from_line, from_col);
+		
+		local to_file_id = add_funcfile(to_func_file);
+		local to_func_id = get_func_decl_id(to_file_id, to_func, to_func_line, to_func_col);
+		
+		stmt_insert_call.bind(1, from_func_id);
+		stmt_insert_call.bind(2, to_func_id);
+		stmt_insert_call.bind(3, file_id);
+		stmt_insert_call.bind(4, line);
+		stmt_insert_call.bind(5, col);
+
+		local rc = stmt_insert_call.step();
+		if (rc != db.SQLITE_DONE) {
+			print("Can't insert: %d : %s\n", rc, db.errmsg());
+			os.exit(-1);
+		}
+
+		stmt_insert_call.reset();
+	}
+
+	db.exec_dml("BEGIN;");
+
+	auto libclang = new LibClang();
+
+
+	local function libclangVisitor(...)
+	{
+		//print("Hello!");
+		//print(vargv.join("\t"));
+
+		//try
+		{
+			local vtype = vargv[0];
+			switch(vtype)
+			{
+				case "CallExpr":
+					//vtype, file_name, line, col, from_func, from_line, from_col, to_func_file, to_func_line, to_func_col, to_func
+					add_funccall(vargv[1], vargv[2], vargv[3], vargv[4], vargv[5], vargv[6], vargv[7], vargv[8], vargv[9], vargv[10]);
+				break;
+				case "FuncDecl":
+					//vtype, file_name, line, col, func_name, func_type, return_type, linkage_type
+					add_funcdecl(vargv[1], vargv[2], vargv[3], vargv[4], vargv[5], vargv[6], vargv[7]);
+				break;
+				case "FuncParam":
+					//vtype, file_name, line, col, func_name, param_name, param_type, type_kind
+					add_funcparam(vargv[1], vargv[2], vargv[3], vargv[4], vargv[5], vargv[6], vargv[7]);
+				break;
+			}
+		}
+		//catch(e)
+		{
+			//print(e);
+		}
+	}
+
+	//libclang.parseTranslationUnit(libclangVisitor, source_file_name, "-I.", "-I/home/mingo/local/clang-3.6/include");
+	auto call_args = [libclang, libclangVisitor, source_file_name];
+	foreach(p in vargv)
+	{
+		call_args.append(p);
+	}
+	libclang.parseTranslationUnit.acall(call_args);
+
+	libclang.close();
+
+	db.exec_dml([==[
+	CREATE VIEW IF NOT EXISTS "function_calling_list_view" AS
+	SELECT
+		a."id",
+		d.name AS caller,
+		c.name AS callee,
+		b.file_name,
+		a."line",
+		a."col",
+		a."caller_id",
+		a."callee_id",
+		a."file_id"
+	FROM "function_calling" AS a
+	LEFT JOIN "function_file" AS b ON a."file_id" = b."id"
+	LEFT JOIN "function_declaration" AS c ON a."callee_id" = c."id"
+	LEFT JOIN "function_declaration" AS d ON a."caller_id" = d."id";
+
+	CREATE VIEW IF NOT EXISTS "function_declaration_list_view" AS
+	SELECT
+		a."id",
+		a."name",
+		a."ftype",
+		a."return_type",
+		a."linkage_type",
+		b.file_name,
+		a."line",
+		a."col",
+		a."file_id"
+	FROM "function_declaration" AS a
+	LEFT JOIN "function_file" AS b ON a."file_id" = b."id";
+
+	CREATE VIEW IF NOT EXISTS "function_param_list_view" AS
+	SELECT
+		a."id",
+		b."name" AS function_name,
+		a."name" AS param_name,
+		a."type",
+		a."kind_id",
+		a."function_id"
+	FROM "function_param" AS a
+	LEFT JOIN "function_declaration" AS b ON a."function_id" = b."id";
+
+	CREATE VIEW IF NOT EXISTS function_calling_count_view AS
+	SELECT b.id, b.name, COUNT(*) AS calls, c.file_name
+	FROM function_calling a
+		LEFT JOIN function_declaration b
+			ON a.callee_id = b.id
+		LEFT JOIN function_file c
+			ON b.file_id = c.id
+	GROUP BY a.callee_id
+	ORDER BY 3 DESC, 2 ASC;
+	]==]);
+
+/*
+	db.exec_dml([==[
+	CREATE VIEW IF NOT EXISTS functions_of_interest_view AS
+	WITH
+	source_file AS(
+		SELECT id FROM function_file WHERE file_name = 'SOURCE_FILE_NAME'
+	)
+	SELECT caller_id as fid FROM function_calling a, source_file as b WHERE a.file_id = b.id
+	UNION
+	SELECT callee_id as fid FROM function_calling a, source_file as b WHERE a.file_id = b.id
+	UNION
+	SELECT a.id as fid FROM function_declaration a, source_file as b WHERE a.file_id = b.id;
+	]==].gsub("SOURCE_FILE_NAME", source_file_name));
+
+	db.exec_dml([==[
+	-- remove function parameter not in use
+	DELETE FROM function_param 
+	WHERE function_id NOT IN(
+		SELECT fid FROM functions_of_interest_view
+	);
+
+	-- remove functio_declaration not in use
+	DELETE FROM function_declaration 
+	WHERE id NOT IN(
+		SELECT fid FROM functions_of_interest_view
+	);
+
+	-- remove function_file not in use
+	DELETE FROM function_file 
+	WHERE id NOT IN(
+		SELECT DISTINCT file_id FROM function_declaration
+	);
+	]==]);
+*/
+	db.exec_dml("COMMIT;");
+
+	stmt_insert_param.finalize();
+	stmt_insert_call.finalize();
+	stmt_insert_function.finalize();
+	stmt_get_func_decl_id.finalize();
+	stmt_insert_file.finalize();
+	stmt_get_file_id.finalize();
+	db.close();
+}
+
+//libclangParse2sqlite("c2sqlite.db", "c2sqlite.c", "-I.", "-I/home/mingo/local/clang-3.6/include");

+ 1 - 0
SquiLu/samples/run-clang-parser

@@ -0,0 +1 @@
+clang-3.6-env squilu clang-parse.nut #> clang-parse.log 2>&1