MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mf_format.c
1 /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include "mysys_priv.h"
17 #include <m_string.h>
18 
19 /*
20  Formats a filename with possible replace of directory of extension
21  Function can handle the case where 'to' == 'name'
22  For a description of the flag values, consult my_sys.h
23  The arguments should be in unix format.
24 */
25 
26 char * fn_format(char * to, const char *name, const char *dir,
27  const char *extension, uint flag)
28 {
29  char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos;
30  const char *ext;
31  reg1 size_t length;
32  size_t dev_length;
33  my_bool not_used;
34  DBUG_ENTER("fn_format");
35  DBUG_ASSERT(name != NULL);
36  DBUG_ASSERT(extension != NULL);
37  DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d",
38  name,dir,extension,flag));
39 
40  /* Copy and skip directory */
41  name+=(length=dirname_part(dev, (startpos=(char *) name), &dev_length));
42  if (length == 0 || (flag & MY_REPLACE_DIR))
43  {
44  DBUG_ASSERT(dir != NULL);
45  /* Use given directory */
46  convert_dirname(dev,dir,NullS); /* Fix to this OS */
47  }
48  else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(dev))
49  {
50  DBUG_ASSERT(dir != NULL);
51  /* Put 'dir' before the given path */
52  strmake(buff,dev,sizeof(buff)-1);
53  pos=convert_dirname(dev,dir,NullS);
54  strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev));
55  }
56 
57  if (flag & MY_PACK_FILENAME)
58  pack_dirname(dev,dev); /* Put in ./.. and ~/.. */
59  if (flag & MY_UNPACK_FILENAME)
60  (void) unpack_dirname(dev, dev, &not_used); /* Replace ~/.. with dir */
61 
62  if (!(flag & MY_APPEND_EXT) &&
63  (pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
64  {
65  if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */
66  {
67  length=strlength(name); /* Use old extension */
68  ext = "";
69  }
70  else
71  {
72  length= (size_t) (pos-(char*) name); /* Change extension */
73  ext= extension;
74  }
75  }
76  else
77  {
78  length=strlength(name); /* No ext, use the now one */
79  ext=extension;
80  }
81 
82  if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
83  {
84  /* To long path, return original or NULL */
85  size_t tmp_length;
86  if (flag & MY_SAFE_PATH)
87  DBUG_RETURN(NullS);
88  tmp_length= strlength(startpos);
89  DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
90  (uint) length));
91  (void) strmake(to, startpos, MY_MIN(tmp_length, FN_REFLEN-1));
92  }
93  else
94  {
95  if (to == startpos)
96  {
97  bmove(buff,(uchar*) name,length); /* Save name for last copy */
98  name=buff;
99  }
100  pos=strmake(strmov(to,dev),name,length);
101  (void) strmov(pos,ext); /* Don't convert extension */
102  }
103  /*
104  If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do
105  realpath if the file is a symbolic link
106  */
107  if (flag & MY_RETURN_REAL_PATH)
108  (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ?
109  MY_RESOLVE_LINK: 0));
110  else if (flag & MY_RESOLVE_SYMLINKS)
111  {
112  strmov(buff,to);
113  (void) my_readlink(to, buff, MYF(0));
114  }
115  DBUG_RETURN(to);
116 } /* fn_format */
117 
118 
119 /*
120  strlength(const string str)
121  Return length of string with end-space:s not counted.
122 */
123 
124 size_t strlength(const char *str)
125 {
126  reg1 const char * pos;
127  reg2 const char * found;
128  DBUG_ENTER("strlength");
129 
130  pos= found= str;
131 
132  while (*pos)
133  {
134  if (*pos != ' ')
135  {
136  while (*++pos && *pos != ' ') {};
137  if (!*pos)
138  {
139  found=pos; /* String ends here */
140  break;
141  }
142  }
143  found=pos;
144  while (*++pos == ' ') {};
145  }
146  DBUG_RETURN((size_t) (found - str));
147 } /* strlength */