1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
9 * C Implementation File *
11 * Copyright (C) 2001-2002, Free Software Foundation, Inc. *
13 * GNAT is free software; you can redistribute it and/or modify it under *
14 * terms of the GNU General Public License as published by the Free Soft- *
15 * ware Foundation; either version 2, or (at your option) any later ver- *
16 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
17 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
19 * for more details. You should have received a copy of the GNU General *
20 * Public License distributed with GNAT; see file COPYING. If not, write *
21 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
22 * MA 02111-1307, USA. *
24 * As a special exception, if you link this file with other files to *
25 * produce an executable, this file does not by itself cause the resulting *
26 * executable to be covered by the GNU General Public License. This except- *
27 * ion does not however invalidate any other reasons why the executable *
28 * file might be covered by the GNU Public License. *
30 * GNAT was originally developed by the GNAT team at New York University. *
31 * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
33 ****************************************************************************/
40 #define PARMS(ARGS) ARGS
44 #include "adadecode.h"
46 static void add_verbose PARAMS ((const char *, char *));
47 static int has_prefix PARAMS ((char *, const char *));
48 static int has_suffix PARAMS ((char *, const char *));
50 /* Set to nonzero if we have written any verbose info. */
51 static int verbose_info;
53 /* Add TEXT to end of ADA_NAME, putting a leading " (" or ", ", depending
56 static void add_verbose (text, ada_name)
60 strcat (ada_name, verbose_info ? ", " : " (");
61 strcat (ada_name, text);
66 /* Returns 1 if NAME starts with PREFIX. */
69 has_prefix (name, prefix)
73 return strncmp (name, prefix, strlen (prefix)) == 0;
76 /* Returns 1 if NAME ends with SUFFIX. */
79 has_suffix (name, suffix)
83 int nlen = strlen (name);
84 int slen = strlen (suffix);
86 return nlen > slen && strncmp (name + nlen - slen, suffix, slen) == 0;
89 /* This function will return the Ada name from the encoded form.
90 The Ada coding is done in exp_dbug.ads and this is the inverse function.
91 see exp_dbug.ads for full encoding rules, a short description is added
92 below. Right now only objects and routines are handled. There is no support
95 CODED_NAME is the encoded entity name.
97 ADA_NAME is a pointer to a buffer, it will receive the Ada name. A safe
98 size for this buffer is: strlen (coded_name) * 2 + 60. (60 is for the
101 VERBOSE is nonzero if more information about the entity is to be
102 added at the end of the Ada name and surrounded by ( and ).
104 Coded name Ada name verbose info
105 ---------------------------------------------------------------------
106 _ada_xyz xyz library level
108 x__yTKB x.y task body
110 x__yX x.y body nested
111 x__yXb x.y body nested
113 x__y$2 x.y overloaded
114 x__y__3 x.y overloaded
136 __gnat_decode (coded_name, ada_name, verbose)
137 const char *coded_name;
147 /* Copy the coded name into the ada name string, the rest of the code will
148 just replace or add characters into the ada_name. */
149 strcpy (ada_name, coded_name);
151 /* Check for library level subprogram. */
152 if (has_prefix (ada_name, "_ada_"))
154 strcpy (ada_name, ada_name + 5);
158 /* Check for task body. */
159 if (has_suffix (ada_name, "TKB"))
161 ada_name[strlen (ada_name) - 3] = '\0';
165 if (has_suffix (ada_name, "B"))
167 ada_name[strlen (ada_name) - 1] = '\0';
171 /* Check for body-nested entity: X[bn] */
172 if (has_suffix (ada_name, "X"))
174 ada_name[strlen (ada_name) - 1] = '\0';
178 if (has_suffix (ada_name, "Xb"))
180 ada_name[strlen (ada_name) - 2] = '\0';
184 if (has_suffix (ada_name, "Xn"))
186 ada_name[strlen (ada_name) - 2] = '\0';
190 /* Change instance of TK__ (object declared inside a task) to __. */
194 while ((tktoken = (char *) strstr (ada_name, "TK__")) != NULL)
196 strcpy (tktoken, tktoken + 2);
201 /* Check for overloading: name terminated by $nn or __nn. */
203 int len = strlen (ada_name);
207 while (isdigit ((int) ada_name[(int) len - 1 - n_digits]))
210 /* Check if we have $ or __ before digits. */
211 if (ada_name[len - 1 - n_digits] == '$')
213 ada_name[len - 1 - n_digits] = '\0';
216 else if (ada_name[len - 1 - n_digits] == '_'
217 && ada_name[len - 1 - n_digits - 1] == '_')
219 ada_name[len - 1 - n_digits - 1] = '\0';
224 /* Change all "__" to ".". */
226 int len = strlen (ada_name);
231 if (ada_name[k] == '_' && ada_name[k+1] == '_')
234 strcpy (ada_name + k + 1, ada_name + k + 2);
241 /* Checks for operator name. */
243 const char *trans_table[][2]
244 = {{"Oabs", "\"abs\""}, {"Oand", "\"and\""}, {"Omod", "\"mod\""},
245 {"Onot", "\"not\""}, {"Oor", "\"or\""}, {"Orem", "\"rem\""},
246 {"Oxor", "\"xor\""}, {"Oeq", "\"=\""}, {"One", "\"/=\""},
247 {"Olt", "\"<\""}, {"Ole", "\"<=\""}, {"Ogt", "\">\""},
248 {"Oge", "\">=\""}, {"Oadd", "\"+\""}, {"Osubtract", "\"-\""},
249 {"Oconcat", "\"&\""}, {"Omultiply", "\"*\""}, {"Odivide", "\"/\""},
250 {"Oexpon", "\"**\""}, {NULL, NULL} };
257 if ((optoken = (char *) strstr (ada_name, trans_table[k][0])) != NULL)
259 int codedlen = strlen (trans_table[k][0]);
260 int oplen = strlen (trans_table[k][1]);
262 if (codedlen > oplen)
263 /* We shrink the space. */
264 strcpy (optoken, optoken + codedlen - oplen);
265 else if (oplen > codedlen)
267 /* We need more space. */
268 int len = strlen (ada_name);
269 int space = oplen - codedlen;
270 int num_to_move = &ada_name[len] - optoken;
273 for (t = 0; t < num_to_move; t++)
274 ada_name[len + space - t - 1] = ada_name[len - t - 1];
277 /* Write symbol in the space. */
278 strncpy (optoken, trans_table[k][1], oplen);
283 /* Check for table's ending. */
284 if (trans_table[k][0] == NULL)
289 /* If verbose mode is on, we add some information to the Ada name. */
293 add_verbose ("overloaded", ada_name);
296 add_verbose ("library level", ada_name);
299 add_verbose ("body nested", ada_name);
302 add_verbose ("in task", ada_name);
305 add_verbose ("task body", ada_name);
307 if (verbose_info == 1)
308 strcat (ada_name, ")");
313 ada_demangle (coded_name)
314 const char *coded_name;
319 __gnat_decode (coded_name, ada_name, 0);
321 result = (char *) xmalloc (strlen (ada_name) + 1);
322 strcpy (result, ada_name);