LCOV - code coverage report
Current view: top level - libreoffice/dmake - path.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 88 93 94.6 %
Date: 2012-12-17 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* RCS  $Id: path.c,v 1.6 2008-03-05 18:29:34 kz Exp $
       2             : --
       3             : -- SYNOPSIS
       4             : --      Pathname manipulation code
       5             : --
       6             : -- DESCRIPTION
       7             : --  Pathname routines to handle building and pulling appart
       8             : --  pathnames.
       9             : --
      10             : -- AUTHOR
      11             : --      Dennis Vadura, dvadura@dmake.wticorp.com
      12             : --
      13             : -- WWW
      14             : --      http://dmake.wticorp.com/
      15             : --
      16             : -- COPYRIGHT
      17             : --      Copyright (c) 1996,1997 by WTI Corp.  All rights reserved.
      18             : --
      19             : --      This program is NOT free software; you can redistribute it and/or
      20             : --      modify it under the terms of the Software License Agreement Provided
      21             : --      in the file <distribution-root>/readme/license.txt.
      22             : --
      23             : -- LOG
      24             : --      Use cvs log to obtain detailed change logs.
      25             : */
      26             : 
      27             : #include "extern.h"
      28             : #if __CYGWIN__
      29             : #include <sys/cygwin.h>
      30             : #include <errno.h>
      31             : #endif
      32             : 
      33             : 
      34             : /*
      35             : ** Return the suffix portion of a filename, assumed to begin with a `.'.
      36             : */
      37             : PUBLIC char *
      38       37761 : Get_suffix(name)
      39             : char *name;
      40             : {
      41             :    char *suff;
      42             : 
      43       37761 :    if(name == NIL(char)  || (suff = strrchr(name, '.')) == NIL(char))
      44        1127 :       suff = ".NULL";
      45             : 
      46       37761 :    return (suff);
      47             : }
      48             : 
      49             : 
      50             : PUBLIC char *
      51      120634 : Basename(path)/*
      52             : ================
      53             :    Return pointer to the basename part of path. path itself remains
      54             :    unchanged. */
      55             : char *path;
      56             : {
      57             :    char *p;
      58             :    char *q;
      59             : 
      60      120634 :    if( path && *(q = path) ) {
      61      120634 :       for(; *(p=DmStrPbrk(q, DirBrkStr)) != '\0'; q = p+1 );
      62      120634 :       if( !*q ) {
      63           0 :      for( p=q-1; p != path; --p )
      64           0 :         if( strchr( DirBrkStr, *p ) == NIL(char) ) return( p+1 );
      65           0 :      return( strchr(DirBrkStr, *p)?path:(p+1) );
      66             :       }
      67      120634 :       path = q;
      68             :    }
      69      120634 :    return( path );
      70             : }
      71             : 
      72             : 
      73             : PUBLIC char *
      74       37761 : Filedir(path)
      75             : char *path;
      76             : {
      77             :    char *p;
      78             :    char *q;
      79             : 
      80       37761 :    if( path && *(q = path) ) {
      81       37761 :       for(; *(p=DmStrPbrk(q,DirBrkStr)) != '\0'; q=p+1 );
      82             : 
      83       37761 :       if (q == path) return("");
      84             : 
      85       75522 :       for(p=q-1; p!=path; --p)
      86       75522 :      if( strchr(DirBrkStr,*p) == NIL(char) )
      87       37761 :         break;
      88             : 
      89       37761 :       p[1] = '\0';
      90             :    }
      91             : 
      92       37761 :    return(path);
      93             : }
      94             : 
      95             : 
      96             : 
      97             : PUBLIC char *
      98       44253 : Build_path(dir, name)/*
      99             : =======================
     100             :    Return a path that is created by concatenating dir and name. A directory
     101             :    separater is added between them if needed. If dir is empty name is stripped
     102             :    of leading slashes (if there) and returned.
     103             : 
     104             :    The returned path is also cleaned from unneeded './' and 'foo/../'
     105             :    elements and also multiple consequtive '/' are removed.
     106             : 
     107             :    Note, the returned path is built in a static buffer, if it is to be used
     108             :    later strdup should be used on the result returned by Build_path to create
     109             :    a copy. */
     110             : 
     111             : char *dir;
     112             : char *name;
     113             : {
     114             :    static char     *path  = NIL(char);
     115             :    static unsigned buflen = 0;
     116       44253 :    int  plen = 0;
     117       44253 :    int  dlen = 0;
     118             :    int  len;
     119             : 
     120             :    DB_ENTER( "Build_path" );
     121             : 
     122       44253 :    if( dir  != NIL(char) ) dlen = strlen( dir  );
     123       44253 :    if( name != NIL(char) ) plen = strlen( name );
     124       44253 :    len = plen+dlen+1+1; /* Reserve space for extra path separator. */
     125             : 
     126       44253 :    if( len > buflen ) {
     127         704 :       buflen = (len+16) & ~0xf;     /* buf is always multiple of 16 */
     128             : 
     129         704 :       if( path == NIL(char) )
     130         184 :          path = MALLOC( buflen, char );
     131             :       else
     132         520 :          path = realloc( path, (unsigned) (buflen*sizeof(char)) );
     133             :    }
     134             : 
     135       44253 :    *path = '\0';
     136             : 
     137       44253 :    if( dlen ) {
     138       44253 :       strcpy( path, dir );
     139       44253 :       if( *path && strchr(DirBrkStr, dir[dlen-1]) == NIL(char) )
     140       44253 :      strcat( path, DirSepStr );
     141             :    }
     142             : 
     143       44253 :    if ( plen ) {
     144       44253 :       while ( *name && strchr(DirBrkStr,*name) != 0 ) name++;
     145       44253 :       strcat( path, name );
     146             :    }
     147             : 
     148             :    DB_PRINT( "path", ("dir: %s  name: %s", dir, name ));
     149             :    DB_PRINT( "path", ("joined to: %s", path ));
     150             : 
     151       44253 :    Clean_path( path );
     152             :    DB_PRINT( "path", ("cleaned to: %s", path ));
     153             : 
     154       44253 :    DB_RETURN( path );
     155             : }
     156             : 
     157             : 
     158             : void
     159      152263 : Clean_path(path)/*
     160             : ==================
     161             :    Clean the path from irregular directory separators (if more than one are
     162             :    allowed), remove unneeded './' and 'foo/../' elements and also multiple
     163             :    consequtive '/'.
     164             : 
     165             :    The resulting string is shorter than the original, therefore this function
     166             :    works on the original string. */
     167             : 
     168             : char *path;
     169             : {
     170             :    register char *p;
     171             :    register char *q;
     172             :    char *tpath;
     173      152263 :    int hasdriveletter = 0;
     174             :    int delentry;
     175             :    size_t len;
     176             : 
     177             :    DB_ENTER( "Clean_path" );
     178             : 
     179             :    /* Skip the root part. */
     180      152263 :    tpath=path;
     181             : 
     182             : #ifdef HAVE_DRIVE_LETTERS
     183             : 
     184             :    /* Change all occurrences from DirBrkStr to *DirSepStr. This assumes
     185             :     * that when HAVE_DRIVE_LETTERS is set the directory separator is
     186             :     * either '\' or '/'. */
     187             :    if (*DirSepStr == '/')
     188             :       for( q = tpath; (q = strchr(q, '\\')) != NIL(char); )
     189             :          *q = *DirSepStr;
     190             :    else
     191             :       for( q = tpath; (q = strchr(q, '/')) != NIL(char); )
     192             :          *q = *DirSepStr;
     193             : 
     194             :    /* The following dosn't trigger often because normalize_path() uses
     195             :     * a cygwin function and bypasses Clean_path() if it encounters a path
     196             :     * with a drive letter. */
     197             :    if( *tpath && tpath[1] == ':' && isalpha(*tpath) ) {
     198             :       hasdriveletter = 1;
     199             :       tpath+=2;
     200             :       if( *tpath != *DirSepStr )
     201             :      Warning("Malformed DOS path %s", path);
     202             :    }
     203             : 
     204             : #endif
     205             : 
     206             :    /* Collapse > 2 ( > 1 if its an absolute DOS path ) into one slash.
     207             :     * Keep // as it is reserved in posix. */
     208      152263 :    q = tpath;
     209      152263 :    for( ; *q == *DirSepStr ; ++q )
     210             :       ;
     211      152263 :    if( q - tpath > 2 - hasdriveletter ) {
     212           0 :       strcpy(tpath+1, q);
     213             :    }
     214             : 
     215             :    /* Set tpath after leading slash / drive letter. */
     216      152263 :    for( ; *tpath == *DirSepStr ; ++tpath )
     217             :       ;
     218      152263 :    q = tpath;
     219             : 
     220     1527810 :    while( *q ) {
     221             :       char *t;
     222             : 
     223             :       /* p is NULL or greater than q. */
     224     1375547 :       p=strchr(q, *DirSepStr);
     225     1375547 :       if( !p ) break;
     226             : 
     227             :       /* Remove multiple consequtive DirSepStr. */
     228     1334139 :       if( p[1] == *DirSepStr ) {
     229          26 :      t = p++; /* t points to first, p to second DirStrSep. */
     230             :      /* Move p after the second (or possible more) DirSepStr. */
     231             :      do {
     232          26 :         p++;
     233             :      }
     234          26 :      while( *p == *DirSepStr);
     235          26 :      len = strlen(p)+1;
     236          26 :      memmove(t+1,p,len);
     237          26 :      continue;
     238             :       }
     239             : 
     240             :       /* Remove './'. If OOODMAKEMODE is set do this only if it is not at
     241             :        * the start of the path. */
     242     1334113 :       if ( p-q == 1 && *q == '.' && (q != path || !STOBOOL(OOoDmMode)) ) {
     243          54 :      len = strlen(p+1)+1;
     244          54 :      memmove(q,p+1,len);
     245          54 :      q = tpath;
     246          54 :      continue;
     247             :       }
     248             : 
     249             :       /* If two '/' are in path check/remove 'foo/../' elements. */
     250     1334059 :       t=strchr(p+1, *DirSepStr);
     251     1334059 :       if( !t ) break;
     252             : 
     253             :       /* Collaps this only if foo is neither '.' nor '..'. */
     254     1223204 :       switch( p-q ) {
     255             :      case 2:
     256      177472 :         delentry = !((q[0] == '.') && (q[1] == '.'));
     257      177472 :         break;
     258             :      case 1:
     259         302 :         delentry = !(q[0] == '.');
     260         302 :         break;
     261             :      default:
     262     1045430 :         delentry = TRUE;
     263     1045430 :         break;
     264             :       }
     265             : 
     266     1223204 :       if ( delentry
     267     1048186 :        && (t-p-1 == 2 && strncmp(p+1,"..",2) == 0) ) {
     268             :      /* Skip one (or possible more) DirSepStr. */
     269             :      do {
     270       60790 :         t++;
     271             :      }
     272       60790 :      while( *t == *DirSepStr);
     273             :      /* q points to first letter of the current directory/file. */
     274       60790 :      len = strlen(t)+1;
     275       60790 :      memmove(q,t,len);
     276       60790 :      q = tpath;
     277             :       }
     278             :       else
     279     1162414 :      q = p+1;
     280             :    }
     281             : 
     282             :    DB_PRINT( "path", ("Cleaned path: %s", path ));
     283             : 
     284      152263 :    DB_VOID_RETURN;
     285             : }
     286             : 
     287             : 
     288             : char *
     289      126972 : normalize_path(path)/*
     290             : =======================
     291             :    Normalize the given path unless it contains a $ indicating a dynamic
     292             :    prerequisite.
     293             :    Special case: For absolute DOSish paths under cygwin a cygwin API
     294             :    function is used to normalize the path optherwise Clean_path() is used.
     295             : 
     296             :    Note, the returned path is built in a static buffer, if it is to be used
     297             :    later a copy should be created. */
     298             : 
     299             : char *path;
     300             : {
     301             :    static char *cpath = NIL(char);
     302             : 
     303             :    DB_ENTER( "normalize_path" );
     304             : 
     305      126972 :    if ( !cpath && ( (cpath = MALLOC( PATH_MAX, char)) == NIL(char) ) )
     306           0 :       No_ram();
     307             : 
     308             :    /* If there is a $ in the path this can either mean a '$' character in
     309             :     * a target definition or a dynamic macro expression in a prerequisite
     310             :     * list. As dynamic macro expression must not be normalized and is
     311             :     * indistinguishable from a literal $ characters at this point we skip
     312             :     * the normalization if a $ is found.  */
     313      126972 :    if( strchr(path, '$') ) {
     314       18962 :       DB_RETURN( path );
     315             :    }
     316             : 
     317             : #if __CYGWIN__
     318             :    /* Use cygwin function to convert a DOS path to a POSIX path. */
     319             :    if( *path && path[1] == ':' && isalpha(*path) ) {
     320             :       int err = cygwin_conv_to_posix_path(path, cpath);
     321             :       if (err)
     322             :      Fatal( "error converting \"%s\" - %s\n",
     323             :         path, strerror (errno));
     324             :       if( path[2] != '/' && path[2] != '\\' )
     325             :      Warning("Malformed DOS path %s converted to %s", path, cpath);
     326             :    }
     327             :    else
     328             : #endif
     329             :    {
     330      108010 :       strcpy( cpath, path );
     331      108010 :       Clean_path( cpath );
     332             :    }
     333             : 
     334             :    DB_PRINT( "path", ("normalized: %s", cpath ));
     335             : 
     336      108010 :    DB_RETURN( cpath );
     337             : }

Generated by: LCOV version 1.10