Apply patch from Daniel Schürmann: https://sourceforge.net/p/boomerang/bugs/78/
[boomerang.git] / boomerang / util / util.cpp
blobd79d06c66100f2b40da86ca53d1510eef1b8c11b
1 /*
2 * Copyright (C) 2000-2001, The University of Queensland
3 * Copyright (C) 2001, Sun Microsystems, Inc
4 * Copyright (C) 2002, Trent Waddington
6 * See the file "LICENSE.TERMS" for information on usage and
7 * redistribution of this file, and for a DISCLAIMER OF ALL
8 * WARRANTIES.
12 /*==============================================================================
13 * FILE: util.cc
14 * OVERVIEW: This file contains miscellaneous functions that don't belong to
15 * any particular subsystem of UQBT.
16 *============================================================================*/
19 * $Revision$
21 * 05 Sep 00 - Mike: moved getCodeInfo here from translate2c.cc
22 * 10 Apr 02 - Mike: Mods for boomerang; put expSimplify here
25 #include <cassert>
26 #if defined(_MSC_VER) && _MSC_VER <= 1200
27 #pragma warning(disable:4786)
28 #endif
29 #if defined(_MSC_VER) && _MSC_VER >= 1400
30 #pragma warning(disable:4996) // Warnings about e.g. _strdup deprecated in VS 2005
31 #endif
33 #include <string>
34 #include <sstream>
35 #include <iostream>
36 #include <fstream>
37 #include <cstdio>
38 #include <cstring>
39 #include "util.h"
41 #ifndef _WIN32
42 #include <unistd.h>
43 #define _FLOCK_
44 #else
45 #include <io.h>
46 #endif
48 #include <fcntl.h>
49 #include <iomanip> // For setw
51 /*==============================================================================
52 * FUNCTION: string::operator+(string, int)
53 * OVERVIEW: Append an int to a string
54 * PARAMETERS: s: the string to append to
55 * i: the integer whose ascii representation is to be appended
56 * RETURNS: A copy of the modified string
57 *============================================================================*/
58 std::string operator+(const std::string& s, int i)
60 static char buf[50];
61 std::string ret(s);
63 sprintf(buf,"%d",i);
64 return ret.append(buf);
67 /*==============================================================================
68 * FUNCTION: initCapital
69 * OVERVIEW: Return a string the same as the input string, but with the
70 * first character capitalised
71 * PARAMETERS: s: the string to capitalise
72 * RETURNS: A copy of the modified string
73 *============================================================================*/
74 std::string initCapital(const std::string& s)
76 std::string res(s);
77 res[0] = toupper(res[0]);
78 return res;
81 /*==============================================================================
82 * FUNCTION: hasExt
83 * OVERVIEW: Returns true if the given file name has the given extension
84 * and false otherwise.
85 * PARAMETERS: s: string representing a file name (e.g. string("foo.c"))
86 * e: the extension (e.g. ".o")
87 * RETURNS: Boolean indicating whether the file name has the extension.
88 *============================================================================*/
89 bool hasExt(const std::string& s, const char* ext)
91 std::string tailStr = std::string(".") + std::string(ext);
92 size_t i = s.rfind(tailStr);
93 if (i == std::string::npos)
95 return false;
97 else
99 unsigned int sLen = s.length();
100 unsigned int tailStrLen = tailStr.length();
101 return ((i + tailStrLen) == sLen);
105 /*==============================================================================
106 * FUNCTION: changeExt
107 * OVERVIEW: Change the extension of the given file name
108 * PARAMETERS: s: string representing the file name to be modified
109 * (e.g. string("foo.c"))
110 * e: the new extension (e.g. ".o")
111 * RETURNS: The converted string (e.g. "foo.o")
112 *============================================================================*/
113 std::string changeExt(const std::string& s, const char* ext)
115 size_t i = s.rfind(".");
116 if (i == std::string::npos)
118 return s + ext;
120 else
122 return s.substr(0, i) + ext;
126 /*==============================================================================
127 * FUNCTION: searchAndReplace
128 * OVERVIEW: returns a copy of a string will all occurances of match
129 * replaced with rep. (simple version of s/match/rep/g)
130 * PARAMETERS: in: the source string
131 * match: the search string
132 * rep: the string to replace match with.
133 * RETURNS: The updated string.
134 *============================================================================*/
135 std::string searchAndReplace( const std::string &in, const std::string &match,
136 const std::string &rep )
138 std::string result;
139 for ( size_t n = 0; n != std::string::npos; )
141 size_t l = in.find(match,n);
142 result.append( in.substr(n,(l==std::string::npos?in.length() : l )-n) );
143 if ( l != std::string::npos )
145 result.append( rep );
146 l+=match.length();
148 n = l;
150 return result;
153 /*==============================================================================
154 * FUNCTION: upperStr
155 * OVERVIEW: Uppercase a C string
156 * PARAMETERS: s: the string (char*) to start with
157 * d: the string (char*) to write to (can be the same string)
158 * RETURNS: Nothing; the string is modified as a side effect
159 *============================================================================*/
160 void upperStr(const char* s, char* d)
162 int len = strlen(s);
163 for (int i=0; i < len; i++)
164 d[i] = toupper(s[i]);
165 d[len] = '\0';
168 int lockFileRead(const char *fname)
170 int fd = open("filename", O_RDONLY); /* get the file descriptor */
171 #ifdef _FLOCK_
172 struct flock fl;
173 fl.l_type = F_RDLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
174 fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
175 fl.l_start = 0; /* Offset from l_whence */
176 fl.l_len = 0; /* length, 0 = to EOF */
177 fl.l_pid = getpid(); /* our PID */
178 fcntl(fd, F_SETLKW, &fl); /* set the lock, waiting if necessary */
179 #endif
180 return fd;
183 int lockFileWrite(const char *fname)
185 int fd = open("filename", O_WRONLY); /* get the file descriptor */
186 #ifdef _FLOCK_
187 struct flock fl;
188 fl.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */
189 fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
190 fl.l_start = 0; /* Offset from l_whence */
191 fl.l_len = 0; /* length, 0 = to EOF */
192 fl.l_pid = getpid(); /* our PID */
193 fcntl(fd, F_SETLKW, &fl); /* set the lock, waiting if necessary */
194 #endif
195 return fd;
198 void unlockFile(int fd)
200 #ifdef _FLOCK_
201 struct flock fl;
202 fl.l_type = F_UNLCK; /* tell it to unlock the region */
203 fcntl(fd, F_SETLK, &fl); /* set the region to unlocked */
204 #endif
205 close(fd);
208 void escapeXMLChars(std::string &s)
210 std::string bad = "<>&";
211 const char *replace[] =
213 "&lt;", "&gt;", "&amp;"
215 for (size_t i = 0; i < s.size(); i++)
217 size_t n = bad.find(s[i]);
218 if (n != std::string::npos)
220 s.replace(i, 1, replace[n]);
225 // Turn things like newline, return, tab into \n, \r, \t etc
226 // Note: assumes a C or C++ back end...
227 char* escapeStr( const char* str )
229 std::ostringstream out;
230 char unescaped[]="ntvbrfa\"";
231 char escaped[]="\n\t\v\b\r\f\a\"";
232 bool escapedSucessfully;
234 // test each character
235 for (; *str; str++)
237 if (isprint((unsigned char)*str) && *str != '\"' )
239 // it's printable, so just print it
240 out << *str;
242 else
244 // in fact, this shouldn't happen, except for "
245 // maybe it's a known escape sequence
246 escapedSucessfully=false;
247 for (int i=0; escaped[i] && !escapedSucessfully ; i++)
249 if (*str == escaped[i])
251 out << "\\" << unescaped[i];
252 escapedSucessfully=true;
255 if (!escapedSucessfully)
257 // it isn't so just use the \xhh escape
258 out << "\\x" << std::hex << std::setfill('0') << std::setw(2) << (int)*str;
259 out << std::setfill(' ');
264 char* ret = new char[out.str().size()+1];
265 strcpy(ret, out.str().c_str());
266 return ret;