0024716: OSD_Path - remove excessive validity checks and allow non-ascii strings
[occt.git] / src / OSD / OSD_Path.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <OSD_Path.ixx>
16
17 static OSD_SysType whereAmI(){
18 #if defined(__digital__) || defined(__FreeBSD__) || defined(SUNOS) || defined(__APPLE__)
19   return OSD_UnixBSD;
20 }
21 #elif defined(sgi)  || defined(IRIX) || defined(__sun)  || defined(SOLARIS) ||  defined(__sco__) || defined(__hpux) || defined(HPUX)
22   return OSD_UnixSystemV;
23 }
24 #elif defined(__osf__) || defined(DECOSF1)
25   return OSD_OSF;
26 }
27 #elif defined(OS2)
28   return OSD_WindowsNT;
29 }
30 #elif defined(_WIN32) || defined(__WIN32__)
31   return OSD_WindowsNT;
32 }
33 #elif defined(__CYGWIN32_) || defined(__MINGW32__)
34   return OSD_WindowsNT;
35 }
36 #elif defined(vax) || defined(__vms)
37   return OSD_VMS;
38 }
39 #elif defined(__linux__) || defined(LIN)
40   return OSD_LinuxREDHAT;
41 }
42 #elif defined(_AIX) || defined(AIX)
43   return OSD_Aix;
44 }
45 #else
46   struct utsname info;
47   uname(&info);
48   cout << info.sysname << endl;
49   cout << info.nodename << endl;
50   cout << info.release << endl;
51   cout << info.version << endl;
52   cout << info.machine << endl;
53   return OSD_Default;
54 }
55 #endif
56
57 #if !(defined(_WIN32) || defined(__WIN32__))
58
59 #include <Standard_NumericError.hxx>
60 #include <Standard_NullObject.hxx>
61 #include <Standard_ProgramError.hxx>
62 #include <Standard_ConstructionError.hxx>
63 #include <OSD_WhoAmI.hxx>
64
65 OSD_Path::OSD_Path(){
66  mySysDep = whereAmI();
67 }
68
69 static void VmsExtract(const TCollection_AsciiString& what,
70                 TCollection_AsciiString& node,
71                 TCollection_AsciiString& username,
72                 TCollection_AsciiString& password,
73                 TCollection_AsciiString& disk,
74                 TCollection_AsciiString& trek,
75                 TCollection_AsciiString& name,
76                 TCollection_AsciiString& ext){
77
78  TCollection_AsciiString buffer;
79  Standard_Integer pos;
80
81  buffer = what;
82
83  if (buffer.Search("\"") != -1){  // a username to extract
84
85    if (buffer.Value(1) != '"') { // Begins with Node
86     node = buffer.Token("\"");
87     buffer.Remove(1,node.Length());
88    }
89    else node = "";
90
91    username = buffer.Token("\" ");
92    buffer.Remove(1,username.Length()+2); // Removes <<"username ' ' or '"' >>
93
94    if (buffer.Search("\"") != -1){ // a password to extract
95     password = buffer.Token("\"");
96     buffer.Remove(1,password.Length()+1);  // removes <<password">>
97    }
98
99    // If we found a node then we must find "::"
100    if (buffer.Search("::") != -1)
101     buffer.Remove(1,2);            // Removes <<::>>
102  }
103  else  // No name or password
104  if (buffer.Search("::") != -1){ // a node to extract
105   node = buffer.Token(":");
106   buffer.Remove(1,node.Length()+2); // Removes <<node::>
107  }
108
109  if (buffer.Search(":") != -1){ // a disk to extract
110    disk = buffer.Token(":");
111    buffer.Remove(1,disk.Length()+1);  // Removes <<disk:>>
112  }
113  else disk = "";
114
115  // Analyse trek
116
117  if (buffer.Search("[") != -1){  // There is atrek to extract
118   trek = buffer.Token("[]");
119
120   if (trek.Value(1) == '.') trek.Remove(1,1);  // Removes first '.'
121     else trek.Insert(1,'|');                   // Add root
122
123   trek.ChangeAll('.','|');   // Translates to portable syntax
124   trek.ChangeAll('-','^');  
125
126   pos = trek.Search("000000");
127   if (pos != -1) {
128    trek.Remove(pos,6); // on VMS [000000] is the root
129    if (trek.Search("||") != -1) trek.Remove(1,1); // When [000000.xxx] -> ||xxx
130   }
131
132   name = buffer.Token("]",2);
133  }
134  else name = buffer;
135
136  if (name.Search(".") != -1){
137   ext = name.Token(".",2);
138   ext.Insert(1,'.');
139   name.Remove(name.Search("."),ext.Length());
140  }
141  else ext = "";
142   
143 }
144
145
146 //=======================================================================
147 //function : UnixExtract
148 //purpose  : 
149 //=======================================================================
150 static void UnixExtract(const TCollection_AsciiString& what,
151                         TCollection_AsciiString& node,
152                         TCollection_AsciiString& username,
153                         TCollection_AsciiString& password,
154                         TCollection_AsciiString& trek,
155                         TCollection_AsciiString& name,
156                         TCollection_AsciiString& ext){
157
158  Standard_Integer pos;
159  TCollection_AsciiString buffer;   // To manipulate 'what' without modifying it
160
161  Standard_PCharacter p;
162  buffer = what;
163
164 #ifdef TOTO  // Username, password and node are no longer given in the string (LD)
165
166  if (buffer.Search("@") != -1){  // There is a name to extract
167   username = buffer.Token("\"@");
168   buffer.Remove(1,username.Length()+1);   // Removes << user@ >>
169
170   if (buffer.Search("\"") != -1){       // There is a password to extract
171    password = buffer.Token("\"");
172    buffer.Remove(1,password.Length()+2);  // Removes << "password" >>
173   }
174
175  }
176  else {
177   username = "";
178   password = "";
179  }
180
181 #endif  // node must be given (for DBT, DM) (ADN 29/8/96)
182
183  if (buffer.Search(":/") != -1){      // There is a node to extract
184   node = buffer.Token(":/");
185   buffer.Remove(1,node.Length()+1);  // Removes << node: >>
186  }
187  else node = ""; 
188
189   username = "";
190   password = "";
191 //  node = ""; 
192  
193  trek = buffer;
194
195  trek.ChangeAll('/','|');  // Translates to portable syntax
196
197  pos = trek.SearchFromEnd("|");  // Extract name
198  if (pos != -1) {
199   p = (Standard_PCharacter)trek.ToCString();
200   name = &p[pos];
201   if(name.Length()) trek.Remove(pos+1,name.Length());
202  }
203  else {   // No '|' means no trek but a name
204   name = buffer;
205   trek = "";
206  }
207
208  pos = trek.Search("..");
209  while (pos != -1){        // Changes every ".." by '^'
210   trek.SetValue(pos,'^');
211   trek.Remove(pos+1,1);
212   pos = trek.Search("..");
213  }
214
215   pos = name.SearchFromEnd(".") ;   // LD : debug
216   if (pos != -1)      // There is an extension to extract
217     ext = name.Split(pos - 1) ;  
218
219
220 // if (name.Search(".") != -1){ // There is an extension to extract
221 //   if ( name.Value(1) == '.' ) {
222 //     ext = name;
223 //     name.Clear();
224 //   }
225 //   else {
226 //     ext = name.Token(".",2); 
227 //     ext.Insert(1,'.');            // Prepends 'dot'
228 //     pos = name.Search(".");     // Removes extension from buffer
229 //     if (pos != -1)
230 //       name.Remove(pos,ext.Length());
231 //   }
232 // }
233
234 }
235
236
237 //=======================================================================
238 //function : DosExtract
239 //purpose  : 
240 //=======================================================================
241 static void DosExtract(const TCollection_AsciiString& what,
242                 TCollection_AsciiString& disk,
243                 TCollection_AsciiString& trek,
244                 TCollection_AsciiString& name,
245                 TCollection_AsciiString& ext){
246
247  TCollection_AsciiString buffer;
248  Standard_Integer pos;
249  Standard_PCharacter p;
250
251  buffer = what;
252
253  if (buffer.Search(":") != -1){ // There is a disk to extract
254   disk = buffer.Token(":");
255   disk += ":";
256   buffer.Remove(1,disk.Length());  // Removes <<disk:>>
257  }
258
259  if (buffer.Search(".") != -1){ // There is an extension to extract
260   ext = buffer.Token(".",2); 
261   ext.Insert(1,'.');            // Prepends 'dot'
262   pos = buffer.Search(".");     // Removes extension from buffer
263   if (pos != -1)
264    buffer.Remove(pos,ext.Length());
265  }
266
267  trek = buffer;
268
269  trek.ChangeAll('\\','|');  
270
271  pos = trek.Search("..");
272  while (pos != -1){        // Changes every ".." by '^'
273   trek.SetValue(pos,'^');
274   trek.Remove(pos+1,1);
275   pos = trek.Search("..");
276  }
277
278  pos = trek.SearchFromEnd("|");  // Extract name
279  if (pos != -1) {
280   p = (Standard_PCharacter)trek.ToCString();
281   name = &p[pos];
282   trek.Remove(trek.Search(name),name.Length());
283  }
284  else {   // No '|' means no trek but a name
285   name = buffer;
286   trek = "";
287  }
288 }
289
290
291 //=======================================================================
292 //function : MacExtract
293 //purpose  : 
294 //=======================================================================
295 static void MacExtract(const TCollection_AsciiString& what,
296                 TCollection_AsciiString& ,
297                 TCollection_AsciiString& trek,
298                 TCollection_AsciiString& name,
299                 TCollection_AsciiString& ){
300
301   Standard_Integer pos;
302   Standard_PCharacter p;
303   
304   // I don't know how to distingish a disk from a trek !
305   
306   trek = what;
307   
308   pos = trek.Search("::");
309   while (pos != -1){        // Changes every "::" by '^'
310     trek.SetValue(pos,'^');
311     trek.Remove(pos+1,1);
312     pos = trek.Search("::");
313   }
314
315   trek.ChangeAll(':','|');  // Translates to portable syntax
316
317   pos = trek.SearchFromEnd("|");  // Extract name
318   if (pos != -1) {
319     p = (Standard_PCharacter)trek.ToCString();
320     name = &p[pos+1];
321     trek.Remove(trek.Search(name),name.Length());
322   }
323   else {   // No '|' means no trek but a name
324     name = what;
325     trek = "";
326   }
327 }
328
329
330 OSD_Path::OSD_Path(const TCollection_AsciiString& aDependentName,
331                    const OSD_SysType aSysType){
332
333  mySysDep = whereAmI();
334
335  OSD_SysType todo;
336 //  Standard_Integer i,l;
337
338   if (aSysType == OSD_Default) {
339     todo = mySysDep;
340   } else {
341     todo = aSysType;
342   }
343
344  switch (todo){
345   case OSD_VMS:
346      VmsExtract(aDependentName,myNode,myUserName,myPassword,myDisk,myTrek,myName,myExtension);
347      break;
348   case OSD_LinuxREDHAT:
349   case OSD_UnixBSD:
350   case OSD_UnixSystemV:
351   case OSD_Aix:
352   case OSD_OSF:
353      UnixExtract(aDependentName,myNode,myUserName,myPassword,myTrek,myName,myExtension);
354      break;
355   case OSD_OS2:
356   case OSD_WindowsNT:
357      DosExtract(aDependentName,myDisk,myTrek,myName,myExtension);
358      break;
359   case OSD_MacOs:
360      MacExtract(aDependentName,myDisk,myTrek,myName,myExtension);
361      break;
362   default:
363 #ifdef DEB
364        cout << " WARNING WARNING : OSD Path for an Unknown SYSTEM : " << (Standard_Integer)todo << endl;
365 #endif 
366      break ;
367  } 
368 }
369
370
371
372 OSD_Path::OSD_Path(const TCollection_AsciiString& Nod,
373                    const TCollection_AsciiString& UsrNm,
374                    const TCollection_AsciiString& Passwd,
375                    const TCollection_AsciiString& Dsk,
376                    const TCollection_AsciiString& Trk,
377                    const TCollection_AsciiString& Nam,
378                    const TCollection_AsciiString& ext){
379
380  mySysDep = whereAmI();
381
382  SetValues ( Nod, UsrNm, Passwd, Dsk, Trk, Nam, ext);
383
384
385 }
386
387
388 void OSD_Path::Values(TCollection_AsciiString& Nod, 
389                       TCollection_AsciiString& UsrNm, 
390                       TCollection_AsciiString& Passwd, 
391                       TCollection_AsciiString& Dsk, 
392                       TCollection_AsciiString& Trk,
393                       TCollection_AsciiString& Nam,
394                       TCollection_AsciiString& ext)const{
395
396  Nod = myNode;
397  UsrNm = myUserName;
398  Passwd = myPassword;
399  Dsk = myDisk;
400  Trk = myTrek;
401  Nam = myName;
402  ext = myExtension;
403 }
404
405
406 void OSD_Path::SetValues(const TCollection_AsciiString& Nod, 
407                          const TCollection_AsciiString& UsrNm, 
408                          const TCollection_AsciiString& Passwd,
409                          const TCollection_AsciiString& Dsk,
410                          const TCollection_AsciiString& Trk,
411                          const TCollection_AsciiString& Nam,
412                          const TCollection_AsciiString& ext){
413
414  if (!Nod.IsAscii())
415   Standard_ConstructionError::Raise("OSD_Path::SetValues argument : Node");
416  if (!UsrNm.IsAscii())
417   Standard_ConstructionError::Raise("OSD_Path::SetValues argument : User Name");
418  if (!Dsk.IsAscii())
419   Standard_ConstructionError::Raise("OSD_Path::SetValues argument : Disk");
420  if (!Trk.IsAscii())
421   Standard_ConstructionError::Raise("OSD_Path::SetValues argument : Trek");
422  if (!Nam.IsAscii())
423   Standard_ConstructionError::Raise("OSD_Path::SetValues argument : Name");
424  if (!ext.IsAscii())
425   Standard_ConstructionError::Raise("OSD_Path::SetValues argument : Extension");
426
427  myNode = Nod;
428  myUserName = UsrNm;
429  myPassword = Passwd;
430  myDisk = Dsk;
431  myTrek = Trk;
432  myName = Nam;
433  myExtension = ext;
434 }
435
436 void OSD_Path::UpTrek(){
437  Standard_Integer length=TrekLength();
438
439  if (length == 0) return;
440
441  Standard_Integer awhere,aHowmany;
442  TCollection_AsciiString tok;
443
444  tok = myTrek.Token("|",length);
445  awhere = myTrek.SearchFromEnd(tok);
446  aHowmany = tok.Length();
447  myTrek.Remove(awhere,aHowmany);
448
449  awhere = myTrek.Search("||");   // Searches leaving "||"
450  if (awhere != -1)
451   myTrek.Remove(awhere);
452 }
453
454
455 void OSD_Path::DownTrek(const TCollection_AsciiString& aName){
456  myTrek += aName;
457 // Pb signale par GG : pour ne pas avoir "||" ;
458  if ( aName.ToCString()[ aName.Length() - 1 ] != '|' )
459    myTrek += "|";
460 }
461
462
463 Standard_Integer OSD_Path::TrekLength()const{
464  Standard_Integer cpt=0;
465
466  while (myTrek.Token("|",cpt+1) != "")  // Counts token separated by '|'
467   cpt++;
468
469  return(cpt);
470 }
471
472
473 void OSD_Path::RemoveATrek(const Standard_Integer thewhere){
474  Standard_Integer length=TrekLength();
475
476  if (length <= 0 || thewhere > length)
477   Standard_NumericError::Raise("OSD_Path::RemoveATrek : where has an invalid value");
478
479  Standard_Integer posit,aHowmany;
480  TCollection_AsciiString tok;
481
482  tok = myTrek.Token("|",thewhere);
483  posit = myTrek.Search(tok);
484  aHowmany = tok.Length();
485  myTrek.Remove(posit,aHowmany);
486
487  posit = myTrek.Search("||");   // Searches leaving "||"
488  if (posit != -1)
489   myTrek.Remove(posit);
490 }
491
492
493 void OSD_Path::RemoveATrek(const TCollection_AsciiString& aName){
494  Standard_Integer length=TrekLength();
495
496  if (length == 0) return;
497
498  Standard_Integer awhere;
499
500  awhere = myTrek.Search(aName);
501  if (awhere != -1){
502   myTrek.Remove(awhere,aName.Length());
503
504   awhere = myTrek.Search("||");   // Searches leaving "||"
505   if (awhere != -1)
506    myTrek.Remove(awhere); 
507  } 
508 }
509
510
511 TCollection_AsciiString OSD_Path::TrekValue(const Standard_Integer thewhere)const{
512  TCollection_AsciiString result=myTrek.Token("|",thewhere);
513
514  if (result == "")
515   Standard_NumericError::Raise("OSD_Path::TrekValue : where is invalid");
516
517  return(result);
518 }
519
520 void OSD_Path::InsertATrek(const TCollection_AsciiString& aName,
521                            const Standard_Integer thewhere){
522  Standard_Integer length=TrekLength();
523
524  if (thewhere <= 0 || thewhere > length)
525   Standard_NumericError::Raise("OSD_Path::InsertATrek : where has an invalid value");
526
527  TCollection_AsciiString tok=myTrek.Token("|",thewhere);
528  Standard_Integer wwhere = myTrek.Search(tok);
529  TCollection_AsciiString what = aName;
530  what += "|";
531
532  myTrek.Insert(wwhere,what);
533 }
534
535
536 // The 4 following methods will be PUBLIC in the future
537
538 // Converts a VMS disk to other system syntax
539
540 static void VMSDisk2Other(TCollection_AsciiString & Disk){
541  Disk.RemoveAll('$');
542 }
543
544
545 // Convert a Trek to VMS syntax
546
547 static void P2VMS (TCollection_AsciiString & Way){
548  Standard_Integer length = Way.Length();
549
550  if (length == 0) return;
551
552  if (Way.Value(1) == '|')             // If begin with '|' remove '|'
553   if (Way.Value(1) != '\0')
554    Way.Remove(1,1);
555   else Way = "000000";             // Si uniquement la racine -> [000000]
556  else
557   if (Way.Length()!=0)
558    Way.Insert(1,'|');          // Else insert '|' at beginning if not empty;
559
560  Way.ChangeAll('|','.');
561  Way.ChangeAll('^','-');
562
563 }
564
565 // Convert a Trek to MAC syntax
566
567 static void P2MAC (TCollection_AsciiString & Way){
568  int i,l;
569  Way.ChangeAll('|',':');
570
571  l = (int)Way.Length();
572  for (i=1; i <= l; i++)             // Replace '^' by "::"
573   if (Way.Value(i) == '^'){
574    Way.SetValue(i,':');
575    Way.Insert(i,':');
576    i++; l++;
577   } 
578 }
579
580
581 // Convert a Trek to UNIX syntax
582
583 static void P2UNIX (TCollection_AsciiString & Way){
584  int i,l;
585  Standard_Integer length = Way.Length();
586
587  if (length == 0) return;
588
589  // if (Way.Value(length) == '|') // If Finishes with "|" removes it
590  // Way.Trunc(length-1);
591
592  Way.ChangeAll('|','/');
593  
594  l = (int)Way.Length();
595  for (i=1; i <= l; i++)             // Replace '^' by "../"
596   if (Way.Value(i) == '^'){
597    Way.SetValue(i,'.');
598    Way.Insert(i+1,'.');
599    //Way.Insert(i+2,'/');
600    i +=1; l +=1;
601   } 
602 }
603
604
605 // Convert a Trek to DOS like syntax
606
607 static void P2DOS (TCollection_AsciiString & Way){
608  int i,l;
609  Standard_Integer len = Way.Length();
610
611  if (len == 0) return;
612
613  if (Way.Value(len) == '|')   // If Finishes with "|" removes it
614   Way.Trunc(len-1);
615
616  Way.ChangeAll('|','\\');
617  
618  l = (int)Way.Length();
619  for (i=1; i <= l; i++)             // Replace '^' by ".."
620   if (Way.Value(i) == '^'){
621    Way.SetValue(i,'.');
622    Way.Insert(i,'.');
623    i++; l++;
624   } 
625
626 }
627
628
629
630
631 // Convert a path to system dependant syntax
632
633 void OSD_Path::SystemName (TCollection_AsciiString& FullName,
634                            const OSD_SysType aType)const{
635 TCollection_AsciiString Way;
636 TCollection_AsciiString pNode;
637 TCollection_AsciiString pDisk;
638 OSD_SysType pType;
639
640  if (aType == OSD_Default) {
641    pType = mySysDep;
642  } else {
643    pType = aType;
644  }
645
646  Way = myTrek;
647  FullName.Clear();
648
649  switch (pType){
650   case OSD_VMS :
651    pNode = myNode;
652
653    P2VMS (Way);    // Convert path
654
655    if (myNode.Length()!=0) FullName += myNode;      // Append Node
656
657    if (myUserName.Length()!=0){   // Append User name
658
659     if (pNode.Length()==0) {    // If a user name but no node, catenate "0"
660      pNode = "0";
661      FullName += pNode;
662     }
663
664
665     FullName += "\"";
666     FullName += myUserName;
667
668     if (myPassword.Length()!=0){  // Append password
669      FullName += " ";
670      FullName += myPassword;
671     }
672
673     FullName += "\"";
674    }
675
676    if (pNode.Length()!=0) FullName += "::";
677
678    if (myDisk.Length()!=0){       // Append Disk
679     FullName += myDisk;
680     FullName += ":";
681    }
682     
683
684    if (Way.Length()!=0)         // Append VMS path
685     FullName = FullName + "[" + Way + "]" + myName + myExtension;
686
687 //   FullName.UpperCase();
688    break;
689
690
691    case OSD_OS2 :
692    case OSD_WindowsNT :            // MSDOS-like syntax
693     {
694     int length = (int)myDisk.Length();
695
696     P2DOS (Way);
697     if (length != 1)
698
699     if (myDisk.Length()!=0){
700
701      if (
702          (length == 1 && IsAlphabetic(myDisk.Value(1))) ||     // 'A/a' to 'Z/z'
703          (length == 2 &&
704           IsAlphabetic(myDisk.Value(1)) &&
705           myDisk.Value(2) == ':')                         // 'A:' to 'Z:'
706         )    // This is a MSDOS disk syntax
707      {
708       FullName += myDisk;
709       if (myDisk.Value(length) != ':') FullName += ":";
710      }
711      else   // This is an assigned Disk
712      {
713       FullName += "\\";
714       pDisk = myDisk;
715       VMSDisk2Other(pDisk);
716       FullName += pDisk;
717       if (Way.Value(1) != '\\') FullName += "\\";
718      }
719     }
720
721     if (Way.Length()!=0)
722      FullName = FullName + Way + "\\";
723     
724     FullName += myName; 
725     FullName += myExtension;
726 //    FullName.UpperCase();
727     break;
728    }
729
730    case OSD_MacOs :                // Mackintosh-like syntax
731     if (myDisk.Length()!=0){
732      FullName += myDisk ;
733      FullName += ":";
734     }
735     P2MAC(Way); 
736     FullName += myName;
737     FullName += myExtension;
738    break;
739
740
741
742    default :                      // UNIX-like syntax
743
744  // Syntax :
745  //             user"password"@host:/disk/xxx/xxx/filename
746     P2UNIX (Way);
747
748     if (myUserName.Length()!=0 && myNode.Length()!=0){  // If USER name
749      FullName += myUserName;                        // appends user name 
750
751      if (myPassword.Length()!=0)
752       FullName = FullName + "\"" + myPassword + "\""; // a password if not empty
753
754      FullName += "@";                            // and character '@'
755     }
756
757     if (myNode.Length()!=0){                     // Appends HOST name
758      FullName += myNode;
759      FullName += ":";
760     }
761
762     if (myDisk.Length()!=0) {                    // Appends Disk name as path
763      FullName += "/";
764      pDisk = myDisk;
765      VMSDisk2Other(pDisk);
766      FullName += pDisk;
767     }
768
769 //    if (FullName.Length()) {                     // Adds a "/" if necessary
770 //      FullName += "/";
771 //    }
772
773     if (Way.Length()!=0) {                       // Appends a path if not empty
774       FullName += Way ; 
775     }
776
777     if (FullName.Length()){
778         if (FullName.Value(FullName.Length()) != '/') {
779            FullName += "/";                      // Adds a / if necessary
780        }
781     }
782
783     if (myName.Length()){                        // Adds the file name
784       FullName += myName;
785     }
786
787     if (myExtension.Length()) {                  // Adds the extension
788       FullName += myExtension;
789     }
790     break;
791  }
792 }
793
794 #ifdef TOTO  // A reactiver...
795
796 void OSD_Path::SetSystemName(const TCollection_AsciiString& aDependentName,
797                    const OSD_SysType aSysType){
798   UnixExtract(aDependentName,myNode,myUserName,myPassword,myTrek,myName,myExtension);
799 }
800 #endif
801
802 TCollection_AsciiString OSD_Path::Node()const{
803  return(myNode);
804 }
805
806
807 TCollection_AsciiString OSD_Path::UserName()const{
808  return(myUserName);
809 }
810
811
812 TCollection_AsciiString OSD_Path::Password()const{
813  return(myPassword);
814 }
815
816
817 TCollection_AsciiString OSD_Path::Disk()const{
818  return(myDisk);
819 }
820
821
822 TCollection_AsciiString OSD_Path::Trek()const{
823  return(myTrek);
824 }
825
826
827 // Return extension (suffix) of file/directory name
828
829 TCollection_AsciiString OSD_Path::Extension()const{
830  return(myExtension);
831 }
832
833
834 TCollection_AsciiString OSD_Path::Name()const{
835  return(myName);
836 }
837
838
839 void OSD_Path::SetNode(const TCollection_AsciiString& aName){
840  if (!aName.IsAscii())
841   Standard_ConstructionError::Raise("OSD_Path::SetNode bad name");
842  myNode = aName;
843 }
844
845
846
847
848 void OSD_Path::SetUserName(const TCollection_AsciiString& aName){
849  if (!aName.IsAscii())
850   Standard_ConstructionError::Raise("OSD_Path::SetUserName bad name");
851  myUserName = aName;
852 }
853
854
855
856
857 void OSD_Path::SetPassword(const TCollection_AsciiString& aName){
858  if (!aName.IsAscii())
859   Standard_ConstructionError::Raise("OSD_Path::SetPassword bad name");
860   myPassword = aName;
861 }
862
863
864
865
866 void OSD_Path::SetDisk(const TCollection_AsciiString& aName){
867  if (!aName.IsAscii())
868   Standard_ConstructionError::Raise("OSD_Path::SetDisk bad name");
869   myDisk = aName;
870 }
871
872
873
874
875 void OSD_Path::SetTrek(const TCollection_AsciiString& aName){
876  if (!aName.IsAscii())
877   Standard_ConstructionError::Raise("OSD_Path::SetTrek bad name");
878   myTrek = aName;
879 }
880
881
882
883
884 void OSD_Path::SetName(const TCollection_AsciiString& aName){
885  if (!aName.IsAscii())
886   Standard_ConstructionError::Raise("OSD_Path::SetName bad name");
887   myName = aName;
888 }
889
890
891
892
893 void OSD_Path::SetExtension(const TCollection_AsciiString& aName){
894  if (!aName.IsAscii())
895   Standard_ConstructionError::Raise("OSD_Path::SetExtension bad name");
896   myExtension = aName;
897 }
898
899 #else
900
901 //------------------------------------------------------------------------
902 //-------------------  Windows sources for OSD_Path -------------------
903 //------------------------------------------------------------------------
904
905 #include <Standard_ProgramError.hxx>
906
907 #include <windows.h>
908 #include <stdlib.h>
909
910 #define TEST_RAISE( type, arg ) _test_raise (  ( type ), ( arg )  )
911
912 static void __fastcall _test_raise ( OSD_SysType, Standard_CString );
913 static void __fastcall _remove_dup ( TCollection_AsciiString& );
914
915 OSD_Path :: OSD_Path () {
916
917 }  // end constructor ( 1 )
918
919 OSD_Path ::  OSD_Path (
920               const TCollection_AsciiString& aDependentName,
921               const OSD_SysType aSysType
922                           ) :
923   myUNCFlag(Standard_False),
924   mySysDep(OSD_WindowsNT)
925 {
926
927  Standard_Integer        i, j, len;
928  static char __drive [ _MAX_DRIVE ];
929  static char __dir [ _MAX_DIR ];
930  static char __trek [ _MAX_DIR ];
931  static char __fname [ _MAX_FNAME ];
932  static char __ext [ _MAX_EXT ];
933
934  memset(__drive, 0,_MAX_DRIVE);
935  memset(__dir, 0,_MAX_DIR);
936  memset(__trek, 0,_MAX_DIR);
937  memset(__fname, 0,_MAX_FNAME);
938  memset(__ext, 0,_MAX_EXT);
939  Standard_Character      chr;
940
941  TEST_RAISE(  aSysType, "OSD_Path"  );
942
943  _splitpath (  aDependentName.ToCString (), __drive, __dir, __fname, __ext );
944  
945  
946
947  myDisk      = __drive;
948  myName      = __fname;
949  myExtension = __ext;
950
951  {
952    TCollection_AsciiString dir   = __dir;
953    len = dir.Length ();
954  }
955
956  for ( i = j = 0; i < len; ++i, ++j ) {
957
958   chr = __dir[i];
959  
960   if (  chr == '\\' || chr == '/'  )
961
962    __trek[j] = '|';
963
964   else if (  chr == '.'&& (i+1) < len && __dir[i+1] == '.'  ) {
965   
966    __trek[j] = '^';
967    ++i;
968   
969   } else
970
971    __trek[j] = chr;
972  
973  }  // end for
974  __trek[j] = '\0';
975  TCollection_AsciiString trek  = __trek;
976  _remove_dup ( trek );
977  myTrek = trek;
978
979 }  // end constructor ( 2 )
980
981 OSD_Path :: OSD_Path (
982              const TCollection_AsciiString& aNode,
983              const TCollection_AsciiString& aUsername,
984              const TCollection_AsciiString& aPassword,
985              const TCollection_AsciiString& aDisk,
986              const TCollection_AsciiString& aTrek,
987              const TCollection_AsciiString& aName,
988              const TCollection_AsciiString& anExtension
989                          ) :
990   myUNCFlag(Standard_False),
991   mySysDep(OSD_WindowsNT)
992 {
993
994  SetValues ( aNode, aUsername, aPassword, aDisk, aTrek, aName, anExtension );
995
996 }  // end constructor ( 3 )
997
998 void OSD_Path :: Values (
999                   TCollection_AsciiString& aNode,
1000                   TCollection_AsciiString& aUsername,
1001                   TCollection_AsciiString& aPassword,
1002                   TCollection_AsciiString& aDisk,
1003                   TCollection_AsciiString& aTrek,
1004                   TCollection_AsciiString& aName,
1005                   TCollection_AsciiString& anExtension
1006                  ) const {
1007
1008  aNode       = myNode;
1009  aUsername   = myUserName;
1010  aPassword   = myPassword;
1011  aDisk       = myDisk;
1012  aTrek       = myTrek;
1013  if (!aTrek.IsEmpty() && aTrek.Value(aTrek.Length()) != '|')
1014    aTrek += "|" ; // (LD)
1015  aName       = myName;
1016  anExtension = myExtension;
1017
1018 }  // end OSD_Path :: Values
1019
1020 void OSD_Path :: SetValues (
1021                   const TCollection_AsciiString& aNode,
1022                   const TCollection_AsciiString& aUsername,
1023                   const TCollection_AsciiString& aPassword,
1024                   const TCollection_AsciiString& aDisk,
1025                   const TCollection_AsciiString& aTrek,
1026                   const TCollection_AsciiString& aName,
1027                   const TCollection_AsciiString& anExtension
1028                  ) {
1029
1030  myNode      = aNode;
1031  myUserName  = aUsername;
1032  myPassword  = aPassword;
1033  myDisk      = aDisk;
1034  myTrek      = aTrek;
1035  myName      = aName;
1036  myExtension = anExtension;
1037
1038  if (  myExtension.Length () && myExtension.Value ( 1 ) != '.'  )
1039
1040   myExtension.Insert (  1, '.'  );
1041
1042  _remove_dup ( myTrek );
1043
1044 }  // end OSD_Path :: SetValues
1045
1046 void OSD_Path :: SystemName (
1047                   TCollection_AsciiString& FullName,
1048                   const OSD_SysType aType
1049                  ) const {
1050
1051  Standard_Integer        i, j;
1052  TCollection_AsciiString fullPath;
1053  static Standard_Character trek [ _MAX_PATH ];
1054  Standard_Character      chr;
1055
1056  memset(trek,0,_MAX_PATH);
1057
1058  TEST_RAISE(  aType, "SystemName"  );
1059
1060  for ( i = j = 1; i <= myTrek.Length () && j <= _MAX_PATH; ++i, ++j ) {
1061
1062   chr = myTrek.Value ( i );   
1063
1064   if (  chr == '|'  ) {
1065   
1066    trek[j-1] = '/';
1067   
1068   } else if (  chr == '^' && j <= _MAX_PATH - 1  ) {
1069    
1070    strcpy(&(trek[(j++) - 1]),"..");
1071
1072   } else
1073
1074    trek[j-1] = chr ;
1075  
1076  }  //end for
1077
1078  fullPath = myDisk + TCollection_AsciiString(trek);
1079  
1080  if ( trek[0] ) fullPath += "/";
1081  
1082  fullPath += ( myName + myExtension );
1083
1084  if (  fullPath.Length () > 0  )
1085
1086   FullName = fullPath;
1087
1088  else
1089
1090   FullName.Clear ();
1091
1092 }  // end OSD_Path :: SystemName
1093
1094 void OSD_Path :: UpTrek () {
1095
1096  Standard_Integer pos = myTrek.SearchFromEnd (  "|"  );
1097
1098  if ( pos == -1 )
1099
1100   pos = 0;
1101
1102  else if ( pos > 1 ) {
1103
1104   while (  myTrek.Value ( pos ) == '|' && pos != 1  ) --pos;
1105
1106  }  // end if
1107
1108  myTrek.Trunc ( pos );
1109
1110 }  // end OSD_Path :: UpTrek
1111
1112 void OSD_Path :: DownTrek ( const TCollection_AsciiString& aName ) {
1113
1114  Standard_Integer pos = myTrek.Length ();
1115
1116  if (  aName.Value ( 1 ) != '|'    &&
1117        pos                                 &&
1118        myTrek.Value ( pos ) != '|'
1119  )
1120
1121   myTrek += "|";
1122
1123  myTrek += aName;
1124
1125  _remove_dup ( myTrek );
1126
1127 }  // end OSD_Path :: DownTrek
1128
1129 Standard_Integer OSD_Path :: TrekLength () const {
1130
1131  Standard_Integer i      = 1;
1132  Standard_Integer retVal = 0;
1133
1134  if (  myTrek.IsEmpty () || myTrek.Length () == 1 && myTrek.Value ( 1 ) == '|'  )
1135
1136   return retVal;
1137
1138  for (;;) {
1139  
1140   if (  myTrek.Token (  "|", i++  ).IsEmpty ()  )
1141
1142    break;
1143
1144   ++retVal;
1145  
1146  }  //end while
1147
1148  return retVal;
1149
1150 }  // end TrekLength
1151
1152 void OSD_Path :: RemoveATrek ( const Standard_Integer thewhere ) {
1153
1154  Standard_Integer i, j;
1155  Standard_Boolean flag = Standard_False;
1156
1157  if (  TrekLength () < thewhere  )
1158
1159   return;
1160
1161  if (  myTrek.Value ( 1 ) != '|'  ) {
1162  
1163   flag = Standard_True;
1164   myTrek.Insert (  1, '|'  );
1165  
1166  }  // end if
1167
1168  i = myTrek.Location (
1169              thewhere, '|',
1170              1, myTrek.Length ()
1171             );
1172
1173  if ( i ) {
1174
1175   j = myTrek.Location (
1176               thewhere + 1, '|',
1177               1, myTrek.Length ()
1178              );
1179
1180   if ( j == 0 )
1181
1182    j = myTrek.Length () + 1;
1183
1184   myTrek.Remove ( i, j - i );
1185
1186  }  // end if
1187
1188  if ( flag )
1189
1190   myTrek.Remove ( 1 );
1191
1192 }  // end OSD_Path :: RemoveATrek ( 1 )
1193
1194 void OSD_Path :: RemoveATrek ( const TCollection_AsciiString& aName ) {
1195
1196  Standard_Integer        i;
1197  Standard_Boolean        flag = Standard_False;
1198  TCollection_AsciiString tmp;
1199
1200  if (  myTrek.Value ( 1 ) != '|'  ) {
1201  
1202   flag = Standard_True;
1203   myTrek.Insert (  1, '|'  );
1204  
1205  }  // end if
1206
1207  myTrek += '|';
1208
1209  tmp = aName;
1210
1211  if (  tmp.Value ( 1 ) != '|'  )
1212
1213   tmp.Insert (  1, '|'  );
1214
1215  if (   tmp.Value (  tmp.Length ()  ) != '|'   )
1216
1217   tmp += '|';
1218
1219  i = myTrek.Search ( tmp );
1220
1221  if ( i != -1 )
1222  
1223   myTrek.Remove (  i + 1, tmp.Length () - 1  );
1224
1225  if ( flag )
1226
1227   myTrek.Remove ( 1 );
1228  
1229  if (   myTrek.Value (  myTrek.Length ()  ) == '|'  )
1230
1231   myTrek.Trunc (  myTrek.Length () - 1  );
1232
1233 }  // end OSD_Path :: RemoveATrek ( 2 )
1234
1235 TCollection_AsciiString OSD_Path :: TrekValue (
1236                                      const Standard_Integer thewhere
1237                                     ) const {
1238
1239  TCollection_AsciiString retVal;
1240  TCollection_AsciiString trek = myTrek;
1241
1242  if (  trek.Value ( 1 ) != '|'  )
1243  
1244   trek.Insert (  1, '|'  );
1245  
1246  retVal = trek.Token (  "|", thewhere  );
1247
1248  return retVal;
1249
1250 }  // end OSD_Path :: TrekValue
1251
1252 void OSD_Path :: InsertATrek (
1253                   const TCollection_AsciiString& aName,
1254                   const Standard_Integer thewhere
1255                  ) {
1256
1257  Standard_Integer        pos;
1258  TCollection_AsciiString tmp = aName;
1259  Standard_Boolean        flag = Standard_False;
1260
1261  if (  myTrek.Value ( 1 ) != '|'  ) {
1262  
1263   flag = Standard_True;
1264   myTrek.Insert (  1, '|'  );
1265  
1266  }  // end if
1267
1268  myTrek += '|';
1269
1270  pos = myTrek.Location (
1271                thewhere, '|',
1272                1, myTrek.Length ()
1273               );
1274
1275  if ( pos ) {
1276
1277   if (   tmp.Value (  tmp.Length ()  ) != '|'   )
1278
1279    tmp += '|';
1280
1281   myTrek.Insert ( pos + 1, tmp );
1282
1283  }  // end if
1284
1285  if ( flag )
1286
1287   myTrek.Remove ( 1 );
1288
1289  if (   myTrek.Value (  myTrek.Length ()  ) == '|'  )
1290
1291   myTrek.Trunc (  myTrek.Length () - 1  );
1292
1293  _remove_dup ( myTrek );
1294
1295 }  // end OSD_Path :: InsertATrek
1296
1297 TCollection_AsciiString OSD_Path :: Node () const {
1298
1299  return myNode;
1300
1301 }  // end OSD_Path :: Node
1302
1303 TCollection_AsciiString OSD_Path :: UserName () const {
1304
1305  return myUserName;
1306
1307 }  // end OSD_Path :: UserName
1308
1309 TCollection_AsciiString OSD_Path :: Password () const {
1310
1311  return myPassword;
1312
1313 }  // end OSD_Path :: Password
1314
1315 TCollection_AsciiString OSD_Path :: Disk () const {
1316
1317  return myDisk;
1318
1319 }  // end OSD_Path :: Disk
1320
1321 TCollection_AsciiString OSD_Path :: Trek () const {
1322
1323  TCollection_AsciiString retVal ;
1324  retVal = myTrek ;
1325  if (!retVal.IsEmpty() && retVal.Value(retVal.Length()) != '|')
1326    retVal += "|" ;          // (LD)
1327  return retVal;
1328
1329 }  // end OSD_Path :: Trek
1330
1331 TCollection_AsciiString OSD_Path :: Name () const {
1332
1333  return myName;
1334
1335 }  // end OSD_Path :: Name
1336
1337 TCollection_AsciiString OSD_Path :: Extension () const {
1338
1339  return myExtension;
1340
1341 }  // end OSD_Path :: Extension
1342
1343 void OSD_Path :: SetNode ( const TCollection_AsciiString& aName ) {
1344
1345  myNode = aName;
1346
1347 }  // end OSD_Path :: SetNode
1348
1349 void OSD_Path :: SetUserName (const TCollection_AsciiString& aName ) {
1350
1351  myUserName = aName;
1352
1353 }  // end OSD_Path :: SetUserName
1354
1355 void OSD_Path :: SetPassword ( const TCollection_AsciiString& aName ) {
1356
1357  myPassword = aName;
1358
1359 }  // end OSD_Path :: SetPassword
1360
1361 void OSD_Path :: SetDisk ( const TCollection_AsciiString& aName ) {
1362
1363  myDisk = aName;
1364
1365 }  // end OSD_Path :: SetDisk
1366
1367 void OSD_Path :: SetTrek (const TCollection_AsciiString& aName ) {
1368
1369  myTrek = aName;
1370
1371  _remove_dup ( myTrek );
1372
1373 }  // end OSD_Path :: SetTrek
1374
1375 void OSD_Path :: SetName ( const TCollection_AsciiString& aName ) {
1376
1377  myName = aName;
1378
1379 }  // end OSD_Path :: SetName
1380
1381 void OSD_Path :: SetExtension ( const TCollection_AsciiString& aName ) {
1382
1383  myExtension = aName;
1384
1385 }  // end OSD_Path :: SetExtension
1386
1387 static void __fastcall _test_raise ( OSD_SysType type, Standard_CString str ) {
1388
1389  Standard_Character buff[ 64 ];
1390
1391  if ( type != OSD_Default && type != OSD_WindowsNT ) {
1392  
1393   strcpy (  buff, "OSD_Path :: "  );
1394   strcat (  buff, str );
1395   strcat (  buff, " (): unknown system type"  );
1396
1397   Standard_ProgramError :: Raise ( buff );
1398  
1399  }  // end if
1400
1401 }  // end _test_raise
1402
1403 static void __fastcall _remove_dup ( TCollection_AsciiString& str ) {
1404
1405  Standard_Integer pos = 1, orgLen, len = str.Length ();
1406
1407  orgLen = len;
1408
1409  while ( pos <= len ) {
1410  
1411   if (  str.Value ( pos     ) == '|' && pos != len &&
1412         str.Value ( pos + 1 ) == '|' && pos != 1
1413   ) {
1414   
1415    ++pos;
1416
1417    while (  pos <= len && str.Value ( pos ) == '|'  ) str.Remove ( pos ), --len;
1418   
1419   } else
1420
1421    ++pos;
1422  
1423  }  // end while
1424
1425  if (  orgLen > 1 && len > 0 && str.Value ( len ) == '|'  ) str.Remove ( len );
1426
1427  pos = 1;
1428  orgLen = len = str.Length ();
1429
1430  while ( pos <= len ) {
1431  
1432   if (  str.Value ( pos ) == '^' && pos != len && str.Value ( pos + 1 ) == '^'  ) {
1433   
1434    ++pos;
1435
1436    while (  pos <= len && str.Value ( pos ) == '^'  ) str.Remove ( pos ), --len;
1437   
1438   } else
1439
1440    ++pos;
1441  
1442  }  // end while
1443
1444 // if (  orgLen > 1 && len > 0 && str.Value ( len ) == '^'  ) str.Remove ( len );
1445
1446 }  // end _remove_dup
1447
1448 #endif // Windows sources for OSD_Path
1449
1450 // =======================================================================
1451 // function : Analyse_VMS
1452 // purpose  :
1453 // =======================================================================
1454 static Standard_Boolean Analyse_VMS (const TCollection_AsciiString& theName)
1455 {
1456   if (theName.Search ("/")  != -1
1457    || theName.Search ("@")  != -1
1458    || theName.Search ("\\") != -1)
1459   {
1460     return Standard_False;
1461   }
1462
1463   return Standard_True;
1464 }
1465
1466 // =======================================================================
1467 // function : Analyse_DOS
1468 // purpose  :
1469 // =======================================================================
1470 static Standard_Boolean Analyse_DOS(const TCollection_AsciiString& theName)
1471 {
1472   if (theName.Search ("/")  != -1
1473    || theName.Search (":")  != -1
1474    || theName.Search ("*")  != -1
1475    || theName.Search ("?")  != -1
1476    || theName.Search ("\"") != -1
1477    || theName.Search ("<")  != -1
1478    || theName.Search (">")  != -1
1479    || theName.Search ("|")  != -1)
1480   {
1481     return Standard_False;
1482   }
1483
1484  return Standard_True;
1485 }
1486
1487 // =======================================================================
1488 // function : Analyse_MACOS
1489 // purpose  :
1490 // =======================================================================
1491 static Standard_Boolean Analyse_MACOS (const TCollection_AsciiString& theName)
1492 {
1493   return theName.Search(":") == -1 ? theName.Length() <= 31 : Standard_True;
1494 }
1495
1496 // =======================================================================
1497 // function : IsValid
1498 // purpose  :
1499 // =======================================================================
1500 Standard_Boolean OSD_Path::IsValid (const TCollection_AsciiString& theDependentName,
1501                                     const OSD_SysType theSysType)
1502 {
1503   if (theDependentName.Length() == 0)
1504   {
1505     return Standard_True;
1506   }
1507
1508   switch (theSysType == OSD_Default ? whereAmI() : theSysType)
1509   {
1510     case OSD_VMS:
1511       return Analyse_VMS (theDependentName);
1512     case OSD_OS2:
1513     case OSD_WindowsNT:
1514       return Analyse_DOS (theDependentName);
1515     case OSD_MacOs:
1516       return Analyse_MACOS (theDependentName);
1517     default:
1518       return Standard_True;
1519   }
1520 }
1521
1522 // ---------------------------------------------------------------------------
1523
1524 // Elimine les separateurs inutiles
1525
1526
1527 static Standard_Integer RemoveExtraSeparator(TCollection_AsciiString& aString) {
1528
1529   Standard_Integer i, j, len,start = 1 ;
1530
1531   len = aString.Length() ;
1532 #ifdef _WIN32
1533   if (len > 1 && aString.Value(1) == '/' && aString.Value(2) == '/')
1534     start = 2;
1535 #endif 
1536   for (i = j = start ; j <= len ; i++,j++) {
1537       Standard_Character c = aString.Value(j) ;
1538       aString.SetValue(i,c) ;
1539       if (c == '/')
1540           while(j < len && aString.Value(j+1) == '/') j++ ;
1541   }
1542   len = i-1 ;
1543   if (aString.Value(len) == '/') len-- ;  
1544   aString.Trunc(len) ;
1545   return len ;
1546 }
1547
1548 // ---------------------------------------------------------------------------
1549
1550 TCollection_AsciiString OSD_Path::RelativePath(
1551                             const TCollection_AsciiString& aDirPath,
1552                             const TCollection_AsciiString& aAbsFilePath)
1553 {
1554   TCollection_AsciiString EmptyString = "" ;
1555   TCollection_AsciiString FilePath ;
1556   Standard_Integer len ;
1557   Standard_Integer i, n ;
1558   Standard_Boolean Wnt = 0 ;
1559
1560   FilePath = aAbsFilePath ;
1561
1562   if (aDirPath.Search(":") == 2) {    // Cas WNT
1563       Wnt = 1 ;
1564       if (FilePath.Search(":") != 2 || 
1565           UpperCase(aDirPath.Value(1)) != UpperCase(FilePath.Value(1))
1566       )
1567           return  EmptyString ;
1568
1569       FilePath.ChangeAll('\\','/') ;
1570       if (FilePath.Search("/") != 3 )
1571           return  EmptyString ;
1572   }
1573   else {        // Cas Unix
1574       if (aDirPath.Value(1) != '/' || FilePath.Value(1) != '/')
1575           return  EmptyString ;
1576   }
1577
1578   // Eliminer les separateurs redondants
1579
1580   len = RemoveExtraSeparator(FilePath) ;
1581
1582   if (!Wnt) {
1583      if (len < 2)
1584          return  EmptyString ;
1585      FilePath = FilePath.SubString(2,len) ;
1586   }
1587   TCollection_AsciiString DirToken, FileToken ;
1588   Standard_Boolean Sibling = 0 ;
1589
1590   for (i = n = 1 ;; n++) {
1591       DirToken = aDirPath.Token("/\\",n) ;
1592       if (DirToken.IsEmpty())
1593           return FilePath ;
1594
1595       if (!Sibling) {
1596           len = FilePath.Length() ;
1597           i = FilePath.Search("/") ;
1598           if (i > 0) {
1599               if (i == len)
1600                   return EmptyString ;
1601
1602               FileToken = FilePath.SubString(1,i-1) ;
1603               if (Wnt) {
1604                   DirToken.UpperCase() ;
1605                   FileToken.UpperCase() ;
1606               }
1607               if (DirToken == FileToken) {
1608                   FilePath = FilePath.SubString(i+1,len) ;
1609                   continue ;
1610               }
1611           }
1612           else if (DirToken == FilePath)
1613               return EmptyString ;
1614  
1615           else
1616               Sibling = 1 ;
1617       }
1618       FilePath.Insert(1,"../") ;
1619   }
1620 }
1621       
1622 // ---------------------------------------------------------------------------
1623     
1624 TCollection_AsciiString OSD_Path::AbsolutePath(
1625                             const TCollection_AsciiString& aDirPath,
1626                             const TCollection_AsciiString& aRelFilePath)
1627 {
1628   TCollection_AsciiString EmptyString = "" ;
1629   if (aRelFilePath.Search("/") == 1 || aRelFilePath.Search(":") == 2)
1630       return aRelFilePath ;
1631   TCollection_AsciiString DirPath = aDirPath, RelFilePath = aRelFilePath  ;
1632   Standard_Integer i,len ;
1633
1634   if (DirPath.Search("/") != 1 && DirPath.Search(":") != 2)
1635       return EmptyString ;
1636
1637   if ( DirPath.Search(":") == 2)
1638       DirPath.ChangeAll('\\','/') ;
1639   RelFilePath.ChangeAll('\\','/') ;
1640   RemoveExtraSeparator(DirPath) ;
1641   len = RemoveExtraSeparator(RelFilePath) ;
1642   
1643   while (RelFilePath.Search("../") == 1) {
1644       if (len == 3)
1645           return EmptyString ;
1646       RelFilePath = RelFilePath.SubString(4,len) ;
1647       len -= 3 ;
1648       if (DirPath.IsEmpty())
1649           return EmptyString ;
1650       i = DirPath.SearchFromEnd("/") ;
1651       if (i < 0)
1652           return EmptyString ;
1653       DirPath.Trunc(i-1) ;
1654   }
1655   DirPath += '/' ;
1656   DirPath += RelFilePath ;
1657   return DirPath ;
1658 }
1659
1660 //void OSD_Path::ExpandedName(TCollection_AsciiString& aName)
1661 void OSD_Path::ExpandedName(TCollection_AsciiString& )
1662 {
1663 }
1664
1665 //Standard_Boolean LocateExecFile(OSD_Path& aPath)
1666 Standard_Boolean LocateExecFile(OSD_Path& )
1667 {
1668   return Standard_False ;
1669 }