annotate common.cpp @ 172:b6dd1ee0e486

* Fix failure to recognise local uncommitted changes when an untracked file was selected * Win32: Look in installed location (currently just the location of the present .exe) for executables as well as in path * Win32: Search for easyhg extension in same way as executables * Win32: Set installed location to path when running hg commands (for dependent DLLs)
author Chris Cannam
date Wed, 15 Dec 2010 22:07:31 +0000
parents 0dfd6567ec0c
children 1a3af8617ea4
rev   line source
Chris@57 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@57 2
Chris@57 3 /*
Chris@57 4 EasyMercurial
Chris@57 5
Chris@57 6 Based on HgExplorer by Jari Korhonen
Chris@57 7 Copyright (c) 2010 Jari Korhonen
Chris@57 8 Copyright (c) 2010 Chris Cannam
Chris@57 9 Copyright (c) 2010 Queen Mary, University of London
Chris@57 10
Chris@57 11 This program is free software; you can redistribute it and/or
Chris@57 12 modify it under the terms of the GNU General Public License as
Chris@57 13 published by the Free Software Foundation; either version 2 of the
Chris@57 14 License, or (at your option) any later version. See the file
Chris@57 15 COPYING included with this distribution for more information.
Chris@57 16 */
jtkorhonen@0 17
Chris@62 18 #include "common.h"
Chris@62 19 #include "debug.h"
jtkorhonen@0 20
Chris@62 21 #include <QFileInfo>
Chris@62 22 #include <QProcessEnvironment>
Chris@62 23 #include <QStringList>
Chris@77 24 #include <QDir>
Chris@172 25 #include <QRegExp>
jtkorhonen@0 26
Chris@62 27 #include <sys/types.h>
Chris@76 28
Chris@76 29 #ifdef Q_OS_WIN32
Chris@76 30 #define _WIN32_WINNT 0x0500
Chris@166 31 #define SECURITY_WIN32
Chris@76 32 #include <windows.h>
Chris@76 33 #include <security.h>
Chris@76 34 #else
Chris@78 35 #include <errno.h>
Chris@62 36 #include <pwd.h>
Chris@78 37 #include <unistd.h>
Chris@80 38 #include <sys/ioctl.h>
Chris@80 39 #include <sys/types.h>
Chris@80 40 #include <sys/stat.h>
Chris@80 41 #include <fcntl.h>
Chris@105 42 #include <signal.h>
Chris@76 43 #endif
Chris@62 44
Chris@172 45 QString findInPath(QString name, QString installPath, bool executableRequired)
Chris@62 46 {
Chris@77 47 bool found = false;
Chris@62 48 if (name != "") {
Chris@172 49 if (name[0] != '/'
Chris@172 50 #ifdef Q_OS_WIN32
Chris@172 51 && (QRegExp("^[a-zA-Z]:").indexIn(name) != 0)
Chris@172 52 #endif
Chris@172 53 ) {
Chris@77 54 #ifdef Q_OS_WIN32
Chris@77 55 QChar pathSep = ';';
Chris@77 56 #else
Chris@77 57 QChar pathSep = ':';
Chris@77 58 #endif
Chris@62 59 name = QFileInfo(name).fileName();
Chris@62 60 QString path =
Chris@62 61 QProcessEnvironment::systemEnvironment().value("PATH");
Chris@62 62 DEBUG << "findExecutable: seeking location for binary " << name
Chris@74 63 << ": system path is " << path << endl;
Chris@172 64 if (installPath != "") {
Chris@172 65 DEBUG << "findExecutable: install path is " << installPath
Chris@172 66 << ", adding to system path" << endl;
Chris@172 67 //!!! path = path + pathSep + installPath;
Chris@172 68 path = installPath + pathSep + path;
Chris@172 69 }
Chris@74 70 #ifndef Q_OS_WIN32
Chris@172 71 //!!!
Chris@74 72 path = path + ":/usr/local/bin";
Chris@74 73 DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)"
Chris@74 74 << endl;
Chris@74 75 #endif
Chris@62 76 QStringList elements = path.split(pathSep, QString::SkipEmptyParts);
Chris@62 77 foreach (QString element, elements) {
Chris@77 78 QString full = QDir(element).filePath(name);
Chris@62 79 QFileInfo fi(full);
Chris@172 80 DEBUG << "findExecutable: looking at " << full << endl;
Chris@172 81 if (fi.exists() && fi.isFile()) {
Chris@172 82 DEBUG << "findExecutable: it's a file" << endl;
Chris@172 83 if (!executableRequired || fi.isExecutable()) {
Chris@172 84 name = full;
Chris@172 85 DEBUG << "findExecutable: found at " << name << endl;
Chris@172 86 found = true;
Chris@172 87 break;
Chris@172 88 }
Chris@62 89 }
Chris@62 90 }
Chris@62 91 }
Chris@62 92 }
Chris@77 93 #ifdef Q_OS_WIN32
Chris@77 94 if (!found) {
Chris@77 95 if (!name.endsWith(".exe")) {
Chris@172 96 return findInPath(name + ".exe", installPath, executableRequired);
Chris@77 97 }
Chris@77 98 }
Chris@77 99 #endif
Chris@62 100 return name;
Chris@62 101 }
jtkorhonen@0 102
Chris@62 103 #ifdef Q_OS_WIN32
Chris@62 104 QString getUserRealName()
Chris@62 105 {
Chris@76 106 TCHAR buf[1024];
Chris@76 107 long unsigned int maxlen = 1000;
Chris@62 108 LPTSTR info = buf;
jtkorhonen@0 109
Chris@76 110 if (!GetUserNameEx(NameDisplay, info, &maxlen)) {
Chris@76 111 DEBUG << "GetUserNameEx failed: " << GetLastError() << endl;
Chris@62 112 return "";
Chris@62 113 }
jtkorhonen@0 114
Chris@76 115 #ifdef UNICODE
Chris@76 116 return QString::fromUtf16((const unsigned short *)info);
Chris@76 117 #else
Chris@76 118 return QString::fromLocal8Bit(info);
Chris@76 119 #endif
Chris@62 120 }
luisf@71 121 #else
luisf@71 122 #ifdef Q_OS_MAC
Chris@62 123 // Nothing here: definition is in common_osx.mm
Chris@62 124 #else
Chris@62 125 QString getUserRealName()
Chris@62 126 {
Chris@62 127 const int maxlen = 1023;
Chris@62 128 char buf[maxlen + 2];
jtkorhonen@0 129
Chris@62 130 if (getlogin_r(buf, maxlen)) return "";
jtkorhonen@0 131
Chris@62 132 struct passwd *p = getpwnam(buf);
Chris@62 133 if (!p) return "";
Chris@62 134
Chris@62 135 QString s(p->pw_gecos);
Chris@62 136 if (s != "") s = s.split(',')[0];
Chris@62 137 return s;
Chris@62 138 }
Chris@62 139 #endif
luisf@71 140 #endif
jtkorhonen@0 141
Chris@78 142 void loseControllingTerminal()
Chris@78 143 {
Chris@78 144 #ifndef Q_OS_WIN32
Chris@80 145
Chris@80 146 if (!isatty(0)) {
Chris@80 147 DEBUG << "stdin is not a terminal" << endl;
Chris@80 148 } else {
Chris@80 149 DEBUG << "stdin is a terminal, detaching from it" << endl;
Chris@80 150 if (ioctl(0, TIOCNOTTY, NULL) < 0) {
Chris@80 151 perror("ioctl failed");
Chris@83 152 DEBUG << "ioctl for TIOCNOTTY on stdin failed (errno = " << errno << ")" << endl;
Chris@78 153 } else {
Chris@83 154 DEBUG << "ioctl for TIOCNOTTY on stdin succeeded" << endl;
Chris@83 155 return;
Chris@78 156 }
Chris@80 157 }
Chris@80 158
Chris@80 159 int ttyfd = open("/dev/tty", O_RDWR);
Chris@80 160 if (ttyfd < 0) {
Chris@80 161 DEBUG << "failed to open controlling terminal" << endl;
Chris@80 162 } else {
Chris@80 163 if (ioctl(ttyfd, TIOCNOTTY, NULL) < 0) {
Chris@80 164 perror("ioctl failed");
Chris@83 165 DEBUG << "ioctl for TIOCNOTTY on controlling terminal failed (errno = " << errno << ")" << endl;
Chris@80 166 } else {
Chris@83 167 DEBUG << "ioctl for TIOCNOTTY on controlling terminal succeeded" << endl;
Chris@83 168 return;
Chris@78 169 }
Chris@78 170 }
Chris@80 171
Chris@78 172 #endif
Chris@78 173 }
Chris@79 174
Chris@105 175 void installSignalHandlers()
Chris@105 176 {
Chris@105 177 #ifndef Q_OS_WIN32
Chris@105 178 sigset_t sgnals;
Chris@105 179 sigemptyset (&sgnals);
Chris@105 180 sigaddset(&sgnals, SIGHUP);
Chris@105 181 sigaddset(&sgnals, SIGCONT);
Chris@105 182 pthread_sigmask(SIG_BLOCK, &sgnals, 0);
Chris@105 183 #endif
Chris@105 184 }
Chris@105 185
Chris@79 186 FolderStatus getFolderStatus(QString path)
Chris@79 187 {
Chris@85 188 if (path != "/" && path.endsWith("/")) {
Chris@85 189 path = path.left(path.length()-1);
Chris@85 190 }
Chris@84 191 DEBUG << "getFolderStatus: " << path << endl;
Chris@79 192 QFileInfo fi(path);
Chris@79 193 if (fi.exists()) {
Chris@84 194 DEBUG << "exists" << endl;
Chris@79 195 QDir dir(path);
Chris@79 196 if (!dir.exists()) { // returns false for files
Chris@84 197 DEBUG << "not directory" << endl;
Chris@79 198 return FolderIsFile;
Chris@79 199 }
Chris@79 200 if (QDir(dir.filePath(".hg")).exists()) {
Chris@84 201 DEBUG << "has repo" << endl;
Chris@79 202 return FolderHasRepo;
Chris@79 203 }
Chris@79 204 return FolderExists;
Chris@79 205 } else {
Chris@79 206 QDir parent = fi.dir();
Chris@79 207 if (parent.exists()) {
Chris@84 208 DEBUG << "parent exists" << endl;
Chris@79 209 return FolderParentExists;
Chris@79 210 }
Chris@79 211 return FolderUnknown;
Chris@79 212 }
Chris@79 213 }
Chris@79 214
Chris@79 215 QString getContainingRepoFolder(QString path)
Chris@79 216 {
Chris@79 217 if (getFolderStatus(path) == FolderHasRepo) return "";
Chris@79 218
Chris@79 219 QFileInfo me(path);
Chris@79 220 QFileInfo parent(me.dir().absolutePath());
Chris@79 221
Chris@79 222 while (me != parent) {
Chris@79 223 QString parentPath = parent.filePath();
Chris@79 224 if (getFolderStatus(parentPath) == FolderHasRepo) {
Chris@79 225 return parentPath;
Chris@79 226 }
Chris@79 227 me = parent;
Chris@79 228 parent = me.dir().absolutePath();
Chris@79 229 }
Chris@79 230
Chris@79 231 return "";
Chris@79 232 }
Chris@79 233
Chris@79 234 QString xmlEncode(QString s)
Chris@79 235 {
Chris@79 236 s
Chris@79 237 .replace("&", "&amp;")
Chris@79 238 .replace("<", "&lt;")
Chris@79 239 .replace(">", "&gt;")
Chris@79 240 .replace("\"", "&quot;")
Chris@79 241 .replace("'", "&apos;");
Chris@79 242
Chris@79 243 return s;
Chris@79 244 }