1 ! Copyright (C) 2022 Doug Coleman.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types alien.data alien.enums
4 alien.strings ascii byte-arrays classes.struct combinators
5 combinators.smart discord io io.backend io.encodings.utf8
6 io.files.info kernel layouts libc libclang.ffi make math
7 sequences splitting strings ;
15 : <malloced> ( len -- malloced )
16 malloced malloc-struct
17 over 1 + <byte-array> malloc-byte-array >>byte-array
21 : append-oom? ( malloced string -- ? )
22 [ [ len>> ] [ offset>> ] bi - ]
25 : realloc-malloced ( malloced -- malloced' )
27 '[ [ _ 1 + realloc ] change-byte-array ] keep >>len ;
29 : append-malloced ( malloced string -- )
31 [ [ realloc-malloced ] dip append-malloced ] [
34 [ offset>> ] [ byte-array>> ] bi <displaced-alien>
35 ] dip [ utf8 string>alien ] [ length ] bi memcpy
37 '[ _ length + ] change-offset drop
41 : malloced>string ( malloced -- string )
42 [ byte-array>> utf8 alien>string ] [ free ] bi ;
44 : CXCursor>factor ( cursor -- string )
45 dup clang_getCursorKind {
46 { CXCursor_FunctionDecl [ drop f ] }
47 { CXType_Pointer [ drop f ] }
48 { CXType_Invalid [ drop f ] }
52 : clang-get-cstring ( CXString -- string )
53 clang_getCString [ utf8 alien>string ] [ clang_disposeString ] bi ;
55 : remove-const ( strinng -- string' )
56 "const" split1 [ [ blank? ] trim ] bi@ " " glue [ blank? ] trim ;
58 : cursor-type ( cursor -- string )
59 ! [ "cursor display name" g... clang_getCursorDisplayName g... ] keep
61 clang_getTypeSpelling clang-get-cstring ! "type spelling c string" g... dup g...
64 : cursor-name ( cursor -- string )
65 clang_getCursorSpelling clang-get-cstring ;
67 : arg-info ( cursor -- string )
68 [ cursor-type ] [ cursor-name [ "dummy" ] when-empty ] bi " " glue ;
70 : cursor>args ( CXCursor -- args/f )
71 dup clang_Cursor_getNumArguments dup -1 = [
75 clang_Cursor_getArgument
79 : cxprimitive-type>factor ( CXType -- string )
81 { CXType_Bool [ "bool" ] }
82 { CXType_Char_S [ "char" ] }
83 { CXType_Char_U [ "uchar" ] }
84 { CXType_SChar [ "char" ] }
85 { CXType_UChar [ "uchar" ] }
86 { CXType_Short [ "short" ] }
87 { CXType_UShort [ "ushort" ] }
88 { CXType_Int [ "int" ] }
89 { CXType_UInt [ "uint" ] }
90 { CXType_Long [ "long" ] }
91 { CXType_ULong [ "ulong" ] }
92 { CXType_LongLong [ "longlong" ] }
93 { CXType_ULongLong [ "ulonglong" ] }
94 { CXType_Float [ "float" ] }
95 { CXType_Double [ "double" ] }
96 { CXType_Void [ "void" ] }
100 : cxreturn-type>factor ( CXType -- string )
102 { [ dup kind>> CXType_Pointer = ] [
103 clang_getPointeeType cxreturn-type>factor "*" append
105 { [ dup kind>> CXType_Elaborated = ] [
106 clang_getCanonicalType cxreturn-type>factor
108 { [ dup kind>> CXType_Record = ] [
109 clang_getTypeDeclaration clang_getCursorSpelling clang-get-cstring
111 [ kind>> cxprimitive-type>factor ]
114 : cursor>args-info ( CXCursor -- args-info )
115 cursor>args [ arg-info ] map ", " join ;
117 : function>string ( CXCursor -- string )
120 [ drop "FUNCTION: " ]
121 [ clang_getCursorResultType cxreturn-type>factor ]
123 [ clang_getCursorSpelling clang-get-cstring ]
125 [ cursor>args-info dup empty? ")\n" " )\n" ? ]
127 ] "" append-outputs-as ;
129 : typedef>string ( CXCursor -- string )
130 [ clang_getTypedefDeclUnderlyingType cxreturn-type>factor ]
131 [ clang_getCursorSpelling clang-get-cstring ] bi
135 " " glue "TYPEDEF: " "\n" surround
138 : struct>string ( CXCursor -- string )
139 clang_getCursorSpelling clang-get-cstring "STRUCT: " "\n" surround ;
141 : cursor-visitor ( -- callback )
144 malloced memory>struct
145 swap dup clang_getCursorKind
147 { CXCursor_FunctionDecl [ function>string append-malloced CXChildVisit_Continue ] }
148 { CXCursor_TypedefDecl [ typedef>string append-malloced CXChildVisit_Continue ] }
149 { CXCursor_StructDecl [ struct>string append-malloced CXChildVisit_Continue ] }
150 [ dup g... gflush 3drop CXChildVisit_Recurse ]
154 : with-clang-index ( quot: ( index -- string ) -- )
155 [ 0 0 clang_createIndex ] dip keep clang_disposeIndex ; inline
157 : with-clang-translation-unit ( idx source-file command-line-args nargs unsaved-files nunsaved-files options quot: ( tu -- string ) -- )
158 [ enum>number clang_parseTranslationUnit ] dip
159 keep clang_disposeTranslationUnit ; inline
161 : with-clang-default-translation-unit ( path quot: ( path tu -- string ) -- )
163 _ f 0 f 0 CXTranslationUnit_None [
165 ] with-clang-translation-unit
166 ] with-clang-index ; inline
168 : with-clang-cursor ( path quot: ( path tu cursor -- string ) -- )
170 _ f 0 f 0 CXTranslationUnit_None [
171 [ _ ] dip dup clang_getTranslationUnitCursor @
172 ] with-clang-translation-unit
173 ] with-clang-index ; inline
175 : clang-get-file-max-range ( CXTranslationUnit path -- CXSourceRange )
176 [ dupd clang_getFile 0 clang_getLocationForOffset ]
177 [ dupd [ clang_getFile ] [ nip file-info size>> ] 2bi clang_getLocationForOffset ] 2bi
180 : parse-c-defines ( path -- string )
184 dupd clang-get-file-max-range ! tu CXRange
187 [ clang_tokenize ] 2keep
189 [ uint deref <iota> ] bi*
192 cell-bits 8 /i * swap <displaced-alien>
195 ] with-clang-default-translation-unit ;
197 : parse-c-exports ( path -- string )
199 nip cursor-visitor rot file-info size>> 2 * <malloced>
200 [ clang_visitChildren drop ] keep malloced>string
201 ] with-clang-cursor ;
203 : parse-include ( path -- string )
206 ! [ parse-c-defines ]
210 ! "/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/php/ext/sqlite3/libsqlite/sqlite3.h" parse-include