PIPS
attachment_pretty_print.c
Go to the documentation of this file.
1 /*
2 
3  $Id: attachment_pretty_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 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 
32 #include "linear.h"
33 #include "genC.h"
34 
35 #include "misc.h"
36 #include "properties.h"
37 
38 #include "naming.h"
39 #include "text-util.h"
40 
41 /* Used in word_to_attachments: */
42 typedef char * void_star;
43 #include "word_attachment.h"
44 
45 #include "constants.h" // *_EXT macro
46 
47 /* To store the fact a prettyprinter ask for Emacs attachments: */
49 
50 enum {POSITION_UNDEFINED = -1};
51 
52 /*
53 // Mapping from an object to a name and from a name to an object:
54 static hash_table names_of_almost_everything_in_a_module = NULL;
55 static hash_table names_to_almost_everything_in_a_module = NULL;
56 
57 // The unique (well, I hope so...) integer to name an object in PIPS
58 // from the extern world. It is not reset since it could be useful to
59 // name various instance of the same module for example. I hope that
60 // the 2^32 wrap around will not occur too quickly... :-(
61 static int current_name_of_something = 1;
62 */
63 
64 /* To store the attachment before sorting: */
66 
67 /* Declare the various mapping between the words and attachments: */
68 GENERIC_LOCAL_FUNCTION(word_to_attachments_begin, word_to_attachments)
69 GENERIC_LOCAL_FUNCTION(word_to_attachments_end, word_to_attachments)
70 
71 /* Returns the module local user name
72  * FC: DUPLICATED FROM ri-util TO AVOID A DEPENDENCY
73  */
74 static const char* module_local_name(entity e)
75 {
76  /* No difference between modules and other entities, except for prefixes */
77  const char* name = local_name(entity_name(e));
78 
79  return (name
81 }
82 
83 /*
84 bool
85 name_something(chunk * something)
86 {
87  if (hash_defined_p(names_of_almost_everything_in_a_module,
88  (char *) something))
89  // Well, we have already named this object. Return the fact
90  // for gen_recurse:
91  return false;
92 
93  hash_put(names_of_almost_everything_in_a_module,
94  (char *) something,
95  (char *) current_name_of_something);
96 
97  hash_put(names_to_almost_everything_in_a_module,
98  (char *) current_name_of_something,
99  (char *) something);
100 
101  current_name_of_something ++;
102 
103  pips_assert("current_name_of_something should not wrap up to 0 !",
104  current_name_of_something != 0);
105 
106  // Go on in the RI:
107  return true;
108 }
109 
110 void
111 name_almost_everything_in_a_module(statement module)
112 {
113  pips_assert("names_of_almost_everything_in_a_module not NULL",
114  names_of_almost_everything_in_a_module == NULL);
115  pips_assert("names_to_almost_everything_in_a_module not NULL",
116  names_to_almost_everything_in_a_module == NULL);
117 
118  names_of_almost_everything_in_a_module = hash_table_make(hash_pointer, 0);
119  names_to_almost_everything_in_a_module = hash_table_make(hash_int, 0);
120 
121  gen_multi_recurse(module,
122  statement_domain, name_something, gen_null,
123  NULL);
124 }
125 
126 
127 void
128 free_names_of_almost_everything_in_a_module()
129 {
130  hash_table_free(names_of_almost_everything_in_a_module);
131  names_of_almost_everything_in_a_module = NULL;
132  hash_table_free(names_to_almost_everything_in_a_module);
133  names_to_almost_everything_in_a_module = NULL;
134 }
135 */
136 
137 
138 /* The translation functions between unique names and objects: */
139 
140 /* Initialize some things related with the attachment of propertie. To
141  be conservative, if a prettyprinter does not call
142  begin_attachment_prettyprint(), all the attachment stuff is
143  disable. Thus, old prettyprinter can go on without Emacs mode: */
144 void
146 {
147  if (get_bool_property("PRETTYPRINT_ADD_EMACS_PROPERTIES")) {
149  // word_text_attachment_mapping = hash_table_make(hash_pointer, 0);
150  // Initialize the local mapings:
151  init_word_to_attachments_begin();
152  init_word_to_attachments_end();
153  }
154 }
155 
156 
157 /* Clean the things related with the attachment of properties: */
158 void
160 {
163 
164  /* Strings in attachments should already have been freed by
165  print_sentence and attachement it-self (witout "s") by
166  output_an_attachment(): */
167  close_word_to_attachments_begin();
168  /* Should be OK since output_the_attachments_for_emacs() has
169  already unlinked the attachment from
170  ord_to_attachments_begin: */
171  close_word_to_attachments_end();
172 
173  /*free_names_of_almost_everything_in_a_module();*/
174  }
175 }
176 
177 
178 /* Use to create or extend the attachment list of a character: */
179 #define ADD_AN_ATTACHMENT_TO_A_MAPPING(a, \
180  a_char, \
181  a_mapping) \
182  if (bound_##a_mapping##_p(a_char)) { \
183  attachments ats = load_##a_mapping(a_char); \
184  list l = attachments_attachment(ats); \
185  l = CONS(ATTACHMENT, a, l); \
186  attachments_attachment(ats) = l; \
187  } \
188  else { \
189  store_##a_mapping(a_char, \
190  make_attachments(CONS(ATTACHMENT, \
191  a, \
192  NIL))); \
193 }
194 
195 /* Attach something from begin_char up to end_char: */
196 static void
198  char * begin_char,
199  char * end_char,
200  attachee at)
201 {
202  // We do not know the position of the attachement in the output file yet:
204 
205  debug_on("ATTACHMENT_DEBUG_LEVEL");
206  debug(6, "attach_to_character_region",
207  "Attach attachment %p (attachee %p, tag %d) from \"%c\" (%p) to \"%c\" (%p)\n",
208  a, at, attachee_tag(at),
209  *begin_char, begin_char,
210  *end_char, end_char);
211 
212  /* Attach the begin to the first character: */
214  begin_char,
215  word_to_attachments_begin);
216 
217  /* Attach the end to the last character: */
219  end_char,
220  word_to_attachments_end);
221  debug_off();
222 }
223 
224 
225 /* Attach something to a word list, from begin_word to end_word: */
226 static void
227 attach_to_word_list(string begin_word,
228  string end_word,
229  attachee at)
230 {
231  debug_on("ATTACHMENT_DEBUG_LEVEL");
232  debug(6, "attach_to_word_list",
233  "Attach attachee %p from \"%s\" (%p) to \"%s\" (%p)\n",
234  at,
235  begin_word, begin_word,
236  end_word, end_word);
237 
238  /* Attach from the first character of the first word up to the
239  last character of the last word: */
240  attach_to_character_region(begin_word,
241  end_word + strlen(end_word) - 1,
242  at);
243  debug_off();
244 }
245 
246 /* Attach something to all the words of the list given in argument: */
247 static void
249  attachee a)
250 {
252  STRING(CAR(gen_last(l))),
253  a);
254 }
255 
256 
257 /* Attach something to a sentence list: */
258 static void
260  sentence end,
261  attachee a)
262 {
265  a);
266 }
267 
268 
269 /* Attach something to a sentence: */
270 static void
272  attachee a)
273 {
274  attach_to_sentence_list(s, s, a);
275 }
276 
277 
278 /* Attach something to a sentence up to the end of the given text: */
279 static void
281  text t,
282  attachee a)
283 {
285 }
286 
287 
288 /* Attach something to all a text: */
289 static void
291  attachee a)
292 {
295  a);
296 }
297 
298 /* The user interface: */
299 
300 /* Attach a loop: */
301 void
303 {
307  l));
308 }
309 
310 
311 /* Attach the PROGRAM/FUNCTION head: */
312 sentence
314 {
317 
318  return s;
319 }
320 
321 
322 /* Attach a module usage (CALL or function call): */
323 void
325  string end_word,
326  reference r)
327 {
329  attach_to_word_list(begin_word,
330  end_word,
332 }
333 
334 
335 /* Attach a reference: */
336 void
338 {
340  attach_to_word_list(word,
341  word,
343 }
344 
345 
346 /* Attach a declaration to all the words of the given list: */
347 void
349  entity e)
350 {
352  attach_to_words(l,
354 }
355 
356 
357 /* Attach a declaration type to all the words of the given list. No
358  need to use strdup(). May accept an empty list: */
359 void
361  string declaration_type)
362 {
364  if (l != NIL)
365  attach_to_words(l,
367  strdup(declaration_type)));
368 }
369 
370 
371 /* Attach a declaration type with its size to all the words of the
372  given list. No need to use strdup(): */
373 void
375  string declaration_type,
376  int size)
377 {
379  char * size_char = int2a(size);
381  concatenate(declaration_type,
382  "*",
383  size_char,
384  NIL));
385  free(size_char);
386  }
387 }
388 
389 
390 /* Attach some statement information to text: */
391 void
393  statement s)
394 {
396  /* Some prettyprinters such as effects generate NULL
397  text... Just ignore. */
399  (void*) statement_number(s)));
400 }
401 
402 
403 /* Attach a decoration: */
404 void
406 {
408  /* Some prettyprinters such as effects generate NULL
409  text... Just ignore. */
411 }
412 
413 
414 /* Attach a cumulated effects decoration: */
415 void
417 {
420 }
421 
422 
423 /* Attach a proper effects decoration: */
424 void
426 {
429 }
430 
431 
432 /* Attach a preconditions decoration: */
433 void
435 {
438 }
439 
440 /* Attach a total preconditions decoration: */
441 void
443 {
445  pips_internal_error("not implemented yet");
446 }
447 
448 
449 /* Attach a transformers decoration: */
450 void
452 {
455 }
456 
457 
458 /* Try to find some attachments in the given character. If any, note
459  the boundary position, that is a start or an end according to the
460  functions given in parameters: */
461 static void
462 deal_with_attachment_boundary(char * a_character,
464  attachments (* load_word_to_attachments_boundary)(void_star),
465  bool (* bound_word_to_attachments_boundary_p)(void_star))
466 {
467  debug(8, "deal_with_attachment_boundary",
468  "Looking for \"%c\" (%p) at %d\n",
469  *a_character,a_character, position_in_the_output);
470 
471  if (bound_word_to_attachments_boundary_p(a_character)) {
472  /* Well, this word is an attachment boundary: */
473  list some_attachments =
474  attachments_attachment(load_word_to_attachments_boundary(a_character));
475  MAP(ATTACHMENT, an_attachment,
476  {
477  debug(4, "deal_with_attachment_boundary",
478  "*** Found attachment = %p for \"%c\" (%p) at %d\n",
479  an_attachment, *a_character,
480  a_character, position_in_the_output);
481 
482  /* Remind the position of the boundary of the
483  attachment: */
484  if (load_word_to_attachments_boundary
485  == load_word_to_attachments_begin)
486  attachment_begin(an_attachment) = position_in_the_output;
487  else
488  attachment_end(an_attachment) = position_in_the_output;
489  },
490  some_attachments);
491  };
492 }
493 
494 
495 /* Try to find some attachments in the given character that are printed out. If
496  any, note the boundary position. */
497 void
500 {
502  debug_on("ATTACHMENT_DEBUG_LEVEL");
503 
504  /* Look for attachment starts: */
505  debug(8, "deal_with_attachment_boundaries",
506  "Looking for attachment starts\n");
507  deal_with_attachment_boundary(a_character,
509  load_word_to_attachments_begin,
510  bound_word_to_attachments_begin_p);
511  /* Look for attachment ends: */
512  debug(8, "deal_with_attachment_boundaries",
513  "Looking for attachment ends\n");
514  deal_with_attachment_boundary(a_character,
516  load_word_to_attachments_end,
517  bound_word_to_attachments_end_p);
518  debug_off();
519  }
520 }
521 
522 
523 /* Try to find some attachments in the given string. If any, note the
524  boundary position. */
525 void
528 {
529  int i;
530 
531  for(i = 0; a_string[i] != '\0'; i++)
534 }
535 
536 
537 /* Try to find some attachments in the a_length first characters of
538  the given string. If any, note the boundary position. */
539 void
542  int a_length)
543 {
544  int i;
545 
546  for(i = 0; i < a_length; i++) {
547  pips_assert("Length is too big since end of string encountered",
548  a_string[i] != '\0');
551  }
552 }
553 
554 
555 /* Many pretty-printers format their own pseudo-comment by their own
556  and move in memory words that have attachments on them. To be able
557  to track them up to the output, we need to overload the movement
558  function to keep track of these. */
559 void
560 relocate_attachments(char * source,
561  char * new_position)
562 {
563  int i;
564  int source_length = strlen(source);
565 
566  debug_on("ATTACHMENT_DEBUG_LEVEL");
567 
568  pips_debug(5, "source = \"%s\" (%p), new_position = \"%s\" (%p)\n",
569  source, source,
570  new_position, new_position);
571 
572  for(i = 0; i < source_length; i++) {
573  if (bound_word_to_attachments_begin_p(source + i)) {
574  pips_debug(4, "Relocating begin of attachment from %p to %p\n",
575  source + i,
576  new_position + i);
577  pips_assert("There is already an attachment on the target",
578  !bound_word_to_attachments_begin_p(new_position + i));
579  store_word_to_attachments_begin(new_position + i,
580  load_word_to_attachments_begin(source + i));
581  delete_word_to_attachments_begin(source + i);
582  }
583  if (bound_word_to_attachments_end_p(source + i)) {
584  pips_debug(4, "Relocating end of attachment from %p to %p\n",
585  source + i,
586  new_position + i);
587  pips_assert("There is already an attachment on the target",
588  !bound_word_to_attachments_end_p(new_position + i));
589  store_word_to_attachments_end(new_position + i,
590  load_word_to_attachments_end(source + i));
591  delete_word_to_attachments_end(source + i);
592  }
593  }
594  debug_off();
595 }
596 
597 
598 /* Concatenate source to target and update the source attachments to
599  point to the new location: */
600 char *
602  const char * source)
603 {
604  char * new_string;
605 
607  int target_length = strlen(target);
608 
609  /* The actual copy: */
610  new_string = strcat(target, source);
611  relocate_attachments((char*)source, target + target_length);
612  }
613  else
614  /* The actual copy: */
615  new_string = strcat(target, source);
616 
617  return new_string;
618 }
619 
620 
621 /* Duplicate a string and update the attachments to point to the new
622  returned string: */
623 char *
625 {
626  char * new_string = strdup(a_string);
627 
628  if (new_string != NULL && is_emacs_pretty_print_asked)
629  relocate_attachments(a_string, new_string);
630  return new_string;
631 }
632 
633 
634 /* Output an attachment to the output file: */
635 static void
636 output_an_attachment(FILE * output_file,
637  attachment a)
638 {
640  int begin = attachment_begin(a);
641  int end = attachment_end(a);
642 
643  pips_debug(5, "begin: %d, end: %d, attachment %p (attachee %p)\n",
644  begin, end, a, at);
645 
646  if (begin == POSITION_UNDEFINED || end == POSITION_UNDEFINED)
647  {
648  pips_user_warning("begin and end should be initialized.\n");
649  return;
650  }
651 
652  /* Begin an Emacs Lisp properties. + 1 since in a buffer (and not
653  a string). (end + 1) + 1 since the property is set between
654  start and end in Emacs.Use backquoting to evaluate keymaps
655  later: */
656  fprintf(output_file, "(add-text-properties %d %d `(", begin + 1, end + 2);
657 
658  switch(attachee_tag(at))
659  {
661  {
663  pips_debug(5, "\treference %p\n", r);
664  /* Evaluate the keymap: */
665  fprintf(output_file, "face epips-face-reference mouse-face epips-mouse-face-reference local-map ,epips-reference-keymap epips-property-reference \"%p\" epips-property-reference-variable \"%p\"",
666  r, reference_variable(r));
667  break;
668  }
669 
670  case is_attachee_call:
671  {
672  call c = attachee_call(at);
673  pips_debug(5, "\treference %p\n", c);
674  /* Evaluate the keymap: */
675  fprintf(output_file, "face epips-face-call mouse-face epips-mouse-face-call local-map ,epips-call-keymap epips-property-call \"%p\"",
676  c);
677  break;
678  }
679 
681  {
683  pips_debug(5, "\tdeclaration %p\n", e);
684  /* Output the address as a string because Emacs cannot
685  store 32-bit numbers: */
686  fprintf(output_file, "face epips-face-declaration epips-property-declaration \"%p\"",
687  e);
688  break;
689  }
690 
691  case is_attachee_type:
692  {
693  string s = attachee_type(at);
694  pips_debug(5, "\ttype \"%s\"\n", s);
695  fprintf(output_file, "epips-property-type \"%s\"", s);
696  break;
697  }
698 
699  case is_attachee_loop:
700  {
701  loop l = attachee_loop(at);
702  pips_debug(5, "\tloop %p\n", l);
704  fprintf(output_file, "face epips-face-parallel-loop ");
705  fprintf(output_file, "epips-property-loop \"%p\"", l);
706  break;
707  }
708 
710  {
711  entity head = attachee_module_head(at);
712  pips_debug(5, "\tmodule_head %p\n", head);
713  fprintf(output_file,
714  "face epips-face-module-head epips-module-head-name \"%s\"",
715  module_local_name(head));
716  break;
717  }
718 
720  {
721  pips_debug(5, "\tdecoration\n");
722  fprintf(output_file,
723  "invisible epips-invisible-decoration");
724  break;
725  }
726 
728  {
729  pips_debug(5, "\tpreconditions\n");
730  fprintf(output_file,
731  "face epips-face-preconditions invisible epips-invisible-preconditions");
732  break;
733  }
734 
736  {
737  pips_debug(5, "\ttransformers\n");
738  fprintf(output_file,
739  "face epips-face-transformers invisible epips-invisible-transformers");
740  break;
741  }
742 
744  {
745  pips_debug(5, "\tcumulated-effect\n");
746  fprintf(output_file,
747  "face epips-face-cumulated-effect invisible epips-invisible-cumulated-effect");
748  break;
749  }
750 
752  {
753  pips_debug(5, "\tproper-effect\n");
754  fprintf(output_file,
755  "face epips-face-proper-effect invisible epips-invisible-proper-effect");
756  break;
757  }
758 
760  {
761  int line_number = attachee_statement_line_number(at);
762 
763  pips_debug(5, "\tstatement_line_number %d\n", line_number);
764  fprintf(output_file, "epips-line-number %d", line_number);
765  break;
766  }
767 
768  default:
769  pips_internal_error("attachee_tag inconsistent");
770  }
771 
772  /* End an Emacs Lisp properties: */
773  fprintf(output_file, "))\n");
774 }
775 
776 
777 /* The function used by qsort to compare 2 attachment structures: */
778 static int
780  const void *yp)
781 {
782  attachment x = *(attachment *) xp;
783  attachment y = *(attachment *) yp;
784 
786  /* Sort according attachment x begins before y: */
787  return attachment_begin(x) - attachment_begin(y);
788 
789  if (attachment_end(x) != attachment_end(y))
790  /* Sort according attachment x ends after y: */
791  return attachment_end(y) - attachment_begin(x);
792 
793  /* If they have the same range, sort according to the type: */
796 }
797 
798 
799 /* Output the attachment in a sorted order with less precise property
800  first: */
801 static void
803 {
804  attachment * as;
805  int i;
806 
807  int number_of_attachments = gen_length(attachments_before_sorting);
808 
809  as = (attachment *) malloc(number_of_attachments*sizeof(attachment));
810  i = 0;
811  MAP(ATTACHMENT, a, {
812  as[i++] = a;
814 
815  qsort((char *)as,
816  number_of_attachments,
817  sizeof(attachment),
819 
820  for(i = 0; i < number_of_attachments; i++) {
821  output_an_attachment(output_file, as[i]);
822  }
823 
824  /* The attachments them self will be removed later: */
827 }
828 
829 
830 /* Add the attachment to the intermediate list: */
831 static bool
833 {
835  a,
837 
838  /* We do not want to go on the recursion: */
839  return false;
840 }
841 
842 
843 /* Nothing to do... */
844 static void
846 {
847  return;
848 }
849 
850 
851 /* Begin the Emacs Lisp file: */
852 static void
854 {
855  /* Begin a string with Emacs Lisp properties: */
856  fprintf(output_file, "(insert \"");
857 }
858 
859 
860 /* Output the list of all the attachments found in the text file with
861  Emacs Lisp syntax: */
862 static void
864 {
865  debug_on("ATTACHMENT_DEBUG_LEVEL");
866 
867  /* End the string part: */
868  fprintf(output_file, "\")\n");
869 
870  /* Enumerate all the attachments: */
871  gen_multi_recurse(get_word_to_attachments_begin(),
875  NULL);
876 
877  /* Now we try to output the stuff in a decent order: */
879 
880  /* Just for fun, the previous gen_recurse will also recurse
881  through the words of the mapping but it is not deep and thus it
882  does not worth using a gen_multi_recurse with a string_domain
883  and a filter returning always stop to avoid this unnecessary
884  recursion. */
885 
886  WORD_TO_ATTACHMENTS_MAP(word_pointer, attachment_list,
887  {
888  pips_debug(6, "Key %p, value %p\n", word_pointer, attachment_list);
889  /* Unlink the attachment from
890  attachments to avoid double free
891  later since referenced both by
892  word_to_attachments_begin and
893  word_to_attachments_end: */
894  MAPL(ats,
895  {
897  },
898  attachments_attachment(attachment_list));
899  },
900  get_word_to_attachments_begin());
901 
902  /* End the property part: */
903  /* fprintf(output_file, "\n\t)\n)\n"); */
904 
905  debug_off();
906 }
907 
908 
909  /* Add the attachment in Emacs mode by creating a twin file that
910  is decorated with Emacs properties: */
911 void
913 {
915  FILE * file_stream;
916  char * emacs_file_name = strdup(concatenate(file_name, EMACS_FILE_EXT, NULL));
917  FILE * emacs_file_stream = safe_fopen(emacs_file_name, "w");
918  init_output_the_attachments_for_emacs(emacs_file_stream);
919  /* Now include the original plain file: */
920  file_stream = safe_fopen(file_name, "r");
921  for(;;) {
922  char c = getc(file_stream);
923  /* Strange semantics: must have read the character first: */
924  if (feof(file_stream))
925  break;
926 
927  /* Just backslashify the '"' and '\': */
928  if (c == '"' || c == '\\')
929  (void) putc('\\', emacs_file_stream);
930 
931  (void) putc(c, emacs_file_stream);
932  }
933  safe_fclose(file_stream, file_name);
934  /* Actually add the interesting stuff: */
935  output_the_attachments_for_emacs(emacs_file_stream);
936  safe_fclose(emacs_file_stream, emacs_file_name);
937  free(emacs_file_name);
938  }
939 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
attachment make_attachment(attachee a1, intptr_t a2, intptr_t a3)
attachee make_attachee(enum attachee_utype tag, void *val)
void attach_declaration_type_to_words(list l, string declaration_type)
Attach a declaration type to all the words of the given list.
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:
static void attach_to_words(list l, attachee a)
Attach something to all the words of the list given in argument:
void attach_transformers_decoration_to_text(text t)
Attach a transformers decoration:
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 attach_preconditions_decoration_to_text(text t)
Attach a preconditions decoration:
static void attach_to_sentence(sentence s, attachee a)
Attach something to a sentence:
void relocate_attachments(char *source, char *new_position)
Many pretty-printers format their own pseudo-comment by their own and move in memory words that have ...
static const char * module_local_name(entity e)
Declare the various mapping between the words and attachments:
sentence attach_head_to_sentence(sentence s, entity module)
Attach the PROGRAM/FUNCTION head:
static bool is_emacs_pretty_print_asked
To store the fact a prettyprinter ask for Emacs attachments:
void attach_proper_effects_decoration_to_text(text t)
Attach a proper effects decoration:
static void attach_to_character_region(char *begin_char, char *end_char, attachee at)
Attach something from begin_char up to end_char:
#define ADD_AN_ATTACHMENT_TO_A_MAPPING(a, a_char, a_mapping)
Use to create or extend the attachment list of a character:
static void attach_to_sentence_list(sentence begin, sentence end, attachee a)
Attach something to a sentence list:
void attach_declaration_to_words(list l, entity e)
Attach a declaration to all the words of the given list:
static void attach_to_sentence_up_to_end_of_text(sentence s, text t, attachee a)
Attach something to a sentence up to the end of the given text:
void attach_decoration_to_text(text t)
Attach a decoration:
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 begin_attachment_prettyprint(void)
The translation functions between unique names and objects:
void end_attachment_prettyprint(void)
Clean the things related with the attachment of properties:
char * void_star
Used in word_to_attachments:
static void rewrite_an_attachment(attachment __attribute__((unused)) a)
Nothing to do...
void attach_reference_to_word_list(string begin_word, string end_word, reference r)
Attach a module usage (CALL or function call):
@ POSITION_UNDEFINED
void attach_declaration_size_type_to_words(list l, string declaration_type, int size)
Attach a declaration type with its size to all the words of the given list.
void attach_total_preconditions_decoration_to_text(text __attribute__((unused)) t)
Attach a total preconditions decoration:
void attach_regular_call_to_word(string word, call c)
Attach a reference:
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.
void attach_statement_information_to_text(text t, statement s)
Attach some statement information to text:
static void deal_with_attachment_boundary(char *a_character, int position_in_the_output, attachments(*load_word_to_attachments_boundary)(void_star), bool(*bound_word_to_attachments_boundary_p)(void_star))
Try to find some attachments in the given character.
void attach_cumulated_effects_decoration_to_text(text t)
Attach a cumulated effects decoration:
static void attach_to_word_list(string begin_word, string end_word, attachee at)
Attach something to a word list, from begin_word to end_word:
static void attach_to_text(text t, attachee a)
Attach something to all a text:
char * strdup_and_migrate_attachments(char *a_string)
Duplicate a string and update the attachments to point to the new returned string:
list attachments_before_sorting
To store the attachment before sorting:
void write_an_attachment_file(string file_name)
Add the attachment in Emacs mode by creating a twin file that is decorated with Emacs properties:
static bool put_an_attachment_in_the_list(attachment a)
Add the attachment to the intermediate list:
static int compare_attachment_for_qsort(const void *xp, const void *yp)
The function used by qsort to compare 2 attachment structures:
static void output_the_attachments_for_emacs(FILE *output_file)
Output the list of all the attachments found in the text file with Emacs Lisp syntax:
static void init_output_the_attachments_for_emacs(FILE *output_file)
Begin the Emacs Lisp file:
void attach_loop_to_sentence_up_to_end_of_text(sentence s, text t, loop l)
The user interface:
static void output_the_attachments_in_a_sorted_order(FILE *output_file)
Output the attachment in a sorted order with less precise property first:
static void output_an_attachment(FILE *output_file, attachment a)
Output an attachment to the output file:
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
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
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
#define a_string
Definition: genread_lex.c:843
void * malloc(YYSIZE_T)
void free(void *)
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#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
char end
Definition: gtk_status.c:82
#define debug_on(env)
Definition: misc-local.h:157
#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_user_warning
Definition: misc-local.h:146
#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 debug_off()
Definition: misc-local.h:160
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define COMMON_PREFIX
Definition: naming-local.h:34
#define F95MODULE_PREFIX
Definition: naming-local.h:36
#define MAIN_PREFIX
Definition: naming-local.h:32
#define BLOCKDATA_PREFIX
Definition: naming-local.h:35
void * void_star
Definition: newgen.c:33
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define UU
Definition: newgen_types.h:98
static char * module
Definition: pips.c:74
#define loop_execution(x)
Definition: ri.h:1648
#define reference_variable(x)
Definition: ri.h:2326
#define entity_name(x)
Definition: ri.h:2790
#define statement_number(x)
Definition: ri.h:2452
#define execution_parallel_p(x)
Definition: ri.h:1211
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
static char * x
Definition: split_file.c:159
GENERIC_LOCAL_FUNCTION(directives, step_directives)
Copyright 2007, 2008, 2009 Alain Muller, Frederique Silber-Chaussumier.
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
char * int2a(int)
util.c
Definition: util.c:42
string first_word_of_sentence(sentence)
Return the first word of a sentence:
Definition: util.c:76
string last_word_of_sentence(sentence)
Return the last word of a sentence:
Definition: util.c:101
#define SENTENCE(x)
newgen_unformatted_domain_defined
Definition: text.h:36
#define text_sentences(x)
Definition: text.h:113
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
static string file_name
@ is_attachee_preconditions
@ is_attachee_statement_line_number
@ is_attachee_transformers
@ is_attachee_module_head
@ is_attachee_call
@ is_attachee_loop
@ is_attachee_declaration
@ is_attachee_cumulated_effects
@ is_attachee_decoration
@ is_attachee_type
@ is_attachee_proper_effects
@ is_attachee_reference
#define attachment_domain
newgen_attachee_domain_defined
#define ATTACHMENT(x)
ATTACHMENT.
#define attachment_undefined
#define ATTACHMENT_(x)
#define attachment_begin(x)
#define attachee_type(x)
#define attachee_tag(x)
#define attachment_attachee(x)
#define attachee_call(x)
#define attachee_module_head(x)
#define attachment_end(x)
#define WORD_TO_ATTACHMENTS_MAP(k, v, c, f)
#define attachee_declaration(x)
#define attachee_loop(x)
#define attachments_attachment(x)
#define attachee_reference(x)
#define attachee_statement_line_number(x)