sq_libclang.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. //#ifdef WITH_LIBCLANG
  2. #include "squirrel.h"
  3. #include <clang-c/Index.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "sqstdblobimpl.h"
  8. #include "dynamic_library.h"
  9. /*SquiLu
  10. local libclang_functions = [
  11. ["CXCodeCompleteResults *", "clang_codeCompleteAt", @"CXTranslationUnit TU,
  12. const char *complete_filename,
  13. unsigned complete_line,
  14. unsigned complete_column,
  15. struct CXUnsavedFile *unsaved_files,
  16. unsigned num_unsaved_files,
  17. unsigned options"],
  18. ["CXDiagnostic", "clang_codeCompleteGetDiagnostic", @"CXCodeCompleteResults *Results,
  19. unsigned Index"],
  20. ["unsigned", "clang_codeCompleteGetNumDiagnostics", "CXCodeCompleteResults *Results"],
  21. ["CXIndex", "clang_createIndex", @"int excludeDeclarationsFromPCH,
  22. int displayDiagnostics"],
  23. ["CXTranslationUnit", "clang_createTranslationUnit", @"CXIndex CIdx,
  24. const char *source_filename,
  25. int num_clang_command_line_args,
  26. const char * const *clang_command_line_args,
  27. unsigned num_unsaved_files,
  28. struct CXUnsavedFile *unsaved_files"],
  29. ["CXCursor", "clang_Cursor_getArgument", "CXCursor C, unsigned i"],
  30. ["int", "clang_Cursor_getNumArguments", "CXCursor C"],
  31. ["int", "clang_Cursor_isNull", "CXCursor cursor"],
  32. ["unsigned", "clang_CXXMethod_isStatic", "CXCursor C"],
  33. ["unsigned", "clang_CXXMethod_isVirtual", "CXCursor C"],
  34. ["unsigned", "clang_defaultCodeCompleteOptions", "void"],
  35. ["unsigned", "clang_defaultDiagnosticDisplayOptions", "void"],
  36. ["void", "clang_disposeCodeCompleteResults", "CXCodeCompleteResults *Results"],
  37. ["void", "clang_disposeDiagnostic", "CXDiagnostic Diagnostic"],
  38. ["void", "clang_disposeIndex", "CXIndex index"],
  39. ["void", "clang_disposeString", "CXString *str"],
  40. ["unsigned", "clang_equalCursors", "CXCursor, CXCursor"],
  41. ["unsigned", "clang_equalTypes", "CXType A, CXType B"],
  42. ["CXString", "clang_formatDiagnostic", @"CXDiagnostic Diagnostic,
  43. unsigned Options"],
  44. ["CXType", "clang_getCanonicalType", "CXType T"],
  45. ["CXString", "clang_getCompletionAnnotation", @"CXCompletionString completion_string,
  46. unsigned annotation_number"],
  47. ["enum CXCompletionChunkKind", "clang_getCompletionChunkKind", @"CXCompletionString completion_string,
  48. unsigned chunk_number"],
  49. ["CXString", "clang_getCompletionChunkText", @"CXCompletionString completion_string,
  50. unsigned chunk_number"],
  51. ["unsigned", "clang_getCompletionNumAnnotations", "CXCompletionString completion_string"],
  52. ["unsigned", "clang_getCompletionPriority", "CXCompletionString completion_string"],
  53. ["void", "clang_getCString", "PGconn *conn, Oid lobjId"],
  54. ["CXCursor", "clang_getCursorDefinition", "CXCursor"],
  55. ["void", "clang_getCursorDisplayName", "PGconn *conn, int fd"],
  56. ["CXSourceRange", "clang_getCursorExtent", "CXCursor"],
  57. ["CXString", "clang_getCursorKind", "enum CXCursorKind Kind"],
  58. ["CXCursor", "clang_getCursorReferenced", "CXCursor"],
  59. ["CXType", "clang_getCursorResultType", "CXCursor C"],
  60. ["CXCursor", "clang_getCursorSemanticParent", "CXCursor"],
  61. ["CXString", "clang_getCursorSpelling", "CXCursor"],
  62. ["CXType", "clang_getCursorType", "CXCursor"],
  63. ["void", "clang_getCursorUSR", "const char *conninfo"],
  64. ["enum CX_CXXAccessSpecifier", "clang_getCXXAccessSpecifier", "CXCursor"],
  65. ["CXString", "clang_getDiagnosticCategoryText", "CXDiagnostic"],
  66. ["CXDiagnostic", "clang_getDiagnostic", @"CXTranslationUnit Unit,
  67. unsigned Index"],
  68. ["CXString", "clang_getFileName", "CXFile SFile"],
  69. ["time_t", "clang_getFileTime", "CXFile SFile"],
  70. ["unsigned", "clang_getNumCompletionChunks", "CXCompletionString completion_string"],
  71. ["unsigned", "clang_getNumDiagnostics", "CXTranslationUnit Unit"],
  72. ["CXType", "clang_getPointeeType", "CXType"],
  73. ["CXSourceLocation", "clang_getRangeEnd", "CXSourceRange range"],
  74. ["CXSourceLocation", "clang_getRangeStart", "CXSourceRange range"],
  75. ["void", "clang_getSpellingLocation", @"CXSourceLocation location,
  76. CXFile *file,
  77. unsigned *line,
  78. unsigned *column,
  79. unsigned *offset"],
  80. ["CXCursor", "clang_getTranslationUnitCursor", "CXTranslationUnit"],
  81. ["CXCursor", "clang_getTypeDeclaration", "CXType"],
  82. ["CXString", "clang_getTypeKindSpelling", "enum CXTypeKind K"],
  83. ["unsigned", "clang_isPODType", "CXType"],
  84. ["CXTranslationUnit", "clang_parseTranslationUnit", @"CXIndex CIdx,
  85. const char *source_filename,
  86. const char *const *command_line_args,
  87. int num_command_line_args,
  88. struct CXUnsavedFile *unsaved_files,
  89. unsigned num_unsaved_files,
  90. unsigned options"],
  91. ["unsigned", "clang_visitChildren", @"CXCursor parent,
  92. CXCursorVisitor visitor,
  93. CXClientData client_data"],
  94. //next entry should be the last one
  95. //to make valid the test made on load_libclang function
  96. ["void", "clang_getCursorExtent", "const char *conninfo"],
  97. ];
  98. function write_libclang_functions_declaration(){
  99. foreach(k,v in libclang_functions) {
  100. putsnl("typedef " + v[0] + " (*" + v[1] + "_t)(" + v[2] + ");");
  101. putsnl("static " + v[1] + "_t dl" + v[1] + " = 0;");
  102. }
  103. }
  104. function write_libclang_functions_load(){
  105. foreach(k,v in libclang_functions){
  106. putsnl("dl" + v[1] + " = (" + v[1] + "_t) libclang.dlsym(\"" + v[1] + "\");");
  107. putsnl("if(!dl" + v[1] + ") return false;");
  108. }
  109. }
  110. SquiLu*/
  111. static DynamicLibrary libclang;
  112. //@write_libclang_functions_declaration();
  113. // generated-code:begin
  114. typedef CXCodeCompleteResults * (*clang_codeCompleteAt_t)(CXTranslationUnit TU,
  115. const char *complete_filename,
  116. unsigned complete_line,
  117. unsigned complete_column,
  118. struct CXUnsavedFile *unsaved_files,
  119. unsigned num_unsaved_files,
  120. unsigned options);
  121. static clang_codeCompleteAt_t dlclang_codeCompleteAt = 0;
  122. typedef CXDiagnostic (*clang_codeCompleteGetDiagnostic_t)(CXCodeCompleteResults *Results,
  123. unsigned Index);
  124. static clang_codeCompleteGetDiagnostic_t dlclang_codeCompleteGetDiagnostic = 0;
  125. typedef unsigned (*clang_codeCompleteGetNumDiagnostics_t)(CXCodeCompleteResults *Results);
  126. static clang_codeCompleteGetNumDiagnostics_t dlclang_codeCompleteGetNumDiagnostics = 0;
  127. typedef CXIndex (*clang_createIndex_t)(int excludeDeclarationsFromPCH,
  128. int displayDiagnostics);
  129. static clang_createIndex_t dlclang_createIndex = 0;
  130. typedef CXTranslationUnit (*clang_createTranslationUnit_t)(CXIndex CIdx,
  131. const char *source_filename,
  132. int num_clang_command_line_args,
  133. const char * const *clang_command_line_args,
  134. unsigned num_unsaved_files,
  135. struct CXUnsavedFile *unsaved_files);
  136. static clang_createTranslationUnit_t dlclang_createTranslationUnit = 0;
  137. typedef CXCursor (*clang_Cursor_getArgument_t)(CXCursor C, unsigned i);
  138. static clang_Cursor_getArgument_t dlclang_Cursor_getArgument = 0;
  139. typedef int (*clang_Cursor_getNumArguments_t)(CXCursor C);
  140. static clang_Cursor_getNumArguments_t dlclang_Cursor_getNumArguments = 0;
  141. typedef int (*clang_Cursor_isNull_t)(CXCursor cursor);
  142. static clang_Cursor_isNull_t dlclang_Cursor_isNull = 0;
  143. typedef unsigned (*clang_CXXMethod_isStatic_t)(CXCursor C);
  144. static clang_CXXMethod_isStatic_t dlclang_CXXMethod_isStatic = 0;
  145. typedef unsigned (*clang_CXXMethod_isVirtual_t)(CXCursor C);
  146. static clang_CXXMethod_isVirtual_t dlclang_CXXMethod_isVirtual = 0;
  147. typedef unsigned (*clang_defaultCodeCompleteOptions_t)(void);
  148. static clang_defaultCodeCompleteOptions_t dlclang_defaultCodeCompleteOptions = 0;
  149. typedef unsigned (*clang_defaultDiagnosticDisplayOptions_t)(void);
  150. static clang_defaultDiagnosticDisplayOptions_t dlclang_defaultDiagnosticDisplayOptions = 0;
  151. typedef void (*clang_disposeCodeCompleteResults_t)(CXCodeCompleteResults *Results);
  152. static clang_disposeCodeCompleteResults_t dlclang_disposeCodeCompleteResults = 0;
  153. typedef void (*clang_disposeDiagnostic_t)(CXDiagnostic Diagnostic);
  154. static clang_disposeDiagnostic_t dlclang_disposeDiagnostic = 0;
  155. typedef void (*clang_disposeIndex_t)(CXIndex index);
  156. static clang_disposeIndex_t dlclang_disposeIndex = 0;
  157. typedef void (*clang_disposeString_t)(CXString *str);
  158. static clang_disposeString_t dlclang_disposeString = 0;
  159. typedef unsigned (*clang_equalCursors_t)(CXCursor, CXCursor);
  160. static clang_equalCursors_t dlclang_equalCursors = 0;
  161. typedef unsigned (*clang_equalTypes_t)(CXType A, CXType B);
  162. static clang_equalTypes_t dlclang_equalTypes = 0;
  163. typedef CXString (*clang_formatDiagnostic_t)(CXDiagnostic Diagnostic,
  164. unsigned Options);
  165. static clang_formatDiagnostic_t dlclang_formatDiagnostic = 0;
  166. typedef CXType (*clang_getCanonicalType_t)(CXType T);
  167. static clang_getCanonicalType_t dlclang_getCanonicalType = 0;
  168. typedef CXString (*clang_getCompletionAnnotation_t)(CXCompletionString completion_string,
  169. unsigned annotation_number);
  170. static clang_getCompletionAnnotation_t dlclang_getCompletionAnnotation = 0;
  171. typedef enum CXCompletionChunkKind (*clang_getCompletionChunkKind_t)(CXCompletionString completion_string,
  172. unsigned chunk_number);
  173. static clang_getCompletionChunkKind_t dlclang_getCompletionChunkKind = 0;
  174. typedef CXString (*clang_getCompletionChunkText_t)(CXCompletionString completion_string,
  175. unsigned chunk_number);
  176. static clang_getCompletionChunkText_t dlclang_getCompletionChunkText = 0;
  177. typedef unsigned (*clang_getCompletionNumAnnotations_t)(CXCompletionString completion_string);
  178. static clang_getCompletionNumAnnotations_t dlclang_getCompletionNumAnnotations = 0;
  179. typedef unsigned (*clang_getCompletionPriority_t)(CXCompletionString completion_string);
  180. static clang_getCompletionPriority_t dlclang_getCompletionPriority = 0;
  181. typedef void (*clang_getCString_t)(PGconn *conn, Oid lobjId);
  182. static clang_getCString_t dlclang_getCString = 0;
  183. typedef CXCursor (*clang_getCursorDefinition_t)(CXCursor);
  184. static clang_getCursorDefinition_t dlclang_getCursorDefinition = 0;
  185. typedef void (*clang_getCursorDisplayName_t)(PGconn *conn, int fd);
  186. static clang_getCursorDisplayName_t dlclang_getCursorDisplayName = 0;
  187. typedef CXSourceRange (*clang_getCursorExtent_t)(CXCursor);
  188. static clang_getCursorExtent_t dlclang_getCursorExtent = 0;
  189. typedef CXString (*clang_getCursorKind_t)(enum CXCursorKind Kind);
  190. static clang_getCursorKind_t dlclang_getCursorKind = 0;
  191. typedef CXCursor (*clang_getCursorReferenced_t)(CXCursor);
  192. static clang_getCursorReferenced_t dlclang_getCursorReferenced = 0;
  193. typedef CXType (*clang_getCursorResultType_t)(CXCursor C);
  194. static clang_getCursorResultType_t dlclang_getCursorResultType = 0;
  195. typedef CXCursor (*clang_getCursorSemanticParent_t)(CXCursor);
  196. static clang_getCursorSemanticParent_t dlclang_getCursorSemanticParent = 0;
  197. typedef CXString (*clang_getCursorSpelling_t)(CXCursor);
  198. static clang_getCursorSpelling_t dlclang_getCursorSpelling = 0;
  199. typedef CXType (*clang_getCursorType_t)(CXCursor);
  200. static clang_getCursorType_t dlclang_getCursorType = 0;
  201. typedef void (*clang_getCursorUSR_t)(const char *conninfo);
  202. static clang_getCursorUSR_t dlclang_getCursorUSR = 0;
  203. typedef enum CX_CXXAccessSpecifier (*clang_getCXXAccessSpecifier_t)(CXCursor);
  204. static clang_getCXXAccessSpecifier_t dlclang_getCXXAccessSpecifier = 0;
  205. typedef CXString (*clang_getDiagnosticCategoryText_t)(CXDiagnostic);
  206. static clang_getDiagnosticCategoryText_t dlclang_getDiagnosticCategoryText = 0;
  207. typedef CXDiagnostic (*clang_getDiagnostic_t)(CXTranslationUnit Unit,
  208. unsigned Index);
  209. static clang_getDiagnostic_t dlclang_getDiagnostic = 0;
  210. typedef CXString (*clang_getFileName_t)(CXFile SFile);
  211. static clang_getFileName_t dlclang_getFileName = 0;
  212. typedef time_t (*clang_getFileTime_t)(CXFile SFile);
  213. static clang_getFileTime_t dlclang_getFileTime = 0;
  214. typedef unsigned (*clang_getNumCompletionChunks_t)(CXCompletionString completion_string);
  215. static clang_getNumCompletionChunks_t dlclang_getNumCompletionChunks = 0;
  216. typedef unsigned (*clang_getNumDiagnostics_t)(CXTranslationUnit Unit);
  217. static clang_getNumDiagnostics_t dlclang_getNumDiagnostics = 0;
  218. typedef CXType (*clang_getPointeeType_t)(CXType);
  219. static clang_getPointeeType_t dlclang_getPointeeType = 0;
  220. typedef CXSourceLocation (*clang_getRangeEnd_t)(CXSourceRange range);
  221. static clang_getRangeEnd_t dlclang_getRangeEnd = 0;
  222. typedef CXSourceLocation (*clang_getRangeStart_t)(CXSourceRange range);
  223. static clang_getRangeStart_t dlclang_getRangeStart = 0;
  224. typedef void (*clang_getSpellingLocation_t)(CXSourceLocation location,
  225. CXFile *file,
  226. unsigned *line,
  227. unsigned *column,
  228. unsigned *offset);
  229. static clang_getSpellingLocation_t dlclang_getSpellingLocation = 0;
  230. typedef CXCursor (*clang_getTranslationUnitCursor_t)(CXTranslationUnit);
  231. static clang_getTranslationUnitCursor_t dlclang_getTranslationUnitCursor = 0;
  232. typedef CXCursor (*clang_getTypeDeclaration_t)(CXType);
  233. static clang_getTypeDeclaration_t dlclang_getTypeDeclaration = 0;
  234. typedef CXString (*clang_getTypeKindSpelling_t)(enum CXTypeKind K);
  235. static clang_getTypeKindSpelling_t dlclang_getTypeKindSpelling = 0;
  236. typedef unsigned (*clang_isPODType_t)(CXType);
  237. static clang_isPODType_t dlclang_isPODType = 0;
  238. typedef CXTranslationUnit (*clang_parseTranslationUnit_t)(CXIndex CIdx,
  239. const char *source_filename,
  240. const char *const *command_line_args,
  241. int num_command_line_args,
  242. struct CXUnsavedFile *unsaved_files,
  243. unsigned num_unsaved_files,
  244. unsigned options);
  245. static clang_parseTranslationUnit_t dlclang_parseTranslationUnit = 0;
  246. typedef unsigned (*clang_visitChildren_t)(CXCursor parent,
  247. CXCursorVisitor visitor,
  248. CXClientData client_data);
  249. static clang_visitChildren_t dlclang_visitChildren = 0;
  250. typedef void (*clang_getCursorExtent_t)(const char *conninfo);
  251. static clang_getCursorExtent_t dlclang_getCursorExtent = 0;
  252. // generated-code:end
  253. #ifdef WIN32
  254. #define libclang_NAME "libclang.dll"
  255. #else
  256. #define libclang_NAME "libclang.so"
  257. #endif
  258. static bool load_libclang()
  259. {
  260. if(dlPQconnectdb) return true;
  261. if(libclang.open(libclang_NAME))
  262. {
  263. //@write_libclang_functions_load();
  264. // generated-code:begin
  265. dlclang_codeCompleteAt = (clang_codeCompleteAt_t) libclang.dlsym("clang_codeCompleteAt");
  266. if(!dlclang_codeCompleteAt) return false;
  267. dlclang_codeCompleteGetDiagnostic = (clang_codeCompleteGetDiagnostic_t) libclang.dlsym("clang_codeCompleteGetDiagnostic");
  268. if(!dlclang_codeCompleteGetDiagnostic) return false;
  269. dlclang_codeCompleteGetNumDiagnostics = (clang_codeCompleteGetNumDiagnostics_t) libclang.dlsym("clang_codeCompleteGetNumDiagnostics");
  270. if(!dlclang_codeCompleteGetNumDiagnostics) return false;
  271. dlclang_createIndex = (clang_createIndex_t) libclang.dlsym("clang_createIndex");
  272. if(!dlclang_createIndex) return false;
  273. dlclang_createTranslationUnit = (clang_createTranslationUnit_t) libclang.dlsym("clang_createTranslationUnit");
  274. if(!dlclang_createTranslationUnit) return false;
  275. dlclang_Cursor_getArgument = (clang_Cursor_getArgument_t) libclang.dlsym("clang_Cursor_getArgument");
  276. if(!dlclang_Cursor_getArgument) return false;
  277. dlclang_Cursor_getNumArguments = (clang_Cursor_getNumArguments_t) libclang.dlsym("clang_Cursor_getNumArguments");
  278. if(!dlclang_Cursor_getNumArguments) return false;
  279. dlclang_Cursor_isNull = (clang_Cursor_isNull_t) libclang.dlsym("clang_Cursor_isNull");
  280. if(!dlclang_Cursor_isNull) return false;
  281. dlclang_CXXMethod_isStatic = (clang_CXXMethod_isStatic_t) libclang.dlsym("clang_CXXMethod_isStatic");
  282. if(!dlclang_CXXMethod_isStatic) return false;
  283. dlclang_CXXMethod_isVirtual = (clang_CXXMethod_isVirtual_t) libclang.dlsym("clang_CXXMethod_isVirtual");
  284. if(!dlclang_CXXMethod_isVirtual) return false;
  285. dlclang_defaultCodeCompleteOptions = (clang_defaultCodeCompleteOptions_t) libclang.dlsym("clang_defaultCodeCompleteOptions");
  286. if(!dlclang_defaultCodeCompleteOptions) return false;
  287. dlclang_defaultDiagnosticDisplayOptions = (clang_defaultDiagnosticDisplayOptions_t) libclang.dlsym("clang_defaultDiagnosticDisplayOptions");
  288. if(!dlclang_defaultDiagnosticDisplayOptions) return false;
  289. dlclang_disposeCodeCompleteResults = (clang_disposeCodeCompleteResults_t) libclang.dlsym("clang_disposeCodeCompleteResults");
  290. if(!dlclang_disposeCodeCompleteResults) return false;
  291. dlclang_disposeDiagnostic = (clang_disposeDiagnostic_t) libclang.dlsym("clang_disposeDiagnostic");
  292. if(!dlclang_disposeDiagnostic) return false;
  293. dlclang_disposeIndex = (clang_disposeIndex_t) libclang.dlsym("clang_disposeIndex");
  294. if(!dlclang_disposeIndex) return false;
  295. dlclang_disposeString = (clang_disposeString_t) libclang.dlsym("clang_disposeString");
  296. if(!dlclang_disposeString) return false;
  297. dlclang_equalCursors = (clang_equalCursors_t) libclang.dlsym("clang_equalCursors");
  298. if(!dlclang_equalCursors) return false;
  299. dlclang_equalTypes = (clang_equalTypes_t) libclang.dlsym("clang_equalTypes");
  300. if(!dlclang_equalTypes) return false;
  301. dlclang_formatDiagnostic = (clang_formatDiagnostic_t) libclang.dlsym("clang_formatDiagnostic");
  302. if(!dlclang_formatDiagnostic) return false;
  303. dlclang_getCanonicalType = (clang_getCanonicalType_t) libclang.dlsym("clang_getCanonicalType");
  304. if(!dlclang_getCanonicalType) return false;
  305. dlclang_getCompletionAnnotation = (clang_getCompletionAnnotation_t) libclang.dlsym("clang_getCompletionAnnotation");
  306. if(!dlclang_getCompletionAnnotation) return false;
  307. dlclang_getCompletionChunkKind = (clang_getCompletionChunkKind_t) libclang.dlsym("clang_getCompletionChunkKind");
  308. if(!dlclang_getCompletionChunkKind) return false;
  309. dlclang_getCompletionChunkText = (clang_getCompletionChunkText_t) libclang.dlsym("clang_getCompletionChunkText");
  310. if(!dlclang_getCompletionChunkText) return false;
  311. dlclang_getCompletionNumAnnotations = (clang_getCompletionNumAnnotations_t) libclang.dlsym("clang_getCompletionNumAnnotations");
  312. if(!dlclang_getCompletionNumAnnotations) return false;
  313. dlclang_getCompletionPriority = (clang_getCompletionPriority_t) libclang.dlsym("clang_getCompletionPriority");
  314. if(!dlclang_getCompletionPriority) return false;
  315. dlclang_getCString = (clang_getCString_t) libclang.dlsym("clang_getCString");
  316. if(!dlclang_getCString) return false;
  317. dlclang_getCursorDefinition = (clang_getCursorDefinition_t) libclang.dlsym("clang_getCursorDefinition");
  318. if(!dlclang_getCursorDefinition) return false;
  319. dlclang_getCursorDisplayName = (clang_getCursorDisplayName_t) libclang.dlsym("clang_getCursorDisplayName");
  320. if(!dlclang_getCursorDisplayName) return false;
  321. dlclang_getCursorExtent = (clang_getCursorExtent_t) libclang.dlsym("clang_getCursorExtent");
  322. if(!dlclang_getCursorExtent) return false;
  323. dlclang_getCursorKind = (clang_getCursorKind_t) libclang.dlsym("clang_getCursorKind");
  324. if(!dlclang_getCursorKind) return false;
  325. dlclang_getCursorReferenced = (clang_getCursorReferenced_t) libclang.dlsym("clang_getCursorReferenced");
  326. if(!dlclang_getCursorReferenced) return false;
  327. dlclang_getCursorResultType = (clang_getCursorResultType_t) libclang.dlsym("clang_getCursorResultType");
  328. if(!dlclang_getCursorResultType) return false;
  329. dlclang_getCursorSemanticParent = (clang_getCursorSemanticParent_t) libclang.dlsym("clang_getCursorSemanticParent");
  330. if(!dlclang_getCursorSemanticParent) return false;
  331. dlclang_getCursorSpelling = (clang_getCursorSpelling_t) libclang.dlsym("clang_getCursorSpelling");
  332. if(!dlclang_getCursorSpelling) return false;
  333. dlclang_getCursorType = (clang_getCursorType_t) libclang.dlsym("clang_getCursorType");
  334. if(!dlclang_getCursorType) return false;
  335. dlclang_getCursorUSR = (clang_getCursorUSR_t) libclang.dlsym("clang_getCursorUSR");
  336. if(!dlclang_getCursorUSR) return false;
  337. dlclang_getCXXAccessSpecifier = (clang_getCXXAccessSpecifier_t) libclang.dlsym("clang_getCXXAccessSpecifier");
  338. if(!dlclang_getCXXAccessSpecifier) return false;
  339. dlclang_getDiagnosticCategoryText = (clang_getDiagnosticCategoryText_t) libclang.dlsym("clang_getDiagnosticCategoryText");
  340. if(!dlclang_getDiagnosticCategoryText) return false;
  341. dlclang_getDiagnostic = (clang_getDiagnostic_t) libclang.dlsym("clang_getDiagnostic");
  342. if(!dlclang_getDiagnostic) return false;
  343. dlclang_getFileName = (clang_getFileName_t) libclang.dlsym("clang_getFileName");
  344. if(!dlclang_getFileName) return false;
  345. dlclang_getFileTime = (clang_getFileTime_t) libclang.dlsym("clang_getFileTime");
  346. if(!dlclang_getFileTime) return false;
  347. dlclang_getNumCompletionChunks = (clang_getNumCompletionChunks_t) libclang.dlsym("clang_getNumCompletionChunks");
  348. if(!dlclang_getNumCompletionChunks) return false;
  349. dlclang_getNumDiagnostics = (clang_getNumDiagnostics_t) libclang.dlsym("clang_getNumDiagnostics");
  350. if(!dlclang_getNumDiagnostics) return false;
  351. dlclang_getPointeeType = (clang_getPointeeType_t) libclang.dlsym("clang_getPointeeType");
  352. if(!dlclang_getPointeeType) return false;
  353. dlclang_getRangeEnd = (clang_getRangeEnd_t) libclang.dlsym("clang_getRangeEnd");
  354. if(!dlclang_getRangeEnd) return false;
  355. dlclang_getRangeStart = (clang_getRangeStart_t) libclang.dlsym("clang_getRangeStart");
  356. if(!dlclang_getRangeStart) return false;
  357. dlclang_getSpellingLocation = (clang_getSpellingLocation_t) libclang.dlsym("clang_getSpellingLocation");
  358. if(!dlclang_getSpellingLocation) return false;
  359. dlclang_getTranslationUnitCursor = (clang_getTranslationUnitCursor_t) libclang.dlsym("clang_getTranslationUnitCursor");
  360. if(!dlclang_getTranslationUnitCursor) return false;
  361. dlclang_getTypeDeclaration = (clang_getTypeDeclaration_t) libclang.dlsym("clang_getTypeDeclaration");
  362. if(!dlclang_getTypeDeclaration) return false;
  363. dlclang_getTypeKindSpelling = (clang_getTypeKindSpelling_t) libclang.dlsym("clang_getTypeKindSpelling");
  364. if(!dlclang_getTypeKindSpelling) return false;
  365. dlclang_isPODType = (clang_isPODType_t) libclang.dlsym("clang_isPODType");
  366. if(!dlclang_isPODType) return false;
  367. dlclang_parseTranslationUnit = (clang_parseTranslationUnit_t) libclang.dlsym("clang_parseTranslationUnit");
  368. if(!dlclang_parseTranslationUnit) return false;
  369. dlclang_visitChildren = (clang_visitChildren_t) libclang.dlsym("clang_visitChildren");
  370. if(!dlclang_visitChildren) return false;
  371. dlclang_getCursorExtent = (clang_getCursorExtent_t) libclang.dlsym("clang_getCursorExtent");
  372. if(!dlclang_getCursorExtent) return false;
  373. // generated-code:end
  374. return true;
  375. }
  376. return false;
  377. }
  378. ////////////////////////////////////////////////////////////////////////////////
  379. static const SQChar *PostgreSQL_TAG = _SC("PostgreSQL");
  380. static SQRESULT get_pgsql_instance(HSQUIRRELVM v, SQInteger idx, PGconn **self){
  381. SQRESULT _rc_;
  382. if((_rc_ = sq_getinstanceup(v,idx,(SQUserPointer*)self,(void*)PostgreSQL_TAG)) < 0) return _rc_;
  383. if(!*self) return sq_throwerror(v, _SC("database is closed"));
  384. return _rc_;
  385. }
  386. #define GET_pgsql_INSTANCE_AT(idx) \
  387. PGconn *self=NULL; \
  388. if((_rc_ = get_pgsql_instance(v,idx,&self)) < 0) return _rc_;
  389. #define GET_pgsql_INSTANCE() GET_pgsql_INSTANCE_AT(1)
  390. static const SQChar *PostgreSQL_Result_TAG = _SC("PostgreSQL_Result");
  391. static const SQChar *_curr_row_key = _SC("_curr_row");
  392. static SQRESULT get_pgsql_result_instance(HSQUIRRELVM v, SQInteger idx, PGresult **self){
  393. SQRESULT _rc_;
  394. if((_rc_ = sq_getinstanceup(v,idx,(SQUserPointer*)self,(void*)PostgreSQL_Result_TAG)) < 0) return _rc_;
  395. if(!*self) return sq_throwerror(v, _SC("PGresult is closed"));
  396. return _rc_;
  397. }
  398. #define GET_pgsql_result_INSTANCE_AT(idx) \
  399. PGresult *self=NULL; \
  400. if((_rc_ = get_pgsql_result_instance(v,idx,&self)) < 0) return _rc_;
  401. #define GET_pgsql_result_INSTANCE() GET_pgsql_result_INSTANCE_AT(1)
  402. static SQRESULT sq_pgsql_result_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
  403. {
  404. PGresult *self = ((PGresult *)p);
  405. if (self) dlPQclear(self);
  406. return 0;
  407. }
  408. static SQRESULT sq_pgsql_result_close(HSQUIRRELVM v){
  409. SQ_FUNC_VARS_NO_TOP(v);
  410. GET_pgsql_result_INSTANCE();
  411. dlPQclear(self);
  412. sq_setinstanceup(v, 1, 0); //next calls will fail with "Pgresult is closed"
  413. return 0;
  414. }
  415. static SQRESULT sq_pgsql_result_col_count(HSQUIRRELVM v){
  416. SQ_FUNC_VARS_NO_TOP(v);
  417. GET_pgsql_result_INSTANCE();
  418. sq_pushinteger(v, dlPQnfields(self));
  419. return 1;
  420. }
  421. static SQRESULT sq_pgsql_result_row_count(HSQUIRRELVM v){
  422. SQ_FUNC_VARS_NO_TOP(v);
  423. GET_pgsql_result_INSTANCE();
  424. sq_pushinteger(v, dlPQntuples(self));
  425. return 1;
  426. }
  427. static SQRESULT sq_pgsql_result_col_name(HSQUIRRELVM v){
  428. SQ_FUNC_VARS_NO_TOP(v);
  429. GET_pgsql_result_INSTANCE();
  430. SQ_GET_INTEGER(v, 2, col);
  431. sq_pushstring(v, dlPQfname(self, col), -1);
  432. return 1;
  433. }
  434. static SQRESULT sq_pgsql_result_col_index(HSQUIRRELVM v){
  435. SQ_FUNC_VARS_NO_TOP(v);
  436. GET_pgsql_result_INSTANCE();
  437. SQ_GET_STRING(v, 2, name);
  438. sq_pushinteger(v, dlPQfnumber(self, name));
  439. return 1;
  440. }
  441. static SQRESULT sq_pgsql_result_eof(HSQUIRRELVM v){
  442. SQ_FUNC_VARS_NO_TOP(v);
  443. GET_pgsql_result_INSTANCE();
  444. sq_pushstring(v, _curr_row_key, -1);
  445. if(sq_get(v, 1) == SQ_OK){
  446. SQ_GET_INTEGER(v, -1, curr_row);
  447. sq_pushbool(v, curr_row < dlPQntuples(self));
  448. }
  449. else sq_pushbool(v, SQTrue);
  450. return 1;
  451. }
  452. static SQRESULT sq_pgsql_result_next_row(HSQUIRRELVM v){
  453. SQ_FUNC_VARS_NO_TOP(v);
  454. GET_pgsql_result_INSTANCE();
  455. sq_pushstring(v, _curr_row_key, -1);
  456. sq_push(v, -1); //make a copy
  457. if(sq_get(v, 1) == SQ_OK){
  458. SQ_GET_INTEGER(v, -1, curr_row);
  459. if(++curr_row < dlPQntuples(self)){
  460. sq_poptop(v);
  461. sq_pushinteger(v, curr_row);
  462. sq_set(v, 1);
  463. sq_pushbool(v, SQTrue);
  464. return 1;
  465. }
  466. }
  467. sq_pushbool(v, SQFalse);
  468. return 1;
  469. }
  470. static SQRESULT sq_pgsql_result_col_value(HSQUIRRELVM v){
  471. SQ_FUNC_VARS_NO_TOP(v);
  472. GET_pgsql_result_INSTANCE();
  473. SQObjectType ptype = sq_gettype(v, 2);
  474. int col = -1;
  475. if(ptype == OT_STRING){
  476. SQ_GET_STRING(v, 2, col_name);
  477. col = dlPQfnumber(self, col_name);
  478. }
  479. else
  480. {
  481. SQ_GET_INTEGER(v, 2, idx);
  482. col = idx;
  483. }
  484. if(col < 0) return sq_throwerror(v, _SC("invalid col index/name"));
  485. sq_pushstring(v, _curr_row_key, -1);
  486. if(sq_get(v, 1) == SQ_OK){
  487. SQ_GET_INTEGER(v, -1, curr_row);
  488. if(curr_row < dlPQntuples(self)){
  489. sq_pushstring(v, dlPQgetvalue(self, curr_row, col), -1);
  490. return 1;
  491. }
  492. }
  493. return SQ_ERROR;
  494. }
  495. static SQRESULT sq_pgsql_result_row_as_array(HSQUIRRELVM v){
  496. SQ_FUNC_VARS(v);
  497. GET_pgsql_result_INSTANCE();
  498. SQ_OPT_INTEGER(v, 2, row, -1);
  499. if(row < 0){
  500. sq_pushstring(v, _curr_row_key, -1);
  501. if(sq_get(v, 1) == SQ_OK){
  502. sq_getinteger(v, -1, &row);
  503. }
  504. }
  505. int row_count = dlPQntuples(self);
  506. if(row < 0 || row >= row_count) return sq_throwerror(v, _SC("invalid row (%d)"), row);
  507. int col_count = dlPQnfields(self);
  508. sq_newarray(v, col_count);
  509. for(int i=0; i < col_count; ++i){
  510. sq_pushinteger(v, i);
  511. sq_pushstring(v, dlPQgetvalue(self, row, i), -1);
  512. sq_rawset(v, -3);
  513. }
  514. return 1;
  515. }
  516. #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name), sq_pgsql_result_##name,nparams,tycheck}
  517. static SQRegFunction sq_pgsql_result_methods[] =
  518. {
  519. _DECL_FUNC(close, 1, _SC("x")),
  520. _DECL_FUNC(eof, 1, _SC("x")),
  521. _DECL_FUNC(next_row, 1, _SC("x")),
  522. _DECL_FUNC(col_count, 1, _SC("x")),
  523. _DECL_FUNC(row_count, 1, _SC("x")),
  524. _DECL_FUNC(col_name, 2, _SC("xi")),
  525. _DECL_FUNC(col_index, 2, _SC("xs")),
  526. _DECL_FUNC(col_value, 2, _SC("x i|s")),
  527. _DECL_FUNC(row_as_array, -1, _SC("xi")),
  528. {0,0}
  529. };
  530. #undef _DECL_FUNC
  531. struct PgSqlStatement {
  532. PGconn *db;
  533. PGresult *result;
  534. char name[64];
  535. };
  536. static const SQChar *PostgreSQL_Statement_TAG = _SC("PostgreSQL_Statement");
  537. static SQRESULT get_pgsql_statement_instance(HSQUIRRELVM v, SQInteger idx, PgSqlStatement **self){
  538. SQRESULT _rc_;
  539. if((_rc_ = sq_getinstanceup(v,idx,(SQUserPointer*)self,(void*)PostgreSQL_Statement_TAG)) < 0) return _rc_;
  540. if(!*self) return sq_throwerror(v, _SC("PGstatement is closed"));
  541. return _rc_;
  542. }
  543. #define GET_pgsql_statement_INSTANCE_AT(idx) \
  544. PgSqlStatement *self=NULL; \
  545. if((_rc_ = get_pgsql_statement_instance(v,idx,&self)) < 0) return _rc_;
  546. #define GET_pgsql_statement_INSTANCE() GET_pgsql_statement_INSTANCE_AT(1)
  547. static SQRESULT sq_pgsql_statement_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
  548. {
  549. PgSqlStatement *self = ((PgSqlStatement *)p);
  550. if (self && self->result){
  551. char sql[128];
  552. snprintf(sql, sizeof(sql), "DEALLOCATE '%s'", self->name);
  553. PGresult *qres = dlPQexec(self->db, sql);
  554. bool is_ok = dlPQresultStatus(qres) != PGRES_BAD_RESPONSE;
  555. dlPQclear(qres);
  556. if(is_ok) dlPQclear(self->result);
  557. sq_free(self, sizeof(PgSqlStatement));
  558. }
  559. return 0;
  560. }
  561. static SQRESULT sq_pgsql_statement_close(HSQUIRRELVM v){
  562. SQ_FUNC_VARS_NO_TOP(v);
  563. GET_pgsql_statement_INSTANCE();
  564. sq_pgsql_statement_releasehook(self, 0, v);
  565. sq_setinstanceup(v, 1, 0); //next calls will fail with "Pgstatement is closed"
  566. return 0;
  567. }
  568. #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name), sq_pgsql_statement_##name,nparams,tycheck}
  569. static SQRegFunction sq_pgsql_statement_methods[] =
  570. {
  571. _DECL_FUNC(close, 1, _SC("x")),
  572. {0,0}
  573. };
  574. #undef _DECL_FUNC
  575. static SQRESULT sq_pgsql_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
  576. {
  577. PGconn *self = ((PGconn *)p);
  578. if (self) dlPQfinish(self);
  579. return 0;
  580. }
  581. static SQRESULT sq_pgsql_constructor(HSQUIRRELVM v)
  582. {
  583. SQ_FUNC_VARS_NO_TOP(v);
  584. SQ_GET_STRING(v, 2, szConnInfo);
  585. PGconn *self=0;
  586. if(load_libclang())
  587. {
  588. self = dlPQconnectdb(szConnInfo);
  589. if (dlPQstatus(self) == CONNECTION_BAD) return sq_throwerror(v, _SC("Failed to connect ot database !"));
  590. }
  591. else return sq_throwerror(v, _SC("Failed to load libclang !"));
  592. sq_setinstanceup(v, 1, self);
  593. sq_setreleasehook(v,1, sq_pgsql_releasehook);
  594. //save a weakref to allow statement return it's db
  595. sq_pushuserpointer(v, self);
  596. sq_weakref(v, 1);
  597. sq_setonregistrytable(v);
  598. return 1;
  599. }
  600. static SQRESULT sq_pgsql_close(HSQUIRRELVM v){
  601. SQ_FUNC_VARS_NO_TOP(v);
  602. GET_pgsql_INSTANCE();
  603. dlPQfinish(self);
  604. sq_setinstanceup(v, 1, 0); //next calls will fail with "database is closed"
  605. return 0;
  606. }
  607. static SQRESULT sq_pgsql_exec_dml(HSQUIRRELVM v){
  608. SQ_FUNC_VARS_NO_TOP(v);
  609. GET_pgsql_INSTANCE();
  610. SQ_GET_STRING(v, 2, szSQL);
  611. int result = 0;
  612. PGresult *qres = dlPQexec(self, szSQL);
  613. bool is_ok = dlPQresultStatus(qres) == PGRES_COMMAND_OK;
  614. if (is_ok) result = atoi(dlPQcmdTuples(qres));
  615. dlPQclear(qres);
  616. if (!is_ok) return sq_throwerror(v, dlPQerrorMessage(self));
  617. sq_pushinteger(v, result);
  618. return 1;
  619. }
  620. static SQRESULT sq_pgsql_exec_scalar(HSQUIRRELVM v){
  621. SQ_FUNC_VARS_NO_TOP(v);
  622. GET_pgsql_INSTANCE();
  623. SQ_GET_STRING(v, 2, szSQL);
  624. int result = 0;
  625. PGresult *qres = dlPQexec(self, szSQL);
  626. bool is_ok = (dlPQresultStatus(qres) == PGRES_TUPLES_OK) &&
  627. (dlPQntuples(qres) == 1) && (dlPQnfields(qres) > 0);
  628. if (is_ok) result = atoi(dlPQgetvalue(qres, 0, 0));
  629. dlPQclear(qres);
  630. if (!is_ok) return sq_throwerror(v, dlPQerrorMessage(self));
  631. sq_pushinteger(v, result);
  632. return 1;
  633. }
  634. static SQRESULT sq_pgsql_exec_query(HSQUIRRELVM v){
  635. SQ_FUNC_VARS_NO_TOP(v);
  636. GET_pgsql_INSTANCE();
  637. SQ_GET_STRING(v, 2, szSQL);
  638. PGresult *qres = dlPQexec(self, szSQL);
  639. if(dlPQresultStatus(qres) == PGRES_TUPLES_OK){
  640. sq_pushroottable(v);
  641. sq_pushstring(v, PostgreSQL_Result_TAG, -1);
  642. if(sq_get(v, -2) == SQ_OK){
  643. if(sq_createinstance(v, -1) == SQ_OK){
  644. sq_setinstanceup(v, -1, qres);
  645. sq_setreleasehook(v, -1, sq_pgsql_result_releasehook);
  646. sq_pushstring(v, _curr_row_key, -1);
  647. sq_pushinteger(v, -1);
  648. sq_set(v, -3);
  649. return 1;
  650. }
  651. }
  652. }
  653. return sq_throwerror(v, dlPQerrorMessage(self));
  654. }
  655. static SQRESULT sq_pgsql_prepare(HSQUIRRELVM v){
  656. SQ_FUNC_VARS_NO_TOP(v);
  657. GET_pgsql_INSTANCE();
  658. SQ_GET_STRING(v, 2, szSQL);
  659. PgSqlStatement *stmt = (PgSqlStatement*)sq_malloc(sizeof(PgSqlStatement));
  660. stmt->db = self;
  661. snprintf(stmt->name, sizeof(stmt->name), "sq_pg_preared_stmt_%p", stmt);
  662. stmt->result = dlPQprepare(self, stmt->name, szSQL, 0, NULL);
  663. if(dlPQresultStatus(stmt->result) == PGRES_COMMAND_OK){
  664. sq_pushroottable(v);
  665. sq_pushstring(v, PostgreSQL_Statement_TAG, -1);
  666. if(sq_get(v, -2) == SQ_OK){
  667. if(sq_createinstance(v, -1) == SQ_OK){
  668. sq_setinstanceup(v, -1, stmt);
  669. sq_setreleasehook(v, -1, sq_pgsql_statement_releasehook);
  670. return 1;
  671. }
  672. }
  673. }
  674. sq_free(stmt, sizeof(PgSqlStatement));
  675. return sq_throwerror(v, dlPQerrorMessage(self));
  676. }
  677. static SQRESULT sq_pgsql_error_message(HSQUIRRELVM v){
  678. SQ_FUNC_VARS_NO_TOP(v);
  679. GET_pgsql_INSTANCE();
  680. sq_pushstring(v, dlPQerrorMessage(self), -1);
  681. return 1;
  682. }
  683. static SQRESULT sq_pgsql_version(HSQUIRRELVM v){
  684. SQ_FUNC_VARS_NO_TOP(v);
  685. GET_pgsql_INSTANCE();
  686. sq_pushinteger(v, dlPQserverVersion(self));
  687. return 1;
  688. }
  689. static int
  690. inv_read = 0x40000,
  691. inv_write = 0x20000,
  692. invalidoid = 0,
  693. inv_seek_set = 0,
  694. inv_seek_curr = 1,
  695. inv_seek_end = 2;
  696. static SQRESULT sq_pgsql_get_blob_field(HSQUIRRELVM v){
  697. SQ_FUNC_VARS_NO_TOP(v);
  698. GET_pgsql_INSTANCE();
  699. SQ_GET_INTEGER(v, 2, oid);
  700. //begin_recursive_transaction();
  701. char *result = 0;
  702. int ofd = dllo_open(self, oid, inv_read);
  703. if(ofd >= 0){
  704. int blobSize = dllo_lseek(self, ofd, 0, inv_seek_end);
  705. dllo_lseek(self, ofd, 0, inv_seek_set);
  706. SQBlob blob(blobSize);
  707. result = (char*)blob.GetBuf();
  708. int numRead = 0;
  709. while(blobSize > 0){
  710. int i = dllo_read(self, ofd, result+numRead, blobSize);
  711. numRead += i;
  712. blobSize -= i;
  713. }
  714. dllo_close(self, oid);
  715. sq_pushstring(v, (const SQChar*)blob.GetBuf(), blob.Len());
  716. }
  717. //commit_recursive_transaction();
  718. if(!result) sq_pushnull(v);
  719. return 1;
  720. }
  721. static SQRESULT sq_pgsql_insert_blob_field(HSQUIRRELVM v){
  722. SQ_FUNC_VARS_NO_TOP(v);
  723. GET_pgsql_INSTANCE();
  724. int result = 0;
  725. SQ_GET_STRING(v, 2, blob);
  726. SQ_GET_BOOL(v, 3, isFileName);
  727. if(isFileName){
  728. result = dllo_import(self, blob);
  729. } else {
  730. result = dllo_creat(self, inv_write);
  731. if(result){
  732. int ofd = dllo_open(self, result, inv_write);
  733. if (ofd >= 0){
  734. int i = blob_size;
  735. const char *blopPtr = (const char *)blob;
  736. int numWriten = 0;
  737. while(i > 0){
  738. int i2 = dllo_write(self, ofd, blopPtr+numWriten, i);
  739. numWriten += i2;
  740. i -= i2;
  741. }
  742. dllo_close(self, ofd);
  743. }
  744. else return sq_throwerror(v, _SC("Failed to insert blob !"));
  745. }
  746. }
  747. if(!result) sq_pushnull(v);
  748. return 1;
  749. }
  750. static SQRESULT sq_pgsql_update_blob_field(HSQUIRRELVM v){
  751. SQ_FUNC_VARS_NO_TOP(v);
  752. GET_pgsql_INSTANCE();
  753. SQ_GET_INTEGER(v, 2, oid);
  754. SQ_GET_STRING(v, 3, blob);
  755. SQ_GET_BOOL(v, 4, isFileName);
  756. int result_oid = 0;
  757. int result_error = SQ_OK;
  758. int loid = dllo_creat(self, inv_write);
  759. int ofd = dllo_open(self, loid, inv_write);
  760. if(ofd >= 0){
  761. dllo_unlink(self, oid);
  762. result_oid = loid;
  763. if(isFileName)
  764. {
  765. char buf[2048];
  766. FILE *fp = fopen(blob, "rb");
  767. if(!fp) {
  768. sq_throwerror(v, _SC("Failed to update blob from file !"));
  769. result_error = SQ_ERROR;
  770. }
  771. else
  772. {
  773. char *charPtr = buf;
  774. int numRead;
  775. do{
  776. numRead = fread(buf, 1, sizeof(buf), fp);
  777. int numWriten = dllo_write(self, ofd, charPtr, numRead);
  778. if (numWriten != numRead) {
  779. sq_throwerror(v, _SC("Failed to update blob from file !"));
  780. result_error = SQ_ERROR;
  781. break;
  782. }
  783. } while (numRead == 0);
  784. fclose(fp);
  785. }
  786. }else{
  787. int i = blob_size;
  788. const char *blopPtr = (const char *)blob;
  789. int numWriten = 0;
  790. while(i > 0){
  791. int i2 = dllo_write(self, ofd, blopPtr+numWriten, i);
  792. numWriten += i2;
  793. i -= i2;
  794. }
  795. }
  796. dllo_close(self, ofd);
  797. }
  798. if(result_error == SQ_ERROR) return result_error;
  799. sq_pushinteger(v, result_oid);
  800. return 1;
  801. }
  802. static SQRESULT sq_pgsql_delete_blob_field(HSQUIRRELVM v){
  803. SQ_FUNC_VARS_NO_TOP(v);
  804. GET_pgsql_INSTANCE();
  805. SQ_GET_INTEGER(v, 2, oid);
  806. sq_pushinteger(v, dllo_unlink(self, oid));
  807. return 1;
  808. }
  809. #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name), sq_pgsql_##name,nparams,tycheck}
  810. static SQRegFunction sq_pgsql_methods[] =
  811. {
  812. _DECL_FUNC(constructor, 2, _SC("xs")),
  813. _DECL_FUNC(close, 1, _SC("x")),
  814. _DECL_FUNC(exec_dml, 2, _SC("xs")),
  815. _DECL_FUNC(exec_scalar, 2, _SC("xs")),
  816. _DECL_FUNC(exec_query, 2, _SC("xs")),
  817. _DECL_FUNC(prepare, 2, _SC("xs")),
  818. _DECL_FUNC(error_message, 1, _SC("x")),
  819. _DECL_FUNC(version, 1, _SC("x")),
  820. _DECL_FUNC(get_blob_field, 2, _SC("xi")),
  821. _DECL_FUNC(insert_blob_field, 3, _SC("xsb")),
  822. _DECL_FUNC(update_blob_field, 3, _SC("xisb")),
  823. _DECL_FUNC(delete_blob_field, 2, _SC("xi")),
  824. {0,0}
  825. };
  826. #undef _DECL_FUNC
  827. #ifdef __cplusplus
  828. extern "C" {
  829. #endif
  830. SQRESULT sqext_register_PostgreSQL(HSQUIRRELVM v)
  831. {
  832. sq_pushstring(v,PostgreSQL_TAG,-1);
  833. sq_newclass(v,SQFalse);
  834. sq_settypetag(v,-1,(void*)PostgreSQL_TAG);
  835. sq_insert_reg_funcs(v, sq_pgsql_methods);
  836. sq_newslot(v,-3,SQTrue);
  837. sq_pushstring(v,PostgreSQL_Statement_TAG,-1);
  838. sq_newclass(v,SQFalse);
  839. sq_settypetag(v,-1,(void*)PostgreSQL_Statement_TAG);
  840. sq_insert_reg_funcs(v, sq_pgsql_statement_methods);
  841. sq_newslot(v,-3,SQTrue);
  842. sq_pushstring(v,PostgreSQL_Result_TAG,-1);
  843. sq_newclass(v,SQFalse);
  844. sq_settypetag(v,-1,(void*)PostgreSQL_Result_TAG);
  845. sq_insert_reg_funcs(v, sq_pgsql_result_methods);
  846. sq_pushstring(v, _curr_row_key, -1);
  847. sq_pushnull(v);
  848. sq_newslot(v, -3, SQFalse);
  849. sq_newslot(v,-3,SQTrue);
  850. return 0;
  851. }
  852. #ifdef __cplusplus
  853. }
  854. #endif
  855. #endif // WITH_LIBCLANG