sqlite3gen.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include "settings.h"
19 #include "message.h"
20 
21 #if USE_SQLITE3
22 
23 #include "qtbc.h"
24 #include "sqlite3gen.h"
25 #include "doxygen.h"
26 #include "config.h"
27 #include "util.h"
28 #include "docparser.h"
29 #include "language.h"
30 
31 #include "dot.h"
32 #include "arguments.h"
33 #include "classlist.h"
34 #include "filedef.h"
35 #include "namespacedef.h"
36 #include "filename.h"
37 #include "groupdef.h"
38 #include "pagedef.h"
39 #include "dirdef.h"
40 
41 #include <qdir.h>
42 #include <string.h>
43 #include <sqlite3.h>
44 
45 //#define DBG_CTX(x) printf x
46 #define DBG_CTX(x) do { } while(0)
47 
48 const char * schema_queries[][2] = {
49  { "includes",
50  "CREATE TABLE IF NOT EXISTS includes (\n"
51  "\t-- #include relations.\n"
52  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
53  "\tlocal INTEGER NOT NULL,\n"
54  "\tid_src INTEGER NOT NULL, -- File id of the includer.\n"
55  "\tid_dst INTEGER NOT NULL -- File id of the includee.\n"
56  ");\n"
57  "CREATE UNIQUE INDEX idx_includes ON includes\n"
58  "\t(local, id_src, id_dst);"
59  },
60  { "innerclass",
61  "CREATE TABLE IF NOT EXISTS innerclass (\n"
62  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
63  "\trefid TEXT NOT NULL,\n"
64  "\tprot INTEGER NOT NULL,\n"
65  "\tname TEXT NOT NULL\n"
66  ");"
67  },
68  { "files",
69  "CREATE TABLE IF NOT EXISTS files (\n"
70  "\t-- Names of source files and includes.\n"
71  "\tname TEXT PRIMARY KEY NOT NULL\n"
72  ");"
73  },
74  { "refids",
75  "CREATE TABLE IF NOT EXISTS refids (\n"
76  "\trefid TEXT PRIMARY KEY NOT NULL\n"
77  ");"
78  },
79  { "xrefs",
80  "CREATE TABLE IF NOT EXISTS xrefs (\n"
81  "\t-- Cross reference relation.\n"
82  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
83  "\trefid_src INTEGER NOT NULL, -- referrer id.\n"
84  "\trefid_dst INTEGER NOT NULL, -- referee id.\n"
85  "\tid_file INTEGER NOT NULL, -- file where the reference is happening.\n"
86  "\tline INTEGER NOT NULL, -- line where the reference is happening.\n"
87  "\tcolumn INTEGER NOT NULL -- column where the reference is happening.\n"
88  ");\n"
89  "CREATE UNIQUE INDEX idx_xrefs ON xrefs\n"
90  "\t(refid_src, refid_dst, id_file, line, column);"
91  },
92  { "memberdef",
93  "CREATE TABLE IF NOT EXISTS memberdef (\n"
94  "\t-- All processed identifiers.\n"
95  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
96  "\tid_file INTEGER NOT NULL, -- file where this identifier is located\n"
97  "\tline INTEGER NOT NULL, -- line where this identifier is located\n"
98  "\tcolumn INTEGER NOT NULL, -- column where this identifier is located\n"
99  "\trefid TEXT NOT NULL, -- see the refids table\n"
100  "\tname TEXT NOT NULL,\n"
101  "\tdefinition TEXT,\n"
102  "\ttype TEXT,\n"
103  "\targsstring TEXT,\n"
104  "\tscope TEXT,\n"
105  "\tinitializer TEXT,\n"
106  "\tprot INTEGER DEFAULT 0, -- 0:public 1:protected 2:private 3:package\n"
107  "\tconst INTEGER DEFAULT 0, -- 0:non-constant 1:constant\n"
108  "\tvirt INTEGER DEFAULT 0, -- 0:non-virtual 1:virtual 2:pure-virtual\n"
109  "\tstatic INTEGER DEFAULT 0, -- 0:non-static 1:static\n"
110  "\texplicit INTEGER DEFAULT 0,\n"
111  "\tinline INTEGER DEFAULT 0,\n"
112  "\tfinal INTEGER DEFAULT 0,\n"
113  "\tsealed INTEGER DEFAULT 0,\n"
114  "\tnew INTEGER DEFAULT 0,\n"
115  "\toptional INTEGER DEFAULT 0,\n"
116  "\trequired INTEGER DEFAULT 0,\n"
117  "\tmutable INTEGER DEFAULT 0,\n"
118  "\tinitonly INTEGER DEFAULT 0,\n"
119  "\treadable INTEGER DEFAULT 0,\n"
120  "\twritable INTEGER DEFAULT 0,\n"
121  "\tgettable INTEGER DEFAULT 0,\n"
122  "\tsettable INTEGER DEFAULT 0,\n"
123  "\taccessor INTEGER DEFAULT 0,\n"
124  "\taddable INTEGER DEFAULT 0,\n"
125  "\tremovable INTEGER DEFAULT 0,\n"
126  "\traisable INTEGER DEFAULT 0,\n"
127  /// @todo make a `kind' table
128  "\tkind INTEGER DEFAULT 0, -- 0:define 1:function 2:variable 3:typedef 4:enum 5:enumvalue 6:signal 7:slot 8:friend 9:DCOP 10:property 11:event\n"
129  "\tid_bodyfile INTEGER DEFAULT 0, -- file of definition\n"
130  "\tbodystart INTEGER DEFAULT 0, -- starting line of definition\n"
131  "\tbodyend INTEGER DEFAULT 0, -- ending line of definition\n"
132  /// @todo make a `detaileddescription' table
133  "\tdetaileddescription TEXT,\n"
134  "\tbriefdescription TEXT,\n"
135  "\tinbodydescription TEXTi\n"
136  ");"
137  },
138  { "compounddef",
139  "CREATE TABLE IF NOT EXISTS compounddef (\n"
140  "\t-- class/struct definitions.\n"
141  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
142  "\tname TEXT NOT NULL,\n"
143  "\tkind TEXT NOT NULL,\n"
144  "\trefid TEXT NOT NULL,\n"
145  "\tprot INTEGER NOT NULL,\n"
146  "\tid_file INTEGER NOT NULL,\n"
147  "\tline INTEGER NOT NULL,\n"
148  "\tcolumn INTEGER NOT NULL\n"
149  ");"
150  },
151  { "basecompoundref",
152  "CREATE TABLE IF NOT EXISTS basecompoundref (\n"
153  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
154  "\tbase TEXT NOT NULL,\n"
155  "\tderived TEXT NOT NULL,\n"
156  "\trefid TEXT NOT NULL,\n"
157  "\tprot INTEGER NOT NULL,\n"
158  "\tvirt INTEGER NOT NULL\n"
159  ");"
160  },
161  { "derivedcompoundref",
162  "CREATE TABLE IF NOT EXISTS derivedcompoundref (\n"
163  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
164  "\tbase TEXT NOT NULL,\n"
165  "\tderived TEXT NOT NULL,\n"
166  "\trefid TEXT NOT NULL,\n"
167  "\tprot INTEGER NOT NULL,\n"
168  "\tvirt INTEGER NOT NULL\n"
169  ");"
170  },
171  { "params",
172  "CREATE TABLE IF NOT EXISTS params (\n"
173  "\t-- All processed parameters.\n"
174  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
175  "\tattributes TEXT,\n"
176  "\ttype TEXT,\n"
177  "\tdeclname TEXT,\n"
178  "\tdefnname TEXT,\n"
179  "\tarray TEXT,\n"
180  "\tdefval TEXT,\n"
181  "\tbriefdescription TEXT\n"
182  ");"
183  },
184  { "memberdef_params",
185  "CREATE TABLE IF NOT EXISTS memberdef_params (\n"
186  "\t-- Junction table for memberdef parameters.\n"
187  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
188  "\tid_memberdef INTEGER NOT NULL,\n"
189  "\tid_param INTEGER NOT NULL\n"
190  ");"
191  },
192  { "innernamespaces",
193  "CREATE TABLE IF NOT EXISTS innernamespaces (\n"
194  "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
195  "\trefid TEXT NOT NULL,\n"
196  "\tname TEXT NOT NULL\n"
197  ");"
198  }
199 };
200 
201 //////////////////////////////////////////////////////
202 struct SqlStmt {
203  const char *query;
204  sqlite3_stmt *stmt;
205 };
206 //////////////////////////////////////////////////////
207 SqlStmt incl_insert = { "INSERT INTO includes "
208  "( local, id_src, id_dst ) "
209  "VALUES "
210  "(:local,:id_src,:id_dst )"
211  ,NULL
212 };
213 SqlStmt incl_select = { "SELECT COUNT(*) FROM includes WHERE "
214  "local=:local AND id_src=:id_src AND id_dst=:id_dst"
215  ,NULL
216 };
217 //////////////////////////////////////////////////////
218 SqlStmt innerclass_insert={"INSERT INTO innerclass "
219  "( refid, prot, name )"
220  "VALUES "
221  "(:refid,:prot,:name )"
222  ,NULL
223 };
224 //////////////////////////////////////////////////////
225 SqlStmt files_select = {"SELECT rowid FROM files WHERE name=:name"
226  ,NULL
227 };
228 SqlStmt files_insert = {"INSERT INTO files "
229  "( name )"
230  "VALUES "
231  "(:name )"
232  ,NULL
233 };
234 //////////////////////////////////////////////////////
235 SqlStmt refids_select = {"SELECT rowid FROM refids WHERE "
236  "refid=:refid"
237  ,NULL
238 };
239 SqlStmt refids_insert = {"INSERT INTO refids "
240  "( refid )"
241  "VALUES "
242  "(:refid )"
243  ,NULL
244 };
245 //////////////////////////////////////////////////////
246 SqlStmt xrefs_insert= {"INSERT INTO xrefs "
247  "( refid_src, refid_dst, id_file, line, column )"
248  "VALUES "
249  "(:refid_src,:refid_dst,:id_file,:line,:column )"
250  ,NULL
251 };
252 //////////////////////////////////////////////////////
253 SqlStmt memberdef_insert={"INSERT INTO memberdef "
254  "( refid, prot, static, const, explicit, inline, final, sealed, new, optional, required, virt, mutable, initonly, readable, writable, gettable, settable, accessor, addable, removable, raisable, name, type, definition, argsstring, scope, initializer, kind, id_bodyfile, bodystart, bodyend, id_file, line, column, detaileddescription, briefdescription, inbodydescription)"
255  "VALUES "
256  "(:refid,:prot,:static,:const,:explicit,:inline,:final,:sealed,:new,:optional,:required,:virt,:mutable,:initonly,:readable,:writable,:gettable,:settable,:accessor,:addable,:removable,:raisable,:name,:type,:definition,:argsstring,:scope,:initializer,:kind,:id_bodyfile,:bodystart,:bodyend,:id_file,:line,:column,:detaileddescription,:briefdescription,:inbodydescription)"
257  ,NULL
258 };
259 //////////////////////////////////////////////////////
260 SqlStmt compounddef_insert={"INSERT INTO compounddef "
261  "( name, kind, prot, refid, id_file, line, column ) "
262  "VALUES "
263  "(:name,:kind,:prot,:refid,:id_file,:line,:column )"
264  ,NULL
265 };
266 //////////////////////////////////////////////////////
267 SqlStmt basecompoundref_insert={"INSERT INTO basecompoundref "
268  "( base, derived, refid, prot, virt ) "
269  "VALUES "
270  "(:base,:derived,:refid,:prot,:virt )"
271  ,NULL
272 };
273 //////////////////////////////////////////////////////
274 SqlStmt derivedcompoundref_insert={"INSERT INTO derivedcompoundref "
275  "( refid, prot, virt, base, derived ) "
276  "VALUES "
277  "(:refid,:prot,:virt,:base,:derived )"
278  ,NULL
279 };
280 //////////////////////////////////////////////////////
281 SqlStmt params_select = { "SELECT rowid FROM params WHERE "
282  "(attributes IS NULL OR attributes=:attributes) AND "
283  "(type IS NULL OR type=:type) AND "
284  "(declname IS NULL OR declname=:declname) AND "
285  "(defnname IS NULL OR defnname=:defnname) AND "
286  "(array IS NULL OR array=:array) AND "
287  "(defval IS NULL OR defval=:defval) AND "
288  "(briefdescription IS NULL OR briefdescription=:briefdescription)"
289  ,NULL
290 };
291 SqlStmt params_insert = { "INSERT INTO params "
292  "( attributes, type, declname, defnname, array, defval, briefdescription ) "
293  "VALUES "
294  "(:attributes,:type,:declname,:defnname,:array,:defval,:briefdescription)"
295  ,NULL
296 };
297 //////////////////////////////////////////////////////
298 SqlStmt memberdef_params_insert={ "INSERT INTO memberdef_params "
299  "( id_memberdef, id_param)"
300  "VALUES "
301  "(:id_memberdef,:id_param)"
302  ,NULL
303 };
304 //////////////////////////////////////////////////////
305 SqlStmt innernamespace_insert={"INSERT INTO innernamespaces "
306  "( refid, name)"
307  "VALUES "
308  "(:refid,:name)",
309  NULL
310 };
311 
312 
313 class TextGeneratorSqlite3Impl : public TextGeneratorIntf
314 {
315  public:
316  TextGeneratorSqlite3Impl(StringList &l) : l(l) {
317  l.setAutoDelete(TRUE);
318  }
319  void writeString(const char * /*s*/,bool /*keepSpaces*/) const
320  {
321  }
322  void writeBreak(int) const
323  {
324  DBG_CTX(("writeBreak\n"));
325  }
326  void writeLink(const char * /*extRef*/,const char *file,
327  const char *anchor,const char * /*text*/
328  ) const
329  {
330  QCString *rs=new QCString(file);
331  if (anchor)
332  {
333  rs->append("_1").append(anchor);
334  }
335  l.append(rs);
336  }
337  private:
338  StringList &l;
339  // the list is filled by linkifyText and consumed by the caller
340 };
341 
342 
343 static void bindTextParameter(SqlStmt &s,const char *name,const char *value, bool _static=TRUE)
344 {
345  int idx = sqlite3_bind_parameter_index(s.stmt, name);
346  sqlite3_bind_text(s.stmt, idx, value, -1, _static==TRUE?SQLITE_STATIC:SQLITE_TRANSIENT);
347 }
348 
349 static void bindIntParameter(SqlStmt &s,const char *name,int value)
350 {
351  int idx = sqlite3_bind_parameter_index(s.stmt, name);
352  sqlite3_bind_int(s.stmt, idx, value);
353 }
354 
355 static int step(sqlite3 *db, SqlStmt &s,bool getRowId=FALSE, bool select=FALSE)
356 {
357  int rowid=-1;
358  int rc = sqlite3_step(s.stmt);
359  if (rc!=SQLITE_DONE && rc!=SQLITE_ROW)
360  {
361  msg("sqlite3_step failed: %s\n", sqlite3_errmsg(db));
362  sqlite3_clear_bindings(s.stmt);
363  return -1;
364  }
365  if (getRowId && select) rowid = sqlite3_column_int(s.stmt, 0); // works on selects, doesnt on inserts
366  if (getRowId && !select) rowid = sqlite3_last_insert_rowid(db); //works on inserts, doesnt on selects
367  sqlite3_reset(s.stmt);
368  sqlite3_clear_bindings(s.stmt); // XXX When should this really be called
369  return rowid;
370 }
371 
372 static int insertFile(sqlite3 *db, const char* name)
373 {
374  int rowid=-1;
375  if (name==0) return rowid;
376 
377  bindTextParameter(files_select,":name",name);
378  rowid=step(db,files_select,TRUE,TRUE);
379  if (rowid==0)
380  {
381  bindTextParameter(files_insert,":name",name);
382  rowid=step(db,files_insert,TRUE);
383  }
384  return rowid;
385 }
386 
387 static int insertRefid(sqlite3 *db, const char *refid)
388 {
389  int rowid=-1;
390  if (refid==0) return rowid;
391 
392  bindTextParameter(refids_select,":refid",refid);
393  rowid=step(db,refids_select,TRUE,TRUE);
394  if (rowid==0)
395  {
396  bindTextParameter(refids_insert,":refid",refid);
397  rowid=step(db,refids_insert,TRUE);
398  }
399  return rowid;
400 }
401 
402 
403 static void insertMemberReference(sqlite3 *db, const char*src, const char*dst, const char *file, int line, int column)
404 {
405  int id_file = insertFile(db,file);
406  int refid_src = insertRefid(db,src);
407  int refid_dst = insertRefid(db,dst);
408  if (id_file==-1||refid_src==-1||refid_dst==-1)
409  return;
410 
411  bindIntParameter(xrefs_insert,":refid_src",refid_src);
412  bindIntParameter(xrefs_insert,":refid_dst",refid_dst);
413  bindIntParameter(xrefs_insert,":id_file",id_file);
414  bindIntParameter(xrefs_insert,":line",line);
415  bindIntParameter(xrefs_insert,":column",1);
416  step(db,xrefs_insert);
417 }
418 
419 static void insertMemberReference(sqlite3 *db, MemberDef *src, MemberDef *dst, const char*floc)
420 {
421  if (dst->getStartBodyLine()!=-1 && dst->getBodyDef())
422  {
423  static char file[4096];
424  int line=0,column=0;
425  if (floc)
426  {
427  int rv = sscanf(floc,"%[^:]:%d:%d",file,&line,&column);
428  if (rv!=3)
429  {
430  msg("unable to read file:line:col location from string [%s]\n",floc);
431  return;
432  }
433  }
434  insertMemberReference(db,src->anchor().data(),dst->anchor().data(),file,line,column);
435  }
436 }
437 
438 static void insertMemberFunctionParams(sqlite3 *db,int id_memberdef,MemberDef *md,Definition *def)
439 {
440  ArgumentList *declAl = md->declArgumentList();
441  ArgumentList *defAl = md->argumentList();
442  if (declAl!=0 && declAl->count()>0)
443  {
444  ArgumentListIterator declAli(*declAl);
445  ArgumentListIterator defAli(*defAl);
446  Argument *a;
447  for (declAli.toFirst();(a=declAli.current());++declAli)
448  {
449  Argument *defArg = defAli.current();
450 
451  if (!a->attrib.isEmpty())
452  {
453  bindTextParameter(params_select,":attributes",a->attrib.data());
454  bindTextParameter(params_insert,":attributes",a->attrib.data());
455  }
456  if (!a->type.isEmpty())
457  {
458  StringList l;
459  linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,a->type);
460 
461  StringListIterator li(l);
462  QCString *s;
463  while ((s=li.current()))
464  {
465  insertMemberReference(db,md->anchor().data(),s->data(),def->getDefFileName().data(),md->getDefLine(),1);
466  ++li;
467  }
468  bindTextParameter(params_select,":type",a->type.data());
469  bindTextParameter(params_insert,":type",a->type.data());
470  }
471  if (!a->name.isEmpty())
472  {
473  bindTextParameter(params_select,":declname",a->name.data());
474  bindTextParameter(params_insert,":declname",a->name.data());
475  }
476  if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
477  {
478  bindTextParameter(params_select,":defnname",defArg->name.data());
479  bindTextParameter(params_insert,":defnname",defArg->name.data());
480  }
481  if (!a->array.isEmpty())
482  {
483  bindTextParameter(params_select,":array",a->array.data());
484  bindTextParameter(params_insert,":array",a->array.data());
485  }
486  if (!a->defval.isEmpty())
487  {
488  StringList l;
489  linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,a->defval);
490  bindTextParameter(params_select,":defval",a->defval.data());
491  bindTextParameter(params_insert,":defval",a->defval.data());
492  }
493  if (defArg) ++defAli;
494 
495  int id_param=step(db,params_select,TRUE,TRUE);
496  if (id_param==0) {
497  id_param=step(db,params_insert,TRUE);
498  }
499 
500  bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef);
501  bindIntParameter(memberdef_params_insert,":id_param",id_param);
502  step(db,memberdef_params_insert);
503  }
504  }
505 }
506 
507 static void insertMemberDefineParams(sqlite3 *db,int id_memberdef,MemberDef *md,Definition *def)
508 {
509  if (md->argumentList()->count()==0) // special case for "foo()" to
510  // disguish it from "foo".
511  {
512  DBG_CTX(("no params\n"));
513  }
514  else
515  {
517  Argument *a;
518  for (ali.toFirst();(a=ali.current());++ali)
519  {
520  bindTextParameter(params_insert,":defnname",a->type.data());
521  int id_param=step(db,params_insert,TRUE);
522 
523  bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef);
524  bindIntParameter(memberdef_params_insert,":id_param",id_param);
525  step(db,memberdef_params_insert);
526  }
527  }
528 }
529 
530 
531 static void stripQualifiers(QCString &typeStr)
532 {
533  bool done=FALSE;
534  while (!done)
535  {
536  if (typeStr.stripPrefix("static "));
537  else if (typeStr.stripPrefix("virtual "));
538  else if (typeStr.stripPrefix("volatile "));
539  else if (typeStr=="virtual") typeStr="";
540  else done=TRUE;
541  }
542 }
543 
544 static int prepareStatement(sqlite3 *db, SqlStmt &s)
545 {
546  int rc;
547  rc = sqlite3_prepare_v2(db,s.query,-1,&s.stmt,0);
548  if (rc!=SQLITE_OK)
549  {
550  msg("prepare failed for %s\n%s\n", s.query, sqlite3_errmsg(db));
551  return -1;
552  }
553  return rc;
554 }
555 
556 static int prepareStatements(sqlite3 *db)
557 {
558  if (
559  -1==prepareStatement(db, memberdef_insert) ||
560  -1==prepareStatement(db, files_insert) ||
561  -1==prepareStatement(db, files_select) ||
562  -1==prepareStatement(db, refids_insert) ||
563  -1==prepareStatement(db, refids_select) ||
564  -1==prepareStatement(db, incl_insert)||
565  -1==prepareStatement(db, incl_select)||
566  -1==prepareStatement(db, params_insert) ||
567  -1==prepareStatement(db, params_select) ||
568  -1==prepareStatement(db, xrefs_insert) ||
569  -1==prepareStatement(db, innerclass_insert) ||
570  -1==prepareStatement(db, compounddef_insert) ||
571  -1==prepareStatement(db, basecompoundref_insert) ||
572  -1==prepareStatement(db, derivedcompoundref_insert) ||
573  -1==prepareStatement(db, memberdef_params_insert)||
574  -1==prepareStatement(db, innernamespace_insert)
575  )
576  {
577  return -1;
578  }
579  return 0;
580 }
581 
582 static void beginTransaction(sqlite3 *db)
583 {
584  char * sErrMsg = 0;
585  sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
586 }
587 
588 static void endTransaction(sqlite3 *db)
589 {
590  char * sErrMsg = 0;
591  sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &sErrMsg);
592 }
593 
594 static void pragmaTuning(sqlite3 *db)
595 {
596  char * sErrMsg = 0;
597  sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, &sErrMsg);
598  sqlite3_exec(db, "PRAGMA journal_mode = MEMORY", NULL, NULL, &sErrMsg);
599  sqlite3_exec(db, "PRAGMA temp_store = MEMORY;", NULL, NULL, &sErrMsg);
600 }
601 
602 static int initializeSchema(sqlite3* db)
603 {
604  int rc;
605  sqlite3_stmt *stmt = 0;
606 
607  msg("Initializing DB schema...\n");
608  for (unsigned int k = 0; k < sizeof(schema_queries) / sizeof(schema_queries[0]); k++)
609  {
610  const char *q = schema_queries[k][1];
611  // create table
612  rc = sqlite3_prepare_v2(db, q, -1, &stmt, 0);
613  if (rc != SQLITE_OK)
614  {
615  msg("failed to prepare query: %s\n\t%s\n", q, sqlite3_errmsg(db));
616  return -1;
617  }
618  rc = sqlite3_step(stmt);
619  if (rc != SQLITE_DONE)
620  {
621  msg("failed to execute query: %s\n\t%s\n", q, sqlite3_errmsg(db));
622  return -1;
623  }
624  sqlite3_finalize(stmt);
625  }
626  return 0;
627 }
628 
629 ////////////////////////////////////////////
630 static void writeInnerClasses(sqlite3*db,const ClassSDict *cl)
631 {
632  if (!cl) return;
633 
635  ClassDef *cd;
636  for (cli.toFirst();(cd=cli.current());++cli)
637  {
638  if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
639  {
640  bindTextParameter(innerclass_insert,":refid",cd->getOutputFileBase(),FALSE);
641  bindIntParameter(innerclass_insert,":prot",cd->protection());
642  bindTextParameter(innerclass_insert,":name",cd->name());
643  step(db,innerclass_insert);
644  }
645  }
646 }
647 
648 
649 static void writeInnerNamespaces(sqlite3 *db,const NamespaceSDict *nl)
650 {
651  if (nl)
652  {
653  NamespaceSDict::Iterator nli(*nl);
654  NamespaceDef *nd;
655  for (nli.toFirst();(nd=nli.current());++nli)
656  {
657  if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
658  {
659  bindTextParameter(innernamespace_insert,":refid",nd->getOutputFileBase(),FALSE);
660  bindTextParameter(innernamespace_insert,":name",nd->name(),FALSE);
661  step(db,innernamespace_insert);
662  }
663  }
664  }
665 }
666 
667 
668 static void writeTemplateArgumentList(sqlite3* db,
669  ArgumentList * al,
670  Definition * scope,
671  FileDef * fileScope)
672 {
673  if (al)
674  {
675  ArgumentListIterator ali(*al);
676  Argument *a;
677  for (ali.toFirst();(a=ali.current());++ali)
678  {
679  if (!a->type.isEmpty())
680  {
681  #warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
682  bindTextParameter(params_select,":type",a->type);
683  bindTextParameter(params_insert,":type",a->type);
684  }
685  if (!a->name.isEmpty())
686  {
687  bindTextParameter(params_select,":declname",a->name);
688  bindTextParameter(params_insert,":declname",a->name);
689  bindTextParameter(params_select,":defnname",a->name);
690  bindTextParameter(params_insert,":defnname",a->name);
691  }
692  if (!a->defval.isEmpty())
693  {
694  #warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
695  bindTextParameter(params_select,":defval",a->defval);
696  bindTextParameter(params_insert,":defval",a->defval);
697  }
698  if (!step(db,params_select,TRUE,TRUE))
699  step(db,params_insert);
700  }
701  }
702 }
703 
704 static void writeMemberTemplateLists(sqlite3* db,MemberDef *md)
705 {
706  ArgumentList *templMd = md->templateArguments();
707  if (templMd) // function template prefix
708  {
709  writeTemplateArgumentList(db,templMd,md->getClassDef(),md->getFileDef());
710  }
711 }
712 static void writeTemplateList(sqlite3*db,ClassDef *cd)
713 {
715 }
716 ////////////////////////////////////////////
717 
718 //////////////////////////////////////////////////////////////////////////////
719 static void generateSqlite3ForMember(sqlite3*db,MemberDef *md,Definition *def)
720 {
721  // + declaration/definition arg lists
722  // + reimplements
723  // + reimplementedBy
724  // + exceptions
725  // + const/volatile specifiers
726  // - examples
727  // + source definition
728  // + source references
729  // + source referenced by
730  // - body code
731  // + template arguments
732  // (templateArguments(), definitionTemplateParameterLists())
733  // - call graph
734 
735  // enum values are written as part of the enum
736  if (md->memberType()==MemberType_EnumValue) return;
737  if (md->isHidden()) return;
738  //if (md->name().at(0)=='@') return; // anonymous member
739 
740  // group members are only visible in their group
741  //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
742  QCString memType;
743  // memberdef
744  bindTextParameter(memberdef_insert,":refid",md->anchor().data(),FALSE);
745  bindIntParameter(memberdef_insert,":kind",md->memberType());
746  bindIntParameter(memberdef_insert,":prot",md->protection());
747 
748  bindIntParameter(memberdef_insert,":static",md->isStatic());
749 
750  bool isFunc=FALSE;
751  switch (md->memberType())
752  {
753  case MemberType_Function: // fall through
754  case MemberType_Signal: // fall through
755  case MemberType_Friend: // fall through
756  case MemberType_DCOP: // fall through
757  case MemberType_Slot:
758  isFunc=TRUE;
759  break;
760  default:
761  break;
762  }
763 
764  if (isFunc)
765  {
766  ArgumentList *al = md->argumentList();
767  if (al!=0)
768  {
769  bindIntParameter(memberdef_insert,":const",al->constSpecifier);
770  }
771  bindIntParameter(memberdef_insert,":explicit",md->isExplicit());
772  bindIntParameter(memberdef_insert,":inline",md->isInline());
773  bindIntParameter(memberdef_insert,":final",md->isFinal());
774  bindIntParameter(memberdef_insert,":sealed",md->isSealed());
775  bindIntParameter(memberdef_insert,":new",md->isNew());
776  bindIntParameter(memberdef_insert,":optional",md->isOptional());
777  bindIntParameter(memberdef_insert,":required",md->isRequired());
778 
779  bindIntParameter(memberdef_insert,":virt",md->virtualness());
780  }
781  // place in the arguments and linkify the arguments
782 
783  if (md->memberType() == MemberType_Variable)
784  {
785  bindIntParameter(memberdef_insert,":mutable",md->isMutable());
786  bindIntParameter(memberdef_insert,":initonly",md->isInitonly());
787  }
788  else if (md->memberType() == MemberType_Property)
789  {
790  bindIntParameter(memberdef_insert,":readable",md->isReadable());
791  bindIntParameter(memberdef_insert,":writable",md->isWritable());
792  bindIntParameter(memberdef_insert,":gettable",md->isGettable());
793  bindIntParameter(memberdef_insert,":settable",md->isSettable());
794  if (md->isAssign() || md->isCopy() || md->isRetain())
795  {
796  int accessor = md->isAssign() ? md->isAssign() :
797  (md->isCopy() ? md->isCopy() : md->isRetain()) ;
798 
799  bindIntParameter(memberdef_insert,":accessor",accessor);
800  }
801  }
802  else if (md->memberType() == MemberType_Event)
803  {
804  bindIntParameter(memberdef_insert,":addable",md->isAddable());
805  bindIntParameter(memberdef_insert,":removable",md->isRemovable());
806  bindIntParameter(memberdef_insert,":raisable",md->isRaisable());
807  }
808 
809  // + declaration/definition arg lists
810  if (md->memberType()!=MemberType_Define &&
812  )
813  {
814  if (md->memberType()!=MemberType_Typedef)
815  {
817  }
818  QCString typeStr = md->typeString();
819  stripQualifiers(typeStr);
820  StringList l;
821  linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,typeStr);
822  if (typeStr.data())
823  {
824  bindTextParameter(memberdef_insert,":type",typeStr.data(),FALSE);
825  }
826 
827  if (md->definition())
828  {
829  bindTextParameter(memberdef_insert,":definition",md->definition());
830  }
831 
832  if (md->argsString())
833  {
834  bindTextParameter(memberdef_insert,":argsstring",md->argsString());
835  }
836  }
837 
838  bindTextParameter(memberdef_insert,":name",md->name());
839 
840  if (md->memberType() == MemberType_Property)
841  {
842  if (md->isReadable())
843  {
844  bindIntParameter(memberdef_insert,":readable",1);
845  }
846  if (md->isWritable())
847  {
848  bindIntParameter(memberdef_insert,":writable",1);
849  }
850  }
851 
852 
853  // Extract references from initializer
855  {
856  bindTextParameter(memberdef_insert,":initializer",md->initializer().data());
857 
858  StringList l;
859  linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,md->initializer());
860  StringListIterator li(l);
861  QCString *s;
862  while ((s=li.current()))
863  {
864  if (md->getBodyDef())
865  {
866  DBG_CTX(("initializer:%s %s %s %d\n",
867  md->anchor().data(),
868  s->data(),
869  md->getBodyDef()->getDefFileName().data(),
870  md->getStartBodyLine()));
871  insertMemberReference(db,md->anchor().data(),s->data(),md->getBodyDef()->getDefFileName().data(),md->getStartBodyLine(),1);
872  }
873  ++li;
874  }
875  }
876 
877  if ( md->getScopeString() )
878  {
879  bindTextParameter(memberdef_insert,":scope",md->getScopeString().data(),FALSE);
880  }
881 
882  // +Brief, detailed and inbody description
883  bindTextParameter(memberdef_insert,":briefdescription",md->briefDescription(),FALSE);
884  bindTextParameter(memberdef_insert,":detaileddescription",md->documentation(),FALSE);
885  bindTextParameter(memberdef_insert,":inbodydescription",md->inbodyDocumentation(),FALSE);
886 
887  // File location
888  if (md->getDefLine() != -1)
889  {
890  int id_file = insertFile(db,md->getDefFileName());
891  if (id_file!=-1)
892  {
893  bindIntParameter(memberdef_insert,":id_file",id_file);
894  bindIntParameter(memberdef_insert,":line",md->getDefLine());
895  bindIntParameter(memberdef_insert,":column",md->getDefColumn());
896 
897  if (md->getStartBodyLine()!=-1)
898  {
899  int id_bodyfile = insertFile(db,md->getBodyDef()->absFilePath());
900  if (id_bodyfile == -1)
901  {
902  sqlite3_clear_bindings(memberdef_insert.stmt);
903  }
904  else
905  {
906  bindIntParameter(memberdef_insert,":id_bodyfile",id_bodyfile);
907  bindIntParameter(memberdef_insert,":bodystart",md->getStartBodyLine());
908  bindIntParameter(memberdef_insert,":bodyend",md->getEndBodyLine());
909  }
910  }
911  }
912  }
913 
914  int id_memberdef=step(db,memberdef_insert,TRUE);
915 
916  if (isFunc)
917  {
918  insertMemberFunctionParams(db,id_memberdef,md,def);
919  }
920  else if (md->memberType()==MemberType_Define &&
921  md->argsString())
922  {
923  insertMemberDefineParams(db,id_memberdef,md,def);
924  }
925 
926  // + source references
927  // The cross-references in initializers only work when both the src and dst
928  // are defined.
929  MemberSDict *mdict = md->getReferencesMembers();
930  if (mdict!=0)
931  {
932  MemberSDict::IteratorDict mdi(*mdict);
933  MemberDef *rmd;
934  for (mdi.toFirst();(rmd=mdi.current());++mdi)
935  {
936  insertMemberReference(db,md,rmd,mdi.currentKey());
937  }
938  }
939  // + source referenced by
940  mdict = md->getReferencedByMembers();
941  if (mdict!=0)
942  {
943  MemberSDict::IteratorDict mdi(*mdict);
944  MemberDef *rmd;
945  for (mdi.toFirst();(rmd=mdi.current());++mdi)
946  {
947  insertMemberReference(db,rmd,md,mdi.currentKey());
948  }
949  }
950 }
951 
952 static void generateSqlite3Section(sqlite3*db,
953  Definition *d,
954  MemberList *ml,const char * /*kind*/,const char * /*header*/=0,
955  const char * /*documentation*/=0)
956 {
957  if (ml==0) return;
958  MemberListIterator mli(*ml);
959  MemberDef *md;
960  int count=0;
961  for (mli.toFirst();(md=mli.current());++mli)
962  {
963  // namespace members are also inserted in the file scope, but
964  // to prevent this duplication in the XML output, we filter those here.
966  {
967  count++;
968  }
969  }
970  if (count==0) return; // empty list
971  for (mli.toFirst();(md=mli.current());++mli)
972  {
973  // namespace members are also inserted in the file scope, but
974  // to prevent this duplication in the XML output, we filter those here.
975  //if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
976  {
977  generateSqlite3ForMember(db,md,d);
978  }
979  }
980 }
981 
982 
983 static void generateSqlite3ForClass(sqlite3 *db, ClassDef *cd)
984 {
985  // + list of direct super classes
986  // + list of direct sub classes
987  // + include file
988  // + list of inner classes
989  // - template argument list(s)
990  // + member groups
991  // + list of all members
992  // - brief description
993  // - detailed description
994  // - inheritance DOT diagram
995  // - collaboration DOT diagram
996  // - user defined member sections
997  // - standard member sections
998  // - detailed member documentation
999  // - examples using the class
1000 
1001  if (cd->isReference()) return; // skip external references.
1002  if (cd->isHidden()) return; // skip hidden classes.
1003  if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
1004  if (cd->templateMaster()!=0) return; // skip generated template instances.
1005 
1006  msg("Generating Sqlite3 output for class %s\n",cd->name().data());
1007 
1008  bindTextParameter(compounddef_insert,":name",cd->name());
1009  bindTextParameter(compounddef_insert,":kind",cd->compoundTypeString(),FALSE);
1010  bindIntParameter(compounddef_insert,":prot",cd->protection());
1011  bindTextParameter(compounddef_insert,":refid",cd->getOutputFileBase(),FALSE);
1012 
1013  int id_file = insertFile(db,cd->getDefFileName().data());
1014  bindIntParameter(compounddef_insert,":id_file",id_file);
1015  bindIntParameter(compounddef_insert,":line",cd->getDefLine());
1016  bindIntParameter(compounddef_insert,":column",cd->getDefColumn());
1017 
1018  step(db,compounddef_insert);
1019 
1020  // + list of direct super classes
1021  if (cd->baseClasses())
1022  {
1023  BaseClassListIterator bcli(*cd->baseClasses());
1024  BaseClassDef *bcd;
1025  for (bcli.toFirst();(bcd=bcli.current());++bcli)
1026  {
1027  bindTextParameter(basecompoundref_insert,":refid",bcd->classDef->getOutputFileBase(),FALSE);
1028  bindIntParameter(basecompoundref_insert,":prot",bcd->prot);
1029  bindIntParameter(basecompoundref_insert,":virt",bcd->virt);
1030 
1031  if (!bcd->templSpecifiers.isEmpty())
1032  {
1033  bindTextParameter(basecompoundref_insert,":base",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE);
1034  }
1035  else
1036  {
1037  bindTextParameter(basecompoundref_insert,":base",bcd->classDef->displayName(),FALSE);
1038  }
1039  bindTextParameter(basecompoundref_insert,":derived",cd->displayName(),FALSE);
1040  step(db,basecompoundref_insert);
1041  }
1042  }
1043 
1044  // + list of direct sub classes
1045  if (cd->subClasses())
1046  {
1047  BaseClassListIterator bcli(*cd->subClasses());
1048  BaseClassDef *bcd;
1049  for (bcli.toFirst();(bcd=bcli.current());++bcli)
1050  {
1051  bindTextParameter(derivedcompoundref_insert,":base",cd->displayName(),FALSE);
1052  if (!bcd->templSpecifiers.isEmpty())
1053  {
1054  bindTextParameter(derivedcompoundref_insert,":derived",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE);
1055  }
1056  else
1057  {
1058  bindTextParameter(derivedcompoundref_insert,":derived",bcd->classDef->displayName(),FALSE);
1059  }
1060  bindTextParameter(derivedcompoundref_insert,":refid",bcd->classDef->getOutputFileBase(),FALSE);
1061  bindIntParameter(derivedcompoundref_insert,":prot",bcd->prot);
1062  bindIntParameter(derivedcompoundref_insert,":virt",bcd->virt);
1063  step(db,derivedcompoundref_insert);
1064  }
1065  }
1066 
1067  // + include file
1068  IncludeInfo *ii=cd->includeInfo();
1069  if (ii)
1070  {
1071  QCString nm = ii->includeName;
1072  if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
1073  if (!nm.isEmpty())
1074  {
1075  int id_dst=insertFile(db,nm);
1076  if (id_dst!=-1) {
1077  bindIntParameter(incl_select,":local",ii->local);
1078  bindIntParameter(incl_select,":id_src",id_file);
1079  bindIntParameter(incl_select,":id_dst",id_dst);
1080  int count=step(db,incl_select,TRUE,TRUE);
1081  if (count==0)
1082  {
1083  bindIntParameter(incl_insert,":local",ii->local);
1084  bindIntParameter(incl_insert,":id_src",id_file);
1085  bindIntParameter(incl_insert,":id_dst",id_dst);
1086  step(db,incl_insert);
1087  }
1088  }
1089  }
1090  }
1091  // + list of inner classes
1092  writeInnerClasses(db,cd->getClassSDict());
1093 
1094  // - template argument list(s)
1095  writeTemplateList(db,cd);
1096 
1097  // + member groups
1098  if (cd->getMemberGroupSDict())
1099  {
1101  MemberGroup *mg;
1102  for (;(mg=mgli.current());++mgli)
1103  {
1104  generateSqlite3Section(db,cd,mg->members(),"user-defined",mg->header(),
1105  mg->documentation());
1106  }
1107  }
1108 
1109  // + list of all members
1111  MemberList *ml;
1112  for (mli.toFirst();(ml=mli.current());++mli)
1113  {
1114  if ((ml->listType()&MemberListType_detailedLists)==0)
1115  {
1116  generateSqlite3Section(db,cd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
1117  }
1118  }
1119 }
1120 
1121 static void generateSqlite3ForNamespace(sqlite3 *db, NamespaceDef *nd)
1122 {
1123  // + contained class definitions
1124  // + contained namespace definitions
1125  // + member groups
1126  // + normal members
1127  // - brief desc
1128  // - detailed desc
1129  // - location
1130  // - files containing (parts of) the namespace definition
1131 
1132  if (nd->isReference() || nd->isHidden()) return; // skip external references
1133 
1134  // + contained class definitions
1135  writeInnerClasses(db,nd->getClassSDict());
1136 
1137  // + contained namespace definitions
1139 
1140  // + member groups
1141  if (nd->getMemberGroupSDict())
1142  {
1144  MemberGroup *mg;
1145  for (;(mg=mgli.current());++mgli)
1146  {
1147  generateSqlite3Section(db,nd,mg->members(),"user-defined",mg->header(),
1148  mg->documentation());
1149  }
1150  }
1151 
1152  // + normal members
1154  MemberList *ml;
1155  for (mli.toFirst();(ml=mli.current());++mli)
1156  {
1157  if ((ml->listType()&MemberListType_declarationLists)!=0)
1158  {
1159  generateSqlite3Section(db,nd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
1160  }
1161  }
1162 }
1163 
1164 static void generateSqlite3ForFile(sqlite3 *db, FileDef *fd)
1165 {
1166  // + includes files
1167  // + includedby files
1168  // - include graph
1169  // - included by graph
1170  // + contained class definitions
1171  // + contained namespace definitions
1172  // + member groups
1173  // + normal members
1174  // - brief desc
1175  // - detailed desc
1176  // - source code
1177  // - location
1178  // - number of lines
1179 
1180  if (fd->isReference()) return; // skip external references
1181 
1182  // + includes files
1183  IncludeInfo *ii;
1184  if (fd->includeFileList())
1185  {
1187  for (ili.toFirst();(ii=ili.current());++ili)
1188  {
1189  int id_src=insertFile(db,fd->absFilePath().data());
1190  int id_dst=insertFile(db,ii->includeName.data());
1191  bindIntParameter(incl_select,":local",ii->local);
1192  bindIntParameter(incl_select,":id_src",id_src);
1193  bindIntParameter(incl_select,":id_dst",id_dst);
1194  if (step(db,incl_select,TRUE,TRUE)==0) {
1195  bindIntParameter(incl_insert,":local",ii->local);
1196  bindIntParameter(incl_insert,":id_src",id_src);
1197  bindIntParameter(incl_insert,":id_dst",id_dst);
1198  step(db,incl_insert);
1199  }
1200  }
1201  }
1202 
1203  // + includedby files
1204  if (fd->includedByFileList())
1205  {
1207  for (ili.toFirst();(ii=ili.current());++ili)
1208  {
1209  int id_src=insertFile(db,ii->includeName);
1210  int id_dst=insertFile(db,fd->absFilePath());
1211  bindIntParameter(incl_select,":local",ii->local);
1212  bindIntParameter(incl_select,":id_src",id_src);
1213  bindIntParameter(incl_select,":id_dst",id_dst);
1214  if (step(db,incl_select,TRUE,TRUE)==0) {
1215  bindIntParameter(incl_insert,":local",ii->local);
1216  bindIntParameter(incl_insert,":id_src",id_src);
1217  bindIntParameter(incl_insert,":id_dst",id_dst);
1218  step(db,incl_insert);
1219  }
1220  }
1221  }
1222 
1223  // + contained class definitions
1224  if (fd->getClassSDict())
1225  {
1226  writeInnerClasses(db,fd->getClassSDict());
1227  }
1228 
1229  // + contained namespace definitions
1230  if (fd->getNamespaceSDict())
1231  {
1233  }
1234 
1235  // + member groups
1236  if (fd->getMemberGroupSDict())
1237  {
1239  MemberGroup *mg;
1240  for (;(mg=mgli.current());++mgli)
1241  {
1242  generateSqlite3Section(db,fd,mg->members(),"user-defined",mg->header(),
1243  mg->documentation());
1244  }
1245  }
1246 
1247  // + normal members
1249  MemberList *ml;
1250  for (mli.toFirst();(ml=mli.current());++mli)
1251  {
1252  if ((ml->listType()&MemberListType_declarationLists)!=0)
1253  {
1254  generateSqlite3Section(db,fd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
1255  }
1256  }
1257 }
1258 
1259 static void generateSqlite3ForGroup(sqlite3*db,GroupDef *gd)
1260 {
1261 #warning WorkInProgress
1262 }
1263 
1264 static void generateSqlite3ForDir(sqlite3 *db,DirDef *dd)
1265 {
1266 #warning WorkInProgress
1267 }
1268 
1269 static void generateSqlite3ForPage(sqlite3 *db,PageDef *pd,bool isExample)
1270 {
1271 #warning WorkInProgress
1272 }
1273 //////////////////////////////////////////////////////////////////////////////
1274 //////////////////////////////////////////////////////////////////////////////
1275 void generateSqlite3()
1276 {
1277  // + classes
1278  // + namespaces
1279  // + files
1280  // + groups
1281  // + related pages
1282  // + examples
1283  // + main page
1284 
1285  QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
1286  QDir sqlite3Dir(outputDirectory);
1287  sqlite3 *db;
1288  sqlite3_initialize();
1289  int rc = sqlite3_open_v2(outputDirectory+"/doxygen_sqlite3.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
1290  if (rc != SQLITE_OK)
1291  {
1292  sqlite3_close(db);
1293  msg("database open failed: %s\n", "doxygen_sqlite3.db");
1294  return;
1295  }
1296  beginTransaction(db);
1297  pragmaTuning(db);
1298 
1299  if (-1==initializeSchema(db))
1300  return;
1301 
1302  if ( -1 == prepareStatements(db) )
1303  {
1304  err("sqlite generator: prepareStatements failed!");
1305  return;
1306  }
1307 
1308  // + classes
1310  ClassDef *cd;
1311  for (cli.toFirst();(cd=cli.current());++cli)
1312  {
1313  msg("Generating Sqlite3 output for class %s\n",cd->name().data());
1314  generateSqlite3ForClass(db,cd);
1315  }
1316 
1317  // + namespaces
1319  NamespaceDef *nd;
1320  for (nli.toFirst();(nd=nli.current());++nli)
1321  {
1322  msg("Generating Sqlite3 output for namespace %s\n",nd->name().data());
1323  generateSqlite3ForNamespace(db,nd);
1324  }
1325 
1326  // + files
1328  FileName *fn;
1329  for (;(fn=fnli.current());++fnli)
1330  {
1331  FileNameIterator fni(*fn);
1332  FileDef *fd;
1333  for (;(fd=fni.current());++fni)
1334  {
1335  msg("Generating Sqlite3 output for file %s\n",fd->name().data());
1336  generateSqlite3ForFile(db,fd);
1337  }
1338  }
1339 
1340  // + groups
1342  GroupDef *gd;
1343  for (;(gd=gli.current());++gli)
1344  {
1345  msg("Generating Sqlite3 output for group %s\n",gd->name().data());
1346  generateSqlite3ForGroup(db,gd);
1347  }
1348 
1349  // + page
1350  {
1352  PageDef *pd=0;
1353  for (pdi.toFirst();(pd=pdi.current());++pdi)
1354  {
1355  msg("Generating Sqlite3 output for page %s\n",pd->name().data());
1356  generateSqlite3ForPage(db,pd,FALSE);
1357  }
1358  }
1359 
1360  // + dirs
1361  {
1362  DirDef *dir;
1364  for (sdi.toFirst();(dir=sdi.current());++sdi)
1365  {
1366  msg("Generating Sqlite3 output for dir %s\n",dir->name().data());
1367  generateSqlite3ForDir(db,dir);
1368  }
1369  }
1370 
1371  // + examples
1372  {
1374  PageDef *pd=0;
1375  for (pdi.toFirst();(pd=pdi.current());++pdi)
1376  {
1377  msg("Generating Sqlite3 output for example %s\n",pd->name().data());
1378  generateSqlite3ForPage(db,pd,TRUE);
1379  }
1380  }
1381 
1382  // + main page
1383  if (Doxygen::mainPage)
1384  {
1385  msg("Generating Sqlite3 output for the main page\n");
1386  generateSqlite3ForPage(db,Doxygen::mainPage,FALSE);
1387  }
1388 
1389  endTransaction(db);
1390 }
1391 
1392 #else // USE_SQLITE3
1394 {
1395  err("sqlite3 support has not been compiled in!");
1396 }
1397 #endif
1398 // vim: noai:ts=2:sw=2:ss=2:expandtab
static QCString name
Definition: declinfo.cpp:673
Traverses directory structures and contents in a platform-independent way.
Definition: qdir.h:52
bool isFinal() const
Definition: memberdef.cpp:4280
QCString type
Definition: arguments.h:67
bool isReadable() const
Definition: memberdef.cpp:4270
static GroupSDict * groupSDict
Definition: doxygen.h:119
bool isAddable() const
Definition: memberdef.cpp:4255
bool isOptional() const
Definition: memberdef.cpp:4310
This class represents an function or template argument list.
Definition: arguments.h:82
ClassSDict * getClassSDict() const
Definition: filedef.h:134
static QCString scope
Definition: declinfo.cpp:668
bool isMutable() const
Definition: memberdef.cpp:4220
bool isCopy() const
Definition: memberdef.cpp:4325
BaseClassList * subClasses() const
Definition: classdef.cpp:4404
bool hasMultiLineInitializer() const
Definition: memberdef.cpp:3460
IncludeInfo * includeInfo() const
Definition: classdef.cpp:4449
static PageSDict * exampleSDict
Definition: doxygen.h:101
bool isEmpty() const
Definition: qcstring.h:189
void msg(const char *fmt,...)
Definition: message.cpp:107
void append(const type *d)
Definition: qlist.h:73
Protection protection() const
Definition: memberdef.cpp:4120
QCString getOutputFileBase() const
QCString inbodyDocumentation() const
ArgumentList * templateArguments() const
Definition: classdef.cpp:4419
QCString defval
Definition: arguments.h:71
FileDef * getBodyDef() const
QCString compoundTypeString() const
Definition: classdef.cpp:3499
bool isRequired() const
Definition: memberdef.cpp:4315
const bool FALSE
Definition: qglobal.h:370
friend class Iterator
Definition: sortdict.h:598
static FileNameList * inputNameList
Definition: doxygen.h:109
bool isReference() const
Definition: classdef.cpp:3826
const QList< MemberList > & getMemberLists() const
Definition: namespacedef.h:91
struct sqlite3_stmt sqlite3_stmt
bool stripPrefix(const char *prefix)
Definition: qcstring.cpp:201
virtual bool isReference() const
static void writeMemberTemplateLists(MemberDef *md, FTextStream &t)
Definition: xmlgen.cpp:409
string dir
QCString displayName(bool includeScope=TRUE) const
Definition: classdef.cpp:312
int find(char c, int index=0, bool cs=TRUE) const
Definition: qcstring.cpp:41
bool isInline() const
Definition: memberdef.cpp:4210
static constexpr double mg
Definition: Units.h:145
static QStrList * l
Definition: config.cpp:1044
QAsciiDict< Entry > cl
ArgumentList * declArgumentList() const
Definition: memberdef.cpp:4517
ClassSDict * getClassSDict()
Definition: classdef.cpp:4389
Protection protection() const
Definition: classdef.cpp:4414
MemberSDict * getReferencesMembers() const
QCString getDefFileName() const
static void writeString(QFile &f, const char *s)
bool constSpecifier
Definition: arguments.h:99
int getDefColumn() const
Definition: definition.h:191
FileDef * getFileDef() const
Definition: memberdef.cpp:4075
static NamespaceSDict * namespaceSDict
Definition: doxygen.h:120
ClassDef * templateMaster() const
Definition: classdef.cpp:4439
virtual DefType definitionType() const =0
Specifier virtualness(int count=0) const
Definition: memberdef.cpp:3560
def cli(ctx)
Definition: main.py:7
bool isExplicit() const
Definition: memberdef.cpp:4215
This class contains the information about the argument of a function or template. ...
Definition: arguments.h:28
const char * typeString() const
Definition: memberdef.cpp:4035
uint count() const
Definition: qlist.h:66
MemberSDict * getReferencedByMembers() const
static void writeInnerNamespaces(const NamespaceSDict *nl, FTextStream &t)
Definition: docbookgen.cpp:956
bool isNew() const
Definition: memberdef.cpp:4285
QAsciiDict< Entry > fn
const QCString & name() const
Definition: definition.h:114
NamespaceSDict * getNamespaceSDict() const
Definition: filedef.h:133
int getDefLine() const
Definition: definition.h:188
QCString getScopeString() const
Definition: memberdef.cpp:3301
bool isRemovable() const
Definition: memberdef.cpp:4260
QCString name() const
Definition: filedef.cpp:1193
QCString briefDescription(bool abbr=FALSE) const
Definition: memberdef.cpp:5073
QList< IncludeInfo > * includeFileList() const
Definition: filedef.h:124
const double a
static DirSDict * directories
Definition: doxygen.h:139
bool isWritable() const
Definition: memberdef.cpp:4275
bool isAssign() const
Definition: memberdef.cpp:4330
bool isSettable() const
Definition: memberdef.cpp:4240
A bunch of utility functions.
static PageSDict * pageSDict
Definition: doxygen.h:102
bool isInitonly() const
Definition: memberdef.cpp:4300
const char * data() const
Definition: qcstring.h:207
Definition: dirdef.h:44
const QList< MemberList > & getMemberLists() const
Definition: filedef.h:129
QCString anchor() const
Definition: memberdef.cpp:1031
#define Config_getString(val)
Definition: config.cpp:660
bool isGettable() const
Definition: memberdef.cpp:4225
QCString includeName
Definition: filedef.h:50
const char * definition() const
Definition: memberdef.cpp:4025
ClassDef * getClassDef() const
Definition: memberdef.cpp:4070
#define DBG_CTX(x)
Definition: code.cpp:10585
friend class IteratorDict
Definition: sortdict.h:353
void err(const char *fmt,...)
Definition: message.cpp:226
auto select(T const &...t)
Definition: select.h:146
MemberType memberType() const
Definition: memberdef.cpp:4125
struct sqlite3 sqlite3
QCString absFilePath() const
Definition: filedef.h:96
NamespaceSDict * getNamespaceSDict() const
Definition: namespacedef.h:101
static void writeTemplateArgumentList(ArgumentList *al, FTextStream &t, Definition *scope, FileDef *fileScope, int indent)
Definition: docbookgen.cpp:283
QCString getOutputFileBase() const
Definition: classdef.cpp:3533
MemberGroupSDict * getMemberGroupSDict() const
Definition: classdef.cpp:4524
bool hasOneLineInitializer() const
Definition: memberdef.cpp:3451
bool local
Definition: filedef.h:51
QCString documentation() const
Definition: memberdef.cpp:5085
bool isHidden() const
int getEndBodyLine() const
QCString attrib
Definition: arguments.h:66
FileDef * fileDef
Definition: filedef.h:49
ArgumentList * argumentList() const
Definition: memberdef.cpp:4512
int getStartBodyLine() const
static void writeLink(const MemberDef *mdef, OutputList &ol)
Definition: vhdldocgen.cpp:131
QList< IncludeInfo > * includedByFileList() const
Definition: filedef.h:125
bool isRetain() const
Definition: memberdef.cpp:4335
const QCString & initializer() const
Definition: memberdef.cpp:4055
A model of a page symbol.
Definition: pagedef.h:29
QCString name
Definition: arguments.h:69
void line(double t, double *p, double &x, double &y, double &z)
std::vector< std::string > column
MemberGroupSDict * getMemberGroupSDict() const
Definition: filedef.h:132
QCString insertTemplateSpecifierInScope(const QCString &scope, const QCString &templ)
Definition: util.cpp:5527
MemberGroupSDict * getMemberGroupSDict() const
Definition: namespacedef.h:95
NamespaceDef * getNamespaceDef() const
Definition: memberdef.cpp:4080
friend class Iterator
Definition: sortdict.h:289
void generateSqlite3()
ClassSDict * getClassSDict() const
Definition: namespacedef.h:98
const char * argsString() const
Definition: memberdef.cpp:4040
bool isSealed() const
Definition: memberdef.cpp:4290
bool isStatic() const
Definition: memberdef.cpp:4205
void linkifyText(const TextGeneratorIntf &out, Definition *scope, FileDef *fileScope, Definition *self, const char *text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
Definition: util.cpp:1916
query_result< Args... > query(sqlite3 *db, std::string const &ddl)
Definition: select.h:75
virtual QCString documentation() const
bool isRaisable() const
Definition: memberdef.cpp:4265
static void stripQualifiers(QCString &typeStr)
Definition: xmlgen.cpp:493
void setAutoDelete(bool enable)
Definition: qlist.h:99
static ClassSDict * classSDict
Definition: doxygen.h:99
const QList< MemberList > & getMemberLists() const
Definition: classdef.cpp:4519
static PageDef * mainPage
Definition: doxygen.h:103
std::string nl(std::size_t i=1)
const QCString & docName() const
Definition: filedef.h:99
static QCString * s
Definition: config.cpp:1042
const bool TRUE
Definition: qglobal.h:371
QCString & append(const char *s)
Definition: qcstring.cpp:383
BaseClassList * baseClasses() const
Definition: classdef.cpp:4399
ArgumentList * templateArguments() const
Definition: memberdef.cpp:4522
Definition: qlist.h:54
QCString array
Definition: arguments.h:70
static void writeInnerClasses(const ClassSDict *cl, FTextStream &t)
Definition: docbookgen.cpp:916
static void writeTemplateList(ClassDef *cd, FTextStream &t)
Definition: docbookgen.cpp:322