~ubuntu-branches/ubuntu/oneiric/valkyrie/oneiric

« back to all changes in this revision

Viewing changes to valkyrie/vk_utils.cpp

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2011-09-02 22:08:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: package-import@ubuntu.com-20110902220834-kigsixteppj9epp5
Tags: 2.0.0-0ubuntu1
* New upstream release. (LP: #635129, LP: #832886, LP: #721298)
* Standards bumped to 3.9.2, no changes required.
* d/control, d/rules: cdbs removed, dh minimal rule instead.
* d/control: build system is qmake not autotools
* d/control: bump required qt to qt4
* d/valkyrie.install: installing html docs manually as make install
  no longer does so.
* d/patches/valkyrie-2.0.0-fix-doc.dir.patch: Fix doc path to match
  policy. Also corrects LP: #588074 since the documentation link now
  works.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ---------------------------------------------------------------------- 
2
 
 * Various utility functions                                 vk_utils.cpp
3
 
 * ----------------------------------------------------------------------
4
 
 * This file is part of Valkyrie, a front-end for Valgrind
5
 
 * Copyright (C) 2000-2008, OpenWorks LLP <info@open-works.co.uk>
6
 
 * This program is released under the terms of the GNU GPL v.2
7
 
 * See the file COPYING for the full license details.
8
 
 */
9
 
 
10
 
#include "vk_utils.h"
11
 
#include "config.h"                 // PACKAGE_BUGREPORT
12
 
#include "vk_config.h"              // vkname()
13
 
 
14
 
#include <stdlib.h>                 // mkstemp()
15
 
#include <stdarg.h>                 // va_start, va_end
16
 
#include <sys/types.h>              // getpid
17
 
#include <unistd.h>                 // getpid
18
 
#include <pwd.h>                    // getpwuid
19
 
 
20
 
#include <qapplication.h>
21
 
#include <qfileinfo.h>
22
 
#include <qfile.h>
23
 
#include <qdir.h>
24
 
#include <qstringlist.h>
25
 
#include <qregexp.h>
26
 
 
27
 
 
28
 
/* TODO: add user-opt to output valkyrie messages to different fd... a-la valgrind
29
 
    - keeps stdout/err clean for client program output
30
 
    fdopen?
31
 
*/
32
 
 
33
 
/* prints various info msgs to stdout --------------------------------- */
34
 
void vkPrint( const char* msg, ... )
35
 
{
36
 
   const char* vkname = vkConfig ? vkConfig->vkname() : "";
37
 
   va_list ap;
38
 
   va_start( ap, msg );
39
 
   va_end( ap );
40
 
   fprintf( stdout, "===%s:%d=== ", vkname, (int)getpid() ); 
41
 
   vfprintf( stdout, msg, ap );
42
 
   va_end( ap );
43
 
   fprintf( stdout, "\n" );
44
 
   fflush(stdout);
45
 
}
46
 
 
47
 
 
48
 
/* prints error msg -------------------------------------------------- */
49
 
void vkPrintErr( const char* msg, ... )
50
 
{
51
 
   const char* vkname = vkConfig ? vkConfig->vkname() : "";
52
 
   va_list ap;
53
 
   va_start( ap, msg );
54
 
   va_end( ap );
55
 
   fprintf( stderr, "===%s:%d=== ", vkname, (int)getpid() ); 
56
 
   vfprintf( stderr, msg, ap );
57
 
   va_end( ap );
58
 
   fprintf( stderr, "\n" );
59
 
   fflush(stderr);
60
 
}
61
 
 
62
 
 
63
 
/* Kludge to keep vglog happy
64
 
   - Want vk_logmerge to print progress messages from class VgLog,
65
 
     but keep that class within valkyrie...
66
 
   - Hmm... perhaps shove that class into vk_logmerge after all...
67
 
   TODO: Figure out what we want and implement it!
68
 
 */
69
 
void vklmPrint( int, const char*, ... ) { /* nada */ }
70
 
void vklmPrintErr( const char* msg, ... )
71
 
{
72
 
   /* same as vkPrintErr()
73
 
      TODO: how to forward call with mult args? */
74
 
   const char* vkname = vkConfig ? vkConfig->vkname() : "";
75
 
   va_list ap;
76
 
   va_start( ap, msg );
77
 
   va_end( ap );
78
 
   fprintf( stderr, "===%s:%d=== ", vkname, (int)getpid() ); 
79
 
   vfprintf( stderr, msg, ap );
80
 
   va_end( ap );
81
 
   fprintf( stderr, "\n" );
82
 
   fflush(stderr);
83
 
}
84
 
 
85
 
 
86
 
 
87
 
/* prints an "Assertion failed" message and exits ---------------------- */
88
 
__attribute__ ((noreturn))
89
 
   void vk_assert_fail( const char* expr, const char* file,
90
 
                        unsigned int line, const char* fn )
91
 
92
 
   vkPrintErr("Assertion failed '%s':", expr );
93
 
   vkPrintErr("   at %s#%u:%s\n", file, line, fn );
94
 
   exit(1);
95
 
}
96
 
 
97
 
/* prints a message asking user to email a bug report, 
98
 
 * and then exits. ----------------------------------------------------- */
99
 
__attribute__ ((noreturn))
100
 
   void vk_assert_never_reached_fail( const char* file,
101
 
                                      unsigned int line, 
102
 
                                      const char* fn )
103
 
{
104
 
   vkPrintErr("Assertion 'never reached' failed,");
105
 
   vkPrintErr("   at %s#%u:%s", file, line, fn );
106
 
   vkPrintErr("%s version: %s", vkConfig->vkName(), PACKAGE_VERSION);
107
 
   vkPrintErr("Built with QT version:   %s", QT_VERSION_STR);
108
 
   vkPrintErr("Running with QT version: %s", qVersion());
109
 
   vkPrintErr("Hopefully, you should never see this message.");
110
 
   vkPrintErr("If you are, then Something Really Bad just happened.");
111
 
   vkPrintErr("Please report this bug to: %s", PACKAGE_BUGREPORT );
112
 
   vkPrintErr("In the bug report, please send the the above text,");
113
 
   vkPrintErr("along with the output of `uname -a`.");
114
 
   vkPrintErr("Thanks.\n");
115
 
   exit(1);
116
 
}
117
 
 
118
 
 
119
 
/* Create a unique filename, with an optional extension ---------------- */
120
 
QString vk_mkstemp( QString filepath, QString ext/*=QString::null*/ )
121
 
{
122
 
  /* create tempfiles with datetime, so can sort easily if they stay around */
123
 
 
124
 
  QString datetime = QDateTime::currentDateTime().toString( "-yyyy.MM.dd-hh.mm.ss");
125
 
  QString unique = filepath + datetime;
126
 
  if (!ext.isNull()) unique +=  "." + ext;
127
 
 
128
 
  if ( QFile::exists(unique) ) {
129
 
    /* fall back on mkstemp */
130
 
    char* tmpname = vk_str_malloc( unique.length() + 10 );
131
 
    sprintf( tmpname, "%s.XXXXXX", unique.latin1() );
132
 
    int fd = mkstemp( tmpname );
133
 
    if ( fd == -1 ) {
134
 
      /* something went wrong */
135
 
      VK_DEBUG("failed to create unique filename from '%s'.",
136
 
               filepath.latin1() );
137
 
      return QString::null;
138
 
    }
139
 
    unique = QString( tmpname );
140
 
    tmpname = vk_str_free( tmpname );
141
 
  }
142
 
  return unique;
143
 
}
144
 
 
145
 
 
146
 
/* Get the log directory associated with this user --------------------- */
147
 
// Just do this once, and cache the results.
148
 
QString get_VK_LOGS_DIR ()
149
 
{
150
 
  static QString res = NULL;
151
 
  if (!res) {
152
 
     pid_t me = getuid();
153
 
     struct passwd* pw = getpwuid( me );
154
 
     /* This should never fail.  Is it worth trying to continue if it
155
 
        does?  I don't think so. */
156
 
     vk_assert(pw);
157
 
     res = QString( VK_LOGS_DIRP ) + QString( pw->pw_name ) + "/";
158
 
     vk_assert(res);
159
 
  }
160
 
  return res;
161
 
}
162
 
 
163
 
 
164
 
/* Version check ------------------------------------------------------- 
165
 
   Given version string of "major.minor.patch" (e.g. 3.3.0),
166
 
   hex version = (major << 16) + (minor << 8) + patch
167
 
*/
168
 
int strVersion2hex( QString ver_str )
169
 
{
170
 
   QRegExp rxver(".*(\\d{1,2})\\.(\\d{1,2})\\.(\\d{1,2}).*");
171
 
   if ( rxver.search( ver_str ) == -1)
172
 
      return -1;
173
 
   int major = rxver.cap(1).toInt();
174
 
   int minor = rxver.cap(2).toInt();
175
 
   int patch = rxver.cap(3).toInt();
176
 
   return (major << 16) + (minor << 8) + patch;
177
 
}
178
 
 
179
 
 
180
 
 
181
 
/* escape html entities
182
 
   current list: '<', '>', '&' ----------------------------------------- */
183
 
QString escapeEntities( const QString& content )
184
 
{
185
 
   QString ret_str = "";
186
 
 
187
 
   for ( unsigned int i=0; i<content.length(); i++ ) {
188
 
      switch ( content[i].latin1() ) {
189
 
      case '<': ret_str += "&lt;";     break;
190
 
      case '>': ret_str += "&gt;";     break;
191
 
      case '&': {
192
 
         /* already escaped? */
193
 
         if ((content.mid(i+1,4) == "amp;") ||
194
 
             (content.mid(i+1,3) == "lt;" ) ||
195
 
             (content.mid(i+1,3) == "gt;" ))
196
 
            ret_str += content[i];
197
 
         else
198
 
            ret_str += "&amp;";    
199
 
      } break;
200
 
      default:  ret_str += content[i]; break;
201
 
      }
202
 
   }
203
 
  
204
 
   return ret_str;
205
 
}
206
 
 
207
 
 
208
 
/* swap '\n' for <br> */
209
 
QString str2html( QString str )
210
 
{
211
 
   str.replace( '\n', "<br>" );
212
 
   return str;
213
 
}
214
 
 
215
 
 
216
 
/* wrappers for various fns -------------------------------------------- */
217
 
 
218
 
/* wrappers to free(3)
219
 
   hides const compilation noise, permit NULL, return NULL always. */
220
 
void * vk_free( const void* ptr )
221
 
{
222
 
   if ( ptr != NULL ) {
223
 
      free( (void*)ptr );
224
 
      ptr = NULL;
225
 
   }
226
 
   return NULL;
227
 
}
228
 
 
229
 
char * vk_str_free( const char* ptr )
230
 
{
231
 
   if ( ptr != NULL ) {
232
 
      free( (char*)ptr );
233
 
   }
234
 
   return NULL;
235
 
}
236
 
 
237
 
void * vk_malloc( unsigned long n_bytes )
238
 
{
239
 
   void * mem;
240
 
   mem = malloc( n_bytes );
241
 
   if ( !mem ) {
242
 
      VK_DEBUG( "failed to allocate %lu bytes", n_bytes );
243
 
   }
244
 
   return mem;
245
 
}
246
 
 
247
 
 
248
 
char * vk_str_malloc( int sz )
249
 
250
 
   char* arr;
251
 
   arr = (char*) malloc( (size_t) ((sz + 2)*sizeof(char)) );
252
 
   if ( !arr ) {
253
 
      VK_DEBUG("malloc failure: virtual memory exhausted");
254
 
      vk_assert_never_reached();
255
 
   }
256
 
   return arr;
257
 
}
258
 
 
259
 
 
260
 
/* wrapper to strcmp(): returns true || false */
261
 
bool vk_strcmp( const char* str1, const char* str2 )
262
 
{
263
 
   if ( !str1 || !str2 ) {
264
 
      VK_DEBUG("can't call strcmp on null strings:\n"
265
 
               "str1 == %s, str2 == %s\n", str1, str2 );
266
 
      return false;
267
 
   }
268
 
   if ( (strlen(str1) == 0) || (strlen(str2) == 0) ) {
269
 
      VK_DEBUG("one of these two strings is empty:\n"
270
 
               "\tstr1: -->%s<--, str2: -->%s<--\n", str1, str2 );
271
 
      return false;
272
 
   }
273
 
 
274
 
   return (strcmp( str1, str2 ) == 0) ? true : false;
275
 
}
276
 
 
277
 
 
278
 
char* vk_strdup( const char* str )
279
 
{
280
 
   char* new_str;
281
 
   unsigned int length;
282
 
   if ( str ) {
283
 
      length = strlen( str ) + 1;
284
 
      new_str = vk_str_malloc( length );
285
 
      strcpy( new_str, str );
286
 
   } else {
287
 
      new_str = NULL;
288
 
   }
289
 
   return new_str;
290
 
}
291
 
 
292