wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * GlobCmd.java
3 *
4 * This file contains the Jacl implementation of the built-in Tcl "glob"
5 * command.
6 *
7 * Copyright (c) 1997-1998 Sun Microsystems, Inc.
8 *
9 * See the file "license.terms" for information on usage and
10 * redistribution of this file, and for a DISCLAIMER OF ALL
11 * WARRANTIES.
12 *
13 * Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart
14 *
15 * RCS @(#) $Id: GlobCmd.java,v 1.5 1999/08/28 03:55:18 mo Exp $
16 *
17 */
18 using System.IO;
19 using System.Text;
20  
21 namespace tcl.lang
22 {
23  
24 /*
25 * This class implements the built-in "glob" command in Tcl.
26 */
27  
28 class GlobCmd : Command
29 {
30  
31 /*
32 * Special characters that are used for string matching.
33 */
34  
35 private static readonly char[] specCharArr = new char[] { '*', '[', ']', '?', '\\' };
36  
37 /*
38 * Options to the glob command.
39 */
40  
41 private static readonly string[] validOptions = new string[] { "-nocomplain", "--" };
42 private const int OPT_NOCOMPLAIN = 0;
43 private const int OPT_LAST = 1;
44  
45 public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
46 {
47 bool noComplain = false; // If false, error msg will be returned
48 int index; // index of the char just after the end
49 // of the user name
50 int firstArg = 1; // index of the first non-switch arg
51 int i; // generic index
52 string arg; // generic arg string
53 string head = ""; // abs path of user name if provided
54 string tail = ""; // the remaining file path and pattern
55 TclObject resultList; // list of files that match the pattern
56  
57 for ( bool last = false; ( firstArg < argv.Length ) && ( !last ); firstArg++ )
58 {
59  
60  
61 if ( !argv[firstArg].ToString().StartsWith( "-" ) )
62 {
63 break;
64 }
65 int opt = TclIndex.get( interp, argv[firstArg], validOptions, "switch", 1 );
66 switch ( opt )
67 {
68  
69 case OPT_NOCOMPLAIN:
70 noComplain = true;
71 break;
72  
73 case OPT_LAST:
74 last = true;
75 break;
76  
77 default:
78 throw new TclException( interp, "GlobCmd.cmdProc: bad option " + opt + " index to validOptions" );
79  
80 }
81 }
82  
83 if ( firstArg >= argv.Length )
84 {
85 throw new TclNumArgsException( interp, 1, argv, "?switches? name ?name ...?" );
86 }
87  
88 resultList = TclList.newInstance();
89 resultList.preserve();
90  
91 for ( i = firstArg; i < argv.Length; i++ )
92 {
93  
94 arg = argv[i].ToString();
95  
96 string separators; // The system-specific file separators
97 switch ( JACL.PLATFORM )
98 {
99  
100 case JACL.PLATFORM_WINDOWS:
101 separators = "/\\:";
102 break;
103  
104 case JACL.PLATFORM_MAC:
105 if ( arg.IndexOf( (System.Char)':' ) == -1 )
106 {
107 separators = "/";
108 }
109 else
110 {
111 separators = ":";
112 }
113 break;
114  
115 default:
116 separators = "/";
117 break;
118  
119 }
120  
121 // Perform tilde substitution, if needed.
122  
123 index = 0;
124 if ( arg.StartsWith( "~" ) )
125 {
126 // Find the first path separator after the tilde.
127  
128 for ( ; index < arg.Length; index++ )
129 {
130 char c = arg[index];
131 if ( c == '\\' )
132 {
133 if ( separators.IndexOf( (System.Char)arg[index + 1] ) != -1 )
134 {
135 break;
136 }
137 }
138 else if ( separators.IndexOf( (System.Char)c ) != -1 )
139 {
140 break;
141 }
142 }
143  
144 // Determine the home directory for the specified user. Note
145 // that we don't allow special characters in the user name.
146  
147 if ( strpbrk( arg.Substring( 1, ( index ) - ( 1 ) ).ToCharArray(), specCharArr ) < 0 )
148 {
149 try
150 {
151 head = FileUtil.doTildeSubst( interp, arg.Substring( 1, ( index ) - ( 1 ) ) );
152 }
153 catch ( TclException e )
154 {
155 if ( noComplain )
156 {
157 head = null;
158 }
159 else
160 {
161 throw new TclException( interp, e.Message );
162 }
163 }
164 }
165 else
166 {
167 if ( !noComplain )
168 {
169 throw new TclException( interp, "globbing characters not supported in user names" );
170 }
171 head = null;
172 }
173  
174 if ( (System.Object)head == null )
175 {
176 if ( noComplain )
177 {
178 interp.setResult( "" );
179 return TCL.CompletionCode.RETURN;
180 }
181 else
182 {
183 return TCL.CompletionCode.RETURN;
184 }
185 }
186 if ( index != arg.Length )
187 {
188 index++;
189 }
190 }
191  
192 tail = arg.Substring( index );
193  
194 try
195 {
196 doGlob( interp, separators, new StringBuilder( head ), tail, resultList );
197 }
198 catch ( TclException e )
199 {
200 if ( noComplain )
201 {
202 continue;
203 }
204 else
205 {
206 throw new TclException( interp, e.Message );
207 }
208 }
209 }
210  
211 // If the list is empty and the nocomplain switch was not set then
212 // generate and throw an exception. Always release the TclList upon
213 // completion.
214  
215 try
216 {
217 if ( ( TclList.getLength( interp, resultList ) == 0 ) && !noComplain )
218 {
219 string sep = "";
220 StringBuilder ret = new StringBuilder();
221  
222 ret.Append( "no files matched glob pattern" );
223 ret.Append( ( argv.Length == 2 ) ? " \"" : "s \"" );
224  
225 for ( i = firstArg; i < argv.Length; i++ )
226 {
227  
228 ret.Append( sep + argv[i].ToString() );
229 if ( i == firstArg )
230 {
231 sep = " ";
232 }
233 }
234 ret.Append( "\"" );
235 throw new TclException( interp, ret.ToString() );
236 }
237 else if ( TclList.getLength( interp, resultList ) > 0 )
238 {
239 interp.setResult( resultList );
240 }
241 }
242 finally
243 {
244 resultList.release();
245 }
246 return TCL.CompletionCode.RETURN;
247 }
248 private static int SkipToChar( string str, int sIndex, char match )
249 // Ccharacter to find.
250 {
251 int level, length, i;
252 bool quoted = false;
253 char c;
254  
255 level = 0;
256  
257 for ( i = sIndex, length = str.Length; i < length; i++ )
258 {
259 if ( quoted )
260 {
261 quoted = false;
262 continue;
263 }
264 c = str[i];
265 if ( ( level == 0 ) && ( c == match ) )
266 {
267 return i;
268 }
269 if ( c == '{' )
270 {
271 level++;
272 }
273 else if ( c == '}' )
274 {
275 level--;
276 }
277 else if ( c == '\\' )
278 {
279 quoted = true;
280 }
281 }
282 return -1;
283 }
284 private static void doGlob( Interp interp, string separators, StringBuilder headBuf, string tail, TclObject resultList )
285 {
286 int count = 0; // Counts the number of leading file
287 // spearators for the tail.
288 int pIndex; // Current index into tail
289 int tailIndex; // First char after initial file
290 // separators of the tail
291 int tailLen = tail.Length; // Cache the length of the tail
292 int headLen = headBuf.Length; // Cache the length of the head
293 int baseLen; // Len of the substring from tailIndex
294 // to the current specChar []*?{}\\
295 int openBraceIndex; // Index of the current open brace
296 int closeBraceIndex; // Index of the current closed brace
297 int firstSpecCharIndex; // Index of the FSC, if any
298 char lastChar = (char)( 0 ); // Used to see if last char is a file
299 // separator.
300 char ch; // Generic storage variable
301 bool quoted; // True if a char is '\\'
302  
303 if ( headLen > 0 )
304 {
305 lastChar = headBuf[headLen - 1];
306 }
307  
308 // Consume any leading directory separators, leaving tailIndex
309 // just past the last initial separator.
310  
311 string name = tail;
312 for ( tailIndex = 0; tailIndex < tailLen; tailIndex++ )
313 {
314 char c = tail[tailIndex];
315 if ( ( c == '\\' ) && ( ( tailIndex + 1 ) < tailLen ) && ( separators.IndexOf( (System.Char)tail[tailIndex + 1] ) != -1 ) )
316 {
317 tailIndex++;
318 }
319 else if ( separators.IndexOf( (System.Char)c ) == -1 )
320 {
321 break;
322 }
323 count++;
324 }
325  
326 // Deal with path separators. On the Mac, we have to watch out
327 // for multiple separators, since they are special in Mac-style
328 // paths.
329  
330 switch ( JACL.PLATFORM )
331 {
332  
333 case JACL.PLATFORM_MAC:
334  
335 if ( separators[0] == '/' )
336 {
337 if ( ( ( headLen == 0 ) && ( count == 0 ) ) || ( ( headLen > 0 ) && ( lastChar != ':' ) ) )
338 {
339 headBuf.Append( ":" );
340 }
341 }
342 else
343 {
344 if ( count == 0 )
345 {
346 if ( ( headLen > 0 ) && ( lastChar != ':' ) )
347 {
348 headBuf.Append( ":" );
349 }
350 }
351 else
352 {
353 if ( lastChar == ':' )
354 {
355 count--;
356 }
357 while ( count-- > 0 )
358 {
359 headBuf.Append( ":" );
360 }
361 }
362 }
363 break;
364  
365  
366 case JACL.PLATFORM_WINDOWS:
367 if ( name.StartsWith( ":" ) )
368 {
369 headBuf.Append( ":" );
370 if ( count > 1 )
371 {
372 headBuf.Append( "/" );
373 }
374 }
375 else if ( ( tailIndex < tailLen ) && ( ( ( headLen > 0 ) && ( separators.IndexOf( (System.Char)lastChar ) == -1 ) ) || ( ( headLen == 0 ) && ( count > 0 ) ) ) )
376 {
377 headBuf.Append( "/" );
378 if ( ( headLen == 0 ) && ( count > 1 ) )
379 {
380 headBuf.Append( "/" );
381 }
382 }
383 break;
384  
385 default:
386  
387 if ( ( tailIndex < tailLen ) && ( ( ( headLen > 0 ) && ( separators.IndexOf( (System.Char)lastChar ) == -1 ) ) || ( ( headLen == 0 ) && ( count > 0 ) ) ) )
388 {
389 headBuf.Append( "/" );
390 }
391 break;
392  
393 }
394  
395 // Look for the first matching pair of braces or the first
396 // directory separator that is not inside a pair of braces.
397  
398 openBraceIndex = closeBraceIndex = -1;
399 quoted = false;
400  
401 for ( pIndex = tailIndex; pIndex != tailLen; pIndex++ )
402 {
403 ch = tail[pIndex];
404 if ( quoted )
405 {
406 quoted = false;
407 }
408 else if ( ch == '\\' )
409 {
410 quoted = true;
411 if ( ( ( pIndex + 1 ) < tailLen ) && ( separators.IndexOf( (System.Char)tail[pIndex + 1] ) != -1 ) )
412 {
413 // Quoted directory separator.
414  
415 break;
416 }
417 }
418 else if ( separators.IndexOf( (System.Char)ch ) != -1 )
419 {
420 // Unquoted directory separator.
421  
422 break;
423 }
424 else if ( ch == '{' )
425 {
426 openBraceIndex = pIndex;
427 pIndex++;
428 if ( ( closeBraceIndex = SkipToChar( tail, pIndex, '}' ) ) != -1 )
429 {
430 break;
431 }
432 throw new TclException( interp, "unmatched open-brace in file name" );
433 }
434 else if ( ch == '}' )
435 {
436 throw new TclException( interp, "unmatched close-brace in file name" );
437 }
438 }
439  
440 // Substitute the alternate patterns from the braces and recurse.
441  
442 if ( openBraceIndex != -1 )
443 {
444 int nextIndex;
445 StringBuilder baseBuf = new StringBuilder();
446  
447 // For each element within in the outermost pair of braces,
448 // append the element and the remainder to the fixed portion
449 // before the first brace and recursively call doGlob.
450  
451 baseBuf.Append( tail.Substring( tailIndex, ( openBraceIndex ) - ( tailIndex ) ) );
452 baseLen = baseBuf.Length;
453 headLen = headBuf.Length;
454  
455 for ( pIndex = openBraceIndex; pIndex < closeBraceIndex; )
456 {
457 pIndex++;
458 nextIndex = SkipToChar( tail, pIndex, ',' );
459 if ( nextIndex == -1 || nextIndex > closeBraceIndex )
460 {
461 nextIndex = closeBraceIndex;
462 }
463  
464 headBuf.Length = headLen;
465 baseBuf.Length = baseLen;
466  
467 baseBuf.Append( tail.Substring( pIndex, ( nextIndex ) - ( pIndex ) ) );
468 baseBuf.Append( tail.Substring( closeBraceIndex + 1 ) );
469  
470 pIndex = nextIndex;
471 doGlob( interp, separators, headBuf, baseBuf.ToString(), resultList );
472 }
473 return;
474 }
475  
476 // At this point, there are no more brace substitutions to perform on
477 // this path component. The variable p is pointing at a quoted or
478 // unquoted directory separator or the end of the string. So we need
479 // to check for special globbing characters in the current pattern.
480 // We avoid modifying tail if p is pointing at the end of the string.
481  
482 if ( pIndex < tailLen )
483 {
484 firstSpecCharIndex = strpbrk( tail.Substring( 0, ( pIndex ) - ( 0 ) ).ToCharArray(), specCharArr );
485 }
486 else
487 {
488 firstSpecCharIndex = strpbrk( tail.Substring( tailIndex ).ToCharArray(), specCharArr );
489 }
490  
491 if ( firstSpecCharIndex != -1 )
492 {
493 // Look for matching files in the current directory. matchFiles
494 // may recursively call TclDoGlob. For each file that matches,
495 // it will add the match onto the interp.result, or call TclDoGlob
496 // if there are more characters to be processed.
497  
498 matchFiles( interp, separators, headBuf.ToString(), tail.Substring( tailIndex ), ( pIndex - tailIndex ), resultList );
499 return;
500 }
501 headBuf.Append( tail.Substring( tailIndex, ( pIndex ) - ( tailIndex ) ) );
502 if ( pIndex < tailLen )
503 {
504 doGlob( interp, separators, headBuf, tail.Substring( pIndex ), resultList );
505 return;
506 }
507  
508 // There are no more wildcards in the pattern and no more unprocessed
509 // characters in the tail, so now we can construct the path and verify
510 // the existence of the file.
511  
512 string head;
513 switch ( JACL.PLATFORM )
514 {
515  
516 case JACL.PLATFORM_MAC:
517 if ( headBuf.ToString().IndexOf( (System.Char)':' ) == -1 )
518 {
519 headBuf.Append( ":" );
520 }
521 head = headBuf.ToString();
522 break;
523  
524 case JACL.PLATFORM_WINDOWS:
525 if ( headBuf.Length == 0 )
526 {
527 if ( ( ( name.Length > 1 ) && ( name[0] == '\\' ) && ( ( name[1] == '/' ) || ( name[1] == '\\' ) ) ) || ( ( name.Length > 0 ) && ( name[0] == '/' ) ) )
528 {
529 headBuf.Append( "\\" );
530 }
531 else
532 {
533 headBuf.Append( "." );
534 }
535 }
536 head = headBuf.ToString().Replace( '\\', '/' );
537 break;
538  
539 default:
540 if ( headBuf.Length == 0 )
541 {
542 if ( name.StartsWith( "\\/" ) || name.StartsWith( "/" ) )
543 {
544 headBuf.Append( "/" );
545 }
546 else
547 {
548 headBuf.Append( "." );
549 }
550 }
551 head = headBuf.ToString();
552 break;
553  
554 }
555 addFileToResult( interp, head, separators, resultList );
556 }
557 private static void matchFiles( Interp interp, string separators, string dirName, string pattern, int pIndex, TclObject resultList )
558 {
559 bool matchHidden; // True if were matching hidden file
560 int patternEnd = pIndex; // Stores end index of the pattern
561 int dirLen = dirName.Length; // Caches the len of the dirName
562 int patLen = pattern.Length; // Caches the len of the pattern
563 string[] dirListing; // Listing of files in dirBuf
564 FileInfo dirObj; // File object of dirBuf
565 StringBuilder dirBuf = new StringBuilder();
566 // Converts the dirName to string
567 // buffer or initializes it with '.'
568  
569 switch ( JACL.PLATFORM )
570 {
571  
572 case JACL.PLATFORM_WINDOWS:
573  
574 if ( dirLen == 0 )
575 {
576 dirBuf.Append( "./" );
577 }
578 else
579 {
580 dirBuf.Append( dirName );
581 char c = dirBuf[dirLen - 1];
582 if ( ( ( c == ':' ) && ( dirLen == 2 ) ) || ( separators.IndexOf( (System.Char)c ) == -1 ) )
583 {
584 dirBuf.Append( "/" );
585 }
586 }
587  
588 // All comparisons should be case insensitive on Windows.
589  
590 pattern = pattern.ToLower();
591 break;
592  
593 case JACL.PLATFORM_MAC:
594 // Fall through to unix case--mac is not yet implemented.
595 default:
596  
597 if ( dirLen == 0 )
598 {
599 dirBuf.Append( "." );
600 }
601 else
602 {
603 dirBuf.Append( dirName );
604 }
605 break;
606 }
607  
608 dirObj = createAbsoluteFileObj( interp, dirBuf.ToString() );
609 if ( !Directory.Exists( dirObj.FullName ) )
610 {
611 return;
612 }
613  
614 // Check to see if the pattern needs to compare with hidden files.
615 // Get a list of the directory's contents.
616  
617 if ( pattern.StartsWith( "." ) || pattern.StartsWith( "\\." ) )
618 {
619 matchHidden = true;
620 // TODO tcl await only file names
621 dirListing = addHiddenToDirList( dirObj );
622 }
623 else
624 {
625 matchHidden = false;
626 DirectoryInfo dirInfo = new DirectoryInfo( dirObj.FullName );
627 FileSystemInfo[] fileInfos = dirInfo.GetFileSystemInfos();
628 // TCL await only file names
629 // dirListing = Directory.GetFileSystemEntries(dirObj.FullName);
630 dirListing = new string[fileInfos.Length];
631 for ( int x = 0; x < fileInfos.Length; x++ )
632 {
633 dirListing[x] = fileInfos[x].Name;
634 }
635 }
636  
637 // Iterate over the directory's contents.
638  
639 if ( dirListing.Length == 0 )
640 {
641 // Strip off a trailing '/' if necessary, before reporting
642 // the error.
643  
644 if ( dirName.EndsWith( "/" ) )
645 {
646 dirName = dirName.Substring( 0, ( ( dirLen - 1 ) ) - ( 0 ) );
647 }
648 }
649  
650 // Clean up the end of the pattern and the tail pointer. Leave
651 // the tail pointing to the first character after the path
652 // separator following the pattern, or NULL. Also, ensure that
653 // the pattern is null-terminated.
654  
655 if ( ( pIndex < patLen ) && ( pattern[pIndex] == '\\' ) )
656 {
657 pIndex++;
658 }
659 if ( pIndex < ( patLen - 1 ) )
660 {
661 pIndex++;
662 }
663  
664 for ( int i = 0; i < dirListing.Length; i++ )
665 {
666 // Don't match names starting with "." unless the "." is
667 // present in the pattern.
668  
669 if ( !matchHidden && ( dirListing[i].StartsWith( "." ) ) )
670 {
671 continue;
672 }
673  
674 // Now check to see if the file matches. If there are more
675 // characters to be processed, then ensure matching files are
676 // directories before calling TclDoGlob. Otherwise, just add
677 // the file to the resultList.
678  
679 string tmp = dirListing[i];
680 if ( JACL.PLATFORM == JACL.PLATFORM_WINDOWS )
681 {
682 tmp = tmp.ToLower();
683 }
684 if ( Util.stringMatch( tmp, pattern.Substring( 0, ( patternEnd ) - ( 0 ) ) ) )
685 {
686  
687 dirBuf.Length = dirLen;
688 dirBuf.Append( dirListing[i] );
689 if ( pIndex == pattern.Length )
690 {
691 addFileToResult( interp, dirBuf.ToString(), separators, resultList );
692 }
693 else
694 {
695 dirObj = createAbsoluteFileObj( interp, dirBuf.ToString() );
696 if ( Directory.Exists( dirObj.FullName ) )
697 {
698 dirBuf.Append( "/" );
699 doGlob( interp, separators, dirBuf, pattern.Substring( patternEnd + 1 ), resultList );
700 }
701 }
702 }
703 }
704 }
705 private static int strpbrk( char[] src, char[] matches )
706 // The chars to search for in src.
707 {
708 for ( int i = 0; i < src.Length; i++ )
709 {
710 for ( int j = 0; j < matches.Length; j++ )
711 {
712 if ( src[i] == matches[j] )
713 {
714 return ( i );
715 }
716 }
717 }
718 return -1;
719 }
720 private static string[] addHiddenToDirList( FileInfo dirObj )
721 // File object to list contents of
722 {
723 string[] dirListing; // Listing of files in dirObj
724 string[] fullListing; // dirListing + .. and .
725 int i, arrayLen;
726  
727  
728 dirListing = Directory.GetFileSystemEntries( dirObj.FullName );
729 arrayLen = ( (System.Array)dirListing ).Length;
730  
731  
732 try
733 {
734  
735 fullListing = (string[])System.Array.CreateInstance( System.Type.GetType( "java.lang.String" ), arrayLen + 2 );
736 }
737 catch ( System.Exception e )
738 {
739 return dirListing;
740 }
741 for ( i = 0; i < arrayLen; i++ )
742 {
743 fullListing[i] = dirListing[i];
744 }
745 fullListing[arrayLen] = ".";
746 fullListing[arrayLen + 1] = "..";
747  
748 return fullListing;
749 }
750 private static void addFileToResult( Interp interp, string fileName, string separators, TclObject resultList )
751 {
752 string prettyFileName = fileName;
753 int prettyLen = fileName.Length;
754  
755 // Java IO reuqires Windows volumes [A-Za-z]: to be followed by '\\'.
756  
757 if ( ( JACL.PLATFORM == JACL.PLATFORM_WINDOWS ) && ( prettyLen >= 2 ) && ( fileName[1] == ':' ) )
758 {
759 if ( prettyLen == 2 )
760 {
761 fileName = fileName + '\\';
762 }
763 else if ( fileName[2] != '\\' )
764 {
765 fileName = fileName.Substring( 0, ( 2 ) - ( 0 ) ) + '\\' + fileName.Substring( 2 );
766 }
767 }
768  
769 TclObject[] arrayObj = TclList.getElements( interp, FileUtil.splitAndTranslate( interp, fileName ) );
770 fileName = FileUtil.joinPath( interp, arrayObj, 0, arrayObj.Length );
771  
772 FileInfo f;
773 if ( FileUtil.getPathType( fileName ) == FileUtil.PATH_ABSOLUTE )
774 {
775 f = FileUtil.getNewFileObj( interp, fileName );
776 }
777 else
778 {
779 f = new FileInfo( interp.getWorkingDir().FullName + "\\" + fileName );
780 }
781  
782 // If the last character is a spearator, make sure the file is an
783 // existing directory, otherwise check that the file exists.
784  
785 if ( ( prettyLen > 0 ) && ( separators.IndexOf( (System.Char)prettyFileName[prettyLen - 1] ) != -1 ) )
786 {
787 if ( Directory.Exists( f.FullName ) )
788 {
789 TclList.append( interp, resultList, TclString.newInstance( prettyFileName ) );
790 }
791 }
792 else
793 {
794 bool tmpBool;
795 if ( File.Exists( f.FullName ) )
796 tmpBool = true;
797 else
798 tmpBool = Directory.Exists( f.FullName );
799 if ( tmpBool )
800 {
801 TclList.append( interp, resultList, TclString.newInstance( prettyFileName ) );
802 }
803 }
804 }
805 private static FileInfo createAbsoluteFileObj( Interp interp, string fileName )
806 {
807 if ( fileName.Equals( "" ) )
808 {
809 return ( interp.getWorkingDir() );
810 }
811  
812 if ( ( JACL.PLATFORM == JACL.PLATFORM_WINDOWS ) && ( fileName.Length >= 2 ) && ( fileName[1] == ':' ) )
813 {
814 string tmp = null;
815 if ( fileName.Length == 2 )
816 {
817 tmp = fileName.Substring( 0, ( 2 ) - ( 0 ) ) + '\\';
818 }
819 else if ( fileName[2] != '\\' )
820 {
821 tmp = fileName.Substring( 0, ( 2 ) - ( 0 ) ) + '\\' + fileName.Substring( 2 );
822 }
823 if ( (System.Object)tmp != null )
824 {
825 return FileUtil.getNewFileObj( interp, tmp );
826 }
827 }
828  
829 return FileUtil.getNewFileObj( interp, fileName );
830 }
831 } // end GlobCmd class
832 }