btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / terminal / PatternEvaluator.cpp
blobe5ded68ab09b239dd1b7db7d6dafb5a3f7289d0d
1 /*
2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
5 */
8 #include "PatternEvaluator.h"
10 #include <ctype.h>
11 #include <stdlib.h>
12 #include <string.h>
16 // #pragma mark - PatternEvaluator
19 /*static*/ BString
20 PatternEvaluator::Evaluate(const char* pattern, PlaceholderMapper& mapper)
22 BString result;
23 BString before;
24 bool isBefore = false;
25 bool isAfter = false;
26 bool hadResult = false;
27 bool began = false;
29 while (*pattern != '\0') {
30 // find next placeholder
31 const char* placeholder = strchr(pattern, '%');
32 size_t length = 0;
33 if (placeholder != NULL)
34 length = placeholder - pattern;
35 else
36 length = INT_MAX;
38 // append skipped chars
39 if (placeholder != pattern) {
40 if (isBefore) {
41 before.SetTo(pattern, length);
42 isBefore = false;
43 } else if (!isAfter || hadResult) {
44 result.Append(pattern, length);
45 isBefore = false;
46 before.SetTo(NULL);
47 isAfter = false;
50 if (placeholder == NULL)
51 return result;
53 pattern = placeholder + 1;
55 // check for special placeholders
56 switch (pattern[0]) {
57 case '%':
58 // An escaped '%'
59 result += '%';
60 pattern++;
61 continue;
62 case '<':
63 // An optional before string
64 isBefore = began = true;
65 hadResult = false;
66 pattern++;
67 continue;
68 case '>':
69 // An optional after string
70 isAfter = true;
71 began = false;
72 before.SetTo(NULL);
73 pattern++;
74 continue;
75 case '-':
76 // End of any other section; ignore
77 pattern++;
78 isBefore = false;
79 isAfter = false;
80 continue;
82 // Count non alpha numeric characters to the before section
83 while (pattern[0] != '\0' && !isalnum(pattern[0])) {
84 before.Append(pattern[0], 1);
85 pattern++;
88 // parse a number, if there is one
89 int64 number = 0;
90 bool hasNumber = false;
91 if (isdigit(*pattern)) {
92 char* numberEnd;
93 number = strtoll(pattern, &numberEnd, 10);
94 pattern = numberEnd;
95 hasNumber = true;
98 BString mappedValue;
99 if (*pattern != '\0' && mapper.MapPlaceholder(*pattern,
100 number, hasNumber, mappedValue)) {
101 // mapped successfully -- append the replacement string
102 if (began && !mappedValue.IsEmpty())
103 hadResult = true;
104 if (!before.IsEmpty() && !mappedValue.IsEmpty()) {
105 result += before;
106 before.SetTo(NULL);
109 result += mappedValue;
110 pattern++;
111 } else {
112 // something went wrong -- just append the literal part of the
113 // pattern
114 result.Append(placeholder, length);
118 return result;
122 // #pragma mark - PlaceholderMapper
125 PatternEvaluator::PlaceholderMapper::~PlaceholderMapper()