PIPS
text_print.c
Go to the documentation of this file.
1 /*
2 
3  $Id: text_print.c 23065 2016-03-02 09:05:50Z coelho $
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 #include <stdio.h>
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 
32 #include "linear.h"
33 
34 #include "genC.h"
35 #include "ri.h"
36 #include "text.h"
37 
38 #include "misc.h"
39 #include "properties.h"
40 
41 /* FI: just to make sure that text.h is built; pips-makemake -l does not
42  take into account a library whose modules do not use the library header */
43 #include "text-util.h"
44 
45 static int position_in_the_output = 0;
46 
47 /* Before using print_sentence: */
48 static void
50 {
52 }
53 
54 
55 /* Output functions that tracks the number of output characters: */
56 static char
58  FILE * fd)
59 {
61  return putc(c, fd);
62 }
63 
64 static int
65 fprintf_sentence(FILE * fd,
66  char * a_format,
67  ...)
68 {
69  va_list some_arguments;
70  int number_of_printed_char;
71 
72  va_start(some_arguments, a_format);
73  number_of_printed_char = vfprintf(fd, a_format, some_arguments);
74  va_end(some_arguments);
75 
76  position_in_the_output += number_of_printed_char;
77  return number_of_printed_char;
78 }
79 
80 
81 /* print_sentence:
82  *
83  * FI: I had to change this module to handle string longer than the
84  * space available on one line; I tried to preserve as much as I could
85  * of the previous behavior to avoid pseudo-hyphenation at the wrong
86  * place and to avoid extensicve problems with validate; the resulting
87  * code is lousy, of course; FI, 15 March 1993
88  *
89  * RK: the print_sentence could print lower case letter according to
90  * a property... 17/12/1993.
91  */
92 
93 #define MAX_END_COLUMN_F77 (72)
94 #define MAX_END_COLUMN_F95 (132)
95 /* Define a huge line size value because the previous one (999) was too
96  small for PIPS generated declarations after the outliner. Do not use
97  INT_MAX because there are some assertions such as
98  (... < MAX_END_COLUMN_DEFAULT + 1).
99  So (INT_MAX/2) is a rough approximation. :-) */
100 #define MAX_END_COLUMN_DEFAULT (INT_MAX/2)
101 #define MAX_START_COLUMN (42)
102 #define C_STATEMENT_LINE_COLUMN (71)
103 #define C_STATEMENT_LINE_STEP (15)
104 
105 void print_sentence(FILE * fd, sentence s) {
107 
108 
109  if (sentence_formatted_p(s)) {
110  string ps = sentence_formatted(s);
111 
112  while(*ps) {
113  char c = *ps;
114  putc_sentence(c, fd);
116  ps++;
117  }
118  } else {
119  /* col: the next column number, starting from 1.
120  * it means tha columns 1 to col-1 have been output. I guess. FC.
121  */
122  int i, line_num = 1;
123  int col;
125  string label = unformatted_label(u);
126  int em = unformatted_extra_margin(u);
127  int n = unformatted_number(u);
128  cons *lw = unformatted_words(u);
129  int max_line_size;
130  if(lang==is_language_fortran95) {
131  max_line_size = MAX_END_COLUMN_F95;
132  } else if(lang==is_language_fortran ) {
133  max_line_size =MAX_END_COLUMN_F77;
134  } else {
135  max_line_size = MAX_END_COLUMN_DEFAULT;
136  }
137 
138  /* first 6 columns (0-5)
139  */
140  /* 05/08/2003 - Nga Nguyen - Add code for C prettyprinter */
141 
142  if (label != NULL && !string_undefined_p(label)) {
143  /* Keep track of the attachment against the padding: */
145 
146  switch(lang) {
147  case is_language_fortran:
148  fprintf_sentence(fd, "%-5s ", label);
149  break;
151  // Check that the label is non empty
152  if(*label!='\0') {
153  fprintf_sentence(fd, "%-5s ", label);
154  }
155  break;
156  case is_language_c:
157  /* C prettyprinter: a label cannot begin with a number
158  * so "l" is added for this case
159  */
160  if (strlen(label) > 0)
161  fprintf_sentence(fd, get_C_label_printf_format(label), label);
162  break;
163  default:
164  pips_internal_error("language unknown not handled");
165  }
166  } else if (lang==is_language_fortran) {
167  fprintf_sentence(fd, " ");
168  }
169 
170 
171  /* FI: do not indent too much (9 June 1995) */
172  em = (em > MAX_START_COLUMN) ? MAX_START_COLUMN : em;
173  /* Initial tabulation, if needed: do not put useless SPACEs
174  in output file.
175  Well, it's difficult to know if it is useful or not. The
176  test below leads to misplaced opening braces.
177  */
178  if (!ENDP(lw)
179  /*&& gen_length(lw)>1
180  && !same_string_p(STRING(CAR(lw)), "\n")*/)
181  for (i = 0; i < em; i++)
182  putc_sentence(' ', fd);
183 
184  col = em;
185 
186  if (lang == is_language_fortran) {
187  col = col + 7; /* Fortran77 start on 7th column */
188  }
189 
190  pips_assert("not too many columns", col <= max_line_size - 2);
191  FOREACH(string, w, lw) {
192  switch(lang) {
193  case is_language_c:
194  col += fprintf_sentence(fd, "%s", w);
195  break;
196  case is_language_fortran:
197  case is_language_fortran95: {
198  int max_space_on_a_line = max_line_size - em;
199  if(lang==is_language_fortran) {
200  max_space_on_a_line -= 7;
201  }
202 
203 
204  /* if the string fits on the current line: no problem */
205  if (col + (int) strlen(w) <= max_line_size - 2) {
207  col += fprintf_sentence(fd, "%s", w);
208  }
209  /* if the string fits on one line:
210  * use the 88 algorithm to break as few
211  * syntactic constructs as possible */
212  else if ((int)strlen(w) < max_space_on_a_line) {
213  /* Complete current line with the statement
214  line number, if it is significative: */
215  if (n > 0 && get_bool_property("PRETTYPRINT_STATEMENT_NUMBER")) {
216  for (i = col; i <= max_line_size; i++) {
217  putc_sentence(' ', fd);
218  }
219  if (lang == is_language_fortran95) {
220  fprintf_sentence(fd, "! %04d", n);
221  } else {
222  fprintf_sentence(fd, "%04d", n);
223  }
224  }
225 
226  if(lang==is_language_fortran95) {
227  /* prepare to cut the line */
228  fprintf_sentence(fd," &");
229  }
230 
231  /* start a new line with its prefix */
232  putc_sentence('\n', fd);
233 
234  if (label != (char *)NULL && !string_undefined_p(label)
235  && (strcmp(label, "CDIR$") == 0 || strcmp(label, "CDIR@")
236  == 0 || strcmp(label, "CMIC$") == 0)) {
237  pips_assert("Cray with F95 not handled",
238  lang!=is_language_fortran95);
239  /* Special label for Cray directives */
240  fprintf_sentence(fd, "%s%d", label, (++line_num) % 10);
241  } else if (lang == is_language_fortran) {
242  fprintf_sentence(fd, " &");
243  }
244 
245  for (i = 0; i < em; i++)
246  putc_sentence(' ', fd);
247 
248  if (lang == is_language_fortran) {
249  col = 7 + em;
250  } else {
251  col = em;
252  }
254  col += fprintf_sentence(fd, "%s", w);
255  }
256  /* if the string has to be broken in at least two lines:
257  * new algorithmic part
258  * to avoid line overflow (FI, March 1993) */
259  else {
260  char * line = w;
261  int ncar;
262 
263  /* Complete the current line, but not after :-) */
264  ncar = MIN(max_line_size - col + 1, (int) strlen(line));
265  ;
268  ncar);
269  fprintf_sentence(fd, "%.*s", ncar, line);
270  line += ncar;
271  col = max_line_size;
272 
273  pips_debug(9, "line to print, col=%d\n", col);
274 
275  while(strlen(line) != 0) {
276  ncar = MIN(max_line_size - 7 + 1, (int) strlen(line));
277 
278 
279  /* start a new line with its prefix but no indentation
280  * since string constants may be broken onto two lines
281  */
282  if (lang == is_language_fortran95) {
283  /* prepare to cut the line */
284  fprintf_sentence(fd, " &");
285  }
286  putc_sentence('\n', fd);
287 
288  if (label != (char *)NULL
289  && (strcmp(label, "CDIR$") == 0 || strcmp(label, "CDIR@")
290  == 0 || strcmp(label, "CMIC$") == 0)) {
291  /* Special label for Cray directives */
292  (void)fprintf_sentence(fd, "%s%d", label, (++line_num) % 10);
293  } else if (lang == is_language_fortran) {
294  (void)fprintf_sentence(fd, " &");
295  col = 7;
296  } else {
297  col = 0;
298  }
301  ncar);
302  (void)fprintf_sentence(fd, "%.*s", ncar, line);
303  line += ncar;
304  col += ncar;
305  }
306  }
307  break;
308  }
309  default:
310  pips_internal_error("Language unknown !");
311  break;
312  }
313  }
314 
315  pips_debug(9, "line completed, col=%d\n", col);
316  pips_assert("not too many columns", col <= max_line_size + 1);
317 
318  /* statement line number starts at different column depending on
319  * the used language : C or fortran
320  */
321  int column_start = 0;
322  switch (get_prettyprint_language_tag()) {
323  case is_language_fortran:
324  /* fortran case right the line number on the right where characters
325  are ignored by a f77 parser*/
326  column_start = max_line_size;
327  break;
328  case is_language_c:
330  /* C and F95 case, try to align the line number on the right using
331  * commentaries. The alignment is done modulo C_STATEMENT_LINE_STEP
332  */
333  column_start = C_STATEMENT_LINE_COLUMN;
334  while(column_start <= col)
335  column_start += C_STATEMENT_LINE_STEP;
336  break;
337  default:
338  pips_internal_error("Language unknown !");
339  break;
340  }
341 
342  /* Output the statement line number on the right end of the
343  line: */
344  if (n > 0 && get_bool_property("PRETTYPRINT_STATEMENT_NUMBER")) {
345  for (int i = col; i <= column_start; i++) {
346  putc_sentence(' ', fd);
347  }
348  switch (get_prettyprint_language_tag()) {
349  case is_language_fortran:
350  fprintf_sentence(fd, "%04d", n);
351  break;
352  case is_language_c:
353  fprintf_sentence(fd, "/*%04d*/", n);
354  break;
356  fprintf_sentence(fd, "! %04d", n);
357  break;
358  default:
359  pips_internal_error("Language unknown !");
360  break;
361  }
362  }
363  putc_sentence('\n', fd);
364  }
365 }
366 
367 void print_text(FILE *fd, text t)
368 {
370  MAP(SENTENCE, s, print_sentence(fd, s), text_sentences(t));
371 }
372 
374 {
375  print_sentence(stderr, s);
376 }
377 
378 /* FI: print_text() should be fprint_text() and dump_text(), print_text() */
379 
381 {
382  print_text(stderr, t);
383 }
384 
385 string words_join(list ls,const char* sep)
386 {
387  int size = 1; /* 1 for null termination. */
388  size_t sep_sz = strlen(sep);
389  string buffer, p;
390 
391  /* computes the buffer length.
392  */
393  MAP(STRING, s, size+=strlen(s)+sep_sz, ls);
394  buffer = (char*) malloc(sizeof(char)*size);
395  pips_assert("malloc ok", buffer);
396 
397  /* appends to the buffer...
398  */
399  buffer[0] = '\0';
400  p=buffer;
401  FOREACH(STRING, s,ls) {
404  p+=strlen(s);
405  p+=sep_sz;
406  }
407  return buffer;
408 }
409 
410 /* Convert a word list into a string and translate the position of
411  eventual attachment accordingly: */
413 {
414  return words_join(ls,"");
415 }
416 
417 /* SG: moved here from icfdg
418  * BUG (FC): words_to_string is malloced, but sentence_formatted is not:-(
419  */
421 {
422  if (!sentence_formatted_p(sen))
424  else
425  return sentence_formatted(sen);
426 }
427 
428 string text_to_string_gen(text t, bool with_newline)
429 {
431 
433  {
434  string ss = sentence_to_string(sen);
436  // try to avoid a memory leak... see comments above
437  if (sentence_unformatted_p(sen))
438  free(ss);
439  if (with_newline)
440  string_buffer_append(sb, "\n");
441  }
442 
443  string s = string_buffer_to_string(sb);
445 
446  return s;
447 }
448 
449 /* SG: moved here from ricedg */
451 {
452  return text_to_string_gen(t, false);
453 }
454 
456 {
457  return text_to_string_gen(t, true);
458 }
459 
460 void print_words(FILE * fd, list lw)
461 {
462  string s = words_to_string(lw);
463  fputs(s, fd);
464  free(s);
465 }
466 
467 void dump_words(list lw)
468 {
469  print_words(stderr, lw);
470 }
471 
472 
473 /********************************************************************* DEBUG */
474 
475 static void debug_word(string w)
476 {
477  fprintf(stderr, "# string--%s--\n", w? w: "<null>");
478 }
479 
480 void
481 debug_words(list /* of string */ l)
482 {
484 }
485 
486 static void
488 {
489  fprintf(stderr, "# formatted\n%s\n# end formatted\n", s);
490 }
491 
493 {
494  fprintf(stderr, "# unformatted\n# label %s, %td, %td\n",
495  unformatted_label(u)? unformatted_label(u): "<null>",
498  fprintf(stderr, "# end unformatted\n");
499 }
500 
502 {
503  fprintf(stderr, "# sentence\n");
504  switch (sentence_tag(s))
505  {
508  break;
511  break;
512  default:
513  pips_internal_error("unexpected sentence tag %d", sentence_tag(s));
514  }
515 
516  fprintf(stderr,"# end sentence\n");
517 }
518 
520 {
521  fprintf(stderr, "# text\n");
523  fprintf(stderr,"# end text\n");
524 }
#define MIN(x, y)
minimum and maximum if they are defined somewhere else, they are very likely to be defined the same w...
char * strcat_word_and_migrate_attachments(char *target, const char *source)
Concatenate source to target and update the source attachments to point to the new location:
void deal_with_attachments_in_this_string(string a_string, int position_in_the_output)
Try to find some attachments in the given string.
void deal_with_attachments_in_this_string_length(string a_string, int position_in_the_output, int a_length)
Try to find some attachments in the a_length first characters of the given string.
void deal_with_attachments_at_this_character(char *a_character, int position_in_the_output)
Try to find some attachments in the given character that are printed out.
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define STRING(x)
Definition: genC.h:87
void * malloc(YYSIZE_T)
void free(void *)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
void gen_map(gen_iter_func_t fp, const list l)
Definition: list.c:172
#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
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
enum language_utype get_prettyprint_language_tag()
Definition: language.c:67
string get_C_label_printf_format(const char *label)
Get the prettyprint format of a C label.
Definition: language.c:155
#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
void string_buffer_append(string_buffer, const string)
append string s (if non empty) to string buffer sb, the duplication is done if needed according to th...
string string_buffer_to_string(const string_buffer)
return malloc'ed string from string buffer sb
void string_buffer_free(string_buffer *)
free string buffer structure, also free string contents according to the dup field
Definition: string_buffer.c:82
string_buffer string_buffer_make(bool dup)
allocate a new string buffer
Definition: string_buffer.c:58
void(* gen_iter_func_t)(void *)
Definition: newgen_types.h:116
#define string_undefined_p(s)
Definition: newgen_types.h:41
language_utype
Definition: ri.h:1565
@ is_language_fortran
Definition: ri.h:1566
@ is_language_fortran95
Definition: ri.h:1568
@ is_language_c
Definition: ri.h:1567
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static int line
FLEX_SCANNER.
Definition: scanner.c:852
static string buffer
Definition: string.c:113
internally defined structure.
Definition: string_buffer.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:4047
#define sentence_unformatted_p(x)
Definition: text.h:79
#define unformatted_number(x)
Definition: text.h:151
#define SENTENCE(x)
newgen_unformatted_domain_defined
Definition: text.h:36
#define unformatted_extra_margin(x)
Definition: text.h:153
#define sentence_unformatted(x)
Definition: text.h:81
#define sentence_formatted(x)
Definition: text.h:78
#define sentence_tag(x)
Definition: text.h:75
#define text_sentences(x)
Definition: text.h:113
#define unformatted_words(x)
Definition: text.h:155
#define unformatted_label(x)
Definition: text.h:149
@ is_sentence_formatted
Definition: text.h:57
@ is_sentence_unformatted
Definition: text.h:58
#define sentence_formatted_p(x)
Definition: text.h:76
void print_words(FILE *fd, list lw)
Definition: text_print.c:460
void dump_sentence(sentence s)
Definition: text_print.c:373
string text_to_string_nl(text t)
Definition: text_print.c:455
string words_to_string(list ls)
Convert a word list into a string and translate the position of eventual attachment accordingly:
Definition: text_print.c:412
void print_sentence(FILE *fd, sentence s)
cproto-generated files
Definition: text_print.c:105
static char putc_sentence(char c, FILE *fd)
Output functions that tracks the number of output characters:
Definition: text_print.c:57
#define MAX_START_COLUMN
Definition: text_print.c:101
#define MAX_END_COLUMN_F77
print_sentence:
Definition: text_print.c:93
string sentence_to_string(sentence sen)
SG: moved here from icfdg BUG (FC): words_to_string is malloced, but sentence_formatted is not:-(.
Definition: text_print.c:420
static void debug_unformatted(unformatted u)
Definition: text_print.c:492
static void print_sentence_init()
Before using print_sentence:
Definition: text_print.c:49
void print_text(FILE *fd, text t)
Definition: text_print.c:367
#define MAX_END_COLUMN_F95
Definition: text_print.c:94
void debug_words(list l)
Definition: text_print.c:481
string text_to_string_gen(text t, bool with_newline)
Definition: text_print.c:428
static void debug_formatted(string s)
Definition: text_print.c:487
string text_to_string(text t)
SG: moved here from ricedg.
Definition: text_print.c:450
void dump_words(list lw)
Definition: text_print.c:467
#define C_STATEMENT_LINE_STEP
Definition: text_print.c:103
static int fprintf_sentence(FILE *fd, char *a_format,...)
Definition: text_print.c:65
void debug_text(text t)
Definition: text_print.c:519
static void debug_word(string w)
Definition: text_print.c:475
static int position_in_the_output
FI: just to make sure that text.h is built; pips-makemake -l does not take into account a library who...
Definition: text_print.c:45
#define C_STATEMENT_LINE_COLUMN
Definition: text_print.c:102
void debug_sentence(sentence s)
Definition: text_print.c:501
void dump_text(text t)
FI: print_text() should be fprint_text() and dump_text(), print_text()
Definition: text_print.c:380
string words_join(list ls, const char *sep)
Definition: text_print.c:385
#define MAX_END_COLUMN_DEFAULT
Define a huge line size value because the previous one (999) was too small for PIPS generated declara...
Definition: text_print.c:100