~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
#include "mysys_priv.h"
17
#include <m_string.h>
18
19
	/* Functions definied in this file */
20
21
size_t dirname_length(const char *name)
22
{
23
  register char *pos, *gpos;
24
#ifdef BASKSLASH_MBTAIL
25
  CHARSET_INFO *fs= fs_character_set();
26
#endif
27
#ifdef FN_DEVCHAR
28
  if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0)
29
#endif
30
    pos=(char*) name-1;
31
32
  gpos= pos++;
33
  for ( ; *pos ; pos++)				/* Find last FN_LIBCHAR */
34
  {
35
#ifdef BASKSLASH_MBTAIL
36
    uint l;
37
    if (use_mb(fs) && (l= my_ismbchar(fs, pos, pos + 3)))
38
    {
39
      pos+= l - 1;
40
      continue;
41
    }
42
#endif
43
    if (*pos == FN_LIBCHAR || *pos == '/'
44
#ifdef FN_C_AFTER_DIR
45
	|| *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2
46
#endif
47
	)
48
      gpos=pos;
49
  }
50
  return (size_t) (gpos+1-(char*) name);
51
}
52
53
54
/*
55
  Gives directory part of filename. Directory ends with '/'
56
57
  SYNOPSIS
58
    dirname_part()
59
    to		Store directory name here
60
    name	Original name
61
    to_length	Store length of 'to' here
62
63
  RETURN
64
   #  Length of directory part in 'name'
65
*/
66
67
size_t dirname_part(char *to, const char *name, size_t *to_res_length)
68
{
69
  size_t length;
70
  DBUG_ENTER("dirname_part");
71
  DBUG_PRINT("enter",("'%s'",name));
72
73
  length=dirname_length(name);
74
  *to_res_length= (size_t) (convert_dirname(to, name, name+length) - to);
75
  DBUG_RETURN(length);
76
} /* dirname */
77
78
79
/*
80
  Convert directory name to use under this system
81
82
  SYNPOSIS
83
    convert_dirname()
84
    to				Store result here. Must be at least of size
85
    				min(FN_REFLEN, strlen(from) + 1) to make room
86
    				for adding FN_LIBCHAR at the end.
87
    from			Original filename. May be == to
88
    from_end			Pointer at end of filename (normally end \0)
89
90
  IMPLEMENTATION
91
    If MSDOS converts '/' to '\'
92
    If VMS converts '<' to '[' and '>' to ']'
93
    Adds a FN_LIBCHAR to end if the result string if there isn't one
94
    and the last isn't dev_char.
95
    Copies data from 'from' until ASCII(0) for until from == from_end
96
    If you want to use the whole 'from' string, just send NullS as the
97
    last argument.
98
99
    If the result string is larger than FN_REFLEN -1, then it's cut.
100
101
  RETURN
102
   Returns pointer to end \0 in to
103
*/
104
105
#ifndef FN_DEVCHAR
106
#define FN_DEVCHAR '\0'				/* For easier code */
107
#endif
108
109
char *convert_dirname(char *to, const char *from, const char *from_end)
110
{
111
  char *to_org=to;
112
#ifdef BACKSLASH_MBTAIL
113
  CHARSET_INFO *fs= fs_character_set();
114
#endif
115
  DBUG_ENTER("convert_dirname");
116
117
  /* We use -2 here, becasue we need place for the last FN_LIBCHAR */
118
  if (!from_end || (from_end - from) > FN_REFLEN-2)
119
    from_end=from+FN_REFLEN -2;
120
121
#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
122
  {
123
    for (; from != from_end && *from ; from++)
124
    {
125
      if (*from == '/')
126
	*to++= FN_LIBCHAR;
127
#ifdef FN_C_BEFORE_DIR_2
128
      else if (*from == FN_C_BEFORE_DIR_2)
129
	*to++= FN_C_BEFORE_DIR;
130
      else if (*from == FN_C_AFTER_DIR_2)
131
	*to++= FN_C_AFTER_DIR;
132
#endif
133
      else
134
      {
135
#ifdef BACKSLASH_MBTAIL
136
        uint l;
137
        if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3)))
138
        {
139
          memmove(to, from, l);
140
          to+= l;
141
          from+= l - 1;
142
          to_org= to; /* Don't look inside mbchar */
143
        }
144
        else
145
#endif
146
        {
147
          *to++= *from;
148
        }
149
      }
150
    }
151
    *to=0;
152
  }
153
#else
154
  /* This is ok even if to == from, becasue we need to cut the string */
155
  to= strmake(to, from, (size_t) (from_end-from));
156
#endif
157
158
  /* Add FN_LIBCHAR to the end of directory path */
159
  if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR))
160
  {
161
    *to++=FN_LIBCHAR;
162
    *to=0;
163
  }
164
  DBUG_RETURN(to);                              /* Pointer to end of dir */
165
} /* convert_dirname */