MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
conf_to_src.c
1 /* Copyright (c) 2000, 2011, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 #include <my_global.h>
17 #include <m_string.h>
18 #include <m_ctype.h>
19 #include <fcntl.h>
20 #include <my_xml.h>
21 
22 #define ROW_LEN 16
23 #define ROW16_LEN 8
24 #define MAX_BUF 64*1024
25 
26 static CHARSET_INFO all_charsets[512];
27 
28 
29 void
30 print_array(FILE *f, const char *set, const char *name, uchar *a, int n)
31 {
32  int i;
33 
34  fprintf(f,"uchar %s_%s[] = {\n", name, set);
35 
36  for (i=0 ;i<n ; i++)
37  {
38  fprintf(f,"0x%02X",a[i]);
39  fprintf(f, (i+1<n) ? "," :"" );
40  fprintf(f, ((i+1) % ROW_LEN == n % ROW_LEN) ? "\n" : "" );
41  }
42  fprintf(f,"};\n\n");
43 }
44 
45 
46 void
47 print_array16(FILE *f, const char *set, const char *name, uint16 *a, int n)
48 {
49  int i;
50 
51  fprintf(f,"uint16 %s_%s[] = {\n", name, set);
52 
53  for (i=0 ;i<n ; i++)
54  {
55  fprintf(f,"0x%04X",a[i]);
56  fprintf(f, (i+1<n) ? "," :"" );
57  fprintf(f, ((i+1) % ROW16_LEN == n % ROW16_LEN) ? "\n" : "" );
58  }
59  fprintf(f,"};\n\n");
60 }
61 
62 
63 static int get_charset_number(const char *charset_name)
64 {
65  CHARSET_INFO *cs;
66  for (cs= all_charsets;
67  cs < all_charsets + array_elements(all_charsets);
68  cs++)
69  {
70  if ( cs->name && !strcmp(cs->name, charset_name))
71  return cs->number;
72  }
73  return 0;
74 }
75 
76 char *mdup(const char *src, uint len)
77 {
78  char *dst=(char*)malloc(len);
79  if (!dst)
80  exit(1);
81  memcpy(dst,src,len);
82  return dst;
83 }
84 
85 static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
86 {
87  to->number= from->number ? from->number : to->number;
88  to->state|= from->state;
89 
90  if (from->csname)
91  to->csname= strdup(from->csname);
92 
93  if (from->name)
94  to->name= strdup(from->name);
95 
96  if (from->ctype)
97  to->ctype= (uchar*) mdup((char*) from->ctype, MY_CS_CTYPE_TABLE_SIZE);
98  if (from->to_lower)
99  to->to_lower= (uchar*) mdup((char*) from->to_lower, MY_CS_TO_LOWER_TABLE_SIZE);
100  if (from->to_upper)
101  to->to_upper= (uchar*) mdup((char*) from->to_upper, MY_CS_TO_UPPER_TABLE_SIZE);
102  if (from->sort_order)
103  {
104  to->sort_order= (uchar*) mdup((char*) from->sort_order, MY_CS_SORT_ORDER_TABLE_SIZE);
105  /*
106  set_max_sort_char(to);
107  */
108  }
109  if (from->tab_to_uni)
110  {
111  uint sz= MY_CS_TO_UNI_TABLE_SIZE*sizeof(uint16);
112  to->tab_to_uni= (uint16*) mdup((char*)from->tab_to_uni, sz);
113  /*
114  create_fromuni(to);
115  */
116  }
117 }
118 
119 static my_bool simple_cs_is_full(CHARSET_INFO *cs)
120 {
121  return ((cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper &&
122  cs->to_lower) &&
123  (cs->number && cs->name &&
124  (cs->sort_order || (cs->state & MY_CS_BINSORT))));
125 }
126 
127 static int add_collation(CHARSET_INFO *cs)
128 {
129  if (cs->name && (cs->number || (cs->number=get_charset_number(cs->name))))
130  {
131  if (!(all_charsets[cs->number].state & MY_CS_COMPILED))
132  {
133  simple_cs_copy_data(&all_charsets[cs->number],cs);
134 
135  }
136 
137  cs->number= 0;
138  cs->name= NULL;
139  cs->state= 0;
140  cs->sort_order= NULL;
141  cs->state= 0;
142  }
143  return MY_XML_OK;
144 }
145 
146 
147 static void
148 default_reporter(enum loglevel level __attribute__ ((unused)),
149  const char *format __attribute__ ((unused)),
150  ...)
151 {
152 }
153 
154 
155 static void
156 my_charset_loader_init(MY_CHARSET_LOADER *loader)
157 {
158  loader->error[0]= '\0';
159  loader->once_alloc= malloc;
160  loader->malloc= malloc;
161  loader->realloc= realloc;
162  loader->free= free;
163  loader->reporter= default_reporter;
164  loader->add_collation= add_collation;
165 }
166 
167 
168 static int my_read_charset_file(const char *filename)
169 {
170  char buf[MAX_BUF];
171  int fd;
172  uint len;
173  MY_CHARSET_LOADER loader;
174 
175  my_charset_loader_init(&loader);
176  if ((fd=open(filename,O_RDONLY)) < 0)
177  {
178  fprintf(stderr,"Can't open '%s'\n",filename);
179  return 1;
180  }
181 
182  len=read(fd,buf,MAX_BUF);
183  DBUG_ASSERT(len < MAX_BUF);
184  close(fd);
185 
186  if (my_parse_charset_xml(&loader, buf, len))
187  {
188  fprintf(stderr, "Error while parsing '%s': %s\n", filename, loader.error);
189  exit(1);
190  }
191 
192  return FALSE;
193 }
194 
195 static int
196 is_case_sensitive(CHARSET_INFO *cs)
197 {
198  return (cs->sort_order &&
199  cs->sort_order['A'] < cs->sort_order['a'] &&
200  cs->sort_order['a'] < cs->sort_order['B']) ? 1 : 0;
201 }
202 
203 
204 void dispcset(FILE *f,CHARSET_INFO *cs)
205 {
206  fprintf(f,"{\n");
207  fprintf(f," %d,%d,%d,\n",cs->number,0,0);
208  fprintf(f," MY_CS_COMPILED%s%s%s%s%s,\n",
209  cs->state & MY_CS_BINSORT ? "|MY_CS_BINSORT" : "",
210  cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : "",
211  is_case_sensitive(cs) ? "|MY_CS_CSSORT" : "",
212  my_charset_is_8bit_pure_ascii(cs) ? "|MY_CS_PUREASCII" : "",
213  !my_charset_is_ascii_compatible(cs) ? "|MY_CS_NONASCII": "");
214 
215  if (cs->name)
216  {
217  fprintf(f," \"%s\", /* cset name */\n",cs->csname);
218  fprintf(f," \"%s\", /* coll name */\n",cs->name);
219  fprintf(f," \"\", /* comment */\n");
220  fprintf(f," NULL, /* tailoring */\n");
221  fprintf(f," ctype_%s, /* ctype */\n",cs->name);
222  fprintf(f," to_lower_%s, /* lower */\n",cs->name);
223  fprintf(f," to_upper_%s, /* upper */\n",cs->name);
224  if (cs->sort_order)
225  fprintf(f," sort_order_%s, /* sort_order */\n",cs->name);
226  else
227  fprintf(f," NULL, /* sort_order */\n");
228  fprintf(f," NULL, /* uca */\n");
229  fprintf(f," to_uni_%s, /* to_uni */\n",cs->name);
230  }
231  else
232  {
233  fprintf(f," NULL, /* cset name */\n");
234  fprintf(f," NULL, /* coll name */\n");
235  fprintf(f," NULL, /* comment */\n");
236  fprintf(f," NULL, /* tailoging */\n");
237  fprintf(f," NULL, /* ctype */\n");
238  fprintf(f," NULL, /* lower */\n");
239  fprintf(f," NULL, /* upper */\n");
240  fprintf(f," NULL, /* sort order */\n");
241  fprintf(f," NULL, /* uca */\n");
242  fprintf(f," NULL, /* to_uni */\n");
243  }
244 
245  fprintf(f," NULL, /* from_uni */\n");
246  fprintf(f," &my_unicase_default, /* caseinfo */\n");
247  fprintf(f," NULL, /* state map */\n");
248  fprintf(f," NULL, /* ident map */\n");
249  fprintf(f," 1, /* strxfrm_multiply*/\n");
250  fprintf(f," 1, /* caseup_multiply*/\n");
251  fprintf(f," 1, /* casedn_multiply*/\n");
252  fprintf(f," 1, /* mbminlen */\n");
253  fprintf(f," 1, /* mbmaxlen */\n");
254  fprintf(f," 0, /* min_sort_char */\n");
255  fprintf(f," 255, /* max_sort_char */\n");
256  fprintf(f," ' ', /* pad_char */\n");
257  fprintf(f," 0, /* escape_with_backslash_is_dangerous */\n");
258  fprintf(f," 1, /* levels_for_compare */\n");
259  fprintf(f," 1, /* levels_for_order */\n");
260 
261  fprintf(f," &my_charset_8bit_handler,\n");
262  if (cs->state & MY_CS_BINSORT)
263  fprintf(f," &my_collation_8bit_bin_handler,\n");
264  else
265  fprintf(f," &my_collation_8bit_simple_ci_handler,\n");
266  fprintf(f,"}\n");
267 }
268 
269 
270 static void
271 fprint_copyright(FILE *file)
272 {
273  fprintf(file,
274 "/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.\n"
275 "\n"
276 " This program is free software; you can redistribute it and/or modify\n"
277 " it under the terms of the GNU General Public License as published by\n"
278 " the Free Software Foundation; version 2 of the License.\n"
279 "\n"
280 " This program is distributed in the hope that it will be useful,\n"
281 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
282 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
283 " GNU General Public License for more details.\n"
284 "\n"
285 " You should have received a copy of the GNU General Public License\n"
286 " along with this program; if not, write to the Free Software\n"
287 " Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */\n"
288 "\n");
289 }
290 
291 
292 int
293 main(int argc, char **argv __attribute__((unused)))
294 {
295  CHARSET_INFO ncs;
296  CHARSET_INFO *cs;
297  char filename[256];
298  FILE *f= stdout;
299 
300  if (argc < 2)
301  {
302  fprintf(stderr, "usage: %s source-dir\n", argv[0]);
303  exit(EXIT_FAILURE);
304  }
305 
306  memset(&ncs, 0, sizeof(ncs));
307  memset(&all_charsets, 0, sizeof(all_charsets));
308 
309  sprintf(filename,"%s/%s",argv[1],"Index.xml");
310  my_read_charset_file(filename);
311 
312  for (cs= all_charsets;
313  cs < all_charsets + array_elements(all_charsets);
314  cs++)
315  {
316  if (cs->number && !(cs->state & MY_CS_COMPILED))
317  {
318  if ( (!simple_cs_is_full(cs)) && (cs->csname))
319  {
320  sprintf(filename,"%s/%s.xml",argv[1],cs->csname);
321  my_read_charset_file(filename);
322  }
323  }
324  }
325 
326  fprintf(f, "/*\n");
327  fprintf(f, " This file was generated by the conf_to_src utility. "
328  "Do not edit it directly,\n");
329  fprintf(f, " edit the XML definitions in sql/share/charsets/ instead.\n\n");
330  fprintf(f, " To re-generate, run the following in the strings/ "
331  "directory:\n");
332  fprintf(f, " ./conf_to_src ../sql/share/charsets/ > FILE\n");
333  fprintf(f, "*/\n\n");
334  fprint_copyright(f);
335  fprintf(f,"#include <my_global.h>\n");
336  fprintf(f,"#include <m_ctype.h>\n\n");
337 
338 
339  for (cs= all_charsets;
340  cs < all_charsets + array_elements(all_charsets);
341  cs++)
342  {
343  if (simple_cs_is_full(cs))
344  {
345  fprintf(f,"#ifdef HAVE_CHARSET_%s\n",cs->csname);
346  print_array(f, cs->name, "ctype", cs->ctype, MY_CS_CTYPE_TABLE_SIZE);
347  print_array(f, cs->name, "to_lower", cs->to_lower, MY_CS_TO_LOWER_TABLE_SIZE);
348  print_array(f, cs->name, "to_upper", cs->to_upper, MY_CS_TO_UPPER_TABLE_SIZE);
349  if (cs->sort_order)
350  print_array(f, cs->name, "sort_order", cs->sort_order, MY_CS_SORT_ORDER_TABLE_SIZE);
351  print_array16(f, cs->name, "to_uni", cs->tab_to_uni, MY_CS_TO_UNI_TABLE_SIZE);
352  fprintf(f,"#endif\n");
353  fprintf(f,"\n");
354  }
355  }
356 
357  fprintf(f,"CHARSET_INFO compiled_charsets[] = {\n");
358  for (cs= all_charsets;
359  cs < all_charsets + array_elements(all_charsets);
360  cs++)
361  {
362  if (simple_cs_is_full(cs))
363  {
364  fprintf(f,"#ifdef HAVE_CHARSET_%s\n",cs->csname);
365  dispcset(f,cs);
366  fprintf(f,",\n");
367  fprintf(f,"#endif\n");
368  }
369  }
370 
371  dispcset(f,&ncs);
372  fprintf(f,"};\n");
373 
374  return 0;
375 }