Logo Search packages:      
Sourcecode: djvulibre version File versions

GUTF8String GURL::expand_name ( const GUTF8String filename,
const char *  fromdirname = 0 
) [static]

Returns fully qualified file names. This functions constructs the fully qualified name of file or directory filename#. When provided, the optional argument fromdirname# is used as the current directory when interpreting relative specifications in filename#. Function expand_name# is very useful for logically concatenating file names. It knows which separators should be used for each operating system and it knows which syntactical rules apply.

Definition at line 1673 of file GURL.cpp.

References GOS::cwd(), fname(), GUTF8String::getbuf(), GOS::getenv(), GBaseString::getNative2UTF8(), GBaseString::getUTF82Native(), is_file(), and GBaseString::length().

Referenced by get_string(), and UTF8Filename().

{
  const char *fname=xfname;
  GUTF8String retval;
  const size_t maxlen=xfname.length()*9+MAXPATHLEN+10;
  char * const string_buffer = retval.getbuf(maxlen);
  // UNIX implementation
#ifdef UNIX
  // Perform tilde expansion
  GUTF8String senv;
  if (fname && fname[0]==tilde)
  {
    int n;
    for(n=1;fname[n] && fname[n]!= slash;n++) 
      EMPTY_LOOP;
    struct passwd *pw=0;
    if (n!=1)
    {
      GUTF8String user(fname+1, n-1);
      pw=getpwnam(user);
    }else if ((senv=GOS::getenv("HOME")).length())
    {
      from=(const char *)senv;
      fname = fname + n;
    }else if ((senv=GOS::getenv("LOGNAME")).length())
    {
      pw = getpwnam((const char *)senv.getUTF82Native());
    }else
    {
      pw=getpwuid(getuid());
    }
    if (pw)
    {
      senv=GNativeString(pw->pw_dir).getNative2UTF8();
      from = (const char *)senv;
      fname = fname + n;
    }
    for(;fname[0] == slash; fname++)
      EMPTY_LOOP;
  }
  // Process absolute vs. relative path
  if (fname && fname[0]== slash)
  {
    string_buffer[0]=slash;
    string_buffer[1]=0;
  }else if (from)
  {
    strcpy(string_buffer, expand_name(from));
  }else
  {
    strcpy(string_buffer, GOS::cwd());
  }
  char *s = string_buffer + strlen(string_buffer);
  if(fname)
  {
    for(;fname[0]== slash;fname++)
      EMPTY_LOOP;
    // Process path components
    while(fname[0])
    {
      if (fname[0] == dot )
      {
        if (!fname[1] || fname[1]== slash)
        {
          fname++;
          continue;
        }else if (fname[1]== dot && (fname[2]== slash || !fname[2]))
        {
          fname +=2;
          for(;s>string_buffer+1 && *(s-1)== slash; s--)
            EMPTY_LOOP;
          for(;s>string_buffer+1 && *(s-1)!= slash; s--)
            EMPTY_LOOP;
          continue;
        }
      }
      if ((s==string_buffer)||(*(s-1)!= slash))
      {
        *s = slash;
        s++;
      }
      while (*fname &&(*fname!= slash))
      {
        *s = *fname++;
        if ((size_t)((++s)-string_buffer) > maxlen)
        {
          G_THROW( ERR_MSG("GURL.big_name") );
        }
      }
      *s = 0;
      for(;fname[0]== slash;fname++)
        EMPTY_LOOP;
    }
  }
  if (!fname || !fname[0])
  {
    for(;s>string_buffer+1 && *(s-1) == slash; s--)
      EMPTY_LOOP;
    *s = 0;
  }
#elif defined (WIN32) && !defined (UNDER_CE) // WIN32 implementation
  // Handle base
  strcpy(string_buffer, (char const *)(from ? expand_name(from) : GOS::cwd()));
  //  GNativeString native;
  if (fname)
  {
    char *s = string_buffer;
    char  drv[4];
    // Handle absolute part of fname
    //      Put absolute part of the file name in string_buffer, and
    //      the relative part pointed to by fname.
    if (fname[0]== slash || fname[0]== backslash)
    {
      if (fname[1]== slash || fname[1]== backslash)
      {       // Case "//abcd"
        s[0]=s[1]= backslash; s[2]=0;
      }
      else
      {       // Case "/abcd" or "/"
              //    File is at the root of the current drive. Delete the
              //    slash at the beginning of the filename and leave
              //    an explicit identification of the root of the drive in
              //    string_buffer.
        fname++;
        s[3] = '\0';
      }
    }
    else if (fname[0] && fname[1]==colon)
    {
      if (fname[2]!= slash && fname[2]!= backslash)
      {       // Case "x:abcd"
        if ( toupper((unsigned char)s[0]) != toupper((unsigned char)fname[0])
          || s[1]!=colon)
        {
          drv[0]=fname[0];
          drv[1]=colon;
          drv[2]= dot ;
          drv[3]=0;
          GetFullPathName(drv, maxlen, string_buffer, &s);
          strcpy(string_buffer,(const char *)GUTF8String(string_buffer).getNative2UTF8());
          s = string_buffer;
        }
        fname += 2;
      }
      else if (fname[3]!= slash && fname[3]!= backslash)
      {       // Case "x:/abcd"
        s[0]=toupper((unsigned char)fname[0]);
        s[1]=colon;
        s[2]=backslash;
        s[3]=0;
        fname += 3;
      }
      else
      {       // Case "x://abcd"
        s[0]=s[1]=backslash;
        s[2]=0;
        fname += 4;
      }
    }
    // Process path components
    for(;*fname== slash || *fname==backslash;fname++)
      EMPTY_LOOP;
    while(*fname)
    {
      if (fname[0]== dot )
      {
        if (fname[1]== slash || fname[1]==backslash || !fname[1])
        {
          fname++;
          continue;
        }else if ((fname[1] == dot)
          && (fname[2]== slash || fname[2]==backslash || !fname[2]))
        {
          fname += 2;
          char *back=_tcsrchr(string_buffer,backslash);
          char *forward=_tcsrchr(string_buffer,slash);
          if(back>forward)
          {
            *back=0;
          }else if(forward)
          {
            *forward=0;
          }
          s = string_buffer;
          continue;
        }
        char* s2=s;//MBCS DBCS
        for(;*s;s++) 
          EMPTY_LOOP;
        char* back = _tcsrchr(s2,backslash);//MBCS DBCS
        if ((s>string_buffer)&&(*(s-1)!= slash)&&(back == NULL || (back!=NULL && s-1 != back) ))//MBCS DBCS
          //if ((s>string_buffer)&&(*(s-1)!= slash)&&(*(s-1)!= backslash))
        {
          *s = backslash;
          s++;
        }
        while (*fname && *fname!= slash && *fname!=backslash)
        {
          *s = *fname++;
          if ((size_t)((++s)-string_buffer) > maxlen)
            G_THROW( ERR_MSG("GURL.big_name") );
        }
        *s = 0;
      }
      char* s2=s;//MBCS DBCS
      for(;*s;s++) 
        EMPTY_LOOP;
      char* back = _tcsrchr(s2,backslash);//MBCS DBCS
      if ((s>string_buffer)&&(*(s-1)!= slash)&&(back == NULL || (back!=NULL && s-1 != back) ))//MBCS DBCS
        //if ((s == string_buffer)||((*(s-1)!= slash) && (*(s-1)!=backslash)))
      {
        *s = backslash;
        s++;
      }
      while (*fname && (*fname!= slash) && (*fname!=backslash))
      {
        *s = *fname++;
        if ((size_t)((++s)-string_buffer) > maxlen)
          G_THROW( ERR_MSG("GURL.big_name") );
      }
      *s = 0;
      for(;(*fname== slash)||(*fname==backslash);fname++)
        EMPTY_LOOP;
    }
  }
#elif defined(macintosh) // MACINTOSH implementation
  strcpy(string_buffer, (const char *)(from?from:GOS::cwd()));
  
  if (!GStringRep::cmp(fname, string_buffer,strlen(string_buffer)) || is_file(fname))
  {
    strcpy(string_buffer, "");//please don't expand, the logic of filename is chaos.
  }
  
  // Process path components
  char *s = string_buffer + strlen(string_buffer);
  if(fname)
  {
    for(;fname[0]==colon;fname++)
      EMPTY_LOOP;
    while(fname[0])
    {
      if (fname[0]== dot )
      {
        if (fname[1]==colon || !fname[1])
        {
          fname++;
          continue;
        }
        if ((fname[1]== dot )
          &&(fname[2]==colon || fname[2]==0))
        {
          fname +=2;
          for(;(s>string_buffer+1)&&(*(s-1)==colon);s--)
            EMPTY_LOOP;
          for(;(s>string_buffer+1)&&(*(s-1)!=colon);s--)
            EMPTY_LOOP;
          continue;
        }
      }
      if ((s==string_buffer)||(*(s-1)!=colon))
      {
        *s = colon;
        s++;
      }
      while (*fname!=0 && *fname!=colon)
      {
        *s = *fname++;
        if ((++s)-string_buffer > maxlen)
          G_THROW( ERR_MSG("GURL.big_name") );
      }
      *s = 0;
      for(;fname[0]==colon;fname++)
        EMPTY_LOOP;
    }
  }
  for(;(s>string_buffer+1) && (*(s-1)==colon);s--)
    EMPTY_LOOP;
  *s = 0;
  return ((string_buffer[0]==colon)?(string_buffer+1):string_buffer);
#elif   defined(UNDER_CE) || defined(OS2)
  retval=fname;
#else
#error "Define something here for your operating system"
#endif  
  return retval;
}


Generated by  Doxygen 1.6.0   Back to index