JWM Source Documentation
misc.c
Go to the documentation of this file.
1 
10 #include "jwm.h"
11 #include "misc.h"
12 #include "debug.h"
13 
14 static char ToLower(char ch);
15 static char IsSymbolic(char ch);
16 static char *GetSymbolName(const char *str);
17 static void ReplaceSymbol(char **str, unsigned int offset,
18  const char *name, const char *value);
19 
21 char IsSpace(char ch, unsigned int *lineNumber)
22 {
23  switch(ch) {
24  case ' ':
25  case '\t':
26  case '\r':
27  return 1;
28  case '\n':
29  *lineNumber += 1;
30  return 1;
31  default:
32  return 0;
33  }
34 }
35 
37 char ToLower(char ch)
38 {
39  /* This should work in either ASCII or EBCDIC. */
40  if( (ch >= 'A' && ch <= 'I')
41  || (ch >= 'J' && ch <= 'R')
42  || (ch >= 'S' && ch <= 'Z')) {
43  return ch - 'A' + 'a';
44  } else {
45  return ch;
46  }
47 }
48 
50 char IsSymbolic(char ch)
51 {
52  /* This should work in either ASCII or EBCDIC. */
53  if(ch >= 'A' && ch <= 'I') {
54  return 1;
55  } else if(ch >= 'J' && ch <= 'R') {
56  return 1;
57  } else if(ch >= 'S' && ch <= 'Z') {
58  return 1;
59  } else if(ch >= 'a' && ch <= 'i') {
60  return 1;
61  } else if(ch >= 'j' && ch <= 'r') {
62  return 1;
63  } else if(ch >= 's' && ch <= 'z') {
64  return 1;
65  } else if(ch >= '0' && ch <= '9') {
66  return 1;
67  } else if(ch == '_') {
68  return 1;
69  } else {
70  return 0;
71  }
72 }
73 
75 char *GetSymbolName(const char *str)
76 {
77 
78  char *temp;
79 
80  if(*str == '$') {
81  temp = Allocate(2);
82  temp[0] = '$';
83  temp[1] = 0;
84  } else {
85  int stop;
86  for(stop = 0; IsSymbolic(str[stop]); stop++);
87  temp = Allocate(stop + 1);
88  memcpy(temp, str, stop);
89  temp[stop] = 0;
90  }
91 
92  return temp;
93 
94 }
95 
97 void ReplaceSymbol(char **str, unsigned int offset,
98  const char *name, const char *value)
99 {
100 
101  char *temp;
102  int strLength;
103  int nameLength;
104  int valueLength;
105 
106  Assert(str);
107  Assert(name);
108 
109  /* Determine string lengths. */
110  strLength = strlen(*str);
111  nameLength = strlen(name) + 1; /* Account for the '$'. */
112  if(value) {
113  valueLength = strlen(value);
114  } else {
115  valueLength = 0;
116  }
117 
118  /* Allocate extra space if necessary. */
119  if(valueLength > nameLength) {
120  const size_t totalLen = strLength - nameLength + valueLength + 1;
121  temp = Allocate(totalLen);
122  memcpy(temp, *str, strLength + 1);
123  Release(*str);
124  *str = temp;
125  }
126 
127  /* Offset to '$'. */
128  temp = *str + offset;
129 
130  if(nameLength > valueLength) {
131 
132  /* Move left */
133  memmove(temp, temp + nameLength - valueLength,
134  strLength - offset - nameLength + valueLength + 1);
135 
136  } else if(nameLength < valueLength) {
137 
138  /* Move right */
139  memmove(temp + valueLength, temp + nameLength,
140  strLength + - nameLength - offset + 1);
141 
142  }
143 
144  if(value) {
145  memcpy(temp, value, valueLength);
146  }
147 
148 }
149 
151 void ExpandPath(char **path)
152 {
153 
154  char *name;
155  char *value;
156  unsigned int x;
157 
158  Assert(path);
159 
160  for(x = 0; (*path)[x]; x++) {
161 
162  if((*path)[x] == '$') {
163  name = GetSymbolName(*path + x + 1);
164  value = getenv(name);
165  ReplaceSymbol(path, x, name, value);
166  Release(name);
167  if(value) {
168  x += strlen(value) - 1;
169  }
170  }
171 
172  }
173 
174 }
175 
177 void Trim(char *str)
178 {
179 
180  unsigned int length;
181  unsigned int start;
182  unsigned int x;
183  unsigned int line;
184 
185  Assert(str);
186 
187  length = strlen(str);
188 
189  /* Determine how much to cut off of the left. */
190  line = 0;
191  for(start = 0; IsSpace(str[start], &line); start++);
192 
193  /* Trim the left. */
194  if(start > 0) {
195  length -= start;
196  for(x = 0; x < length + 1; x++) {
197  str[x] = str[x + start];
198  }
199  }
200 
201  /* Trim the right. */
202  while(length > 0 && IsSpace(str[length - 1], &line)) {
203  length -= 1;
204  str[length] = 0;
205  }
206 
207 }
208 
210 char *CopyString(const char *str)
211 {
212 
213  char *temp;
214  unsigned int len;
215 
216  if(!str) {
217  return NULL;
218  }
219 
220  len = strlen(str) + 1;
221  temp = Allocate(len);
222  memcpy(temp, str, len);
223 
224  return temp;
225 
226 }
227 
229 float ParseFloat(const char *str)
230 {
231  float result;
232 #if defined(HAVE_SETLOCALE) && (defined(ENABLE_NLS) || defined(ENABLE_ICONV))
233  setlocale(LC_ALL, "C");
234 #endif
235  result = atof(str);
236 #if defined(HAVE_SETLOCALE) && (defined(ENABLE_NLS) || defined(ENABLE_ICONV))
237  setlocale(LC_ALL, "");
238 #endif
239  return result;
240 }
241 
243 int FindValue(const StringMappingType *mapping, int count, const char *key)
244 {
245  int left = 0;
246  int right = count - 1;
247  while(right >= left) {
248  const int x = (left + right) / 2;
249  Assert(x >= 0);
250  Assert(x < count);
251  const int rc = strcmp(key, mapping[x].key);
252  if(rc < 0) {
253  right = x - 1;
254  } else if(rc > 0) {
255  left = x + 1;
256  } else {
257  return mapping[x].value;
258  }
259  }
260  return -1;
261 }
262 
264 const char *FindKey(const StringMappingType *mapping, int count, int value)
265 {
266  int x;
267  for(x = 0; x < count; x++) {
268  if(mapping[x].value == value) {
269  return mapping[x].key;
270  }
271  }
272  return NULL;
273 }
274 
276 int StrCmpNoCase(const char *a, const char *b)
277 {
278  while(*a && *b && ToLower(*a) == ToLower(*b)) {
279  a += 1;
280  b += 1;
281  }
282  return *b - *a;
283 }

joewing.net / Projects / JWM