Task #3969 - Merge String.cpp and StringUtil.cpp

This commit is contained in:
Nick Bolton 2014-03-21 08:32:36 +00:00
parent a4416d4b16
commit 0745d5884b
26 changed files with 360 additions and 408 deletions

View File

@ -76,8 +76,8 @@ CArchInternetWindows::urlEncode(const CString& url)
// the win32 url encoding funcitons are pretty useless (to us) and only
// escape "unsafe" chars, but not + or =, so we need to replace these
// manually (and probably many other chars).
find_replace_all(result, "+", "%2B");
find_replace_all(result, "=", "%3D");
synergy::string::findReplaceAll(result, "+", "%2B");
synergy::string::findReplaceAll(result, "=", "%3D");
return result;
}

View File

@ -38,7 +38,7 @@ XArchEvalWindows::eval() const throw()
0,
NULL) == 0) {
cmsg = NULL;
return string_format("Unknown error, code %d", m_error);
return synergy::string::sprintf("Unknown error, code %d", m_error);
}
std::string smsg(cmsg);
LocalFree(cmsg);

View File

@ -20,7 +20,6 @@
#include "arch/XArch.h"
#include "base/Log.h"
#include "base/String.h"
#include "base/StringUtil.h"
#include "base/log_outputters.h"
#include "common/Version.h"

View File

@ -15,13 +15,148 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arch/Arch.h"
#include "base/String.h"
#include "common/common.h"
#include "common/stdvector.h"
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <stdio.h>
#include <cstdarg>
namespace synergy {
namespace string {
CString
format(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
CString result = vformat(fmt, args);
va_end(args);
return result;
}
CString
vformat(const char* fmt, va_list args)
{
// find highest indexed substitution and the locations of substitutions
std::vector<size_t> pos;
std::vector<size_t> width;
std::vector<int> index;
int maxIndex = 0;
for (const char* scan = fmt; *scan != '\0'; ++scan) {
if (*scan == '%') {
++scan;
if (*scan == '\0') {
break;
}
else if (*scan == '%') {
// literal
index.push_back(0);
pos.push_back(static_cast<int>(scan - 1 - fmt));
width.push_back(2);
}
else if (*scan == '{') {
// get argument index
char* end;
int i = static_cast<int>(strtol(scan + 1, &end, 10));
if (*end != '}') {
// invalid index -- ignore
scan = end - 1;
}
else {
index.push_back(i);
pos.push_back(static_cast<int>(scan - 1 - fmt));
width.push_back(static_cast<int>(end - scan + 2));
if (i > maxIndex) {
maxIndex = i;
}
scan = end;
}
}
else {
// improper escape -- ignore
}
}
}
// get args
std::vector<const char*> value;
std::vector<size_t> length;
value.push_back("%");
length.push_back(1);
for (int i = 0; i < maxIndex; ++i) {
const char* arg = va_arg(args, const char*);
size_t len = strlen(arg);
value.push_back(arg);
length.push_back(len);
}
// compute final length
size_t resultLength = strlen(fmt);
const int n = static_cast<int>(pos.size());
for (int i = 0; i < n; ++i) {
resultLength -= width[i];
resultLength += length[index[i]];
}
// substitute
CString result;
result.reserve(resultLength);
size_t src = 0;
for (int i = 0; i < n; ++i) {
result.append(fmt + src, pos[i] - src);
result.append(value[index[i]]);
src = pos[i] + width[i];
}
result.append(fmt + src);
return result;
}
CString
sprintf(const char* fmt, ...)
{
char tmp[1024];
char* buffer = tmp;
int len = (int)(sizeof(tmp) / sizeof(tmp[0]));
CString result;
while (buffer != NULL) {
// try printing into the buffer
va_list args;
va_start(args, fmt);
int n = ARCH->vsnprintf(buffer, len, fmt, args);
va_end(args);
// if the buffer wasn't big enough then make it bigger and try again
if (n < 0 || n > len) {
if (buffer != tmp) {
delete[] buffer;
}
len *= 2;
buffer = new char[len];
}
// if it was big enough then save the string and don't try again
else {
result = buffer;
if (buffer != tmp) {
delete[] buffer;
}
buffer = NULL;
}
}
return result;
}
void
find_replace_all(
findReplaceAll(
CString& subject,
const CString& find,
const CString& replace)
@ -33,30 +168,49 @@ find_replace_all(
}
}
CString
string_format(const std::string fmt, ...)
//
// CaselessCmp
//
bool
CaselessCmp::cmpEqual(
const CString::value_type& a,
const CString::value_type& b)
{
int size = 100;
std::string str;
va_list ap;
while (true) {
str.resize(size);
va_start(ap, fmt);
int n = vsnprintf((char *)str.c_str(), size, fmt.c_str(), ap);
va_end(ap);
if (n > -1 && n < size) {
str.resize(n);
return str;
}
if (n > -1) {
size = n + 1;
}
else {
size *= 2;
}
}
return str;
// should use std::tolower but not in all versions of libstdc++ have it
return tolower(a) == tolower(b);
}
bool
CaselessCmp::cmpLess(
const CString::value_type& a,
const CString::value_type& b)
{
// should use std::tolower but not in all versions of libstdc++ have it
return tolower(a) < tolower(b);
}
bool
CaselessCmp::less(const CString& a, const CString& b)
{
return std::lexicographical_compare(
a.begin(), a.end(),
b.begin(), b.end(),
&synergy::string::CaselessCmp::cmpLess);
}
bool
CaselessCmp::equal(const CString& a, const CString& b)
{
return !(less(a, b) || less(b, a));
}
bool
CaselessCmp::operator()(const CString& a, const CString& b) const
{
return less(a, b);
}
}
}

View File

@ -21,8 +21,72 @@
#include "common/common.h"
#include "common/stdstring.h"
#include <stdarg.h>
// use standard C++ string class for our string class
typedef std::string CString;
void find_replace_all(CString& subject, const CString& find, const CString& replace);
CString string_format(const CString format, ...);
namespace synergy {
//! String utilities
/*!
Provides functions for string manipulation.
*/
namespace string {
//! Format positional arguments
/*!
Format a string using positional arguments. fmt has literal
characters and conversion specifications introduced by `\%':
- \%\% -- literal `\%'
- \%{n} -- positional element n, n a positive integer, {} are literal
All arguments in the variable list are const char*. Positional
elements are indexed from 1.
*/
CString format(const char* fmt, ...);
//! Format positional arguments
/*!
Same as format() except takes va_list.
*/
CString vformat(const char* fmt, va_list);
//! Print a string using sprintf-style formatting
/*!
Equivalent to sprintf() except the result is returned as a CString.
*/
CString sprintf(const char* fmt, ...);
//! Find and replace all
/*!
Finds \c find inside \c subject and replaces it with \c replace
*/
void findReplaceAll(CString& subject, const CString& find, const CString& replace);
//! Case-insensitive comparisons
/*!
This class provides case-insensitve comparison functions.
*/
class CaselessCmp {
public:
//! Same as less()
bool operator()(const CString& a, const CString& b) const;
//! Returns true iff \c a is lexicographically less than \c b
static bool less(const CString& a, const CString& b);
//! Returns true iff \c a is lexicographically equal to \c b
static bool equal(const CString& a, const CString& b);
//! Returns true iff \c a is lexicographically less than \c b
static bool cmpLess(const CString::value_type& a,
const CString::value_type& b);
//! Returns true iff \c a is lexicographically equal to \c b
static bool cmpEqual(const CString::value_type& a,
const CString::value_type& b);
};
}
}

View File

@ -1,200 +0,0 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/StringUtil.h"
#include "arch/Arch.h"
#include "common/common.h"
#include "common/stdvector.h"
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
//
// CStringUtil
//
CString
CStringUtil::format(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
CString result = vformat(fmt, args);
va_end(args);
return result;
}
CString
CStringUtil::vformat(const char* fmt, va_list args)
{
// find highest indexed substitution and the locations of substitutions
std::vector<size_t> pos;
std::vector<size_t> width;
std::vector<int> index;
int maxIndex = 0;
for (const char* scan = fmt; *scan != '\0'; ++scan) {
if (*scan == '%') {
++scan;
if (*scan == '\0') {
break;
}
else if (*scan == '%') {
// literal
index.push_back(0);
pos.push_back(static_cast<int>(scan - 1 - fmt));
width.push_back(2);
}
else if (*scan == '{') {
// get argument index
char* end;
int i = static_cast<int>(strtol(scan + 1, &end, 10));
if (*end != '}') {
// invalid index -- ignore
scan = end - 1;
}
else {
index.push_back(i);
pos.push_back(static_cast<int>(scan - 1 - fmt));
width.push_back(static_cast<int>(end - scan + 2));
if (i > maxIndex) {
maxIndex = i;
}
scan = end;
}
}
else {
// improper escape -- ignore
}
}
}
// get args
std::vector<const char*> value;
std::vector<size_t> length;
value.push_back("%");
length.push_back(1);
for (int i = 0; i < maxIndex; ++i) {
const char* arg = va_arg(args, const char*);
size_t len = strlen(arg);
value.push_back(arg);
length.push_back(len);
}
// compute final length
size_t resultLength = strlen(fmt);
const int n = static_cast<int>(pos.size());
for (int i = 0; i < n; ++i) {
resultLength -= width[i];
resultLength += length[index[i]];
}
// substitute
CString result;
result.reserve(resultLength);
size_t src = 0;
for (int i = 0; i < n; ++i) {
result.append(fmt + src, pos[i] - src);
result.append(value[index[i]]);
src = pos[i] + width[i];
}
result.append(fmt + src);
return result;
}
CString
CStringUtil::print(const char* fmt, ...)
{
char tmp[1024];
char* buffer = tmp;
int len = (int)(sizeof(tmp) / sizeof(tmp[0]));
CString result;
while (buffer != NULL) {
// try printing into the buffer
va_list args;
va_start(args, fmt);
int n = ARCH->vsnprintf(buffer, len, fmt, args);
va_end(args);
// if the buffer wasn't big enough then make it bigger and try again
if (n < 0 || n > len) {
if (buffer != tmp) {
delete[] buffer;
}
len *= 2;
buffer = new char[len];
}
// if it was big enough then save the string and don't try again
else {
result = buffer;
if (buffer != tmp) {
delete[] buffer;
}
buffer = NULL;
}
}
return result;
}
//
// CStringUtil::CaselessCmp
//
bool
CStringUtil::CaselessCmp::cmpEqual(
const CString::value_type& a,
const CString::value_type& b)
{
// should use std::tolower but not in all versions of libstdc++ have it
return tolower(a) == tolower(b);
}
bool
CStringUtil::CaselessCmp::cmpLess(
const CString::value_type& a,
const CString::value_type& b)
{
// should use std::tolower but not in all versions of libstdc++ have it
return tolower(a) < tolower(b);
}
bool
CStringUtil::CaselessCmp::less(const CString& a, const CString& b)
{
return std::lexicographical_compare(
a.begin(), a.end(),
b.begin(), b.end(),
&CStringUtil::CaselessCmp::cmpLess);
}
bool
CStringUtil::CaselessCmp::equal(const CString& a, const CString& b)
{
return !(less(a, b) || less(b, a));
}
bool
CStringUtil::CaselessCmp::operator()(const CString& a, const CString& b) const
{
return less(a, b);
}

View File

@ -1,78 +0,0 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "base/String.h"
#include <stdarg.h>
//! String utilities
/*!
This class provides various functions for string manipulation.
*/
class CStringUtil {
public:
//! Format positional arguments
/*!
Format a string using positional arguments. fmt has literal
characters and conversion specifications introduced by `\%':
- \%\% -- literal `\%'
- \%{n} -- positional element n, n a positive integer, {} are literal
All arguments in the variable list are const char*. Positional
elements are indexed from 1.
*/
static CString format(const char* fmt, ...);
//! Format positional arguments
/*!
Same as format() except takes va_list.
*/
static CString vformat(const char* fmt, va_list);
//! Print a string using printf-style formatting
/*!
Equivalent to printf() except the result is returned as a CString.
*/
static CString print(const char* fmt, ...);
//! Case-insensitive comparisons
/*!
This class provides case-insensitve comparison functions.
*/
class CaselessCmp {
public:
//! Same as less()
bool operator()(const CString& a, const CString& b) const;
//! Returns true iff \c a is lexicographically less than \c b
static bool less(const CString& a, const CString& b);
//! Returns true iff \c a is lexicographically equal to \c b
static bool equal(const CString& a, const CString& b);
//! Returns true iff \c a is lexicographically less than \c b
static bool cmpLess(const CString::value_type& a,
const CString::value_type& b);
//! Returns true iff \c a is lexicographically equal to \c b
static bool cmpEqual(const CString::value_type& a,
const CString::value_type& b);
};
};

View File

@ -17,7 +17,7 @@
*/
#include "base/XBase.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include <cerrno>
#include <cstdarg>
@ -64,7 +64,7 @@ XBase::format(const char* /*id*/, const char* fmt, ...) const throw()
va_list args;
va_start(args, fmt);
try {
result = CStringUtil::vformat(fmt, args);
result = synergy::string::vformat(fmt, args);
}
catch (...) {
// ignore

View File

@ -17,7 +17,7 @@
*/
#include "net/XSocket.h"
#include "base/StringUtil.h"
#include "base/String.h"
//
// XSocketAddress
@ -69,7 +69,7 @@ XSocketAddress::getWhat() const throw()
};
return format(s_errorID[m_error], s_errorMsg[m_error],
m_hostname.c_str(),
CStringUtil::print("%d", m_port).c_str());
synergy::string::sprintf("%d", m_port).c_str());
}

View File

@ -18,7 +18,7 @@
#include "platform/MSWindowsClipboardHTMLConverter.h"
#include "base/StringUtil.h"
#include "base/String.h"
//
// CMSWindowsClipboardHTMLConverter
@ -63,11 +63,11 @@ CMSWindowsClipboardHTMLConverter::doFromIClipboard(const CString& data) const
UInt32 EndHTML = EndFragment + (UInt32)suffix.size();
prefix.replace(prefix.find("XXXXXXXXXX"), 10,
CStringUtil::print("%010u", StartFragment));
synergy::string::sprintf("%010u", StartFragment));
prefix.replace(prefix.find("YYYYYYYYYY"), 10,
CStringUtil::print("%010u", EndFragment));
synergy::string::sprintf("%010u", EndFragment));
prefix.replace(prefix.find("ZZZZZZZZZZ"), 10,
CStringUtil::print("%010u", EndHTML));
synergy::string::sprintf("%010u", EndHTML));
// concatenate
prefix += data;

View File

@ -23,7 +23,7 @@
#include "arch/win32/ArchMiscWindows.h"
#include "base/FunctionJob.h"
#include "base/Log.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include "base/IEventQueue.h"
#include "base/TMethodEventJob.h"

View File

@ -37,7 +37,6 @@
#include "base/FunctionJob.h"
#include "base/Log.h"
#include "base/String.h"
#include "base/StringUtil.h"
#include "base/IEventQueue.h"
#include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"

View File

@ -18,7 +18,7 @@
#include "platform/MSWindowsUtil.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include <stdio.h>
@ -69,8 +69,8 @@ CMSWindowsUtil::getErrorString(HINSTANCE hinstance, DWORD error, DWORD id)
(LPTSTR)&buffer,
0,
NULL) == 0) {
CString errorString = CStringUtil::print("%d", error);
return CStringUtil::format(getString(hinstance, id).c_str(),
CString errorString = synergy::string::sprintf("%d", error);
return synergy::string::format(getString(hinstance, id).c_str(),
errorString.c_str());
}
else {

View File

@ -20,7 +20,7 @@
#include "platform/XWindowsUtil.h"
#include "base/Log.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include "common/stdmap.h"
#include <cstddef>

View File

@ -30,7 +30,7 @@
#include "arch/Arch.h"
#include "base/Log.h"
#include "base/Stopwatch.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include "base/IEventQueue.h"
#include "base/TMethodEventJob.h"

View File

@ -21,7 +21,7 @@
#include "synergy/key_types.h"
#include "mt/Thread.h"
#include "base/Log.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include <X11/Xatom.h>
#define XK_APL
@ -1617,10 +1617,10 @@ CXWindowsUtil::atomToString(Display* display, Atom atom)
CXWindowsUtil::CErrorLock lock(display, &error);
char* name = XGetAtomName(display, atom);
if (error) {
return CStringUtil::print("<UNKNOWN> (%d)", (int)atom);
return synergy::string::sprintf("<UNKNOWN> (%d)", (int)atom);
}
else {
CString msg = CStringUtil::print("%s (%d)", name, (int)atom);
CString msg = synergy::string::sprintf("%s (%d)", name, (int)atom);
XFree(name);
return msg;
}
@ -1636,12 +1636,12 @@ CXWindowsUtil::atomsToString(Display* display, const Atom* atom, UInt32 num)
CString msg;
if (error) {
for (UInt32 i = 0; i < num; ++i) {
msg += CStringUtil::print("<UNKNOWN> (%d), ", (int)atom[i]);
msg += synergy::string::sprintf("<UNKNOWN> (%d), ", (int)atom[i]);
}
}
else {
for (UInt32 i = 0; i < num; ++i) {
msg += CStringUtil::print("%s (%d), ", names[i], (int)atom[i]);
msg += synergy::string::sprintf("%s (%d), ", names[i], (int)atom[i]);
XFree(names[i]);
}
}

View File

@ -28,6 +28,8 @@
#include <cstdlib>
using namespace synergy::string;
//
// CConfig
//
@ -75,7 +77,7 @@ CConfig::renameScreen(const CString& oldName,
// accept if names are equal but replace with new name to maintain
// case. otherwise, the new name must not exist.
if (!CStringUtil::CaselessCmp::equal(oldName, newName) &&
if (!CaselessCmp::equal(oldName, newName) &&
m_nameToCanonicalName.find(newName) != m_nameToCanonicalName.end()) {
return false;
}
@ -96,10 +98,10 @@ CConfig::renameScreen(const CString& oldName,
}
// update alias targets
if (CStringUtil::CaselessCmp::equal(oldName, oldCanonical)) {
if (CaselessCmp::equal(oldName, oldCanonical)) {
for (CNameMap::iterator iter = m_nameToCanonicalName.begin();
iter != m_nameToCanonicalName.end(); ++iter) {
if (CStringUtil::CaselessCmp::equal(
if (CaselessCmp::equal(
iter->second, oldCanonical)) {
iter->second = newName;
}
@ -444,7 +446,7 @@ bool
CConfig::isCanonicalName(const CString& name) const
{
return (!name.empty() &&
CStringUtil::CaselessCmp::equal(getCanonicalName(name), name));
CaselessCmp::equal(getCanonicalName(name), name));
}
CString
@ -579,7 +581,7 @@ CConfig::operator==(const CConfig& x) const
index2 = x.m_map.begin();
index1 != m_map.end(); ++index1, ++index2) {
// compare names
if (!CStringUtil::CaselessCmp::equal(index1->first, index2->first)) {
if (!CaselessCmp::equal(index1->first, index2->first)) {
return false;
}
@ -593,8 +595,8 @@ CConfig::operator==(const CConfig& x) const
index2 = x.m_nameToCanonicalName.begin();
index1 != m_nameToCanonicalName.end();
++index1, ++index2) {
if (!CStringUtil::CaselessCmp::equal(index1->first, index2->first) ||
!CStringUtil::CaselessCmp::equal(index1->second, index2->second)) {
if (!CaselessCmp::equal(index1->first, index2->first) ||
!CaselessCmp::equal(index1->second, index2->second)) {
return false;
}
}
@ -645,7 +647,7 @@ CConfig::formatInterval(const CInterval& x)
if (x.first == 0.0f && x.second == 1.0f) {
return "";
}
return CStringUtil::print("(%d,%d)", (int)(x.first * 100.0f + 0.5f),
return synergy::string::sprintf("(%d,%d)", (int)(x.first * 100.0f + 0.5f),
(int)(x.second * 100.0f + 0.5f));
}
@ -1426,7 +1428,7 @@ CConfig::getOptionValue(OptionID id, OptionValue value)
id == kOptionScreenSwitchCornerSize ||
id == kOptionScreenSwitchDelay ||
id == kOptionScreenSwitchTwoTap) {
return CStringUtil::print("%d", value);
return synergy::string::sprintf("%d", value);
}
if (id == kOptionScreenSwitchCorners) {
std::string result("none");
@ -1464,7 +1466,7 @@ bool
CConfig::CName::operator==(const CString& name) const
{
CString canonical = m_config->getCanonicalName(name);
return CStringUtil::CaselessCmp::equal(canonical, m_name);
return CaselessCmp::equal(canonical, m_name);
}
@ -1726,7 +1728,7 @@ CConfig::CCell::operator==(const CCell& x) const
// operator== doesn't compare names. only compare destination
// names.
if (!CStringUtil::CaselessCmp::equal(index1->second.getName(),
if (!CaselessCmp::equal(index1->second.getName(),
index2->second.getName())) {
return false;
}
@ -1812,7 +1814,7 @@ operator<<(std::ostream& s, const CConfig& config)
if (config.m_map.size() != config.m_nameToCanonicalName.size()) {
// map canonical to alias
typedef std::multimap<CString, CString,
CStringUtil::CaselessCmp> CMNameMap;
CaselessCmp> CMNameMap;
CMNameMap aliases;
for (CConfig::CNameMap::const_iterator
index = config.m_nameToCanonicalName.begin();
@ -1907,7 +1909,7 @@ CConfigReadContext::readLine(CString& line)
if (!isgraph(line[i]) && line[i] != ' ' && line[i] != '\t') {
throw XConfigRead(*this,
"invalid character %{1}",
CStringUtil::print("%#2x", line[i]));
synergy::string::sprintf("%#2x", line[i]));
}
}
@ -1935,10 +1937,10 @@ CConfigReadContext::operator!() const
OptionValue
CConfigReadContext::parseBoolean(const CString& arg) const
{
if (CStringUtil::CaselessCmp::equal(arg, "true")) {
if (CaselessCmp::equal(arg, "true")) {
return static_cast<OptionValue>(true);
}
if (CStringUtil::CaselessCmp::equal(arg, "false")) {
if (CaselessCmp::equal(arg, "false")) {
return static_cast<OptionValue>(false);
}
throw XConfigRead(*this, "invalid boolean argument \"%{1}\"", arg);
@ -1965,25 +1967,25 @@ CConfigReadContext::parseInt(const CString& arg) const
OptionValue
CConfigReadContext::parseModifierKey(const CString& arg) const
{
if (CStringUtil::CaselessCmp::equal(arg, "shift")) {
if (CaselessCmp::equal(arg, "shift")) {
return static_cast<OptionValue>(kKeyModifierIDShift);
}
if (CStringUtil::CaselessCmp::equal(arg, "ctrl")) {
if (CaselessCmp::equal(arg, "ctrl")) {
return static_cast<OptionValue>(kKeyModifierIDControl);
}
if (CStringUtil::CaselessCmp::equal(arg, "alt")) {
if (CaselessCmp::equal(arg, "alt")) {
return static_cast<OptionValue>(kKeyModifierIDAlt);
}
if (CStringUtil::CaselessCmp::equal(arg, "altgr")) {
if (CaselessCmp::equal(arg, "altgr")) {
return static_cast<OptionValue>(kKeyModifierIDAltGr);
}
if (CStringUtil::CaselessCmp::equal(arg, "meta")) {
if (CaselessCmp::equal(arg, "meta")) {
return static_cast<OptionValue>(kKeyModifierIDMeta);
}
if (CStringUtil::CaselessCmp::equal(arg, "super")) {
if (CaselessCmp::equal(arg, "super")) {
return static_cast<OptionValue>(kKeyModifierIDSuper);
}
if (CStringUtil::CaselessCmp::equal(arg, "none")) {
if (CaselessCmp::equal(arg, "none")) {
return static_cast<OptionValue>(kKeyModifierIDNull);
}
throw XConfigRead(*this, "invalid argument \"%{1}\"", arg);
@ -1992,34 +1994,34 @@ CConfigReadContext::parseModifierKey(const CString& arg) const
OptionValue
CConfigReadContext::parseCorner(const CString& arg) const
{
if (CStringUtil::CaselessCmp::equal(arg, "left")) {
if (CaselessCmp::equal(arg, "left")) {
return kTopLeftMask | kBottomLeftMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "right")) {
else if (CaselessCmp::equal(arg, "right")) {
return kTopRightMask | kBottomRightMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "top")) {
else if (CaselessCmp::equal(arg, "top")) {
return kTopLeftMask | kTopRightMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "bottom")) {
else if (CaselessCmp::equal(arg, "bottom")) {
return kBottomLeftMask | kBottomRightMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "top-left")) {
else if (CaselessCmp::equal(arg, "top-left")) {
return kTopLeftMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "top-right")) {
else if (CaselessCmp::equal(arg, "top-right")) {
return kTopRightMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "bottom-left")) {
else if (CaselessCmp::equal(arg, "bottom-left")) {
return kBottomLeftMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "bottom-right")) {
else if (CaselessCmp::equal(arg, "bottom-right")) {
return kBottomRightMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "none")) {
else if (CaselessCmp::equal(arg, "none")) {
return kNoCornerMask;
}
else if (CStringUtil::CaselessCmp::equal(arg, "all")) {
else if (CaselessCmp::equal(arg, "all")) {
return kAllCornersMask;
}
throw XConfigRead(*this, "invalid argument \"%{1}\"", arg);
@ -2299,7 +2301,7 @@ CConfigReadContext::concatArgs(const ArgList& args)
XConfigRead::XConfigRead(const CConfigReadContext& context,
const CString& error) :
m_error(CStringUtil::print("line %d: %s",
m_error(synergy::string::sprintf("line %d: %s",
context.getLineNumber(), error.c_str()))
{
// do nothing
@ -2307,8 +2309,8 @@ XConfigRead::XConfigRead(const CConfigReadContext& context,
XConfigRead::XConfigRead(const CConfigReadContext& context,
const char* errorFmt, const CString& arg) :
m_error(CStringUtil::print("line %d: ", context.getLineNumber()) +
CStringUtil::format(errorFmt, arg.c_str()))
m_error(synergy::string::sprintf("line %d: ", context.getLineNumber()) +
synergy::string::format(errorFmt, arg.c_str()))
{
// do nothing
}

View File

@ -23,7 +23,7 @@
#include "synergy/protocol_types.h"
#include "synergy/IPlatformScreen.h"
#include "net/NetworkAddress.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include "base/XBase.h"
#include "common/stdmap.h"
#include "common/stdset.h"
@ -140,8 +140,8 @@ private:
public:
CScreenOptions m_options;
};
typedef std::map<CString, CCell, CStringUtil::CaselessCmp> CCellMap;
typedef std::map<CString, CString, CStringUtil::CaselessCmp> CNameMap;
typedef std::map<CString, CCell, synergy::string::CaselessCmp> CCellMap;
typedef std::map<CString, CString, synergy::string::CaselessCmp> CNameMap;
public:
typedef CCell::const_iterator link_const_iterator;

View File

@ -98,7 +98,7 @@ CInputFilter::CKeystrokeCondition::clone() const
CString
CInputFilter::CKeystrokeCondition::format() const
{
return CStringUtil::print("keystroke(%s)",
return synergy::string::sprintf("keystroke(%s)",
CKeyMap::formatKey(m_key, m_mask).c_str());
}
@ -190,7 +190,7 @@ CInputFilter::CMouseButtonCondition::format() const
if (!key.empty()) {
key += "+";
}
return CStringUtil::print("mousebutton(%s%d)", key.c_str(), m_button);
return synergy::string::sprintf("mousebutton(%s%d)", key.c_str(), m_button);
}
CInputFilter::EFilterStatus
@ -248,7 +248,7 @@ CInputFilter::CScreenConnectedCondition::clone() const
CString
CInputFilter::CScreenConnectedCondition::format() const
{
return CStringUtil::print("connect(%s)", m_screen.c_str());
return synergy::string::sprintf("connect(%s)", m_screen.c_str());
}
CInputFilter::EFilterStatus
@ -303,7 +303,7 @@ CInputFilter::CLockCursorToScreenAction::format() const
{
static const char* s_mode[] = { "off", "on", "toggle" };
return CStringUtil::print("lockCursorToScreen(%s)", s_mode[m_mode]);
return synergy::string::sprintf("lockCursorToScreen(%s)", s_mode[m_mode]);
}
void
@ -346,7 +346,7 @@ CInputFilter::CSwitchToScreenAction::clone() const
CString
CInputFilter::CSwitchToScreenAction::format() const
{
return CStringUtil::print("switchToScreen(%s)", m_screen.c_str());
return synergy::string::sprintf("switchToScreen(%s)", m_screen.c_str());
}
void
@ -400,7 +400,7 @@ CInputFilter::CSwitchInDirectionAction::format() const
"down"
};
return CStringUtil::print("switchInDirection(%s)", s_names[m_direction]);
return synergy::string::sprintf("switchInDirection(%s)", s_names[m_direction]);
}
void
@ -459,10 +459,10 @@ CInputFilter::CKeyboardBroadcastAction::format() const
static const char* s_name = "keyboardBroadcast";
if (m_screens.empty() || m_screens[0] == '*') {
return CStringUtil::print("%s(%s)", s_name, s_mode[m_mode]);
return synergy::string::sprintf("%s(%s)", s_name, s_mode[m_mode]);
}
else {
return CStringUtil::print("%s(%s,%.*s)", s_name, s_mode[m_mode],
return synergy::string::sprintf("%s(%s,%.*s)", s_name, s_mode[m_mode],
m_screens.size() - 2,
m_screens.c_str() + 1);
}
@ -531,17 +531,17 @@ CInputFilter::CKeystrokeAction::format() const
const char* type = formatName();
if (m_keyInfo->m_screens[0] == '\0') {
return CStringUtil::print("%s(%s)", type,
return synergy::string::sprintf("%s(%s)", type,
CKeyMap::formatKey(m_keyInfo->m_key,
m_keyInfo->m_mask).c_str());
}
else if (m_keyInfo->m_screens[0] == '*') {
return CStringUtil::print("%s(%s,*)", type,
return synergy::string::sprintf("%s(%s,*)", type,
CKeyMap::formatKey(m_keyInfo->m_key,
m_keyInfo->m_mask).c_str());
}
else {
return CStringUtil::print("%s(%s,%.*s)", type,
return synergy::string::sprintf("%s(%s,%.*s)", type,
CKeyMap::formatKey(m_keyInfo->m_key,
m_keyInfo->m_mask).c_str(),
strlen(m_keyInfo->m_screens + 1) - 1,
@ -613,7 +613,7 @@ CInputFilter::CMouseButtonAction::format() const
const char* type = formatName();
CString key = CKeyMap::formatKey(kKeyNone, m_buttonInfo->m_mask);
return CStringUtil::print("%s(%s%s%d)", type,
return synergy::string::sprintf("%s(%s%s%d)", type,
key.c_str(), key.empty() ? "" : "+",
m_buttonInfo->m_button);
}

View File

@ -19,7 +19,7 @@
#include "synergy/ClientTaskBarReceiver.h"
#include "client/Client.h"
#include "mt/Lock.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include "base/IEventQueue.h"
#include "arch/Arch.h"
#include "common/Version.h"
@ -117,22 +117,22 @@ CClientTaskBarReceiver::getToolTip() const
{
switch (m_state) {
case kNotRunning:
return CStringUtil::print("%s: Not running", kAppVersion);
return synergy::string::sprintf("%s: Not running", kAppVersion);
case kNotWorking:
return CStringUtil::print("%s: %s",
return synergy::string::sprintf("%s: %s",
kAppVersion, m_errorMessage.c_str());
case kNotConnected:
return CStringUtil::print("%s: Not connected: %s",
return synergy::string::sprintf("%s: Not connected: %s",
kAppVersion, m_errorMessage.c_str());
case kConnecting:
return CStringUtil::print("%s: Connecting to %s...",
return synergy::string::sprintf("%s: Connecting to %s...",
kAppVersion, m_server.c_str());
case kConnected:
return CStringUtil::print("%s: Connected to %s",
return synergy::string::sprintf("%s: Connected to %s",
kAppVersion, m_server.c_str());
default:

View File

@ -1167,7 +1167,7 @@ CKeyMap::formatKey(KeyID key, KeyModifierMask mask)
x += (char)key;
}
else {
x += CStringUtil::print("\\u%04x", key);
x += synergy::string::sprintf("\\u%04x", key);
}
}
else if (!x.empty()) {

View File

@ -20,7 +20,6 @@
#include "synergy/key_types.h"
#include "base/String.h"
#include "base/StringUtil.h"
#include "common/stdmap.h"
#include "common/stdset.h"
#include "common/stdvector.h"
@ -463,9 +462,9 @@ private:
// Key maps for parsing/formatting
typedef std::map<CString, KeyID,
CStringUtil::CaselessCmp> CNameToKeyMap;
synergy::string::CaselessCmp> CNameToKeyMap;
typedef std::map<CString, KeyModifierMask,
CStringUtil::CaselessCmp> CNameToModifierMap;
synergy::string::CaselessCmp> CNameToModifierMap;
typedef std::map<KeyID, CString> CKeyToNameMap;
typedef std::map<KeyModifierMask, CString> CModifierToNameMap;

View File

@ -18,7 +18,7 @@
#include "synergy/PortableTaskBarReceiver.h"
#include "mt/Lock.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include "base/IEventQueue.h"
#include "arch/Arch.h"
#include "common/Version.h"
@ -106,14 +106,14 @@ CPortableTaskBarReceiver::getToolTip() const
{
switch (m_state) {
case kNotRunning:
return CStringUtil::print("%s: Not running", kAppVersion);
return synergy::string::sprintf("%s: Not running", kAppVersion);
case kNotWorking:
return CStringUtil::print("%s: %s",
return synergy::string::sprintf("%s: %s",
kAppVersion, m_errorMessage.c_str());
case kNotConnected:
return CStringUtil::print("%s: Unknown", kAppVersion);
return synergy::string::sprintf("%s: Unknown", kAppVersion);
default:
return "";

View File

@ -19,7 +19,7 @@
#include "synergy/ServerTaskBarReceiver.h"
#include "server/Server.h"
#include "mt/Lock.h"
#include "base/StringUtil.h"
#include "base/String.h"
#include "base/IEventQueue.h"
#include "arch/Arch.h"
#include "common/Version.h"
@ -120,17 +120,17 @@ CServerTaskBarReceiver::getToolTip() const
{
switch (m_state) {
case kNotRunning:
return CStringUtil::print("%s: Not running", kAppVersion);
return synergy::string::sprintf("%s: Not running", kAppVersion);
case kNotWorking:
return CStringUtil::print("%s: %s",
return synergy::string::sprintf("%s: %s",
kAppVersion, m_errorMessage.c_str());
case kNotConnected:
return CStringUtil::print("%s: Waiting for clients", kAppVersion);
return synergy::string::sprintf("%s: Waiting for clients", kAppVersion);
case kConnected:
return CStringUtil::print("%s: Connected", kAppVersion);
return synergy::string::sprintf("%s: Connected", kAppVersion);
default:
return "";

View File

@ -17,7 +17,7 @@
*/
#include "synergy/XSynergy.h"
#include "base/StringUtil.h"
#include "base/String.h"
//
// XBadClient
@ -57,8 +57,8 @@ CString
XIncompatibleClient::getWhat() const throw()
{
return format("XIncompatibleClient", "incompatible client %{1}.%{2}",
CStringUtil::print("%d", m_major).c_str(),
CStringUtil::print("%d", m_minor).c_str());
synergy::string::sprintf("%d", m_major).c_str(),
synergy::string::sprintf("%d", m_minor).c_str());
}
@ -129,5 +129,5 @@ XExitApp::getWhat() const throw()
{
return format(
"XExitApp", "exiting with code %{1}",
CStringUtil::print("%d", m_code).c_str());
synergy::string::sprintf("%d", m_code).c_str());
}

View File

@ -19,24 +19,37 @@
#include "test/global/gtest.h"
TEST(CStringTests, find_replace_all)
using namespace synergy;
TEST(CStringTests, format)
{
const char* format = "%%%{1}=%{2}";
const char* arg1 = "answer";
const char* arg2 = "42";
CString result = string::format(format, arg1, arg2);
EXPECT_EQ("%answer=42", result);
}
TEST(CStringTests, findReplaceAll)
{
CString subject = "foobar";
CString find = "bar";
CString replace = "baz";
find_replace_all(subject, find, replace);
string::findReplaceAll(subject, find, replace);
EXPECT_EQ("foobaz", subject);
}
TEST(CStringTests, string_format)
TEST(CStringTests, sprintf)
{
CString format = "%s=%d";
const char* format = "%s=%d";
const char* arg1 = "answer";
int arg2 = 42;
CString result = string_format(format, arg1, arg2);
CString result = string::sprintf(format, arg1, arg2);
EXPECT_EQ("answer=42", result);
}