Drizzled Public API Documentation

mf_dirname.cc

00001 /* Copyright (C) 2000 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 #include <config.h>
00017 
00018 #include <drizzled/internal/my_sys.h>
00019 #include <drizzled/internal/m_string.h>
00020 
00021 #include <algorithm>
00022 
00023 using namespace std;
00024 
00025 namespace drizzled
00026 {
00027 namespace internal
00028 {
00029 
00030   /* Functions definied in this file */
00031 
00032 size_t dirname_length(const char *name)
00033 {
00034   const char *pos, *gpos;
00035 #ifdef FN_DEVCHAR
00036   if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0)
00037 #endif
00038     pos=name-1;
00039 
00040   gpos= pos++;
00041   for ( ; *pos ; pos++)       /* Find last FN_LIBCHAR */
00042   {
00043     if (*pos == FN_LIBCHAR || *pos == '/')
00044       gpos=pos;
00045   }
00046   return gpos-name+1;
00047 }
00048 
00049 
00050 /*
00051   Gives directory part of filename. Directory ends with '/'
00052 
00053   SYNOPSIS
00054     dirname_part()
00055     to    Store directory name here
00056     name  Original name
00057     to_length Store length of 'to' here
00058 
00059   RETURN
00060    #  Length of directory part in 'name'
00061 */
00062 
00063 size_t dirname_part(char *to, const char *name, size_t *to_res_length)
00064 {
00065   size_t length;
00066 
00067   length=dirname_length(name);
00068   *to_res_length= (size_t) (convert_dirname(to, name, name+length) - to);
00069   return(length);
00070 } /* dirname */
00071 
00072 
00073 /*
00074   Convert directory name to use under this system
00075 
00076   SYNPOSIS
00077     convert_dirname()
00078     to        Store result here. Must be at least of size
00079             min(FN_REFLEN, strlen(from) + 1) to make room
00080             for adding FN_LIBCHAR at the end.
00081     from      Original filename. May be == to
00082     from_end      Pointer at end of filename (normally end \0)
00083 
00084   IMPLEMENTATION
00085     If MSDOS converts '/' to '\'
00086     If VMS converts '<' to '[' and '>' to ']'
00087     Adds a FN_LIBCHAR to end if the result string if there isn't one
00088     and the last isn't dev_char.
00089     Copies data from 'from' until ASCII(0) for until from == from_end
00090     If you want to use the whole 'from' string, just send NULL as the
00091     last argument.
00092 
00093     If the result string is larger than FN_REFLEN -1, then it's cut.
00094 
00095   RETURN
00096    Returns pointer to end \0 in to
00097 */
00098 
00099 #ifndef FN_DEVCHAR
00100 #define FN_DEVCHAR '\0'       /* For easier code */
00101 #endif
00102 
00103 char *convert_dirname(char *to, const char *from, const char *from_end)
00104 {
00105   char *to_org=to;
00106 
00107   /* We use -2 here, becasue we need place for the last FN_LIBCHAR */
00108   if (!from_end || (from_end - from) > FN_REFLEN-2)
00109     from_end=from+FN_REFLEN -2;
00110 
00111 #if FN_LIBCHAR != '/'
00112   {
00113     for (; from != from_end && *from ; from++)
00114     {
00115       if (*from == '/')
00116   *to++= FN_LIBCHAR;
00117       else
00118       {
00119         *to++= *from;
00120       }
00121     }
00122     *to=0;
00123   }
00124 #else
00125   /* This is ok even if to == from, becasue we need to cut the string */
00126   size_t len= min(strlen(from),(size_t)(from_end-from));
00127   void *ret= memmove(to, from, len);
00128   assert(ret != NULL);
00129   to+= len;
00130   to[0]= '\0';
00131 #endif
00132 
00133   /* Add FN_LIBCHAR to the end of directory path */
00134   if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR))
00135   {
00136     *to++=FN_LIBCHAR;
00137     *to=0;
00138   }
00139   return(to);                              /* Pointer to end of dir */
00140 } /* convert_dirname */
00141 
00142 } /* namespace internal */
00143 } /* namespace drizzled */