PIPS
gfc2pips-util.c
Go to the documentation of this file.
1 /*
2 
3  $Id: gfc2pips-util.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6  Copyright 2009-2010 HPC-Project
7 
8  This file is part of PIPS.
9 
10  PIPS is free software: you can redistribute it and/or modify it
11  under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  any later version.
14 
15  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
16  WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  FITNESS FOR A PARTICULAR PURPOSE.
18 
19  See the GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
23 
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "pips_config.h"
28 #endif
29 
30 #include "gfc2pips-private.h"
31 
32 #include "c_parser_private.h"
33 #include "misc.h"
34 #include "text-util.h"
35 #include <stdio.h>
36 
37 /* FIXME: should be generated...
38  */
39 
43 
44 /**
45  * @brief generate an union of unique elements taken from A and B
46  */
48  list c = NULL;
49  while(a) {
50  if(!gen_in_list_p(CHUNK( CAR( a ) ), c))
51  c = gen_cons(CHUNK( CAR( a ) ), c);
52  POP( a );
53  }
54  while(b) {
55  if(!gen_in_list_p(CHUNK( CAR( b ) ), c))
56  c = gen_cons(CHUNK( CAR( b ) ), c);
57  POP( b );
58  }
59  return c;
60 }
61 
62 
63 /**
64  * @brief Add an entity to the list of callees
65  *
66  */
68 
70  != 0) {
71  gfc2pips_debug(5, "Add callee : %s\n", entity_local_name( e ) );
73  }
74 }
75 
76 /**
77  * Here are few utility functions to handle splitted files and do comparisons
78  * with case insensitive
79  */
80 /**
81  * @brief replace lower case char by upper case ones
82  */
83 char * str2upper(char s[]) {
84 
85  // FIXME Disabled !!!
86  // return s;
87 
88  int n = 0;
89  if(s && s[n] != '\0') {
90  do {
91  s[n] = toupper(s[n]);
92  n++;
93  } while(s[n] != '\0');
94  }
95  return s;
96 }
97 /**
98  * @brief replace lower case char by upper case ones
99  */
100 char * strn2upper(char s[], size_t n) {
101  while(n) {
102  s[n - 1] = toupper(s[n - 1]);
103  n--;
104  }
105  return s;
106 }
107 /**
108  * @brief copy a string from the last char (to allow copy on itself)
109  */
110 char * strrcpy(char *dest, __const char *src) {
111  int i = strlen(src);
112  while(i--)
113  dest[i] = src[i];
114  return dest;
115 }
116 /**
117  * @brief insensitive case comparison
118  */
119 int strcmp_(__const char *__s1, __const char *__s2) {
120  char *a = str2upper(strdup(__s1));
121  char *b = str2upper(strdup(__s2));
122  int ret = strcmp(a, b);
123  free(a);
124  free(b);
125  return ret;
126 }
127 
128 /**
129  * @brief insensitive case n-comparison
130  */
131 int strncmp_(__const char *__s1, __const char *__s2, size_t __n) {
132  char *a = str2upper(strdup(__s1));
133  char *b = str2upper(strdup(__s2));
134  int ret = strncmp(a, b, __n);
135  free(a);
136  free(b);
137  return ret;
138 }
139 
140 /**
141  * @brief copy the file called *old to the file called *new
142  */
143 int fcopy(const char* old, const char* new) {
144  if(!old || !new)
145  return 0;
146  FILE * o = fopen(old, "r");
147  if(o) {
148  FILE * n = fopen(new, "w");
149  if(n) {
150  int c = fgetc(o);
151  while(c != EOF) {
152  fputc(c, n);
153  c = fgetc(o);
154  }
155  fclose(n);
156  fclose(o);
157  return 1;
158  }
159  fclose(o);
160  return 0;
161  }
162  return 0;
163 }
164 
165 /**
166  * @brief expurgates a string representing a REAL, could be a pre-prettyprinter
167  * processing
168  *
169  * 1.0000000000e+00 becomes 1.
170  * 1234.5670000e+18 becomes 1234.567e+18
171  */
173  char *start = s;
174  bool has_dot = false;
175  char *end_sci = NULL;//scientific output ?
176  while(*s) {
177  if(*s == '.') {
178  has_dot = true;
179  gfc2pips_debug(9,"found [dot] at %lu\n",s-start);
180  s++;
181  while(*s) {
182  if(*s == 'e') {
183  end_sci = s;
184  break;
185  }
186  s++;
187  }
188  break;
189  }
190  s++;
191  }
192  if(has_dot) {
193  int nb = 0;
194  if(end_sci) {
195  s = end_sci - 1;
196  } else {
197  s = start + strlen(start);
198  }
199 
200  while(s > start) {
201  if(*s == '0') {
202  *s = '\0';
203  nb++;
204  } else {
205  break;
206  }
207  s--;
208  }
209  gfc2pips_debug(9,"%d zero(s) retrieved\n", nb);
210  /*if(*s=='.'){
211  *s='\0';
212  s--;
213  gfc2pips_debug(9,"final dot retrieved\n");
214  }*/
215  if(end_sci) {
216  if(strcmp(end_sci, "e+00") == 0) {
217  *(s + 1) = '\0';
218  } else if(s != end_sci - 1) {
219  strcpy(s + 1, end_sci);
220  }
221  }
222  }
223 }
224 
226  FILE *entities =
227  (FILE *)safe_fopen((char *)gfc_option.gfc2pips_entities, "r");
228  int read = gen_read_tabulated(entities, FALSE);
229  safe_fclose(entities, (char *)gfc_option.gfc2pips_entities);
230  pips_assert("entities were read", read==entity_domain);
231 }
232 
234  FILE *entities =
235  (FILE *)safe_fopen((char *)gfc_option.gfc2pips_entities, "w");
237  safe_fclose(entities, (char *)gfc_option.gfc2pips_entities);
238 }
239 
240 void pips_init() {
241 
242  static int initialized = FALSE;
243 
244  if (!initialized)
245  {
246  // FIXME:
247  set_pips_meta_informations("<unknown>", "<unknown>", "<unknown>");
248 
249  /* get NewGen data type description */
250  // gen_read_spec(ALL_SPECS);
252  text_spec,
255  (char*)NULL);
256 
258  (void* (*)())vect_gen_read,
259  (void(*)())vect_gen_write,
260  (void(*)())vect_gen_free,
261  (void* (*)())vect_gen_copy_tree,
262  (int(*)())vect_gen_allocated_memory);
263 
264  // Pips init
265  load_entities();
266 
267  initialized = TRUE;
268  }
269 }
270 
271 /**
272  * void gfc2pips_get_use_st( void );
273  * @brief This function is called by the GFC parser when encountering a USE
274  * statement. It'll produce an entry in "ns2use" hashtable
275  *
276  */
279 
280  char c;
281  string use = "USE";
282  int len = strlen(use);
283 
284  gfc_char_t *p = gfc_current_locus.nextc;
285  // Fixme : p == NULL
286  while(!(char)*p == '\0')
287  p++;
288  char use_stmt[len + (p - gfc_current_locus.nextc) + 2];
289 
290  strcpy(use_stmt, use);
291  p = gfc_current_locus.nextc;
292  int pos = len;
293  do {
294  if(p == NULL) {
295  c = '\0';
296  } else {
297  c = *p++;
298  }
299 
300  use_stmt[pos++] = c;
301  } while(c != '\0');
302  if(ns2use == NULL) {
304  }
305  list use_stmts;
306  if((use_stmts = hash_get(ns2use, (char *)gfc_current_ns))
308  use_stmts = CONS(string, strdup(use_stmt), NIL );
309  hash_put(ns2use, (char *)gfc_current_ns, (char *)use_stmts);
310  } else {
311  CONS(string, strdup(use_stmt), use_stmts );
312  }
313 
314 }
315 
316 list get_use_entities_list(struct gfc_namespace *ns) {
317  list use_entities = NULL;
318  if(ns2use) {
319  int currentUse = 1;
320  list use_stmts = NULL; // List of entities
321  if((use_stmts = hash_get(ns2use, (char *)ns)) != HASH_UNDEFINED_VALUE) {
322  string use = NULL;
323  int current_len = 1;
324  FOREACH(string, a_use, use_stmts) {
325  int a_len = strlen(a_use);
326  current_len += a_len;
327  if(use == NULL) {
328  use = (string)malloc(current_len * sizeof(char));
329  } else {
330  use = (string)realloc((void*)use, current_len * sizeof(char));
331  }
332  strcpy(&(use[current_len - a_len - 1]), a_use);
333  }
334  /* Create an entity */
335  string entity_name;
336  asprintf(&entity_name, "%s-use-%d", CurrentPackage, currentUse++);
341  use_entities = CONS(ENTITY,e,use_entities);
342  }
343  }
344  return use_entities;
345 }
346 
347 
348 gfc_code* gfc2pips_get_last_loop(void) {
350  return gfc2pips_list_of_loops->car.e;
351  return NULL;
352 }
353 void gfc2pips_push_loop(gfc_code *c) {
355 }
356 void gfc2pips_pop_loop(void) {
358 }
void set_pips_meta_informations(const char *revs, const char *date, const char *comp)
Definition: message.c:102
value make_value_unknown(void)
Definition: ri.c:2847
storage make_storage_rom(void)
Definition: ri.c:2285
type make_type_unknown(void)
Definition: ri.c:2724
#define c_parser_private_spec
#define PVECTEUR_NEWGEN_EXTERNAL
Definition: compsec.h:27
#define ret(why, what)
true if not a remapping for old.
Definition: dynamic.c:986
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
#define CHUNK(x)
Definition: genC.h:90
int gen_write_tabulated(FILE *fd, int domain)
GEN_WRITE_TABULATED writes the tabulated object TABLE on FD.
Definition: genClib.c:1866
int gen_read_tabulated(FILE *file, int create_p)
GEN_READ_TABULATED reads FILE to update the Gen_tabulated_ table.
Definition: genClib.c:2334
void gen_init_external(int which, void *(*read)(FILE *, int(*)(void)), void(*write)(FILE *, void *), void(*free)(void *), void *(*copy)(void *), int(*allocated_memory)(void *))
GEN_INIT_EXTERNAL defines entry points for free, read and write functions of external types.
Definition: genClib.c:2276
void gen_read_spec(char *spec,...)
Definition: genClib.c:2218
static char start[1024]
The name of the variable from which to start counting domain numbers.
Definition: genLisp.c:55
void * malloc(YYSIZE_T)
void free(void *)
#define gfc2pips_debug
void load_entities()
list gen_union(list a, list b)
generate an union of unique elements taken from A and B
Definition: gfc2pips-util.c:47
void gfc2pips_truncate_useless_zeroes(char *s)
expurgates a string representing a REAL, could be a pre-prettyprinter processing
int fcopy(const char *old, const char *new)
copy the file called *old to the file called *new
void gfc2pips_add_to_callees(entity e)
Add an entity to the list of callees.
Definition: gfc2pips-util.c:67
void pips_init()
char * strrcpy(char *dest, __const char *src)
copy a string from the last char (to allow copy on itself)
void gfc2pips_get_use_st(void)
int strcmp_(__const char *__s1, __const char *__s2)
insensitive case comparison
list gfc2pips_list_of_loops
Definition: gfc2pips-util.c:42
gfc_code * gfc2pips_get_last_loop(void)
void save_entities()
list gfc_module_callees
FIXME: should be generated...
Definition: gfc2pips-util.c:40
list get_use_entities_list(struct gfc_namespace *ns)
int strncmp_(__const char *__s1, __const char *__s2, size_t __n)
insensitive case n-comparison
list gfc2pips_list_of_declared_code
Definition: gfc2pips-util.c:41
void gfc2pips_push_loop(gfc_code *c)
hash_table ns2use
void gfc2pips_get_use_st( void );
char * strn2upper(char s[], size_t n)
replace lower case char by upper case ones
char * str2upper(char s[])
Here are few utility functions to handle splitted files and do comparisons with case insensitive.
Definition: gfc2pips-util.c:83
void gfc2pips_pop_loop(void)
gfc_option_t gfc_option
Cmd line options.
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_cons(const void *item, const list next)
Definition: list.c:888
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
#define src(name, suf)
HPFC by Fabien Coelho, May 1993 and later...
Definition: compile.c:41
#define asprintf
Definition: misc-local.h:225
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define F95_USE_LOCAL_NAME
constant names
Definition: naming-local.h:67
Pvecteur vect_gen_copy_tree(Pvecteur)
Definition: Pvecteur.c:163
void vect_gen_write(FILE *, Pvecteur)
Pvecteur.c.
Definition: Pvecteur.c:108
Pvecteur vect_gen_read(FILE *, int(*)(void))
int vect_gen_allocated_memory(Pvecteur)
Definition: Pvecteur.c:168
void vect_gen_free(Pvecteur)
Definition: Pvecteur.c:158
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
char * string
STRING.
Definition: newgen_types.h:39
#define parser_private_spec
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
bool intrinsic_entity_p(entity e)
Definition: entity.c:1272
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
#define entity_name(x)
Definition: ri.h:2790
#define ri_spec
Definition: ri.h:3168
#define entity_type(x)
Definition: ri.h:2792
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define entity_initial(x)
Definition: ri.h:2796
char * strdup()
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
gen_chunk car
The data payload of a list element.
Definition: newgen_list.h:42
const char * CurrentPackage
the name of the current package, i.e.
Definition: parser.c:58
#define text_spec
Definition: text.h:157
void * e
For externals (foreign objects)
Definition: genC.h:65