llvm.org GIT mirror llvm / 1d75d3a
Roll back r82348, which introduced an infinite loop in ParseCStringVector() that a trivial unittest would have caught. This revision also adds the trivial unittest. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82675 91177308-0d34-0410-b5e6-96231b3b80d8 Jeffrey Yasskin 10 years ago
2 changed file(s) with 83 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
350350 /// using strdup(), so it is the caller's responsibility to free()
351351 /// them later.
352352 ///
353 static void ParseCStringVector(std::vector &OutputVector,
354 const char *Input) {
353 static void ParseCStringVector(std::vector &output,
354 const char *input) {
355355 // Characters which will be treated as token separators:
356 StringRef Delims = " \v\f\t\r\n";
357
358 StringRef WorkStr(Input);
359 while (!WorkStr.empty()) {
360 // If the first character is a delimiter, strip them off.
361 if (Delims.find(WorkStr[0]) != StringRef::npos) {
362 size_t Pos = WorkStr.find_first_not_of(Delims);
363 if (Pos == StringRef::npos) Pos = WorkStr.size();
364 WorkStr = WorkStr.substr(Pos);
365 continue;
366 }
367
368 // Find position of first delimiter.
369 size_t Pos = WorkStr.find_first_of(Delims);
370 if (Pos == StringRef::npos) Pos = WorkStr.size();
371
372 // Everything from 0 to Pos is the next word to copy.
373 char *NewStr = (char*)malloc(Pos+1);
374 memcpy(NewStr, WorkStr.data(), Pos);
375 NewStr[Pos] = 0;
376 OutputVector.push_back(NewStr);
377 }
356 static const char *const delims = " \v\f\t\r\n";
357
358 std::string work(input);
359 // Skip past any delims at head of input string.
360 size_t pos = work.find_first_not_of(delims);
361 // If the string consists entirely of delims, then exit early.
362 if (pos == std::string::npos) return;
363 // Otherwise, jump forward to beginning of first word.
364 work = work.substr(pos);
365 // Find position of first delimiter.
366 pos = work.find_first_of(delims);
367
368 while (!work.empty() && pos != std::string::npos) {
369 // Everything from 0 to POS is the next word to copy.
370 output.push_back(strdup(work.substr(0,pos).c_str()));
371 // Is there another word in the string?
372 size_t nextpos = work.find_first_not_of(delims, pos + 1);
373 if (nextpos != std::string::npos) {
374 // Yes? Then remove delims from beginning ...
375 work = work.substr(work.find_first_not_of(delims, pos + 1));
376 // and find the end of the word.
377 pos = work.find_first_of(delims);
378 } else {
379 // No? (Remainder of string is delims.) End the loop.
380 work = "";
381 pos = std::string::npos;
382 }
383 }
384
385 // If `input' ended with non-delim char, then we'll get here with
386 // the last word of `input' in `work'; copy it now.
387 if (!work.empty())
388 output.push_back(strdup(work.c_str()));
378389 }
379390
380391 /// ParseEnvironmentOptions - An alternative entry point to the
0 //===- llvm/unittest/Support/CommandLineTest.cpp - CommandLine tests ------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Support/CommandLine.h"
10
11 #include "gtest/gtest.h"
12
13 #include
14 #include
15
16 using namespace llvm;
17
18 namespace {
19
20 class TempEnvVar {
21 public:
22 TempEnvVar(const char *name, const char *value)
23 : name(name) {
24 const char *old_value = getenv(name);
25 EXPECT_EQ(NULL, old_value) << old_value;
26 setenv(name, value, true);
27 }
28
29 ~TempEnvVar() {
30 unsetenv(name);
31 }
32
33 private:
34 const char *const name;
35 };
36
37 const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS";
38
39 cl::opt EnvironmentTestOption("env-test-opt");
40 TEST(CommandLineTest, ParseEnvironment) {
41 TempEnvVar TEV(test_env_var, "-env-test-opt=hello");
42 EXPECT_EQ("", EnvironmentTestOption);
43 cl::ParseEnvironmentOptions("CommandLineTest", test_env_var);
44 EXPECT_EQ("hello", EnvironmentTestOption);
45 }
46
47 } // anonymous namespace