00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <stdarg.h>
00027 #include <sys/time.h>
00028
00029 #include <QDir>
00030 #include <QFile>
00031 #include <QFileInfo>
00032 #include <QRegExp>
00033 #include <QApplication>
00034 #include <QMetaObject>
00035 #include <QDebug>
00036 #include <QDateTime>
00037
00038 #include "klfdefs.h"
00039
00050
00051
00052
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00878
00879
00903 static char __klf_version_string[] = KLF_VERSION_STRING;
00904
00905
00906 KLF_EXPORT const char * klfVersion()
00907 {
00908 return __klf_version_string;
00909 }
00910
00911 KLF_EXPORT int klfVersionMaj()
00912 {
00913 return KLF_VERSION_MAJ;
00914 }
00915 KLF_EXPORT int klfVersionMin()
00916 {
00917 return KLF_VERSION_MIN;
00918 }
00919 KLF_EXPORT int klfVersionRelease()
00920 {
00921 return KLF_VERSION_REL;
00922 }
00923
00924
00925
00926
00927
00928
00929 class KLFDebugObjectWatcherPrivate
00930 {
00931 public:
00932 QMap<quintptr, QString> refInfos;
00933 };
00934
00935
00936 KLFDebugObjectWatcher *KLFDebugObjectWatcher::instance = NULL;
00937
00938 KLFDebugObjectWatcher *KLFDebugObjectWatcher::getWatcher()
00939 {
00940 if (instance == NULL)
00941 instance = new KLFDebugObjectWatcher;
00942 return instance;
00943 }
00944
00945 void KLFDebugObjectWatcher::registerObjectRefInfo(QObject *object, const QString& refinfo)
00946 {
00947 p->refInfos[(quintptr)object] = refinfo;
00948 }
00949
00950 KLFDebugObjectWatcher::KLFDebugObjectWatcher()
00951 : QObject(qApp)
00952 {
00953 p = new KLFDebugObjectWatcherPrivate;
00954 }
00955 KLFDebugObjectWatcher::~KLFDebugObjectWatcher()
00956 {
00957 delete p;
00958 }
00959 void KLFDebugObjectWatcher::debugObjectDestroyed(QObject *object)
00960 {
00961 quintptr obji = (quintptr) object;
00962 if (p->refInfos.contains(obji)) {
00963 klfDbg(klfFmtCC("Object destroyed: (%s*)%p; object reference name is `%s'",
00964 (object ? object->metaObject()->className() : "void"),
00965 (void*)object, qPrintable(p->refInfos[obji])));
00966 } else {
00967 klfDbg(klfFmtCC("Object destroyed: (%s*)%p",
00968 (object ? object->metaObject()->className() : "void"),
00969 (void*)object));
00970 }
00971 }
00972
00973
00974
00975 KLF_EXPORT QByteArray klfShortFuncSignature(const QByteArray& funcname)
00976 {
00977
00978 int iSpc, iParen;
00979 iParen = funcname.indexOf('(');
00980 iSpc = funcname.lastIndexOf(' ', iParen-2);
00981
00982 if (iParen == -1 || iSpc > iParen) {
00983 qWarning("klfShortFuncSignature('%s'): Signature parse error!", funcname.constData());
00984 return funcname;
00985 }
00986
00987 QByteArray f = funcname.mid(iSpc+1, iParen-(iSpc+1));
00988
00989 if (f.startsWith("operator")) {
00990 return funcname.mid(iSpc+1);
00991 }
00992 return f;
00993 }
00994
00995
00996
00997
00998 KLF_EXPORT QByteArray klfFmt(const char * fmt, va_list pp)
00999 {
01000 static const int bufferSize = 8192;
01001 char buffer[bufferSize];
01002 int len;
01003 #if defined(_BSD_SOURCE) || _XOPEN_SOURCE >= 500 || defined(_ISOC99_SOURCE)
01004
01005 len = vsnprintf(buffer, bufferSize, fmt, pp);
01006 if (len >= bufferSize) {
01007
01008 qWarning("%s(): output from format string \"%s\" was truncated from %d to %d bytes.",
01009 KLF_FUNC_NAME, fmt, len, (bufferSize-1));
01010 len = bufferSize-1;
01011 }
01012 #else
01013 len = vsprintf(buffer, fmt, pp);
01014 #endif
01015
01016 if (len < 0) {
01017 qWarning("%s(): vs(n)printf() failed for format \"%s\"", KLF_FUNC_NAME, fmt);
01018 return QByteArray();
01019 }
01020
01021
01022 QByteArray data;
01023 data = QByteArray(buffer, len);
01024 return data;
01025 }
01026
01027 KLF_EXPORT QByteArray klfFmt(const char * fmt, ...)
01028 {
01029 va_list pp;
01030 va_start(pp, fmt);
01031 QByteArray data = klfFmt(fmt, pp);
01032 va_end(pp);
01033 return data;
01034 }
01035
01036
01037 KLF_EXPORT QByteArray klfFmtDouble(double num, char fmt, int precision)
01038 {
01039 QString s = QString::number(num, fmt, precision);
01040
01041 QByteArray data;
01042 data = s.toLatin1();
01043 return data;
01044 }
01045
01046
01047
01048
01049 KLF_EXPORT QString klfTimeOfDay(bool shortfmt)
01050 {
01051 struct timeval tv;
01052 gettimeofday(&tv, NULL);
01053 char temp[128];
01054 if (shortfmt)
01055 sprintf(temp, "%03ld.%06ld", (ulong)tv.tv_sec % 1000, (ulong)tv.tv_usec);
01056 else
01057 sprintf(temp, "%ld.%06ld", (ulong)tv.tv_sec, (ulong)tv.tv_usec);
01058 return QString::fromLatin1(temp);
01059 }
01060
01061
01062
01063 static int __klf_dbg_block_depth_counter = 0;
01064
01065
01066 KLFDebugBlock::KLFDebugBlock(const QString& blockName)
01067 : pBlockName(blockName), pPrintMsg(true)
01068 {
01069
01070
01071
01072
01073
01074 qDebug("%s: [%02d]block begin", qPrintable(pBlockName), ++__klf_dbg_block_depth_counter);
01075
01076 }
01077 KLFDebugBlock::KLFDebugBlock(bool printmsg, const QString& blockName)
01078 : pBlockName(blockName), pPrintMsg(printmsg)
01079 {
01080
01081
01082 if (printmsg)
01083 qDebug("%s: [%02d]block begin", qPrintable(pBlockName), ++__klf_dbg_block_depth_counter);
01084
01085 }
01086 KLFDebugBlock::~KLFDebugBlock()
01087 {
01088
01089
01090 if (pPrintMsg)
01091 qDebug("%s: [%02d]block end", qPrintable(pBlockName), __klf_dbg_block_depth_counter--);
01092
01093 }
01094 KLFDebugBlockTimer::KLFDebugBlockTimer(const QString& blockName)
01095 : KLFDebugBlock(false, blockName)
01096 {
01097
01098
01099 qDebug("+T:%s: %s: [%02d]block begin", KLF_SHORT_TIME, qPrintable(pBlockName), ++__klf_dbg_block_depth_counter);
01100
01101 }
01102 KLFDebugBlockTimer::~KLFDebugBlockTimer()
01103 {
01104
01105
01106 qDebug("+T:%s: %s: [%02d]block end", KLF_SHORT_TIME, qPrintable(pBlockName), __klf_dbg_block_depth_counter--);
01107
01108 }
01109
01110 inline QString func_name_w_parens(const char *f)
01111 {
01112 QString s = QLatin1String(f);
01113 if (s.indexOf('(') == -1)
01114 return s+"()";
01115 return s;
01116 }
01117
01118
01119
01120 KLF_EXPORT QDebug __klf_dbg_hdr(QDebug dbg, const char * funcname, const char *refinstance, const char * shorttime)
01121 {
01122 if (shorttime == NULL)
01123 return dbg.nospace()<<qPrintable(func_name_w_parens(funcname))<<":"<<refinstance
01124 <<"\n ";
01125 else
01126 return dbg.nospace()<<"+T:"<<shorttime<<": "<<qPrintable(func_name_w_parens(funcname))<<":"<<refinstance
01127 <<"\n ";
01128 }
01129
01130 KLF_EXPORT QDebug __klf_warning_hdr(QDebug warndbg, const char * funcname, const char * shorttime)
01131 {
01132 Q_UNUSED(shorttime) ;
01133 return warndbg.nospace()<<"***** In function "<<qPrintable(func_name_w_parens(funcname))
01134 <<" "
01135 <<qPrintable(QDateTime::currentDateTime().toString(Qt::DefaultLocaleShortDate))
01136 <<" *****"
01137 <<"\n ";
01138
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148 QStringList klf_version_suffixes =
01149 QStringList() << "a" << "alpha" << "b" << "beta" << "p" << "pre" << "preview" << "RC" << "rc"
01150 << ""
01151 << "post" << "dev" << "devel";
01152
01153 static int __klf_version_compare_suffix_words(QString w1, QString w2)
01154 {
01155
01156 const QStringList& words = klf_version_suffixes;
01157
01158 int borderBeforeAfter = words.indexOf("");
01159 if (borderBeforeAfter < 0)
01160 qWarning("klfVersionCompare: suffix words list doesn't contain \"\"!");
01161 int i1 = words.indexOf(w1);
01162 int i2 = words.indexOf(w2);
01163 if (i1 == -1 && i2 == -1)
01164 return QString::compare(w1, w2);
01165 if (i2 == -1)
01166 return i1 < borderBeforeAfter ? -1 : +1;
01167 if (i1 == -1)
01168 return i2 < borderBeforeAfter ? +1 : -1;
01169
01170 return i1 - i2;
01171 }
01172
01173 #define VERSION_RX "^(\\d+)(\\.(\\d+)(\\.(\\d+)([a-zA-Z]+\\d*)?)?)?$"
01174
01175 KLF_EXPORT bool klfIsValidVersion(const QString& v)
01176 {
01177 QRegExp rx(VERSION_RX);
01178 return rx.exactMatch(v);
01179 }
01180
01181 KLF_EXPORT int klfVersionCompare(const QString& v1, const QString& v2)
01182 {
01183 qDebug("klfVersionCompare(): Comparing versions %s and %s", qPrintable(v1), qPrintable(v2));
01184 if (v1 == v2)
01185 return 0;
01186 if (v1.isEmpty())
01187 return -1;
01188 if (v2.isEmpty())
01189 return 1;
01190
01191 QRegExp rx1(VERSION_RX);
01192 QRegExp rx2(rx1);
01193 if (!rx1.exactMatch(v1)) {
01194 qWarning("klfVersionLessThan: Invalid version number format: %s", qPrintable(v1));
01195 return -200;
01196 }
01197 if (!rx2.exactMatch(v2)) {
01198 qWarning("klfVersionLessThan: Invalid version number format: %s", qPrintable(v2));
01199 return -200;
01200 }
01201 int maj1 = rx1.cap(1).toInt();
01202 int maj2 = rx2.cap(1).toInt();
01203 if (maj1 != maj2)
01204 return maj1 - maj2;
01205 bool hasmin1 = !rx1.cap(2).isEmpty();
01206 bool hasmin2 = !rx2.cap(2).isEmpty();
01207 if ( ! hasmin1 && ! hasmin2 )
01208 return 0;
01209 if ( ! hasmin1 && hasmin2 )
01210 return -1;
01211 if ( hasmin1 && ! hasmin2 )
01212 return +1;
01213 int min1 = rx1.cap(3).toInt();
01214 int min2 = rx2.cap(3).toInt();
01215 if ( min1 != min2 )
01216 return min1 - min2;
01217
01218 bool hasrel1 = !rx1.cap(4).isEmpty();
01219 bool hasrel2 = !rx2.cap(4).isEmpty();
01220 if ( ! hasrel1 && ! hasrel2 )
01221 return 0;
01222 if ( ! hasrel1 && hasrel2 )
01223 return -1;
01224 if ( hasrel1 && ! hasrel2 )
01225 return +1;
01226 int rel1 = rx1.cap(5).toInt();
01227 int rel2 = rx2.cap(5).toInt();
01228 if ( rel1 != rel2 )
01229 return rel1 - rel2;
01230
01231 QString suffix1 = rx1.cap(6);
01232 QString suffix2 = rx2.cap(6);
01233
01234
01235
01236 if (suffix1 == suffix2)
01237 return 0;
01238
01239
01240 QRegExp rxs1("^([a-zA-Z]*)(\\d*)$");
01241 QRegExp rxs2(rxs1);
01242 rxs1.exactMatch(suffix1);
01243 rxs2.exactMatch(suffix2);
01244
01245 QString w1 = rxs1.cap(1);
01246 QString w2 = rxs2.cap(1);
01247 QString ns1 = rxs1.cap(2);
01248 QString ns2 = rxs2.cap(2);
01249
01250 int cmp = __klf_version_compare_suffix_words(w1, w2);
01251 if (cmp != 0)
01252 return cmp;
01253
01254
01255 if (ns1.isEmpty()) {
01256 if (ns2.isEmpty())
01257 return 0;
01258
01259 return -1;
01260 }
01261 if (ns2.isEmpty()) {
01262 return +1;
01263 }
01264
01265 int n1 = ns1.toInt();
01266 int n2 = ns2.toInt();
01267 return n1 - n2;
01268 }
01269
01270 KLF_EXPORT bool klfVersionCompareLessThan(const QString& v1, const QString& v2)
01271 {
01272 return klfVersionCompare(v1,v2) < 0;
01273 }
01274
01275