From patchwork Wed Aug 22 18:41:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barker X-Patchwork-Id: 10890 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 6782023E02 for ; Wed, 22 Aug 2012 18:41:20 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id 9D9E7A181E2 for ; Wed, 22 Aug 2012 18:41:07 +0000 (UTC) Received: by yenl8 with SMTP id l8so978821yen.11 for ; Wed, 22 Aug 2012 11:41:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :content-type:mime-version:x-launchpad-project:x-launchpad-branch :x-launchpad-message-rationale:x-launchpad-branch-revision-number :x-launchpad-notification-type:to:from:subject:message-id:date :reply-to:sender:errors-to:precedence:x-generated-by :x-launchpad-hash:x-gm-message-state; bh=2qmpllw+gW+w7iO49sDZQdPnfxXtEIAdyEZ/RmcLEEc=; b=HuTDO/ZDSDMeguJmncBFjyH0t74U7o0pQgWVrTnWfnhsldyMTm7i4OOfzSAaq+S0sL SAmEiJRODtUyOblXCrpJWazbpFztrZmS/t0HCQoNG3rLEyRZG3ASySm9mbH//SICV/gM 7rE6uC2/LUz8tznYEXqCbBSU3zphftSPuPeN9c1b0j2ffDgAAJW1kDBIaWUdixMb3/La gEWOFfdhP4C+EtSC7UziQScYZchJ1IkKCmbHzOh9hN+TGOJfF7jIH4A20xun/ajwcCW9 9x5GTS/jh1TXlolXcdH1aa+WkdPcHxQ3tnyGbfCLdQO6tXi7vLo8eSQVhVhyEWUswbQG 0jqQ== Received: by 10.50.180.129 with SMTP id do1mr3289354igc.28.1345660878407; Wed, 22 Aug 2012 11:41:18 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp217742igc; Wed, 22 Aug 2012 11:41:17 -0700 (PDT) Received: by 10.180.79.229 with SMTP id m5mr7989244wix.13.1345660876801; Wed, 22 Aug 2012 11:41:16 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id et6si49798259wib.1.2012.08.22.11.41.16 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 22 Aug 2012 11:41:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1T4Frf-00067j-Tt for ; Wed, 22 Aug 2012 18:41:15 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id D2A3AE0108 for ; Wed, 22 Aug 2012 18:41:15 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glcompbench X-Launchpad-Branch: ~glcompbench-dev/glcompbench/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 89 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glcompbench-dev/glcompbench/trunk] Rev 89: libmatrix: Update to release 2012.08 Message-Id: <20120822184115.14675.29903.launchpad@ackee.canonical.com> Date: Wed, 22 Aug 2012 18:41:15 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="15822"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: b5d673a1f93d2c1c703dca759d886e8e1e391217 X-Gm-Message-State: ALoCoQl/eKLDoL6cTrdbJV4K4oepMb9oAiWIDk4/TwRO03cOVBXD1UI0TmF0fjkY2HoN7D0bYgeO ------------------------------------------------------------ revno: 89 committer: Jesse Barker branch nick: trunk timestamp: Wed 2012-08-22 11:35:18 -0700 message: libmatrix: Update to release 2012.08 added: src/libmatrix/test/util_split_test.cc src/libmatrix/test/util_split_test.h modified: src/libmatrix/Makefile src/libmatrix/log.cc src/libmatrix/log.h src/libmatrix/program.cc src/libmatrix/program.h src/libmatrix/shader-source.cc src/libmatrix/test/libmatrix_test.cc src/libmatrix/util.cc src/libmatrix/util.h --- lp:glcompbench https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk You are subscribed to branch lp:glcompbench. To unsubscribe from this branch go to https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk/+edit-subscription === modified file 'src/libmatrix/Makefile' --- src/libmatrix/Makefile 2012-05-22 09:55:39 +0000 +++ src/libmatrix/Makefile 2012-08-22 18:35:18 +0000 @@ -9,6 +9,7 @@ $(TESTDIR)/inverse_test.cc \ $(TESTDIR)/transpose_test.cc \ $(TESTDIR)/shader_source_test.cc \ + $(TESTDIR)/util_split_test.cc \ $(TESTDIR)/libmatrix_test.cc TESTOBJS = $(TESTSRCS:.cc=.o) @@ -32,6 +33,7 @@ $(TESTDIR)/inverse_test.o: $(TESTDIR)/inverse_test.cc $(TESTDIR)/inverse_test.h $(TESTDIR)/libmatrix_test.h mat.h $(TESTDIR)/transpose_test.o: $(TESTDIR)/transpose_test.cc $(TESTDIR)/transpose_test.h $(TESTDIR)/libmatrix_test.h mat.h $(TESTDIR)/shader_source_test.o: $(TESTDIR)/shader_source_test.cc $(TESTDIR)/shader_source_test.h $(TESTDIR)/libmatrix_test.h shader-source.h +$(TESTDIR)/util_split_test.o: $(TESTDIR)/util_split_test.cc $(TESTDIR)/util_split_test.h $(TESTDIR)/libmatrix_test.h util.h $(TESTDIR)/libmatrix_test: $(TESTOBJS) libmatrix.a $(CXX) -o $@ $^ run_tests: $(LIBMATRIX_TESTS) === modified file 'src/libmatrix/log.cc' --- src/libmatrix/log.cc 2012-01-27 22:21:17 +0000 +++ src/libmatrix/log.cc 2012-08-22 18:35:18 +0000 @@ -10,6 +10,7 @@ // Alexandros Frantzis // Jesse Barker // +#include #include #include #include @@ -26,8 +27,7 @@ const string Log::continuation_prefix("\x10"); string Log::appname_; bool Log::do_debug_(false); - -#ifndef ANDROID +std::ostream* Log::extra_out_(0); static const string terminal_color_normal("\033[0m"); static const string terminal_color_red("\033[1;31m"); @@ -96,17 +96,26 @@ delete[] buf; } + void Log::info(const char *fmt, ...) { static const string infoprefix("Info"); + const string& prefix(do_debug_ ? infoprefix : empty); + va_list ap; + va_start(ap, fmt); + +#ifndef ANDROID static const string& infocolor(isatty(fileno(stdout)) ? terminal_color_cyan : empty); - va_list ap; - va_start(ap, fmt); - if (do_debug_) - print_prefixed_message(std::cout, infocolor, infoprefix, fmt, ap); - else - print_prefixed_message(std::cout, empty, empty, fmt, ap); + const string& color(do_debug_ ? infocolor : empty); + print_prefixed_message(std::cout, color, prefix, fmt, ap); +#else + __android_log_vprint(ANDROID_LOG_INFO, appname_.c_str(), fmt, ap); +#endif + + if (extra_out_) + print_prefixed_message(*extra_out_, empty, prefix, fmt, ap); + va_end(ap); } @@ -114,12 +123,21 @@ Log::debug(const char *fmt, ...) { static const string dbgprefix("Debug"); + if (!do_debug_) + return; + va_list ap; + va_start(ap, fmt); + +#ifndef ANDROID static const string& dbgcolor(isatty(fileno(stdout)) ? terminal_color_yellow : empty); - if (!do_debug_) - return; - va_list ap; - va_start(ap, fmt); print_prefixed_message(std::cout, dbgcolor, dbgprefix, fmt, ap); +#else + __android_log_vprint(ANDROID_LOG_DEBUG, appname_.c_str(), fmt, ap); +#endif + + if (extra_out_) + print_prefixed_message(*extra_out_, empty, dbgprefix, fmt, ap); + va_end(ap); } @@ -127,52 +145,29 @@ Log::error(const char *fmt, ...) { static const string errprefix("Error"); + va_list ap; + va_start(ap, fmt); + +#ifndef ANDROID static const string& errcolor(isatty(fileno(stderr)) ? terminal_color_red : empty); - va_list ap; - va_start(ap, fmt); print_prefixed_message(std::cerr, errcolor, errprefix, fmt, ap); +#else + __android_log_vprint(ANDROID_LOG_ERROR, appname_.c_str(), fmt, ap); +#endif + + if (extra_out_) + print_prefixed_message(*extra_out_, empty, errprefix, fmt, ap); + va_end(ap); } void Log::flush() { +#ifndef ANDROID std::cout.flush(); std::cerr.flush(); -} -#else -void -Log::info(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - __android_log_vprint(ANDROID_LOG_INFO, appname_.c_str(), fmt, ap); - va_end(ap); -} - -void -Log::debug(const char *fmt, ...) -{ - if (!do_debug_) - return; - va_list ap; - va_start(ap, fmt); - __android_log_vprint(ANDROID_LOG_DEBUG, appname_.c_str(), fmt, ap); - va_end(ap); -} - -void -Log::error(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - __android_log_vprint(ANDROID_LOG_ERROR, appname_.c_str(), fmt, ap); - va_end(ap); -} - -void -Log::flush() -{ -} - #endif + if (extra_out_) + extra_out_->flush(); +} === modified file 'src/libmatrix/log.h' --- src/libmatrix/log.h 2012-01-27 22:21:17 +0000 +++ src/libmatrix/log.h 2012-08-22 18:35:18 +0000 @@ -14,14 +14,17 @@ #define LOG_H_ #include +#include class Log { public: - static void init(const std::string& appname, bool do_debug = false) + static void init(const std::string& appname, bool do_debug = false, + std::ostream *extra_out = 0) { appname_ = appname; do_debug_ = do_debug; + extra_out_ = extra_out; } // Emit an informational message static void info(const char *fmt, ...); @@ -41,6 +44,8 @@ static std::string appname_; // Indicates whether debug level messages should generate any output static bool do_debug_; + // Extra stream to output log messages to + static std::ostream *extra_out_; }; #endif /* LOG_H_ */ === modified file 'src/libmatrix/program.cc' --- src/libmatrix/program.cc 2012-01-26 19:36:28 +0000 +++ src/libmatrix/program.cc 2012-08-22 18:35:18 +0000 @@ -20,6 +20,7 @@ using std::string; using LibMatrix::mat4; +using LibMatrix::mat3; using LibMatrix::vec2; using LibMatrix::vec3; using LibMatrix::vec4; @@ -276,6 +277,17 @@ } Program::Symbol& +Program::Symbol::operator=(const mat3& m) +{ + if (type_ == Uniform) + { + // Our matrix representation is column-major, so transpose is false here. + glUniformMatrix3fv(location_, 1, GL_FALSE, m); + } + return *this; +} + +Program::Symbol& Program::Symbol::operator=(const vec2& v) { if (type_ == Uniform) === modified file 'src/libmatrix/program.h' --- src/libmatrix/program.h 2012-01-26 19:36:28 +0000 +++ src/libmatrix/program.h 2012-08-22 18:35:18 +0000 @@ -127,6 +127,7 @@ // These members cause data to be bound to program variables, so // the program must be bound for use for these to be effective. Symbol& operator=(const LibMatrix::mat4& m); + Symbol& operator=(const LibMatrix::mat3& m); Symbol& operator=(const LibMatrix::vec2& v); Symbol& operator=(const LibMatrix::vec3& v); Symbol& operator=(const LibMatrix::vec4& v); === modified file 'src/libmatrix/shader-source.cc' --- src/libmatrix/shader-source.cc 2012-01-26 19:36:28 +0000 +++ src/libmatrix/shader-source.cc 2012-08-22 18:35:18 +0000 @@ -589,7 +589,7 @@ { std::vector elems; - Util::split(precision_values, ',', elems); + Util::split(precision_values, ',', elems, Util::SplitModeNormal); for (size_t i = 0; i < elems.size() && i < 4; i++) { const std::string& pstr(elems[i]); === modified file 'src/libmatrix/test/libmatrix_test.cc' --- src/libmatrix/test/libmatrix_test.cc 2012-01-26 19:36:28 +0000 +++ src/libmatrix/test/libmatrix_test.cc 2012-08-22 18:35:18 +0000 @@ -8,6 +8,7 @@ // // Contributors: // Jesse Barker - original implementation. +// Alexandros Frantzis - Util::split tests // #include #include @@ -17,6 +18,7 @@ #include "transpose_test.h" #include "const_vec_test.h" #include "shader_source_test.h" +#include "util_split_test.h" using std::cerr; using std::cout; @@ -42,6 +44,8 @@ testVec.push_back(new MatrixTest3x3Transpose()); testVec.push_back(new MatrixTest4x4Transpose()); testVec.push_back(new ShaderSourceBasic()); + testVec.push_back(new UtilSplitTestNormal()); + testVec.push_back(new UtilSplitTestQuoted()); for (vector::iterator testIt = testVec.begin(); testIt != testVec.end(); === added file 'src/libmatrix/test/util_split_test.cc' --- src/libmatrix/test/util_split_test.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/util_split_test.cc 2012-08-22 18:35:18 +0000 @@ -0,0 +1,180 @@ +// +// Copyright (c) 2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis - original implementation. +// +#include +#include +#include +#include "libmatrix_test.h" +#include "util_split_test.h" +#include "../util.h" + +using std::cout; +using std::endl; +using std::string; +using std::vector; + +template static bool +areVectorsEqual(vector& vec1, vector& vec2) +{ + if (vec1.size() != vec2.size()) + return false; + + for (unsigned int i = 0; i < vec1.size(); i++) + { + if (vec1[i] != vec2[i]) + return false; + } + + return true; +} + +template static void +printVector(vector& vec) +{ + cout << "["; + for (unsigned int i = 0; i < vec.size(); i++) + { + cout << '"' << vec[i] << '"'; + if (i < vec.size() - 1) + cout << ", "; + } + cout << "]"; +} + +void +UtilSplitTestNormal::run(const Options& options) +{ + const string test1("abc def ghi"); + const string test2(" abc: def :ghi "); + vector expected1; + vector expected2; + vector results; + + expected1.push_back("abc"); + expected1.push_back("def"); + expected1.push_back("ghi"); + + expected2.push_back(" abc"); + expected2.push_back(" def "); + expected2.push_back("ghi "); + + if (options.beVerbose()) + { + cout << "Testing string \"" << test1 << "\"" << endl; + } + + Util::split(test1, ' ', results, Util::SplitModeNormal); + + if (options.beVerbose()) + { + cout << "Split result: "; + printVector(results); + cout << endl << "Expected: "; + printVector(expected1); + cout << endl; + } + + if (!areVectorsEqual(results, expected1)) + { + return; + } + + results.clear(); + + if (options.beVerbose()) + { + cout << "Testing string \"" << test2 << "\"" << endl; + } + + Util::split(test2, ':', results, Util::SplitModeNormal); + + if (options.beVerbose()) + { + cout << "Split result: "; + printVector(results); + cout << endl << "Expected: "; + printVector(expected2); + cout << endl; + } + + if (!areVectorsEqual(results, expected2)) + { + return; + } + + pass_ = true; +} + +void +UtilSplitTestQuoted::run(const Options& options) +{ + const string test1("abc \"def' ghi\" klm\\ nop -b qr:title='123 \"456'"); + const string test2("abc: def='1:2:3:'ghi : \":jk\""); + vector expected1; + vector expected2; + vector results; + + expected1.push_back("abc"); + expected1.push_back("def' ghi"); + expected1.push_back("klm nop"); + expected1.push_back("-b"); + expected1.push_back("qr:title=123 \"456"); + + expected2.push_back("abc"); + expected2.push_back(" def=1:2:3:ghi "); + expected2.push_back(" :jk"); + + if (options.beVerbose()) + { + cout << "Testing string \"" << test1 << "\"" << endl; + } + + Util::split(test1, ' ', results, Util::SplitModeQuoted); + + if (options.beVerbose()) + { + cout << "Split result: "; + printVector(results); + cout << endl << "Expected: "; + printVector(expected1); + cout << endl; + } + + if (!areVectorsEqual(results, expected1)) + { + return; + } + + results.clear(); + + if (options.beVerbose()) + { + cout << "Testing string \"" << test2 << "\"" << endl; + } + + Util::split(test2, ':', results, Util::SplitModeQuoted); + + if (options.beVerbose()) + { + cout << "Split result: "; + printVector(results); + cout << endl << "Expected: "; + printVector(expected2); + cout << endl; + } + + if (!areVectorsEqual(results, expected2)) + { + return; + } + + pass_ = true; +} === added file 'src/libmatrix/test/util_split_test.h' --- src/libmatrix/test/util_split_test.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/util_split_test.h 2012-08-22 18:35:18 +0000 @@ -0,0 +1,31 @@ +// +// Copyright (c) 2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis - original implementation. +// +#ifndef UTIL_SPLIT_TEST_H_ +#define UTIL_SPLIT_TEST_H_ + +class MatrixTest; +class Options; + +class UtilSplitTestNormal : public MatrixTest +{ +public: + UtilSplitTestNormal() : MatrixTest("Util::split::normal") {} + virtual void run(const Options& options); +}; + +class UtilSplitTestQuoted : public MatrixTest +{ +public: + UtilSplitTestQuoted() : MatrixTest("Util::split::quoted") {} + virtual void run(const Options& options); +}; +#endif // UTIL_SPLIT_TEST_H_ === modified file 'src/libmatrix/util.cc' --- src/libmatrix/util.cc 2012-05-22 09:55:39 +0000 +++ src/libmatrix/util.cc 2012-08-22 18:35:18 +0000 @@ -25,25 +25,102 @@ using std::string; using std::vector; -void -Util::split(const string& src, char delim, vector& elementVec, bool fuzzy) -{ - // Trivial rejection - if (src.empty()) - { - return; - } - - // Simple case: we want to enforce the value of 'delim' strictly - if (!fuzzy) - { - std::stringstream ss(src); - string item; - while(std::getline(ss, item, delim)) - elementVec.push_back(item); - return; - } - +/* + * State machine for bash-like quoted string escaping: + * + * \ + * -----------> +---------+ + * | ---------- | Escaped | + * | | *,ESC +---------+ + * | | + * | v ' + * +--------+ ---> +--------------+ ----- + * | Normal | <--- | SingleQuoted | | *, ESC + * +--------+ ' +--------------+ <---- + * | ^ + * | | + * | | " +--------------+ ---- + * | ---------- | DoubleQuoted | | *, ESC + * -----------> +--------------+ <--- + * " | ^ + * \ | | *, ESC + * v | + * +---------------------+ + * | DoubleQuotedEscaped | + * +---------------------+ + * + * ESC: Mark character as Escaped + */ +static void +fill_escape_vector(const string &str, vector &esc_vec) +{ + enum State { + StateNormal, + StateEscaped, + StateDoubleQuoted, + StateDoubleQuotedEscaped, + StateSingleQuoted + }; + + State state = StateNormal; + + for (string::const_iterator iter = str.begin(); + iter != str.end(); + iter++) + { + const char c(*iter); + bool esc = false; + + switch (state) { + case StateNormal: + if (c == '"') + state = StateDoubleQuoted; + else if (c == '\\') + state = StateEscaped; + else if (c == '\'') + state = StateSingleQuoted; + break; + case StateEscaped: + esc = true; + state = StateNormal; + break; + case StateDoubleQuoted: + if (c == '"') + state = StateNormal; + else if (c == '\\') + state = StateDoubleQuotedEscaped; + else + esc = true; + break; + case StateDoubleQuotedEscaped: + esc = true; + state = StateDoubleQuoted; + break; + case StateSingleQuoted: + if (c == '\'') + state = StateNormal; + else + esc = true; + default: + break; + } + + esc_vec.push_back(esc); + } +} + +static void +split_normal(const string& src, char delim, vector& elementVec) +{ + std::stringstream ss(src); + string item; + while(std::getline(ss, item, delim)) + elementVec.push_back(item); +} + +static void +split_fuzzy(const string& src, char delim, vector& elementVec) +{ // Fuzzy case: Initialize our delimiter string based upon the caller's plus // a space to allow for more flexibility. string delimiter(" "); @@ -76,6 +153,70 @@ elementVec.push_back(str); } +static void +split_quoted(const string& src, char delim, vector& elementVec) +{ + std::stringstream ss; + vector escVec; + + /* Mark characters in the string as escaped or not */ + fill_escape_vector(src, escVec); + + /* Sanity check... */ + if (src.length() != escVec.size()) + return; + + for (vector::const_iterator iter = escVec.begin(); + iter != escVec.end(); + iter++) + { + bool escaped = static_cast(*iter); + char c = src[iter - escVec.begin()]; + + /* Output all characters, except unescaped ",\,' */ + if ((c != '"' && c != '\\' && c != '\'') || escaped) { + /* If we reach an unescaped delimiter character, do a split */ + if (c == delim && !escaped) { + elementVec.push_back(ss.str()); + ss.str(""); + ss.clear(); + } + else { + ss << c; + } + } + + } + + /* Handle final element, delimited by end of string */ + const string &finalElement(ss.str()); + if (!finalElement.empty()) + elementVec.push_back(finalElement); +} + +void +Util::split(const string& src, char delim, vector& elementVec, + Util::SplitMode mode) +{ + // Trivial rejection + if (src.empty()) + { + return; + } + + switch (mode) + { + case Util::SplitModeNormal: + return split_normal(src, delim, elementVec); + case Util::SplitModeFuzzy: + return split_fuzzy(src, delim, elementVec); + case Util::SplitModeQuoted: + return split_quoted(src, delim, elementVec); + default: + break; + } +} + uint64_t Util::get_timestamp_us() { === modified file 'src/libmatrix/util.h' --- src/libmatrix/util.h 2012-05-22 09:55:39 +0000 +++ src/libmatrix/util.h 2012-08-22 18:35:18 +0000 @@ -25,21 +25,33 @@ struct Util { /** + * How to perform the split() operation + */ + enum SplitMode { + /** Normal split operation */ + SplitModeNormal, + /** Allow for spaces and multiple consecutive occurences of the delimiter */ + SplitModeFuzzy, + /** Take into account bash-like quoting and escaping rules */ + SplitModeQuoted + }; + + /** * split() - Splits a string into elements using a provided delimiter * * @s: the string to split * @delim: the delimiter to use * @elems: the string vector to populate - * @fuzzy: (optional) enable/disable strict handling of @delim + * @mode: the SplitMode to use * * Using @delim to determine field boundaries, splits @s into separate * string elements. These elements are returned in the string vector - * @elems. If @fuzzy is true, then the handling of @delim allows for - * spaces and multiple consecutive occurences of @delim in determining - * field boundaries. As long as @s is non-empty, there will be at least - * one element in @elems. + * @elems. As long as @s is non-empty, there will be at least one + * element in @elems. */ - static void split(const std::string &s, char delim, std::vector &elems, bool fuzzy = false); + static void split(const std::string& src, char delim, + std::vector& elems, + Util::SplitMode mode); /** * get_timestamp_us() - Returns the current time in microseconds */