~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"
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
17
#include <mystrings/m_string.h>
1 by brian
clean slate
18
19
	/* Functions definied in this file */
20
21
size_t dirname_length(const char *name)
22
{
266.6.6 by Andy Lester
fixing some constants
23
  register const char *pos, *gpos;
1 by brian
clean slate
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
266.7.7 by Andy Lester
const happiness
30
    pos=name-1;
1 by brian
clean slate
31
32
  gpos= pos++;
33
  for ( ; *pos ; pos++)				/* Find last FN_LIBCHAR */
34
  {
35
#ifdef BASKSLASH_MBTAIL
482 by Brian Aker
Remove uint.
36
    uint32_t l;
1 by brian
clean slate
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
  }
266.7.7 by Andy Lester
const happiness
50
  return gpos-name+1;
1 by brian
clean slate
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
71
  length=dirname_length(name);
72
  *to_res_length= (size_t) (convert_dirname(to, name, name+length) - to);
51.3.17 by Jay Pipes
Phase 4 - Remove DBUG from mysys
73
  return(length);
1 by brian
clean slate
74
} /* dirname */
75
76
77
/*
78
  Convert directory name to use under this system
79
80
  SYNPOSIS
81
    convert_dirname()
82
    to				Store result here. Must be at least of size
398.1.4 by Monty Taylor
Renamed max/min.
83
    				cmin(FN_REFLEN, strlen(from) + 1) to make room
1 by brian
clean slate
84
    				for adding FN_LIBCHAR at the end.
85
    from			Original filename. May be == to
86
    from_end			Pointer at end of filename (normally end \0)
87
88
  IMPLEMENTATION
89
    If MSDOS converts '/' to '\'
90
    If VMS converts '<' to '[' and '>' to ']'
91
    Adds a FN_LIBCHAR to end if the result string if there isn't one
92
    and the last isn't dev_char.
93
    Copies data from 'from' until ASCII(0) for until from == from_end
461 by Monty Taylor
Removed NullS. bu-bye.
94
    If you want to use the whole 'from' string, just send NULL as the
1 by brian
clean slate
95
    last argument.
96
97
    If the result string is larger than FN_REFLEN -1, then it's cut.
98
99
  RETURN
100
   Returns pointer to end \0 in to
101
*/
102
103
#ifndef FN_DEVCHAR
104
#define FN_DEVCHAR '\0'				/* For easier code */
105
#endif
106
107
char *convert_dirname(char *to, const char *from, const char *from_end)
108
{
109
  char *to_org=to;
110
#ifdef BACKSLASH_MBTAIL
111
  CHARSET_INFO *fs= fs_character_set();
112
#endif
113
114
  /* We use -2 here, becasue we need place for the last FN_LIBCHAR */
115
  if (!from_end || (from_end - from) > FN_REFLEN-2)
116
    from_end=from+FN_REFLEN -2;
117
118
#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
119
  {
120
    for (; from != from_end && *from ; from++)
121
    {
122
      if (*from == '/')
123
	*to++= FN_LIBCHAR;
124
#ifdef FN_C_BEFORE_DIR_2
125
      else if (*from == FN_C_BEFORE_DIR_2)
126
	*to++= FN_C_BEFORE_DIR;
127
      else if (*from == FN_C_AFTER_DIR_2)
128
	*to++= FN_C_AFTER_DIR;
129
#endif
130
      else
131
      {
132
#ifdef BACKSLASH_MBTAIL
482 by Brian Aker
Remove uint.
133
        uint32_t l;
1 by brian
clean slate
134
        if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3)))
135
        {
136
          memmove(to, from, l);
137
          to+= l;
138
          from+= l - 1;
139
          to_org= to; /* Don't look inside mbchar */
140
        }
141
        else
142
#endif
143
        {
144
          *to++= *from;
145
        }
146
      }
147
    }
148
    *to=0;
149
  }
150
#else
151
  /* This is ok even if to == from, becasue we need to cut the string */
152
  to= strmake(to, from, (size_t) (from_end-from));
153
#endif
154
155
  /* Add FN_LIBCHAR to the end of directory path */
156
  if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR))
157
  {
158
    *to++=FN_LIBCHAR;
159
    *to=0;
160
  }
51.3.17 by Jay Pipes
Phase 4 - Remove DBUG from mysys
161
  return(to);                              /* Pointer to end of dir */
1 by brian
clean slate
162
} /* convert_dirname */