2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
11 #include <ksimpleconfig.h>
15 #include "typetable.h"
18 //! the TypeTables of all known libraries
19 static QList
<TypeTable
> typeTables
;
20 bool typeTablesInited
= false;
23 //! an indentifier for wchar_t
24 TypeInfo
TypeInfo::m_wchartType("");
26 TypeInfo
TypeInfo::m_unknownType("");
29 void TypeTable::initTypeLibraries()
31 if (!typeTablesInited
) {
32 TypeTable::loadTypeTables();
36 void TypeTable::loadTypeTables()
38 typeTablesInited
= true;
40 const QStringList files
= KGlobal::dirs()->findAllResources("types", "*.kdbgtt",
43 if (files
.isEmpty()) {
44 TRACE("no type tables found");
49 for (QValueListConstIterator
<QString
> p
= files
.begin(); p
!= files
.end(); ++p
) {
51 TypeTable
* newTable
= new TypeTable
;
52 newTable
->loadFromFile(fileName
);
53 typeTables
.append(newTable
);
58 TypeTable::TypeTable() :
59 m_printQStringDataCmd(0)
61 m_typeDict
.setAutoDelete(true);
62 // aliasDict keeps only pointers to items into typeDict
63 m_aliasDict
.setAutoDelete(false);
66 TypeTable::~TypeTable()
68 delete[] m_printQStringDataCmd
;
72 static const char TypeTableGroup
[] = "Type Table";
73 static const char LibDisplayName
[] = "LibDisplayName";
74 static const char ShlibRE
[] = "ShlibRE";
75 static const char EnableBuiltin
[] = "EnableBuiltin";
76 static const char PrintQStringCmd
[] = "PrintQStringCmd";
77 static const char TypesEntryFmt
[] = "Types%d";
78 static const char DisplayEntry
[] = "Display";
79 static const char AliasEntry
[] = "Alias";
80 static const char ExprEntryFmt
[] = "Expr%d";
81 static const char FunctionGuardEntryFmt
[] = "FunctionGuard%d";
84 void TypeTable::loadFromFile(const QString
& fileName
)
86 TRACE("reading file " + fileName
);
87 KSimpleConfig
cf(fileName
, true); /* read-only */
90 * Read library name and properties.
92 cf
.setGroup(TypeTableGroup
);
93 m_displayName
= cf
.readEntry(LibDisplayName
);
94 if (m_displayName
.isEmpty()) {
95 // use file name instead
96 QFileInfo
fi(fileName
);
97 m_displayName
= fi
.baseName(true);
100 m_shlibNameRE
= QRegExp(cf
.readEntry(ShlibRE
));
101 m_enabledBuiltins
= cf
.readListEntry(EnableBuiltin
);
103 QString printQString
= cf
.readEntry(PrintQStringCmd
);
104 const char* ascii
= printQString
.ascii();
107 m_printQStringDataCmd
= new char[strlen(ascii
)+1];
108 strcpy(m_printQStringDataCmd
, ascii
);
111 * Get the types. We search for entries of kind Types1, Types2, etc.
112 * because a single entry Types could get rather long for large
116 for (int i
= 1; ; i
++) {
117 // next bunch of types
118 cf
.setGroup(TypeTableGroup
);
119 typesEntry
.sprintf(TypesEntryFmt
, i
);
120 if (!cf
.hasKey(typesEntry
))
123 QStringList typeNames
= cf
.readListEntry(typesEntry
, ',');
127 for (QStringList::iterator it
= typeNames
.begin(); it
!= typeNames
.end(); ++it
)
130 // check if this is an alias
131 alias
= cf
.readEntry(AliasEntry
);
132 if (alias
.isEmpty()) {
135 // look up the alias type and insert it
136 TypeInfo
* info
= m_typeDict
[alias
];
138 TRACE(*it
+ ": alias " + alias
+ " not found");
140 m_aliasDict
.insert(alias
, info
);
141 TRACE(*it
+ ": alias " + alias
);
148 void TypeTable::readType(KConfigBase
& cf
, const QString
& type
)
150 // the display string
151 QString expr
= cf
.readEntry(DisplayEntry
);
153 TypeInfo
* info
= new TypeInfo(expr
);
154 if (info
->m_numExprs
== 0) {
155 TRACE("bogus type " + type
+ ": no %% in Display: " + expr
);
160 // Expr1, Expr2, etc...
162 QString funcGuardEntry
;
163 for (int j
= 0; j
< info
->m_numExprs
; j
++) {
164 exprEntry
.sprintf(ExprEntryFmt
, j
+1);
165 expr
= cf
.readEntry(exprEntry
);
166 info
->m_exprStrings
[j
] = expr
;
168 funcGuardEntry
.sprintf(FunctionGuardEntryFmt
, j
+1);
169 expr
= cf
.readEntry(funcGuardEntry
);
170 info
->m_guardStrings
[j
] = expr
;
174 m_typeDict
.insert(type
, info
);
175 TRACE(type
+ QString().sprintf(": %d exprs", info
->m_numExprs
));
178 void TypeTable::copyTypes(QDict
<TypeInfo
>& dict
)
180 for (QDictIterator
<TypeInfo
> it
= m_typeDict
; it
!= 0; ++it
) {
181 dict
.insert(it
.currentKey(), it
);
183 for (QDictIterator
<TypeInfo
> it
= m_aliasDict
; it
!= 0; ++it
) {
184 dict
.insert(it
.currentKey(), it
);
188 bool TypeTable::isEnabledBuiltin(const QString
& feature
) const
190 return m_enabledBuiltins
.find(feature
) != m_enabledBuiltins
.end();
193 TypeInfo::TypeInfo(const QString
& displayString
)
195 // decompose the input into the parts
199 while (i
< typeInfoMaxExpr
&&
200 (idx
= displayString
.find('%', startIdx
)) >= 0)
202 m_displayString
[i
] = displayString
.mid(startIdx
, idx
-startIdx
);
208 * Remaining string; note that there's one more display string than
211 m_displayString
[i
] = displayString
.right(displayString
.length()-startIdx
);
214 TypeInfo::~TypeInfo()
219 ProgramTypeTable::ProgramTypeTable() :
220 m_parseQt2QStrings(false),
221 m_QCharIsShort(false),
222 m_printQStringDataCmd(0)
224 m_types
.setAutoDelete(false); /* paranoia */
225 m_aliasDict
.setAutoDelete(false); /* paranoia */
228 ProgramTypeTable::~ProgramTypeTable()
232 void ProgramTypeTable::clear()
237 void ProgramTypeTable::loadTypeTable(TypeTable
* table
)
239 table
->copyTypes(m_types
);
240 // check whether to enable builtin QString support
241 if (!m_parseQt2QStrings
) {
242 m_parseQt2QStrings
= table
->isEnabledBuiltin("QString::Data");
244 if (!m_QCharIsShort
) {
245 m_QCharIsShort
= table
->isEnabledBuiltin("QCharIsShort");
247 if (!m_printQStringDataCmd
&& *table
->printQStringDataCmd()) {
248 m_printQStringDataCmd
= table
->printQStringDataCmd();
252 TypeInfo
* ProgramTypeTable::lookup(const QString
& type
)
254 TypeInfo
* result
= m_types
[type
];
256 result
= m_aliasDict
[type
];
261 void ProgramTypeTable::registerAlias(const QString
& name
, TypeInfo
* type
)
263 ASSERT(lookup(name
) == 0 || lookup(name
) == type
);
264 m_aliasDict
.insert(name
, type
);
267 void ProgramTypeTable::loadLibTypes(const QStrList
& libs
)
269 QStrListIterator it
= libs
;
272 * We use a copy of the list of known libraries, from which we delete
273 * those libs that we already have added. This way we avoid to load a
276 QList
<TypeTable
> allTables
= typeTables
; /* shallow copy! */
277 allTables
.setAutoDelete(false); /* important! */
279 for (; it
&& allTables
.count() > 0; ++it
)
281 // look up the library
283 for (TypeTable
* t
= allTables
.first(); t
!= 0; t
= allTables
.next())
285 if (t
->matchFileName(it
))
287 TRACE("adding types for " + QString(it
));
292 * continue the search (due to remove's unpredictable
293 * behavior of setting the current item we simply go
294 * through the whole list again)