PIPS
tpips.c
Go to the documentation of this file.
1 /*
2 
3  $Id: tpips.c 23628 2020-07-07 12:23:26Z 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 <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <unistd.h>
32 #include <strings.h>
33 #include <sys/param.h>
34 
35 /* Sometimes, already included by unistd.h */
36 #include <getopt.h>
37 
38 #include <readline/readline.h>
39 #include <readline/history.h>
40 
41 #include "linear.h"
42 
43 #include "genC.h"
44 #include "ri.h"
45 #include "database.h"
46 
47 #include "misc.h"
48 #include "newgen.h"
49 #include "database.h"
50 #include "ri-util.h"
51 #include "pipsdbm.h"
52 #include "properties.h"
53 #include "constants.h"
54 #include "resources.h"
55 #include "pipsmake.h"
56 #include "preprocessor.h"
57 #include "top-level.h"
58 
59 #include "tpips.h"
60 #include "completion_list.h"
61 
62 /********************************************************** Static variables */
63 
65 bool tpips_is_interactive = false;
66 
67 static bool tpips_is_a_shell = false;
68 static bool use_readline = false;
69 static FILE * logfile;
70 
71 /* current file being processed, with its name and the line number */
72 static FILE * current_file = NULL;
73 static string current_name = "<unknown>";
74 static int current_line = 0;
75 
77 {
78  return current_name;
79 }
80 
82 {
83  return current_line;
84 }
85 
86 void tpips_next_line(void)
87 {
88  current_line++;
89 }
90 
92 {
93  return current_line;
94 }
95 
96 string tpips_current_name(void)
97 {
98  return current_name;
99 }
100 
101 extern int tgetnum();
102 extern void tp_restart( FILE * ); /* tp_lex.c */
103 
104 /*************************************************************** Some Macros */
105 
106 #define tpips_usage \
107  "Usage: %s [-nscvh?jwa] " \
108  "[-l logfile] [-r rcfile] [-e tpips-cmds] tpips-scripts\n" \
109  "\t-n: no execution mode. just to check a script for syntax errors\n" \
110  "\t-s: behaves like a shell. tpips commands simply extend a shell.\n" \
111  "\t-c: behaves like a command, not a shell (it is the default).\n" \
112  "\t-h: this help. (also -?)\n" \
113  "\t-v: display version and architecture informations.\n" \
114  "\t-a: create a logfile automatically.\n" \
115  "\t-j: jpips special mode.\n" \
116  "\t-w: starts with a wrapper (jpips special again)...\n" \
117  "\t-l logfile: log to logfile.\n" \
118  "\t-r rcfile: tpips rc file to source. (default ~/.tpipsrc)\n" \
119  "\t-x xml-logfile: log to this file in XML.\n" \
120  "\t-e tpips-cmds: here tpips commands.\n" \
121  "\n"
122 
123 #define SEPARATOR_P(c) (index (" \t", c))
124 
125 static bool prefix_equal_p(string str, string prf)
126 {
127  skip_blanks(str);
128  return !strncmp(str, prf, strlen(prf));
129 }
130 
131 static bool string_is_true(string s)
132 {
133  return s && (*s=='1' || *s=='t' || *s=='T' || *s=='y' || *s=='Y' ||
134  *s=='o' || *s=='O');
135 }
136 
137 /* Whether pips should behave as a shell. Can be turned on from
138  * the command line, from properties and from the environment.
139  * Default is FALSE.
140  */
141 #define TPIPS_IS_A_SHELL "TPIPS_IS_A_SHELL"
142 
144 {
147 }
148 
149 /********************************************************************* JPIPS */
150 
151 /* jpips specials.
152  *
153  * #jpips: modules MAIN FOO BLA...
154  * #jpips: prop ...
155  * #jpips: done
156  * #jpips: begin_user_error
157  * ...
158  * #jpips: end_user_error
159  * #jpips: show ...
160  * #jpips: {begin,end}_user_request
161  * #jpips:
162  */
163 
164 #define JPIPS_TAG "#jpips:"
165 
166 bool jpips_is_running = false;
167 
168 /* Ronan suggested a signal driven handling of jpips requests,
169  * so as to let the prompt available for direct commands.
170  * This seems great, but is not implemented at the time.
171  * This would mean interruption driven tpips execution from jpips.
172  * The executions should not interfere...
173  * SIGIO handling on in_from_jpips...
174  * forward to readline maybe...
175  * a new -J option?
176  * how to link C FILE* to unix file descriptors?
177  * ? f = fopen(); dup2(..., fileno(f)); OR freopen()...
178  */
179 static FILE * in_from_jpips;
180 static FILE * out_to_jpips;
181 
182 FILE * jpips_out_file(void)
183 {
184  return out_to_jpips;
185 }
186 
187 void jpips_begin_tag(string s)
188 {
189  fprintf(out_to_jpips, JPIPS_TAG " %s", s);
190 }
191 
192 void jpips_add_tag(string s)
193 {
194  fprintf(out_to_jpips, " %s", s);
195 }
196 
197 void jpips_end_tag(void)
198 {
199  fprintf(out_to_jpips, "\n");
200  fflush(out_to_jpips);
201 }
202 
203 void jpips_tag(string s)
204 {
205  jpips_begin_tag(s);
206  jpips_end_tag();
207 }
208 
209 void jpips_tag2(string s1, string s2)
210 {
212  jpips_add_tag(s2);
213  jpips_end_tag();
214 }
215 
216 void jpips_done(void)
217 {
218  jpips_tag("done");
219 }
220 
221 void jpips_string(const char* a_message_format, va_list some_arguments)
222 {
223  vfprintf(out_to_jpips, a_message_format, some_arguments);
224  fflush(out_to_jpips);
225 }
226 
227 #include <stdarg.h>
228 
229 void jpips_printf(const string format, ...)
230 {
231  va_list some_arguments;
232  va_start(some_arguments, format);
233  (void) vfprintf(out_to_jpips, format, some_arguments);
234  va_end(some_arguments);
235 }
236 
237 /********************************************************** TPIPS COMPLETION */
238 
240 
250 };
251 
253 {
254  char *fun_name;
257 };
258 
259 static struct t_completion_scheme completion_scheme[] =
260 {
264 { QUIT, COMP_NONE, COMP_NONE },
265 { "checkpoint", COMP_NONE, COMP_NONE },
268 { "open", COMP_NONE, COMP_NONE },
269 { "create", COMP_NONE, COMP_FILENAME },
270 { "close", COMP_NONE, COMP_NONE },
271 { "delete", COMP_NONE, COMP_NONE },
272 { "module", COMP_MODULE, COMP_NONE },
273 { "make", COMP_RESOURCE, COMP_NONE },
274 { "remove", COMP_RESOURCE, COMP_NONE },
275 { "apply", COMP_RULE, COMP_NONE },
276 { "capply", COMP_RULE, COMP_NONE },
277 { "display", COMP_FILE_RSC, COMP_NONE },
278 { "activate", COMP_RULE, COMP_NONE },
281 { "unsetenv", COMP_NONE, COMP_NONE },
284 { "info", COMP_NONE, COMP_NONE },
285 { "show", COMP_RESOURCE, COMP_NONE },
286 { "timeout", COMP_NONE, COMP_NONE },
287 { (char*)NULL, COMP_FILENAME, COMP_FILENAME } /* default: files... */
288 };
289 
290 static char *tp_help_topics[] =
291 {
292  "readline", "create","close","delete","echo","module","activate",
293  "make","apply","capply","display",SET_ENV, SET_PROP,GET_PROP,SHELL_ESCAPE,
294  CHANGE_DIR,QUIT,"source", HELP,"rule","resource","owner", "remove",
295  "checkpoint", "info", "show", "timeout", "checkactive", (char*) NULL
296 };
297 
298 /* Generator function for command completion. STATE lets us know whether
299  * to start from scratch; without any state (i.e. STATE == 0), then we
300  * start at the top of the list.
301  */
302 static char * fun_generator(const char *texte, int state)
303 {
304  static int list_index, len;
305  char *name;
306 
307  /* If this is a new word to complete, initialize now. This includes
308  saving the length of TEXT for efficiency, and initializing the index
309  variable to 0. */
310  if (!state)
311  {
312  list_index = 0;
313  len = strlen (texte);
314  }
315 
316  /* Return the next name which partially matches from the command list. */
317  while ((name = completion_scheme[list_index].fun_name))
318  {
319  list_index++;
320 
321  if (strncmp (name, texte, len) == 0)
322  return (strdup(name));
323  }
324 
325  /* If no names matched, then return NULL. */
326  return NULL;
327 }
328 
329 
330 /* Build an array with the names of all available modules. */
331 
332 char **get_module_names(void)
333 {
334  static char **names = NULL;
335  static gen_array_t modules = NULL;
336 
337  if (names != NULL) {
338  /* Free after a previous use: */
339  free(names);
340  gen_array_full_free(modules);
341  /* By default, no available module: */
342  names = NULL;
343  }
344 
345  /* Mainly inspired from wpips/emacs.c
346 
347  Overkilling since most of time, the module list does not change but I
348  guess there is no indicator in PIPS to tell some modules have been
349  created or destroyed. */
350  if (db_get_current_workspace_name() != NULL) {
351  int module_list_length, i;
352  modules = db_get_module_list();
353  module_list_length = gen_array_nitems(modules);
354  /* Note that since calloc initialize the memory to 0, this array will
355  end with a NULL pointer as expected. */
356  names = calloc(module_list_length + 1, sizeof(char *));
357  for(i = 0; i < module_list_length; i++)
358  names[i] = gen_array_item(modules, i);
359  }
360  return names;
361 }
362 
363 /* Generator function for param. completion. STATE lets us know whether
364  * to start from scratch; without any state (i.e. STATE == 0), then we
365  * start at the top of the list.
366  */
367 static char * param_generator(const char *texte, int state)
368 {
369  static int list_index, len;
370  char *name;
371 
372  /* If this is a new word to complete, initialize now. This includes
373  saving the length of TEXT for efficiency, and initializing the index
374  variable to 0. */
375  if (!state)
376  {
377  int number_of_sep = 0;
378  int current_pos = 0;
380  int completion_type;
381 
382  pips_debug (9, "completing parameters\n\n");
383 
384  /*We should count the number of separator before the actual pos*/
385  while (rl_line_buffer[current_pos])
386  {
387  if (SEPARATOR_P(rl_line_buffer[current_pos]))
388  {
389  number_of_sep ++;
390  current_pos++;
391  while ((rl_line_buffer[current_pos]) &&
392  (SEPARATOR_P(rl_line_buffer[current_pos])))
393  current_pos++;
394  }
395  else
396  current_pos++;
397  }
398  pips_debug (9, "%d separator have been found on line\n\n",
399  number_of_sep);
400 
401  /* We scan the array of function to find
402  the used function */
403  while ((cs->fun_name) &&
404  !prefix_equal_p(rl_line_buffer, cs->fun_name))
405  {
406  cs++;
407  pips_debug (9, "text is '%s', function found is '%s'\n\n",
408  rl_line_buffer,
409  cs->fun_name!=NULL? cs->fun_name : "<none>");
410  }
411 
412  /* Now we can determine the completion type */
413  if (number_of_sep == 1)
414  completion_type = cs->first_completion_type;
415  else
416  completion_type = cs->other_completion_type;
417 
418  pips_debug (9, "completion type %d has been selected\n\n",
419  completion_type);
420 
421  switch (completion_type)
422  {
423  case COMP_NONE:
425  break;
426  case COMP_FILENAME:
427 #define RESERVED_FOR_FILENAME (char**) 0x01
429  break;
430  case COMP_MODULE:
432  break;
433  case COMP_RULE:
435  break;
436  case COMP_RESOURCE:
438  break;
439  case COMP_PROPERTY:
441  break;
442  case COMP_HELP_TOPIC:
444  break;
445  case COMP_FILE_RSC:
447  break;
448  default:
450  }
451  list_index = 0;
452  len = strlen (texte);
453  }
454 
455  if (current_completion_array == NULL)
456  return NULL;
458  return rl_filename_completion_function(texte,state);
459 
460  /* Return the next name which partially matches from the command list. */
461  while ((name = current_completion_array[list_index]))
462  {
463  list_index++;
464 
465  if (strncmp (name, texte, len) == 0)
466  return (strdup(name));
467  }
468 
469  /* If no names matched, then return NULL. */
470  return NULL;
471 }
472 
473 /* Attempt to complete on the contents of TEXT. START and END show the
474  * region of TEXT that contains the word to complete. We can use the
475  * entire line in case we want to do some simple parsing. Return the
476  * array of matches, or NULL if there aren't any.
477  */
478 static char ** fun_completion(char *texte, int start, int end)
479 {
480 
481  char **matches;
482 
483  matches = (char **)NULL;
484 
485  /* If this word is at the start of the line, then it is a command
486  to complete. Otherwise it is the name of a file in the current
487  directory. */
488  if (start == 0)
489  {
490  pips_debug (9, "completing function (START = %d, END= %d)\n\n",
491  start, end);
492  matches = rl_completion_matches (texte , fun_generator);
493  }
494  return matches;
495 }
496 
497 /* Tell the GNU Readline library how to complete. We want to try to complete
498  * on command names if this is the first word in the line, or on filenames
499  * if not.
500  */
501 static void initialize_readline(void)
502 {
503  // Allow conditional parsing of the ~/.inputrc file.
504  rl_readline_name = "Tpips";
505 
506  // allow "." to separate words
507  rl_basic_word_break_characters = " \t\n\"\\@$><=;|&{(";
508 
509  // Tell the completer that we want a crack first.
510 #if defined (_RL_FUNCTION_TYPEDEF)
511  rl_attempted_completion_function = (rl_completion_func_t *) fun_completion;
512 #else
513  rl_attempted_completion_function = (CPPFunction *) fun_completion;
514 #endif
515 
516  // function for completing parameters
517  rl_completion_entry_function = (rl_compentry_func_t *) param_generator;
518 
519  // do not override pips signals?
520  rl_catch_signals = 0;
521 }
522 
523 
524 /*************************************************** FILE OR TTY INTERACTION */
525 
526 /* returns the next line from the input, interactive tty or file...
527  * the final \n does not appear.
528  */
529 static char * get_next_line(char * prompt)
530 {
531  tpips_next_line();
532  return use_readline? readline(prompt): safe_readline(current_file);
533 }
534 
535 /* returns an allocated line read, including continuations.
536  * may return NULL at end of file.
537  */
538 static char * tpips_read_a_line(char * main_prompt)
539 {
540  char *line;
541  int l;
542 
543  line = get_next_line(main_prompt);
544 
545  // handle backslash-style continuations
546  while (line && (l=strlen(line), l>1 && line[l-1]==TPIPS_CONTINUATION_CHAR))
547  {
548  char * next = get_next_line(TPIPS_SECONDARY_PROMPT);
549  line[l-1] = '\0';
550  char * tmp = strdup(concatenate(line, next, NULL));
551  free(line); if (next) free(next);
552  line = tmp;
553  }
554 
555  // keep track of commands (there is also a log_file...)
556  if (logfile && line)
557  fprintf(logfile,"%s\n",line);
558 
559  pips_debug(3, "line is --%s--\n", line? line: "<NULL>");
560 
561  return line;
562 }
563 
564 /************************************************* TPIPS HANDLERS FOR PIPS */
565 
566 /* Tpips user request */
567 
568 #define BEGIN_RQ "begin_user_request"
569 #define END_RQ "end_user_request"
570 
571 static string tpips_user_request(const char * fmt, va_list * args)
572 {
573  char * response;
574  va_list acpy;
575  va_copy(acpy, *args);
576 
577  debug_on("TPIPS_DEBUG_LEVEL");
578 
579  if (jpips_is_running)
580  {
582  jpips_string( fmt, acpy);
583  jpips_printf("\n");
584  jpips_tag(END_RQ);
585  }
586  else if (use_readline)
587  {
588  (void) fprintf(stdout,"\nWaiting for your response: ");
589  (void) vfprintf(stdout, fmt, acpy);
590  fflush(stdout);
591  }
592  va_end(acpy);
593 
595 
596  pips_debug(2, "returning --%s--\n", response? response: "<NULL>");
597 
598  debug_off();
599 
600  return response;
601 }
602 
603 /********************************************************** TPIPS USER ERROR */
604 
605 #define BEGIN_UE "begin_user_error"
606 #define END_UE "end_user_error"
607 
608 /* handle a user error
609  * DO NOT TERMINATE here, see pips_log_end
610  */
611 static void tpips_user_error(
612  const char * calling_function_name,
613  const char * format,
614  va_list * args)
615 {
616  if (jpips_is_running)
617  {
618  va_list acpy;
619  va_copy(acpy, *args);
621  jpips_printf("%s\n", calling_function_name);
622  jpips_string(format, acpy);
623  jpips_tag(END_UE);
624  va_end(acpy);
625  }
626 
627  if (properties_initialized_p() &&
628  get_bool_property("CLOSE_WORKSPACE_AND_QUIT_ON_ERROR"))
629  {
631  {
632  pips_user_warning("Close workspace and quit on user error requested.");
633  db_close_workspace(true);
634  }
635  }
636 
637  // DO NOT TERMINATE
638 }
639 
640 /* In case of a tpips internal error, either core dump or try to save
641  * the workspace.
642 */
644  _UNUSED_ const char * calling_function_name,
645  _UNUSED_ const char * a_message_format,
646  ...)
647 {
648  if (get_bool_property("CLOSE_WORKSPACE_AND_QUIT_ON_ERROR"))
649  {
650  // Try to close the workspace... hmmm, it may raise an internal error...
651  db_close_workspace(true);
652  // FI: it should be exit(1), but this is not compatible with the
653  // current validation process. -- FC: why???
654  exit(1);
655  }
656 }
657 
658 /* returns the allocated full tpips history file name, i.e.
659  * - $TPIPS_HISTORY (if any)
660  * - $HOME/"TPIPS_HISTORY"
661  */
662 static string default_hist_file_name(void)
663 {
664  string home, hist = getenv(TPIPS_HISTENV);
665  if (hist) return strdup(hist);
666  /* else builds the default name.
667  */
668  home = getenv("HOME");
669  return strdup(concatenate(home? home: "", "/", TPIPS_HISTORY, NULL));
670 }
671 
672 static void initialize_tpips_history(void)
673 {
675  // read the history file, then point to the last entry.
676  using_history();
677  read_history(file_name);
678  free(file_name);
679  history_set_pos(history_length);
680 }
681 
682 /* Handlers
683  */
684 #define TP_HELP(prefix, simple, full) \
685  if (!*line || prefix_equal_p(line, prefix)) { \
686  printf(simple); if (*line) printf(full);}
687 
688 void tpips_help(string line)
689 {
690  skip_blanks(line);
691 
692  printf("\n");
693  TP_HELP("readline", "* readline interaction facilities\n",
694  "\ttry <tab><tab> for automatic completion\n"
695  "\temacs-tyle editing capabilities (see man readline)\n");
696  TP_HELP("create", "create <workspace-name> <file-name>...\n",
697  "\tcreate a new worspace from a list of fortran files\n"
698  "\tfirst delete the workspace if it exists\n");
699  TP_HELP("open", "open <workspace-name>\n",
700  "\topen an existing workspace\n");
701  TP_HELP("checkactive", "checkactive <resourcename>\n",
702  "\ttell which phase would produce this resource.\n");
703  TP_HELP("checkpoint", "checkpoint\n",
704  "\tcheckpoint the current workspace\n");
705  TP_HELP("close", "close\n",
706  "\tclose the current opened workspace\n");
707  TP_HELP("delete", "delete <workspace-name>\n",
708  "\tdelete an existing workspace\n");
709  TP_HELP("module", "module <module-name>\n",
710  "\tselect a module from an opened workspace\n");
711  TP_HELP("activate", "activate <rule-name>\n",
712  "\ttell a rule to be active\n");
713  TP_HELP("make", "make <resourcename([OWNER])>\n",
714  "\tbuild a resource\n"
715  "\n\tExamples:\n\n"
716  "\t\t make PRINTED_FILE\n"
717  "\t\t make CALLGRAPH_FILE[my_module]\n"
718  "\t\t make DG_FILE[%%ALL]\n"
719  "\t\t make ICFG_FILE[%%CALLEES]\n\n");
720  TP_HELP("apply", "apply <rulename[(OWNER)]>\n",
721  "\tmake the produced resources of a rule\n"
722  "\n\tExamples:\n\n"
723  "\t\t apply PRINT_SOURCE_WITH_REGIONS\n"
724  "\t\t apply HPFC_CLOSE[my_module]\n"
725  "\t\t apply PRINT_CODE[%%ALL]\n"
726  "\t\t apply PRINT_ICFG[%%CALLEES]\n");
727  TP_HELP("capply", "capply <rulename[(OWNER)]>\n",
728  "\tconcurrently apply a transformation rule\n"
729  "\n\tExamples:\n\n"
730  "\t\t apply SUPPRESS_DEAD_CODE[%%ALL]\n"
731  "\t\t apply PARTIAL_EVAL[%%CALLEES]\n");
732  TP_HELP("display", "display <fileresourcename([OWNER])>\n",
733  "\tprint a file resource\n"
734  "\n\tExamples:\n\n"
735  "\t\t display PRINTED_FILE\n"
736  "\t\t display CALLGRAPH_FILE[my_module]\n"
737  "\t\t display DG_FILE[%%ALL]\n"
738  "\t\t display ICFG_FILE[%%CALLEES]\n\n");
739  TP_HELP("remove", "remove <resourcename([OWNER])>\n",
740  "\tremove a resource from the database.\n");
741  TP_HELP("cd", "cd <dirname>\n",
742  "\tchange directory\n");
743  TP_HELP("pwd", "pwd\n", "\tprint current working directory\n");
744  TP_HELP("setenv", "setenv <name>=<value>\n",
745  "\tchange environment\n");
746  TP_HELP("unsetenv", "unsetenv <name>\n",
747  "\tremove variable from environment\n");
748  TP_HELP("getenv", "getenv <name>\n",
749  "\tprint from environment (echo ${<name>} also ok)\n");
750  TP_HELP("setproperty", "setproperty <name>=<value>\n",
751  "\tchange property\n");
752  TP_HELP(GET_PROP, GET_PROP " <name>\n",
753  "\t print property\n");
754  TP_HELP("echo", "echo <string>\n",
755  "\tprint the string\n");
756  TP_HELP("quit", "quit\n",
757  "\texit tpips (you should close the workspace before\n");
758  TP_HELP("exit", "exit\n",
759  "\texit tpips quickly (rhough!)\n");
760  TP_HELP("source", "source <filenames...>\n",
761  "\tread tpips commands from files.\n");
762  TP_HELP("help", "help (<help-item>)\n",
763  "\tprint a list of all the commands or a \"detailled\""
764  " description of one\n");
765  TP_HELP("show", "show <resourcename([OWNER])>\n",
766  "\treturns the file of this resource\n");
767  TP_HELP("timeout", "timeout <delay>\n",
768  "\tset pips timeout in seconds\n");
769  TP_HELP("info", "info <name>\n",
770  "\tprint information about <name>\n"
771  "\tname: module, modules, workspace, directory\n");
772  TP_HELP("shell", "shell [<shell-function>]\n",
773  "\tallow shell functions call\n");
774  TP_HELP("version", "version\n",
775  "\tshow tpips version informations, such as:\n"
776  "\t\trepository revisions used by the compilation\n"
777  "\t\tdate of compilation\n"
778  "\t\tcompiler used\n");
779  TP_HELP("owner", "- owner : variable*\n",
780  "\tList of available owners:\n"
781  "\t\t%%MODULE\n"
782  "\t\t%%ALL\n"
783  "\t\t%%ALLFUNC\n"
784  "\t\t%%PROGRAM\n"
785  "\t\t%%CALLEES\n"
786  "\t\t%%CALLERS\n"
787  "\t\t<module_name>\n");
788  TP_HELP("*", "* default rule...\n",
789  "\tan implicit \"shell\" is assumed.\n");
790 
791  if (!*line || prefix_equal_p(line,"rulename") ||
792  prefix_equal_p(line,"rule")) {
793  printf("* rulename : variable*\n");
794  if (*line) {
795  char ** ps = tp_phase_names;
796  int big_size = 0;
797  int current_size;
798  int columns, count;
799 
800  while (*ps) {
801  current_size = strlen (*ps);
802  if (big_size < current_size)
803  big_size = current_size;
804  ps++;
805  }
806  big_size++;
807  /* get the number of colunms for 80 chars */
808  columns = tgetnum ("co");
809  pips_debug (1, "number of columns is %d\n", columns);
810  columns = (columns > 0) ? columns /big_size : 1;
811  count = 1;
812  printf("\tList of available rules\n");
813  ps = tp_phase_names;
814  while (*ps)
815  {
816  printf("%-*s",big_size,*ps);
817  if ((count % columns) == 0)
818  printf("\n");
819  ps++;
820  count++;
821  }
822  }
823  }
824  if (!*line || prefix_equal_p(line,"resourcename") ||
825  prefix_equal_p(line,"resource")) {
826  printf("* resourcename : variable*\n");
827  if (*line) {
828  char ** ps = tp_resource_names;
829  int big_size = 0;
830  int current_size;
831  int columns, count;
832 
833  while (*ps)
834  {
835  current_size = strlen (*ps);
836  if (big_size < current_size)
837  big_size = current_size;
838  ps++;
839  }
840  /* get the number of colunms for 80 chars */
841  columns = tgetnum ("co");
842  big_size++;
843  pips_debug (1, "number of columns is %d\n", columns);
844  columns = (columns > 0) ? columns /big_size : 1;
845  count = 1;
846  printf("\tList of available resources\n");
847  ps = tp_resource_names;
848  while (*ps)
849  {
850  printf("%-*s",big_size,*ps);
851  if ((count % columns) == 0)
852  printf("\n");
853  ps++;
854  count++;
855  }
856  }
857  }
858  printf("\n");
859  fflush(stdout);
860 }
861 
862 static void close_workspace_if_opened(bool is_quit)
863 {
865  close_workspace(is_quit);
866 }
867 
868 void tpips_close(void)
869 {
870  // close history: truncate list and write history file
871  if (use_readline)
872  {
874  stifle_history(TPIPS_HISTORY_LENGTH);
875  write_history(file_name);
876  }
877 
879 
880  if (logfile) {
881  safe_fclose (logfile, "the log file");
882  logfile = NULL;
883  }
884 
885  // do not close yet!
886  //close_xml_logfile();
887 }
888 
889 /* in lex file
890  */
891 extern void tpips_set_line_to_parse(char*);
892 extern char * tpips_get_line_to_parse(void);
893 
894 static void handle(string line)
895 {
897 
898  /* parse if non-null line */
899  if (*tpips_get_line_to_parse()) {
900  tp_init_lex ();
901  tp_parse ();
902  }
903 
904  fflush(stderr);
905  fflush(stdout);
906 }
907 
908 /*************************************************************** DO THE JOB */
909 
910 /* whether some substitutions are needed...
911  * variables are restricted to the ${xxx} syntax.
912  */
913 static bool line_with_substitutions(string line)
914 {
915  static char SHELL_CHARS[] = "${`*?"; /* autres : ~ ??? */
916  while (*line)
917  {
918  if (strchr(SHELL_CHARS, *line))
919  return true;
920  line++;
921  }
922  return false;
923 }
924 
925 /* returns an allocated string after shell substitutions.
926  */
927 static string tp_substitutions(string line)
928 {
929  string substituted;
930 
931  /* shell and comments are not substituted...
932  */
933  if (!prefix_equal_p(line, "shell") && !prefix_equal_p(line, "!")
935  {
936  /* substitutions are performed by forking sh;-)
937  * however sh does not understand ~
938  */
939  substituted = safe_system_substitute(line);
940  if (!substituted)
941  {
942  tpips_init();
943  pips_user_warning("error in shell substitutions...\n");
944  if (get_bool_property("ABORT_ON_USER_ERROR")) abort();
945  substituted = strdup(line);
946  }
947  if (line_with_substitutions(substituted))
948  {
949  // not sure whether there is really an error, so we cannot abort
950  tpips_init();
951  pips_user_warning("maybe error in substituted lines:\n\t%s\n"
952  "For instance, check location of your source files.\n",
953  substituted);
954  }
955  }
956  else
957  substituted = strdup(line);
958 
959  pips_debug(2, "after substitution: %s\n", substituted);
960  return substituted;
961 }
962 
963 /* variable globale, utilisee par le parser helas */
964 bool tpips_init_done = false;
965 /* Pipsmake does not enforce consistency when properties are
966  changed. The consistency can be enforced by forbidding setproperty
967  during a processing phase. */
969 
970 void tpips_init(void)
971 {
972  if (tpips_init_done) return;
973 
974  in_from_jpips = stdin;
975  out_to_jpips = stdout;
976 
977  pips_checks();
978 
981  /* set_exception_callbacks(push_pips_context, pop_pips_context); */
982  /* initialize_signal_catcher(); */
983 
984  set_bool_property("ABORT_ON_USER_ERROR", false); /* ??? */
985  consistency_enforced_p = get_bool_property("CONSISTENCY_ENFORCED_P");
986 
990 
991  tpips_init_done = true;
992 }
993 
994 static bool blank_or_comment_line_p(string line)
995 {
996  skip_blanks(line);
997  return line[0]==TPIPS_COMMENT_PREFIX || line[0]=='\0';
998 }
999 
1000 static void tpips_exec(char * line)
1001 {
1002  pips_debug(3, "considering line: %s\n", line? line: " --- empty ---");
1003 
1005 
1007  {
1009 
1011  {
1012  // hmmm... what should it do on timeout?
1013  // currently this is a clean "quit"... should it abort? other??
1014  tpips_close();
1015  pips_stop(user_error_log, TIMEOUT_CODE, "tpips stopped on timeout");
1016  }
1017 
1018  // on other errors, restart
1019  pips_debug(2, "restating tpips scanner\n");
1020  tp_restart(tp_in);
1021  }
1022  TRY
1023  {
1024  char * sline; /* after environment variable substitution */
1025  if (use_readline && line)
1026  add_history(strdup(line));
1027 
1028  pips_debug(2, "restarting tpips scanner\n");
1029  tp_restart(tp_in);
1030 
1031  /* leading setenv/getenv in a tpips script are performed
1032  * PRIOR to pips initialization, hence the environment variable
1033  * NEWGEN_MAX_TABULATED_ELEMENTS can be taken into account
1034  * for a run. little of a hack. That results in a core
1035  * dump when the tpips script starts with setenv
1036  * commands generating user warnings because those
1037  * imply a check of the property NO_USER_WARNING. Also
1038  * errors are likely to lead to a check of
1039  * ABORT_ON_USER_ERROR. And properties cannot be used
1040  * before tpips_init() has been executed. So
1041  * pips_user_warning() have to be protected in tpips.c
1042  * by a preliminary call to tpips_init()
1043  */
1044  if (!tpips_init_done &&
1045  strncmp(line, SET_ENV, strlen(SET_ENV))!=0 &&
1046  strncmp(line, GET_ENV, strlen(GET_ENV))!=0 &&
1047  strncmp(line, TPIPS_SOURCE, strlen(TPIPS_SOURCE))!=0 &&
1049  tpips_init();
1050 
1051  sline = tp_substitutions(line);
1052  handle(sline);
1053  free(sline), sline = (char*) NULL;
1054 
1056  }
1057 }
1058 
1059 /* processing command line per line.
1060  * might be called recursively thru source.
1061  */
1062 void tpips_process_a_file(FILE * file, string name, bool use_rl)
1063 {
1064  static bool readline_initialized = false;
1065  char * line;
1066 
1067  // PUSH
1068  FILE * saved_file = current_file;
1069  string saved_name = current_name;
1070  int saved_line = current_line;
1071  bool saved_use_rl = use_readline;
1072 
1073  /* push globals */
1074  current_file = file;
1075  current_name = name;
1076  current_line = 0;
1077  use_readline = use_rl;
1078 
1079  if (use_readline && !readline_initialized)
1080  {
1083  readline_initialized = true;
1084  }
1085 
1086  /* interactive loop
1087  */
1089  {
1090  tpips_exec(line);
1091  free(line);
1092  if (jpips_is_running && file==stdin) jpips_done();
1093  }
1094 
1095  // POP
1096  current_file = saved_file;
1097  current_name = saved_name;
1098  current_line = saved_line;
1099  use_readline = saved_use_rl;
1100 }
1101 
1102 /* default .tpipsrc is $HOME/.tpipsrc. the returned string is allocated.
1103  */
1104 static string default_tpipsrc(void)
1105 {
1106  return strdup(concatenate(getenv("HOME"), "/.tpipsrc", NULL));
1107 }
1108 
1109 extern char *optarg;
1110 extern int optind;
1111 
1112 static void open_logfile(string filename, char opt)
1113 {
1114  if (logfile)
1115  {
1116  fprintf(logfile,
1117  "# logfile moved to %s by -%c tpips option\n", filename, opt);
1118  safe_fclose(logfile, "the current log file");
1119  }
1120  logfile = safe_fopen(filename, "w");
1121 }
1122 
1123 // regenerated in revision.c
1124 extern const char *soft_revisions, *soft_date, *cc_version;
1125 
1126 static void parse_arguments(int argc, char * argv[])
1127 {
1128  int c, opt_ind;
1129  string tpipsrc = default_tpipsrc();
1130  static struct option lopts[] = {
1131  { "version", 0, NULL, 'v' },
1132  { "jpips", 0, NULL, 'j' },
1133  { "help", 0, NULL, 'h' },
1134  { "shell", 0, NULL, 's' },
1135  { "log", 1, NULL, 'l' },
1136  { "rc", 1, NULL, 'r' },
1137  { "xml", 1, NULL, 'x' },
1138  { NULL, 0, NULL, 0 }
1139  };
1140 
1141  while ((c = getopt_long(argc, argv, "ane:l:h?vscr:jwx:", lopts, &opt_ind))
1142  != -1)
1143  {
1144  switch (c)
1145  {
1146  case 'j':
1147  jpips_is_running = true;
1148  // -j => -a
1149  _FALLTHROUGH_;
1150  case 'a':
1151  {
1152  string filename = safe_new_tmp_file("tpips_session");
1153  fprintf(stderr, "tpips session logged in \"%s\"\n", filename);
1154  open_logfile(filename, c);
1155  free(filename);
1156  break;
1157  }
1158  case 's':
1159  tpips_is_a_shell = true;
1160  break;
1161  case 'c':
1162  tpips_is_a_shell = false;
1163  break;
1164  case 'l':
1165  open_logfile(optarg, c);
1166  break;
1167  case 'x':
1169  break;
1170  case 'h':
1171  case '?':
1172  fprintf (stderr, tpips_usage, argv[0]);
1173  return;
1174  break;
1175  case 'n':
1176  tpips_execution_mode = false;
1177  break;
1178  case 'e':
1179  tpips_exec(optarg);
1180  break;
1181  case 'v':
1182  fprintf(stdout,
1183  "tpips: (%s)\n"
1184  "ARCH=" STRINGIFY(SOFT_ARCH) "\n"
1185  "REVS=\n"
1186  "%s"
1187  "DATE=%s\n"
1188  "CC_VERSION=%s\n",
1189  argv[0], soft_revisions, soft_date, cc_version);
1190  exit(0);
1191  break;
1192  case 'r':
1193  free(tpipsrc);
1194  tpipsrc = strdup(optarg);
1195  break;
1196  case 'w':
1197  tpips_wrapper(); /* the wrapper process will never return */
1198  break;
1199  default:
1200  fprintf(stderr, tpips_usage, argv[0]);
1201  exit(1);
1202  }
1203  }
1204 
1205  /* sources ~/.tpipsrc or the like, if any.
1206  */
1207  if (tpipsrc)
1208  {
1209  if (file_exists_p(tpipsrc))
1210  {
1211  FILE * rc = fopen(tpipsrc, "r");
1212  if (rc)
1213  {
1214  user_log("sourcing tpips rc file: %s\n", tpipsrc);
1215  tpips_process_a_file(rc, tpipsrc, false);
1216  fclose(rc);
1217  }
1218  }
1219  free(tpipsrc), tpipsrc=NULL;
1220  }
1221 
1222  if (argc == optind)
1223  {
1224  /* no arguments, parses stdin. */
1225  bool use_rl = isatty(0);
1226  tpips_is_interactive = use_rl;
1227  pips_debug(1, "reading from stdin, which is%s a tty\n",
1228  use_rl ? "" : " not");
1229  tpips_process_a_file(stdin, "<stdin>", use_rl);
1230  }
1231  else
1232  {
1233  /* process file arguments. */
1234  while (optind < argc)
1235  {
1236  string tps = NULL, saved_srcpath = NULL;
1237  FILE * toprocess = (FILE*) NULL;
1238  bool use_rl = false;
1239 
1240  if (same_string_p(argv[optind], "-"))
1241  {
1242  tps = strdup("-");
1243  toprocess = stdin;
1244  use_rl = isatty(0);
1245  tpips_is_interactive = use_rl;
1246  }
1247  else
1248  {
1249  tpips_is_interactive = false;
1250  tps = find_file_in_directories(argv[optind],
1251  getenv("PIPS_SRCPATH"));
1252  if (tps)
1253  {
1254  /* the tpips dirname is appended to PIPS_SRCPATH */
1255  string dir = pips_dirname(tps);
1257  saved_srcpath = pips_srcpath_append(dir);
1258  free(dir), dir = NULL;
1259 
1260  if ((toprocess = fopen(tps, "r"))==NULL)
1261  {
1262  perror(tps);
1263  fprintf(stderr, "[TPIPS] cannot open \"%s\"\n", tps);
1264  free(tps), tps=NULL;
1265  }
1266 
1267  use_rl = false;
1268  }
1269  else
1270  fprintf(stderr, "[TPIPS] \"%s\" not found...\n",
1271  argv[optind]);
1272  }
1273 
1274  if (tps)
1275  {
1276  pips_debug(1, "reading from file %s\n", tps);
1277 
1278  tpips_process_a_file(toprocess, tps, use_rl);
1279 
1280  safe_fclose(toprocess, tps);
1281  if (!same_string_p(tps, "-"))
1282  free(tps), tps = NULL;
1283  }
1284 
1285  if (saved_srcpath)
1286  {
1287  pips_srcpath_set(saved_srcpath);
1288  free(saved_srcpath), saved_srcpath = NULL;
1289  }
1290 
1291  optind++;
1292  }
1293  }
1294 }
1295 
1296 /* MAIN: interactive loop and history management.
1297  */
1298 int tpips_main(int argc, char * argv[])
1299 {
1300  // what about initialize_sc?
1302  debug_on("TPIPS_DEBUG_LEVEL");
1304  /* I need this one right now, as tpips init may be called too late. */
1307 
1308  {
1309  char *pid = NULL;
1310  asprintf(&pid, "PID=%d", (int) getpid());
1311  putenv(pid);
1312  }
1313 
1314  parse_arguments(argc, argv);
1315  fprintf(stdout, "\n"); // for Ctrl-D terminations
1316  tpips_close();
1317  pips_stop(info_log, 0, "tpips end of main");
1318  return 0; // not reached
1319 }
1320 
1321 
1322 /*************************************************************** IS IT A... */
1323 
1324 #define CACHED_STRING_LIST(NAME) \
1325  bool NAME##_name_p(string name) \
1326  { \
1327  static hash_table cache = NULL; \
1328  if (!cache) { \
1329  char ** p; \
1330  cache = hash_table_make(hash_string, \
1331  2*sizeof(tp_##NAME##_names)/sizeof(char*)); \
1332  for (p=tp_##NAME##_names; *p; p++) \
1333  hash_put(cache, *p, (char*) 1); \
1334  } \
1335  \
1336  return hash_get(cache, name)!=HASH_UNDEFINED_VALUE; \
1337  }
1338 
1339 CACHED_STRING_LIST(phase)
void(* pips_internal_error_handler)(const char *, const char *,...)
PIPS_ERROR is a function that should be called to terminate PIPS execution when data structures are c...
Definition: message.c:511
void open_xml_logfile(const char *filename)
Definition: message.c:607
void user_log(const char *format,...)
Definition: message.c:234
bool properties_initialized_p(void)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
string(* pips_request_handler)(const char *, va_list *)
default assignment of pips_request_handler is default_user_request.
Definition: message.c:139
void(* pips_error_handler)(const char *, const char *, va_list *)
PROMPT_USER schould be implemented.
Definition: message.c:455
void set_pips_meta_informations(const char *revs, const char *date, const char *comp)
Definition: message.c:102
static int count
Definition: SDG.c:519
#define CATCH(what)
@ timeout_error
@ any_exception_error
catch all
#define UNCATCH(what)
#define TRY
linear_exception_t the_last_just_thrown_exception
void set_exception_callbacks(exception_callback_t, exception_callback_t)
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void gen_array_full_free(gen_array_t a)
Definition: array.c:77
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
static char * tp_file_rsc_names[]
static char * tp_phase_names[]
static char * tp_resource_names[]
static char * tp_property_names[]
bool close_workspace(bool is_quit)
Definition: dbm.c:346
void push_pips_context(char const *file, char const *function, int line)
exception.c
Definition: exception.c:43
void pop_pips_context(char const *file, char const *function, int line)
Definition: exception.c:50
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
bool file_exists_p(const char *name)
Definition: file.c:321
char * find_file_in_directories(const char *file_name, const char *dir_path)
returns an allocated string pointing to the file, possibly with an additional path taken from colon-s...
Definition: file.c:399
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
some path to file suffix some path to *char * pips_dirname(char *fullpath)
Definition: file.c:837
char * safe_new_tmp_file(char *prefix)
SunOS forgets to declare this one.
Definition: file.c:935
char * safe_readline(FILE *file)
returns the allocated line read, whatever its length.
Definition: file.c:497
char * safe_system_substitute(char *what)
returns what after variable, command and file substitutions.
Definition: file.c:919
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void set_script_directory_name(string dn)
Definition: file_names.c:105
static int current_size
returns the number of bytes allocated for a given structure may need additional fonctions for externa...
Definition: genClib.c:2561
static char start[1024]
The name of the variable from which to start counting domain numbers.
Definition: genLisp.c:55
void free(void *)
gen_array_t db_get_module_list(void)
Get an array of all the modules (functions, procedures and compilation units) of a workspace.
Definition: database.c:1266
char end
Definition: gtk_status.c:82
void pips_checks(void)
add checkings here (FI: why in help.c?) SG : PIPS_ROOT should not be required :)
Definition: help.c:100
char *(* variable_debug_name)(Variable)
Debug support: pointer to the function used by debug print outs.
Definition: variable.c:114
#define debug_on(env)
Definition: misc-local.h:157
#define _UNUSED_
Definition: misc-local.h:232
#define TIMEOUT_CODE
Definition: misc-local.h:43
#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 STRINGIFY(symbol)
If not using this 2-stage macro evaluation, the generated string is not the value of the macro but th...
Definition: misc-local.h:50
#define asprintf
Definition: misc-local.h:225
@ user_error_log
Definition: misc-local.h:37
@ info_log
Definition: misc-local.h:33
#define pips_stop
Definition: misc-local.h:151
#define debug_off()
Definition: misc-local.h:160
#define exit(code)
Definition: misc-local.h:54
#define _FALLTHROUGH_
Definition: misc-local.h:238
#define abort()
Definition: misc-local.h:53
void set_debug_stack_pointer(const int i)
Definition: debug.c:97
_int get_debug_stack_pointer(void)
The pair get_ and set_debug_stack_pointer() should never be used except to clean up the stack after a...
Definition: debug.c:92
void initialize_newgen()
cproto-generated files
Definition: newgen.c:48
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
intptr_t _int
_INT
Definition: newgen_types.h:53
bool db_close_workspace(bool)
Definition: workspace.c:367
string db_get_current_workspace_name(void)
the function is used to check that there is some current workspace...
Definition: workspace.c:82
void initialize_signal_catcher(void)
Definition: signal.c:126
string pips_srcpath_append(string)
returns an allocated pointer to the old value
Definition: source_file.c:177
void pips_srcpath_set(string)
Set the PIPS source path.
Definition: source_file.c:167
void set_bool_property(const char *, bool)
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
void initialize_sc(char *(*var_to_string)(Variable))
Definition: sc_debug.c:253
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
int printf()
static int line
FLEX_SCANNER.
Definition: scanner.c:852
s1
Definition: set.c:247
static hash_table matches
Definition: simdizer.c:60
int first_completion_type
Definition: tpips.c:255
int other_completion_type
Definition: tpips.c:256
char * fun_name
Definition: tpips.c:254
int tp_parse(void)
#define SET_PROP
Definition: tpips-local.h:63
void tp_init_lex()
#define ECHO_N
macro ECHO is reserved by flex
Definition: tpips-local.h:69
FILE * tp_in
Definition: tpips.h:128
#define SHELL_ESCAPE
Definition: tpips-local.h:56
#define TPIPS_HISTORY_LENGTH
Definition: tpips-local.h:52
#define GET_ENV
Definition: tpips-local.h:61
#define SET_ENV
Definition: tpips-local.h:60
#define TPIPS_SOURCE
Definition: tpips-local.h:58
#define TPIPS_SECONDARY_PROMPT
Definition: tpips-local.h:48
#define TPIPS_REQUEST_PROMPT
Definition: tpips-local.h:47
#define CHANGE_DIR
Definition: tpips-local.h:57
#define GET_PROP
Definition: tpips-local.h:64
#define TPIPS_COMMENT_PREFIX
Definition: tpips-local.h:53
#define TPIPS_HISTENV
Definition: tpips-local.h:51
#define TPIPS_CONTINUATION_CHAR
Definition: tpips-local.h:49
#define skip_blanks(str)
Definition: tpips-local.h:71
#define QUIT
Definition: tpips-local.h:66
#define HELP
Definition: tpips-local.h:67
#define TPIPS_HISTORY
Definition: tpips-local.h:54
#define TPIPS_PRIMARY_PROMPT
Definition: tpips-local.h:46
#define BEGIN_UE
Definition: tpips.c:605
void tpips_close(void)
Definition: tpips.c:868
static void initialize_readline(void)
Tell the GNU Readline library how to complete.
Definition: tpips.c:501
static void tpips_exec(char *line)
Definition: tpips.c:1000
static void close_workspace_if_opened(bool is_quit)
Definition: tpips.c:862
void tpips_process_a_file(FILE *file, string name, bool use_rl)
processing command line per line.
Definition: tpips.c:1062
#define tpips_usage
tp_lex.c
Definition: tpips.c:106
int tgetnum()
static FILE * in_from_jpips
Ronan suggested a signal driven handling of jpips requests, so as to let the prompt available for dir...
Definition: tpips.c:179
bool tpips_init_done
variable globale, utilisee par le parser helas
Definition: tpips.c:964
static void tpips_user_error(const char *calling_function_name, const char *format, va_list *args)
handle a user error DO NOT TERMINATE here, see pips_log_end
Definition: tpips.c:611
const char * soft_date
Definition: tpips.c:1124
int tpips_current_line(void)
Definition: tpips.c:91
static void parse_arguments(int argc, char *argv[])
Definition: tpips.c:1126
static char * fun_generator(const char *texte, int state)
Generator function for command completion.
Definition: tpips.c:302
bool jpips_is_running
Definition: tpips.c:166
static char ** fun_completion(char *texte, int start, int end)
Attempt to complete on the contents of TEXT.
Definition: tpips.c:478
static bool tpips_is_a_shell
Definition: tpips.c:67
void tpips_help(string line)
Definition: tpips.c:688
static bool prefix_equal_p(string str, string prf)
Definition: tpips.c:125
void tpips_init(void)
Definition: tpips.c:970
static FILE * current_file
current file being processed, with its name and the line number
Definition: tpips.c:72
bool tpips_behaves_like_a_shell(void)
Definition: tpips.c:143
void tpips_next_line(void)
Definition: tpips.c:86
void jpips_end_tag(void)
Definition: tpips.c:197
bool consistency_enforced_p
Pipsmake does not enforce consistency when properties are changed.
Definition: tpips.c:968
static string tp_substitutions(string line)
returns an allocated string after shell substitutions.
Definition: tpips.c:927
static char * tp_help_topics[]
Definition: tpips.c:290
static char * tpips_read_a_line(char *main_prompt)
returns an allocated line read, including continuations.
Definition: tpips.c:538
static char ** current_completion_array
Definition: tpips.c:239
#define CACHED_STRING_LIST(NAME)
Definition: tpips.c:1324
int tpips_main(int argc, char *argv[])
MAIN: interactive loop and history management.
Definition: tpips.c:1298
static int current_line
Definition: tpips.c:74
#define BEGIN_RQ
Tpips user request.
Definition: tpips.c:568
void jpips_done(void)
Definition: tpips.c:216
#define SEPARATOR_P(c)
Definition: tpips.c:123
void jpips_string(const char *a_message_format, va_list some_arguments)
Definition: tpips.c:221
void tpips_set_line_to_parse(char *)
in lex file
Definition: tp_lex.c:953
#define END_RQ
Definition: tpips.c:569
string tpips_current_name(void)
Definition: tpips.c:96
void jpips_add_tag(string s)
Definition: tpips.c:192
static string tpips_user_request(const char *fmt, va_list *args)
Definition: tpips.c:571
static bool string_is_true(string s)
Definition: tpips.c:131
static bool use_readline
Definition: tpips.c:68
char * tpips_get_line_to_parse(void)
Definition: tp_lex.c:961
void tpips_internal_error(_UNUSED_ const char *calling_function_name, _UNUSED_ const char *a_message_format,...)
In case of a tpips internal error, either core dump or try to save the workspace.
Definition: tpips.c:643
const char * cc_version
Definition: tpips.c:1124
static string default_hist_file_name(void)
returns the allocated full tpips history file name, i.e.
Definition: tpips.c:662
#define TP_HELP(prefix, simple, full)
Handlers.
Definition: tpips.c:684
void jpips_tag2(string s1, string s2)
Definition: tpips.c:209
void jpips_begin_tag(string s)
Definition: tpips.c:187
void jpips_printf(const string format,...)
Definition: tpips.c:229
static bool blank_or_comment_line_p(string line)
Definition: tpips.c:994
bool tpips_is_interactive
Definition: tpips.c:65
const char * soft_revisions
could be shared somewhere?
Definition: revisions.c:33
int tpips_current_line_number()
Definition: tpips.c:81
static FILE * logfile
Definition: tpips.c:69
static FILE * out_to_jpips
Definition: tpips.c:180
#define TPIPS_IS_A_SHELL
Whether pips should behave as a shell.
Definition: tpips.c:141
#define END_UE
Definition: tpips.c:606
#define JPIPS_TAG
jpips specials.
Definition: tpips.c:164
static struct t_completion_scheme completion_scheme[]
Definition: tpips.c:259
static string default_tpipsrc(void)
default .tpipsrc is $HOME/.tpipsrc.
Definition: tpips.c:1104
static char * param_generator(const char *texte, int state)
Generator function for param.
Definition: tpips.c:367
string tpips_current_file_name()
Definition: tpips.c:76
static string current_name
Definition: tpips.c:73
static void initialize_tpips_history(void)
Definition: tpips.c:672
int optind
COMPLETION_TYPES
Definition: tpips.c:241
@ COMP_RESOURCE
Definition: tpips.c:246
@ COMP_MODULE
Definition: tpips.c:244
@ COMP_HELP_TOPIC
Definition: tpips.c:248
@ COMP_PROPERTY
Definition: tpips.c:247
@ COMP_RULE
Definition: tpips.c:245
@ COMP_FILENAME
Definition: tpips.c:243
@ COMP_FILE_RSC
Definition: tpips.c:249
@ COMP_NONE
Definition: tpips.c:242
void jpips_tag(string s)
Definition: tpips.c:203
char * optarg
void tp_restart(FILE *)
FILE * jpips_out_file(void)
Definition: tpips.c:182
#define RESERVED_FOR_FILENAME
bool tpips_execution_mode
Sometimes, already included by unistd.h.
Definition: tpips.c:64
static bool line_with_substitutions(string line)
whether some substitutions are needed...
Definition: tpips.c:913
static char * get_next_line(char *prompt)
returns the next line from the input, interactive tty or file...
Definition: tpips.c:529
char ** get_module_names(void)
Build an array with the names of all available modules.
Definition: tpips.c:332
static void open_logfile(string filename, char opt)
Definition: tpips.c:1112
static void handle(string line)
Definition: tpips.c:894
void tpips_wrapper(void)
wrapper.c
Definition: wrapper.c:270
static string file_name
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60