]> icculus.org git repositories - divverent/nexuiz.git/blob - data/menuqc/util/altstring.qc
Commit flush my old working copy.
[divverent/nexuiz.git] / data / menuqc / util / altstring.qc
1 // NG-Menu
2 // util/altstring.qc
3
4 #ifndef OLDFUNCTIONSET
5
6 #define ALTSTRING_SEPERATOR1 ";"
7 #define ALTSTRING_SEPERATOR2 ":"
8 #define ALTSTRING_ESCAPE "\\"
9
10 void() Util_AltString_UnitTest =
11 {
12         local float lCount;
13         {
14                 local zoned lTestCount;
15
16                 lTestCount = String_Zone( "normal;use escape \\; ;another escape \\; ;" );
17                 lCount = Util_GetAltStringCount( lTestCount );
18                 print( "'", lTestCount, "' <- item count: ", ftos( lCount ), "\n" );
19
20                 {
21                         local float lIndex;
22                         for( lIndex = 0 ; lIndex <= lCount ; lIndex++ ) {
23                                 local float lStart;
24                                 lStart = Util_GetAltStringItemStart( lTestCount, lIndex );
25                                 print( "Start of item ", ftos( lIndex ), " at ", ftos( lStart ), "\n" );
26                         }
27                 }
28
29                 {
30                         local float lIndex;
31                         for( lIndex = 0 ; lIndex <= lCount ; lIndex++ ) {
32                                 local zoned lItem;
33                                 lItem = Util_GetAltStringItem( lTestCount, lIndex );
34                                 print( "Item #", ftos( lIndex ), ": ", lItem, "\n" );
35                                 String_Free( lItem );
36                         }
37                 }
38
39                 String_Free( lTestCount );
40         }
41
42         {
43                 local zoned lTest;
44                 local float lIndex;
45
46                 lTest = String_Zone( "alt1;alt2;alt3;" );
47                 print( lTest, "\n" );
48
49                 for( lIndex = 0 ; lIndex <= lCount * 2; lIndex = lIndex + 2 ) {
50                         lTest = Util_InsAltStringItem( lTest, lIndex, ftos( lIndex ) );
51                         print( lTestCount, "\n" );
52                 }
53
54                 for( lIndex = 0 ; lIndex <= lCount * 2; lIndex = lIndex + 2 ) {
55                         lTest = Util_SetAltStringItem( lTest, lIndex, strcat( "#", ftos( lIndex ) ) );
56                         print( lTestCount, "\n" );
57                 }
58
59                 for( lIndex = 0 ; lIndex <= lCount ; lIndex = lIndex + 1 ) {
60                         lTest = Util_DelAltStringItem( lTest, lIndex );
61                         print( lTestCount, "\n" );
62                 }
63         }
64
65         print( "\nTest AltString(Un)Prepare\n" );
66         {
67                 local string lTest;
68
69                 lTest = "\\;\\a\\b\\\\ \\;";
70                 print( "'", lTest, "'" );
71                 lTest = Util_AltStringPrepare( lTest );
72                 print( "->'", lTest, "'" );
73                 lTest = Util_AltStringUnprepare( String_Normal( lTest ) );
74                 print( "\n->'", lTest, "'\n" );
75                 String_Free( lTest );
76         }
77
78         // TODO: add stack unit test
79 };
80
81 float( zoned pAlt ) Util_GetAltStringCount =
82 {
83         local float lPosition, lLength;
84         local float lCount;
85
86         lCount = 0;
87         for( lPosition = 0, lLength = strlen( pAlt ) ; lPosition < lLength ; lPosition++ ) {
88                 local string lChar;
89                 lChar = substring( pAlt, lPosition, 1 );
90                 if( lChar == ALTSTRING_SEPERATOR1 || lChar == ALTSTRING_SEPERATOR2 ) {
91                         lCount++;
92                 } else if( lChar == ALTSTRING_ESCAPE ) {
93                         lPosition++;
94                 }
95         }
96
97         return lCount;
98 };
99
100 float( zoned pAlt, float pIndex ) Util_GetAltStringItemStart =
101 {
102         local float lPosition, lLength;
103         local float lCount;
104
105         lCount = 0;
106         for( lPosition = 0, lLength = strlen( pAlt ) ; lPosition < lLength && lCount < pIndex ; lPosition++ ) {
107                 local string lChar;
108                 lChar = substring( pAlt, lPosition, 1 );
109                 if( lChar == ALTSTRING_SEPERATOR1 || lChar == ALTSTRING_SEPERATOR2 ) {
110                         lCount++;
111                 } else if( lChar == ALTSTRING_ESCAPE ) {
112                         lPosition++;
113                 }
114         }
115         return lPosition;
116 }
117
118 zoned( zoned pAlt, float pIndex ) Util_GetAltStringItem =
119 {
120         local float lStart, lEnd;
121         local string lItem;
122
123         lStart = Util_GetAltStringItemStart( pAlt, pIndex );
124         lEnd = Util_GetAltStringItemStart( pAlt, pIndex + 1 ) - 2;
125
126         lItem = substring( pAlt, lStart, lEnd - lStart + 1 );
127         return Util_AltStringUnprepare( lItem );
128 };
129
130 zoned( zoned pAlt, float pIndex, string pSet ) Util_SetAltStringItem =
131 {
132         local float lStart, lEnd;
133         local zoned lResult;
134         local string lItem;
135
136         pSet = String_Zone( pSet );
137
138         lStart = Util_GetAltStringItemStart( pAlt, pIndex );
139         lEnd = Util_GetAltStringItemStart( pAlt, pIndex + 1 ) - 1; // include the seperator
140
141         lResult = String_Substring( pAlt, 0, lStart - 1 + 1 );
142
143         lItem = String_Normal( Util_AltStringPrepare( pSet ) );
144         lResult = String_Append( lResult, lItem );
145
146         lResult = String_Append( lResult, substring( pAlt, lEnd, INFINITY ) );
147
148         String_Free( pSet );
149
150         return String_Set( pAlt, String_Normal( lResult ) );
151 }
152
153 zoned( zoned pAlt, float pIndex ) Util_DelAltStringItem =
154 {
155         local float lStart, lEnd;
156         local zoned lResult;
157
158         lStart = Util_GetAltStringItemStart( pAlt, pIndex );
159         lEnd = Util_GetAltStringItemStart( pAlt, pIndex + 1 );
160
161         lResult = String_Substring( pAlt, 0, lStart - 1 + 1 );
162         lResult = String_Append( lResult, substring( pAlt, lEnd, INFINITY ) );
163
164         return String_Set( pAlt, String_Normal( lResult ) );
165 };
166
167 // insert a new item after the indexed (to insert an item at the front use -1)
168 zoned( zoned pAlt, float pIndex, string pSet ) Util_InsAltStringItem =
169 {
170         local float lStart;
171         local zoned lResult;
172         local string lItem;
173
174         pSet = String_Zone( pSet );
175
176         lStart = Util_GetAltStringItemStart( pAlt, pIndex );
177         lResult = String_Substring( pAlt, 0, lStart - 1 + 1 );
178
179         lItem = String_Normal( Util_AltStringPrepare( pSet ) );
180         lResult = String_Append( lResult, lItem );
181
182         lResult = String_Append( lResult, ";" );
183         lResult = String_Append( lResult, substring( pAlt, lStart, INFINITY ) );
184
185         String_Free( pSet );
186
187         return String_Set( pAlt, lResult );
188 };
189
190 zoned( string pString ) Util_AltStringPrepare =
191 {
192         local float lPosition, lLength;
193         local zoned lIn;
194         local string lOut;
195
196         lIn = String_Zone( pString );
197         lOut = "";
198         for( lPosition = 0, lLength = strlen( pString ) ; lPosition < lLength ; lPosition++ ) {
199                 local string lChar;
200                 lChar = substring( lIn, lPosition, 1 );
201
202                 if( lChar == ALTSTRING_SEPERATOR1 || lChar == ALTSTRING_SEPERATOR2 || lChar == ALTSTRING_ESCAPE ) {
203                         lOut = strcat( lOut, "\\", lChar );
204                 } else {
205                         lOut = strcat( lOut, lChar );
206                 }
207         }
208
209         String_Free( lIn );
210         return String_Zone( lOut );
211 };
212
213 zoned( string pString ) Util_AltStringUnprepare =
214 {
215         local float lPosition, lLength;
216         local zoned lIn;
217         local string lOut;
218
219         lIn = String_Zone( pString );
220         lOut = "";
221         for( lPosition = 0, lLength = strlen( pString ) ; lPosition < lLength ; lPosition++ ) {
222                 local string lChar;
223                 lChar = substring( lIn, lPosition, 1 );
224
225                 if( lChar == ALTSTRING_ESCAPE ) {
226                         lPosition++;
227                         lChar = substring( lIn, lPosition, 1 );
228                 }
229
230                 lOut = strcat( lOut, lChar );
231         }
232
233         String_Free( lIn );
234         return String_Zone( lOut );
235 }
236
237 zoned( zoned pAlt, string pPush ) Util_AltStringPush =
238 {
239         local zoned lPrepared;
240
241         lPrepared = Util_AltStringPrepare( pPush );
242         pAlt = String_Set( pAlt, strcat( lPrepared, ";", pAlt ) );
243         String_Free( lPrepared );
244
245         return pAlt;
246 };
247
248 zoned( zoned pAlt, string pPush ) Util_AltStringPushBack =
249 {
250         local zoned lPrepared;
251
252         lPrepared = Util_AltStringPrepare( pPush );
253         pAlt = String_Set( pAlt, strcat( pAlt, pPush, ";" ) );
254         String_Free( lPrepared );
255
256         return pAlt;
257 };
258
259 zoned( zoned pAlt ) Util_GetAltStringTop =
260 {
261         return Util_GetAltStringItem( pAlt, 0 );
262 };
263
264 zoned( zoned pAlt ) Util_AltStringPop =
265 {
266         local float lCount;
267         lCount = Util_GetAltStringCount( pAlt );
268         return Util_DelAltStringItem( pAlt, lCount - 1 );
269 };
270
271 #else
272 #ifdef UTILALTSTRING
273 /*
274 ===================
275 Util_GetAltStringCount
276 ===================
277 */
278 float( string pStr )    Util_GetAltStringCount =
279 {
280         local float lLength;
281         local float lCount;
282         local float lPosition;
283         local string lLetter;
284
285         lPosition = lCount = 0;
286         for( lLength = strlen( pStr ) ; lPosition < lLength ; lPosition++ ) {
287                 lLetter = substring( pStr, lPosition, 1 );
288                 if( lLetter == "'" )
289                         lCount++;
290                 else if( lLetter == "\\" )
291                         lPosition++;
292         }
293
294         return floor( lCount / 2 );
295 };
296
297 /*
298 ===================
299 Util_GetAltStringItem
300 ===================
301 */
302 string( string pStr, float pCount ) Util_GetAltStringItem =
303 {
304         local float lCount;
305         local float lPosition;
306         local float lLength;
307         local string lLetter;
308         local string lOut;
309
310         pCount = pCount*2 + 1; // number of ' until item starts
311         lCount = lPosition = 0;
312         for( lLength = strlen( pStr ) ; lPosition < lLength && lCount < pCount ; lPosition++ ) {
313                 lLetter = substring( pStr, lPosition, 1 );
314
315                 if( lLetter == "'" )
316                         lCount = lCount + 1;
317                 else if( lLetter == "\\" )
318                         lPosition++;
319         }
320
321         if( lCount != pCount )
322                 return String_Create();
323
324         for( lOut = "" ; lPosition < lLength ; lPosition++ ) {
325                 lLetter = substring( pStr, lPosition, 1 );
326
327                 if( lLetter == "'" )
328                         break;
329                 else if( lLetter == "\\" ) {
330                         lPosition++;
331                         if( lPosition >= lLength )
332                                 break;
333                         lLetter = substring( pStr, lPosition, 1 );
334                 }
335
336                 // no need for strzone since there are 16 buffers and we use 2 in the for
337                 lOut = strcat( lOut, lLetter );
338         }
339
340         return String_Zone( lOut ); // return a strzoned string
341 };
342 #else
343 float( string pStr )    Util_GetAltStringCount =
344 {
345         return altstr_count( pStr );
346 };
347 string( string pStr, float pCount ) Util_GetAltStringItem =
348 {
349         return String_Zone( altstr_get( pStr, pCount ) );
350 };
351 #endif
352
353
354 /*
355 ===================
356 Util_SetAltStringItem
357 ===================
358 */
359 #ifdef UTILALTSTRING
360 string( string pAlt, float pIndex, string pSet ) Util_SetAltStringItem =
361 {
362         local float lCount;
363         local float lPosition;
364         local float lStart;
365         local float lLength;
366         local string lLetter;
367         local string lOut;
368
369         pSet = String_Zone( pSet );
370
371         pIndex = pIndex*2 + 1; // number of ' until item starts
372         lCount = lPosition = 0;
373         for( lLength = strlen( pAlt ) ; lPosition < lLength && lCount < pIndex ; lPosition = lPosition + 1 ) {
374                 lLetter = substring( pAlt, lPosition, 1 );
375
376                 if( lLetter == "'" )
377                         lCount = lCount + 1;
378                 else if( lLetter == "\\" )
379                         lPosition = lPosition + 1;
380         }
381
382         if( lCount != pIndex )
383                 return pAlt;
384
385         lStart = lPosition;
386         // find the end of it
387         for( ; lPosition < lLength ; lPosition++ ) {
388                 lLetter = substring( pAlt, lPosition, 1 );
389
390                 if( lLetter == "'" )
391                         break;
392                 else if( lLetter == "\\" )
393                         lPosition = lPosition + 1;
394         }
395
396         lOut = String_Substring( pAlt, 0, lStart );
397         pSet = String_Normal( Util_AltStringPrepare( String_Normal( pSet ) ) );
398         lOut = strcat( lOut, pSet, substring( pAlt, lPosition, lLength - lPosition ) );
399
400         return String_Set( pAlt, lOut );
401 };
402 #else
403 string( string pAlt, float pIndex, string pSet ) Util_SetAltStringItem =
404 {
405         return String_Set( pAlt, altstr_set( pAlt, pIndex, pSet ) );
406 };
407 #endif
408
409 /*
410 ===================
411 Util_DelAltStringItem
412 ===================
413 */
414 string( string pAlt, float pIndex ) Util_DelAltStringItem =
415 {
416         local float lCount;
417         local float lPosition;
418         local float lStart;
419         local float lLength;
420         local string lLetter;
421         local string lOut;
422
423         pIndex = pIndex*2 + 1; // number of ' until item starts
424         lCount = lPosition = 0;
425         for( lLength = strlen( pAlt ) ; lPosition < lLength && lCount < pIndex ; lPosition = lPosition + 1 ) {
426                 lLetter = substring( pAlt, lPosition, 1 );
427
428                 if( lLetter == "'" )
429                         lCount = lCount + 1;
430                 else if( lLetter == "\\" )
431                         lPosition = lPosition + 1;
432         }
433
434         if( lCount != pIndex )
435                 return pAlt;
436
437         lStart = lPosition;
438         // find the end of it
439         for( ; lPosition < lLength ; lPosition++ ) {
440                 lLetter = substring( pAlt, lPosition, 1 );
441
442                 if( lLetter == "'" )
443                         break;
444                 else if( lLetter == "\\" )
445                         lPosition = lPosition + 1;
446         }
447
448         if( lStart > 0 )
449                 lOut = substring( pAlt, 0, lStart - 1 );
450         if( lPosition < lLength - 1)
451                 lOut = strcat( lOut, substring( pAlt, lPosition + 1, lLength - lPosition - 1) );
452
453         return String_Set( pAlt, lOut );
454 };
455
456 /*
457 ===================
458 Util_InsAltStringItem
459 ===================
460 */
461 #ifdef UTILALTSTRING
462 string( string pAlt, float pIndex, string pSet ) Util_InsAltStringItem =
463 {
464         local float lCount;
465         local float lPosition;
466         local float lLength;
467         local string lLetter;
468         local string lOut;
469
470         pSet = String_Zone( pSet );
471
472         pIndex = pIndex*2 + 2; // number of ' until item starts
473         lCount = lPosition = 0;
474         for( lLength = strlen( pAlt ) ; lPosition < lLength && lCount < pIndex ; lPosition = lPosition + 1 ) {
475                 lLetter = substring( pAlt, lPosition, 1 );
476
477                 if( lLetter == "'" )
478                         lCount = lCount + 1;
479                 else if( lLetter == "\\" )
480                         lPosition = lPosition + 1;
481         }
482
483         if( lCount != pIndex )
484                 return pAlt;
485
486         lOut = String_Substring( pAlt, 0, lPosition );
487         pSet = String_Normal( Util_AltStringPrepare( String_Normal( pSet ) ) );
488         lOut = strcat( lOut, "'", pSet, "'", substring( pAlt, lPosition, lLength - lPosition ) );
489
490         return String_Set( pAlt, lOut );
491 };
492 #else
493 string( string pAlt, float pIndex, string pSet ) Util_InsAltStringItem =
494 {
495         return String_Set( pAlt, altstr_ins( pAlt, pIndex, pSet ) );
496 };
497 #endif
498
499 /*
500 ===================
501 Util_AltStringPrepare
502 ===================
503 */
504 #ifdef UTILALTSTRING
505 string( string pString ) Util_AltStringPrepare =
506 {
507         local string lOut, lChar;
508         local float lPos, lLength;
509
510         pString = String_Zone( pString );
511
512         lOut = "";
513         lLength = strlen( pString );
514         for( lPos = 0; lPos < lLength  ; lPos = lPos + 1 ) {
515                 lChar = substring( pString, lPos, 1 );
516                 if( lChar == "'" )
517                         lChar = "\\'";
518                 lOut = strcat( lOut, lChar );
519         }
520
521         String_Free( pString );
522         return String_Zone( lOut );
523 };
524 #else
525 string( string pString ) Util_AltStringPrepare =
526 {
527         return String_Zone( altstr_prepare( pString ) );
528 };
529 #endif
530
531 /*
532 ===================
533 Util_AltStringPush
534 ===================
535 */
536 string( string pAlt, string pPush ) Util_AltStringPush =
537 {
538         return String_Set( pAlt, strcat( "'", altstr_prepare( pPush ), "'", pAlt ) );
539 };
540
541 /*
542 ===================
543 Util_AltStringPushBack
544 ===================
545 */
546 string( string pAlt, string pPush )     Util_AltStringPushBack =
547 {
548         return String_Set( pAlt, strcat( pAlt, "'", altstr_prepare( pPush ), "'" ) );
549 };
550
551 /*
552 ===================
553 Util_GetAltStringTop
554 ===================
555 */
556 string( string pAlt ) Util_GetAltStringTop =
557 {
558         return Util_GetAltStringItem( pAlt, 0 );
559 };
560
561 /*
562 ===================
563 Util_AltStringPop
564 ===================
565 */
566 string( string pAlt ) Util_AltStringPop =
567 {
568         local float lPos, lCount, lLength;
569         local string lChar;
570
571         lCount = 0;
572         lLength = strlen( pAlt );
573         for( lPos = 0 ; lPos < lLength && lCount < 2 ; lPos++) {
574                 lChar = substring( pAlt, lPos, 1 );
575                 if( lChar == "\\" )
576                         lPos++;
577                 else if( lChar == "'" )
578                         lCount++;
579         }
580
581         return String_Set( pAlt, substring( pAlt, lPos, lLength - lPos ) ); // no - 1 because this time we dont break after the '
582 };
583 #endif