PIPS
entity_names.c
Go to the documentation of this file.
1 /*
2 
3  $Id:naming.c$
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #include "genC.h"
29 #include "misc.h"
30 #include "naming.h"
31 
32 /* The names of PIPS entities carry information about their nature. A
33  * lot of string-based functions are used to know what an entity is
34  * according to its name.
35  *
36  * The purpose of this file (library?) is to keep together these basic
37  * string functions for entity names, with no dependence on ri.newgen.
38  *
39  * Different kinds of names:
40  * - module name
41  * - compilation unit name: "file!"
42  * - static module name: "file!foo"
43  *
44  * At execution time, this encoding leads to over using string
45  * functions. This was studied by HPC Project and Beatrice
46  * Creusillet. She suggested to add a new field to entities, which
47  * would carry this information.
48  */
49 
50 /* Check if the given name is a compilation unit internal name.
51  *
52  * Should be called "compilation_unit_name_p()" to avoid ambiguity about
53  * the argument.
54  */
55 
56 bool compilation_unit_p(const char* module_name) {
57  /* A module name is a compilation unit if and only if its last character is
58  FILE_SEP */
59  unsigned int len = strlen(module_name);
60  if (len > 0) {
61  if (module_name[len - 1] == FILE_SEP) {
62  return true;
63  }
64  }
65  return false;
66 }
67 
68 /* Check if the given name is the name of a plain module and not of a
69  * compilation unit.
70  *
71  * Argument "name" is supposed to be an internal name.
72  */
73 bool module_name_p(string name) {
74  return (!compilation_unit_p(name) && strstr(name, MODULE_SEP_STRING) == NULL);
75 }
76 
77 /* Argument "name" is a global name
78  *
79  * In C, the main module is always called "main".
80  *
81  * In Fortran, the main module can have any declared name and a
82  * special prefix is used.
83  *
84  * In both cases, they are part of TOP-LEVEL
85  */
86 bool main_module_global_name_p(const char * name)
87 {
88  bool main_p = false;
89  /* Look for a C main name */
91  if(!main_p) {
92  /* Look for a Fortran main */
94  main_p = strncmp(prefix, name, strlen(prefix)) == 0;
95  }
96  return main_p;
97 }
98 
99 /* Argument "name" is a local name (not a user name)
100  *
101  * In C, the main module is always called "main".
102  *
103  * In Fortran, the main module can have any declared name and a
104  * special prefix is used.
105  *
106  * In both cases, they are part of TOP-LEVEL
107  */
108 bool main_module_name_p(const char * name)
109 {
110  bool main_p = false;
111  /* Look for a C main name */
112  main_p = same_string_p(name, "main");
113  if(!main_p) {
114  /* Look for a Fortran main */
115  main_p = name[0]==MAIN_PREFIX_CHAR;
116  }
117  return main_p;
118 }
119 
120 /* Check if the given name is a static module name.
121  */
122 bool static_module_name_p(const char* name)
123 {
124  /* An entity is a static module if its name contains the FILE_SEP_STRING
125  but the last one is not the last character of the name string */
126  /* FI: I doubt this is true. Maybe if you're sure name is the name of a module? */
127  return (!compilation_unit_p(name) && strstr(name, FILE_SEP_STRING) != NULL);
128 }
129 /* functions on strings for entity names */
130 
131 /* BEGIN_EOLE */ /* - please do not remove this line */
132 /* Lines between BEGIN_EOLE and END_EOLE tags are automatically included
133  in the EOLE project (JZ - 11/98) */
134 
135 /* Does take care of block scopes */
136 const char* global_name_to_user_name(const char* global_name)
137 {
138  const char* user_name = string_undefined;
139  char lc = global_name[strlen(global_name)-1];
140  const char* p;
141 
142  /* First, take care of constrant strings and characters, wich may
143  contain any of the PIPS special characters and strings.
144  And do not forget Fortran format */
145 
146  if(lc=='"' || lc=='\'') {
147  user_name = strchr(global_name, lc);
148  }
149  else if(lc==')') {
150  user_name = strchr(global_name, '(');
151  }
152  else {
153 
154  /* Then all possible prefixes first */
155 
156  if (strstr(global_name,STRUCT_PREFIX) != NULL)
157  user_name = strstr(global_name,STRUCT_PREFIX) + 1;
158  else if (strstr(global_name,UNION_PREFIX) != NULL) {
159  user_name = strstr(global_name,UNION_PREFIX) + 1;
160  }
161  else if (strstr(global_name,ENUM_PREFIX) != NULL)
162  user_name = strstr(global_name,ENUM_PREFIX) + 1;
163  else if (strstr(global_name,TYPEDEF_PREFIX) != NULL)
164  user_name = strstr(global_name,TYPEDEF_PREFIX) + 1;
165 
166  else if (strstr(global_name,MEMBER_SEP_STRING) != NULL)
167  user_name = strstr(global_name,MEMBER_SEP_STRING) + 1;
168 
169  else if (strstr(global_name,LABEL_PREFIX) != NULL)
170  user_name = strstr(global_name,LABEL_PREFIX) + 1;
171  else if (strstr(global_name,COMMON_PREFIX) != NULL)
172  user_name = strstr(global_name,COMMON_PREFIX) + 1;
173  else if (strstr(global_name,BLOCKDATA_PREFIX) != NULL) {
174  /* Clash with the address-of C operator */
175  user_name = strstr(global_name,BLOCKDATA_PREFIX)+1;
176  //string s = strstr(global_name,BLOCKDATA_PREFIX);
177  //
178  //if(strlen(s)>1)
179  // user_name = s + 1);
180  //else
181  //user_name = s;
182  }
183  else if (strstr(global_name,MAIN_PREFIX) != NULL) {
184  string s = strstr(global_name,MAIN_PREFIX) + 1;
185  pips_debug(8, "name = %s \n", s);
186  user_name = s;
187  }
188  /* Then F95 module separator */
189  else if (strstr(global_name,F95MODULE_PREFIX) != NULL)
190  user_name = strstr(global_name,F95MODULE_PREFIX) + 1;
191 
192  /* Then block seperators */
193  else if (strstr(global_name,BLOCK_SEP_STRING) != NULL)
194  user_name = strrchr(global_name,BLOCK_SEP_CHAR) + 1;
195 
196  /* Then module separator */
197  else if (strstr(global_name,MODULE_SEP_STRING) != NULL)
198  user_name = strstr(global_name,MODULE_SEP_STRING) + 1;
199 
200 
201  /* Then file separator */
202  else if (strstr(global_name,FILE_SEP_STRING) != NULL)
203  user_name = strstr(global_name,FILE_SEP_STRING) + 1;
204  else {
205  pips_internal_error("no seperator ?");
206  user_name = NULL;
207  }
208 
209  /* Take care of the special case of static functions, leaving
210  compilation unit names untouched */
211  if ((p=strstr(user_name,FILE_SEP_STRING)) != NULL && *(p+1)!='\0')
212  user_name = p + 1;
213  }
214 
215  pips_debug(9, "global name = \"%s\", user_name = \"%s\"\n",
216  global_name, user_name);
217  return user_name;
218 }
219 
220 /* Does not take care of block scopes and returns a pointer */
221 const char* local_name(const char * s)
222 {
223  char *start_ptr = strchr(s, MODULE_SEP);
224  pips_assert("some separator", start_ptr != NULL);
225  return start_ptr+1;
226 }
227 
228 /* END_EOLE */
229 
230 string make_entity_fullname(const char* module_name, const char* local_name)
231 {
232  return(concatenate(module_name,
234  local_name,
235  (char *) 0));
236 }
237 
238 //empty_local_label_name_p(s)
239 bool empty_string_p(const char* s)
240 {
241  return(strcmp(s, "") == 0);
242 }
243 
244 
245 bool blank_string_p(const char*s ){
246  extern int isspace(int);
247  while(*s&&isspace(*s++));
248  return !*s;
249 }
250 
251 bool return_local_label_name_p(const char* s)
252 {
253  return(strcmp(s, RETURN_LABEL_NAME) == 0);
254 }
255 
256 bool empty_label_p(const char* s)
257 {
258  // s must be a local label name
259  pips_assert("no separator", strchr(s, MODULE_SEP) == NULL);
260  // return(empty_local_label_name_p(local_name(s)+sizeof(LABEL_PREFIX)-1)) ;
261  return (strcmp(s, EMPTY_LABEL_NAME) == 0);
262 }
263 
264 bool empty_global_label_p(const char* gln)
265 {
266  // gln must be a global label name
267  const char* lln = local_name(gln);
268 
269  return empty_label_p(lln);
270 }
271 
272 bool return_label_p(const char* s)
273 {
274  return(return_local_label_name_p(local_name(s)+sizeof(LABEL_PREFIX)-1)) ;
275 }
276 
277 /* Return the module part of an entity name.
278  *
279  * OK, this function name is pretty misleading: entity_name_to_entity_module_name().
280  *
281  * Maybe, it should be wrapped up in a higher-level function such as
282  * entity_to_module_name().
283  *
284  * It uses a static buffer and should create trouble with long
285  * function names.
286  *
287  * No memory allocation is performed, but it's result is transient. It
288  * must be strdup'ed by the caller if it is to be preserved.
289  *
290  * To eliminate the static buffer and to allocate the returned string
291  * would require lots of changes or add lots of memory leaks in PIPS
292  * since the callers do not know they must free the result. Maybe we
293  * should stack allocate a buffer of size strlen(s), but we would end
294  * up returning a pointer to a popped area of the stack...
295  */
296 const char* module_name(const char * s)
297 {
298  static char *local = NULL;
299  static size_t local_size = 0;
300 
301  char * sep = strchr(s, MODULE_SEP);
302  size_t len = sep? (size_t) (sep-s): strlen(s);
303 
304  if (local_size < len + 1)
305  {
306  if (local) free(local);
307  local_size = len + 1 > 100? len + 1: 100;
308  local = malloc(local_size);
309  }
310 
311  strncpy(local, s, len);
312  local[len] = '\0';
313 
314  return local;
315 }
316 
317 /*
318  * that is all
319  */
bool blank_string_p(const char *s)
Definition: entity_names.c:245
bool static_module_name_p(const char *name)
Check if the given name is a static module name.
Definition: entity_names.c:122
bool return_local_label_name_p(const char *s)
Definition: entity_names.c:251
bool main_module_global_name_p(const char *name)
Argument "name" is a global name.
Definition: entity_names.c:86
bool return_label_p(const char *s)
Definition: entity_names.c:272
const char * global_name_to_user_name(const char *global_name)
functions on strings for entity names
Definition: entity_names.c:136
bool empty_label_p(const char *s)
Definition: entity_names.c:256
string make_entity_fullname(const char *module_name, const char *local_name)
END_EOLE.
Definition: entity_names.c:230
bool empty_global_label_p(const char *gln)
Definition: entity_names.c:264
bool compilation_unit_p(const char *module_name)
The names of PIPS entities carry information about their nature.
Definition: entity_names.c:56
bool empty_string_p(const char *s)
Definition: entity_names.c:239
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
bool module_name_p(string name)
Check if the given name is the name of a plain module and not of a compilation unit.
Definition: entity_names.c:73
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool main_module_name_p(const char *name)
Argument "name" is a local name (not a user name)
Definition: entity_names.c:108
void * malloc(YYSIZE_T)
void free(void *)
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define COMMON_PREFIX
Definition: naming-local.h:34
#define LABEL_PREFIX
Definition: naming-local.h:31
#define BLOCK_SEP_CHAR
Definition: naming-local.h:51
#define RETURN_LABEL_NAME
Definition: naming-local.h:106
#define F95MODULE_PREFIX
Definition: naming-local.h:36
#define MODULE_SEP
special characters to build entity names of various kinds
Definition: naming-local.h:27
#define FILE_SEP_STRING
Definition: naming-local.h:41
#define TYPEDEF_PREFIX
Definition: naming-local.h:62
#define MAIN_PREFIX
Definition: naming-local.h:32
#define UNION_PREFIX
Definition: naming-local.h:58
#define EMPTY_LABEL_NAME
Its value is "@", the label prefix followed by nothing.
Definition: naming-local.h:96
#define ENUM_PREFIX
Definition: naming-local.h:60
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define FILE_SEP
Definition: naming-local.h:39
#define BLOCKDATA_PREFIX
Definition: naming-local.h:35
#define MODULE_SEP_STRING
Definition: naming-local.h:30
#define MEMBER_SEP_STRING
Definition: naming-local.h:53
#define STRUCT_PREFIX
Definition: naming-local.h:56
#define BLOCK_SEP_STRING
Scope separator.
Definition: naming-local.h:50
#define MAIN_PREFIX_CHAR
Definition: naming-local.h:33
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
#define string_undefined
Definition: newgen_types.h:40
size_t size_t
Definition: properties.c:413
static const char * prefix