forked from scriptcs/scriptcs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStringExtensions.cs
More file actions
120 lines (108 loc) · 4.97 KB
/
StringExtensions.cs
File metadata and controls
120 lines (108 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System;
using System.Collections.Generic;
using System.Text;
namespace ScriptCs
{
public static class StringExtensions
{
public static string DefineTrace(this string code)
{
return string.Format("#define TRACE{0}{1}", Environment.NewLine, code);
}
/// <summary>
/// Split string on whitespace, but keeps string with quotes together
/// For example: :cd "\\Foo Bar"
/// :cd
/// "\\Foo Bar".
/// </summary>
/// <param name="argument">String with or without quotes.</param>
/// <returns>Array of strings.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods",
Justification = "Guard Against Null Argument method is not need because of the if statement.",
MessageId = "0")]
public static string[] SplitQuoted(this string argument)
{
if (string.IsNullOrWhiteSpace(argument))
{
return argument.Split(' ');
}
// count the number of quotes and throw something is not even
// the fastest way is to just loop thru the string
// http://cc.davelozinski.com/c-sharp/fastest-way-to-check-if-a-string-occurs-within-a-string
Func<string, int> quoteCounterFunc = delegate (string line)
{
int count = 0;
for (int x = 0; x < line.Length; x++)
{
if (line[x] == '"')
{
count++;
}
}
return count;
};
int quotes = quoteCounterFunc(argument);
if ((quotes % 2) != 0)
{
throw new ArgumentException("String is missing a closing quote");
}
List<string> list = new List<string>(argument.Split(' '));
// quoted string needs to be combine back together
if (quotes > 0 && list.Count > 0)
{
Predicate<string> findQuoteFunc = delegate (string s) { return s.Contains("\""); };
// create function to find string item with odd number of quotes
Func<int, int> findOddQuotedItemFunc = delegate (int startingIndex) {
if (startingIndex < list.Count)
{
do
{
int quickFind = list.FindIndex(startingIndex, findQuoteFunc);
int quickCount = quoteCounterFunc(list[quickFind]);
if ((quickCount % 2) != 0)
{
return quickFind;
}
// we didn't find the quoted line we are looking for
startingIndex = quickFind + 1;
} while (startingIndex < list.Count);
}
return -1;
};
int index = 0;
do
{
int start = findOddQuotedItemFunc(index);
if (start > 0)
{
// we have to locate the next string with odd number of quotes
int end = findOddQuotedItemFunc(start + 1);
string combined = string.Empty;
for (int x = start; x <= end; x++)
{
// because we split on whitespace, we have to put it back when combining
combined += list[x] + ' ';
}
list[start] = combined.TrimEnd(); // remove the extra whitespace that was added
// removed the other parts of the combined string from the list
do
{
list.RemoveAt(end--); // from the bottom up
} while (start < end);
// advance to next item in the adjusted list
index = start + 1;
}
else
{
break;
}
} while (index < list.Count);
}
return list.ToArray();
}
public static string UndefineTrace(this string code)
{
return string.Format("#undef TRACE{0}{1}", Environment.NewLine, code);
}
}
}