PIPS
daVinci_wrapper.c File Reference
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include "genC.h"
#include "constants.h"
#include "misc.h"
+ Include dependency graph for daVinci_wrapper.c:

Go to the source code of this file.

Functions

static string read_answer_from_daVinci ()
 
static void parse_daVinci_answer ()
 
static void send_command_to_daVinci (string command_format,...)
 Send a command to daVinci with an à la printf syntax: More...
 
static void monitor_daVinci (int sig, int code, struct sigcontext *scp, char *addr)
 
void start_daVinci_if_not_running ()
 
void create_daVinci_new_context ()
 
void send_graph_to_daVinci (string graph_file_name)
 
 main ()
 

Variables

pid_t daVinci_pid = 0
 All the stuff to use the graph viewer daVinci from PIPS. More...
 
int daVinci_current_context = 0
 The daVinci context control: More...
 
int daVinci_next_context_to_create = 0
 
void(* old_SIGCHLD_handler )() = NULL
 To process some eventual handler somewhere else: More...
 
FILE * write_to_daVinci_stream
 The pipes to communicate with daVinci: More...
 
int read_from_daVinci_fd
 

Function Documentation

◆ create_daVinci_new_context()

void create_daVinci_new_context ( )

Definition at line 259 of file daVinci_wrapper.c.

260 {
262  (void) printf("%s\n", read_answer_from_daVinci());
263  send_command_to_daVinci("multi(open_context(\"Context_%d\"))",
265 }
void start_daVinci_if_not_running()
static void send_command_to_daVinci(string command_format,...)
Send a command to daVinci with an à la printf syntax:
static string read_answer_from_daVinci()
int daVinci_next_context_to_create
int printf()

References daVinci_next_context_to_create, printf(), read_answer_from_daVinci(), send_command_to_daVinci(), and start_daVinci_if_not_running().

Referenced by send_graph_to_daVinci().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ main()

main ( void  )

Definition at line 280 of file daVinci_wrapper.c.

281 {
282  /*
283  start_daVinci_if_not_running();
284  send_command_to_daVinci("multi(open_context(\"Context_1\"))");
285  */
286  send_graph_to_daVinci("ESSAI.pref-daVinci%");
287  send_graph_to_daVinci("ESSAI.pref-daVinci");
288  for (;;)
289  (void) printf("%s\n", read_answer_from_daVinci());
290 
291  safe_system("sleep 100");
292  exit(0);
293 }
void send_graph_to_daVinci(string graph_file_name)
#define exit(code)
Definition: misc-local.h:54
void safe_system(string)
system.c
Definition: system.c:38

References exit, printf(), read_answer_from_daVinci(), safe_system(), and send_graph_to_daVinci().

+ Here is the call graph for this function:

◆ monitor_daVinci()

static void monitor_daVinci ( int  sig,
int  code,
struct sigcontext *  scp,
char *  addr 
)
static

Not about daVinci, pass to the old handler:

If the calling process is stopped, pid = 0:

Well, daVinci is no longer here...

Restore the old handler:

Else, the process may have stopped: nothing to do.

Definition at line 162 of file daVinci_wrapper.c.

166 {
167  pid_t pid;
168  int statusp;
169 
170  debug_on("DAVINCI_DEBUG_LEVEL");
171  pid = waitpid(daVinci_pid, &statusp, WNOHANG);
172 
173  pips_debug(5, "waitpid -> %d\n", pid);
174 
175  if (pid == -1) {
176  /* Not about daVinci, pass to the old handler: */
177  debug_off();
178  ( * old_SIGCHLD_handler)(sig, code, scp, addr);
179  }
180 
181  /* If the calling process is stopped, pid = 0: */
182  if (pid != 0 && (statusp & 255) != 127) {
183  /* Well, daVinci is no longer here... */
184  pips_debug(5, "daVinci pid %d exited with status %x\n",
185  daVinci_pid, statusp);
186  daVinci_pid = 0;
187  /* Restore the old handler: */
188  (void) signal(SIGCHLD, old_SIGCHLD_handler);
189  old_SIGCHLD_handler = NULL;
190  }
191  else {
192  /* Else, the process may have stopped: nothing to do. */
193  }
194  debug_off();
195 }
pid_t daVinci_pid
All the stuff to use the graph viewer daVinci from PIPS.
void(* old_SIGCHLD_handler)()
To process some eventual handler somewhere else:
#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 debug_off()
Definition: misc-local.h:160
struct _newgen_struct_code_ * code
Definition: ri.h:79

References daVinci_pid, debug_off, debug_on, old_SIGCHLD_handler, and pips_debug.

Referenced by start_daVinci_if_not_running().

+ Here is the caller graph for this function:

◆ parse_daVinci_answer()

static void parse_daVinci_answer ( )
static

I love scanf-based parser... :-)

Definition at line 116 of file daVinci_wrapper.c.

117 {
118  char * command = read_answer_from_daVinci();
119  char * buffer = malloc(strlen(command));
120 
121  for(;;) {
122  if (strcmp(command, "ok\001")) {
123  pips_debug(8, "\"ok\" parsed\n");
124  break;
125  }
126 
127  /* I love scanf-based parser... :-) */
128  if (sscanf(command, "context(\"Context_%d\")\001",
129  &daVinci_current_context) == 1) {
130  pips_debug(8, "Current context set to %d\n",
132  break;
133  }
134 
135  if (sscanf(command, "communication_error(\"%s\")\001",
136  buffer) == 1) {
137  user_warning("daVinci said...",
138  "communication_error(\"%s\")", buffer);
139  break;
140  }
141  }
142 }
void * malloc(YYSIZE_T)
int daVinci_current_context
The daVinci context control:
#define user_warning(fn,...)
Definition: misc-local.h:262
static string buffer
Definition: string.c:113

References buffer, daVinci_current_context, malloc(), pips_debug, read_answer_from_daVinci(), and user_warning.

Referenced by start_daVinci_if_not_running().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ read_answer_from_daVinci()

static string read_answer_from_daVinci ( )
static

Allocate some place the first time:

A "\n" is used by daVinci to end answers:

Not optimized: read characters one by one...

End of answer found:

Deal with some '\' forms in strings:

Else, '\' -> '\', '"' -> '"' without doing anything.

No more place in the command buffer:

To mark the end to ease later parsing:

Definition at line 60 of file daVinci_wrapper.c.

61 {
62  static char * command = NULL;
63  static int command_size = 0;
64  int position = 0;
65  bool backslash_pending_p = FALSE;
66 
67  debug_on("DAVINCI_DEBUG_LEVEL");
68 
69  if (command_size == 0) {
70  /* Allocate some place the first time: */
71  command_size = 10;
72  command = malloc(10);
73  }
74 
75  /* A "\n" is used by daVinci to end answers: */
76  for(;;) {
77  char a_character;
78  /* Not optimized: read characters one by one... */
79  int length = read(read_from_daVinci_fd, &a_character, 1);
80  if (length == 0)
81  continue;
82 
83  if (length == 1) {
84  pips_debug(8, "Read character \"%c\" (%d)\n",
85  a_character, a_character);
86  if (a_character == '\n')
87  /* End of answer found: */
88  break;
89 
90  /* Deal with some '\' forms in strings: */
91  if (backslash_pending_p) {
92  backslash_pending_p = FALSE;
93  if (a_character == 'n')
94  a_character = '\n';
95  /* Else, '\\' -> '\', '\"' -> '"' without doing
96  anything. */
97  }
98  if (position == command_size - 2) {
99  /* No more place in the command buffer: */
100  command_size *= 2;
101  command = realloc(command, command_size);
102  }
103  command[position++] = a_character;
104  }
105  }
106  /* To mark the end to ease later parsing: */
107  command[position++] = '\001';
108  command[position] = '\0';
109 
110  debug_off();
111  return command;
112 }
int read_from_daVinci_fd

References debug_off, debug_on, malloc(), pips_debug, and read_from_daVinci_fd.

Referenced by create_daVinci_new_context(), main(), parse_daVinci_answer(), and send_graph_to_daVinci().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ send_command_to_daVinci()

static void send_command_to_daVinci ( string  command_format,
  ... 
)
static

Send a command to daVinci with an à la printf syntax:

A "\n" is used by daVinci to end commands:

Definition at line 147 of file daVinci_wrapper.c.

148 {
149  va_list some_arguments;
150 
151  va_start(some_arguments, command_format);
152  vfprintf(write_to_daVinci_stream, command_format, some_arguments);
153  va_end(some_arguments);
154 
155  /* A "\n" is used by daVinci to end commands: */
157  fflush(write_to_daVinci_stream);
158 }
FILE * write_to_daVinci_stream
The pipes to communicate with daVinci:
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References fprintf(), and write_to_daVinci_stream.

Referenced by create_daVinci_new_context(), and send_graph_to_daVinci().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ send_graph_to_daVinci()

void send_graph_to_daVinci ( string  graph_file_name)

Send the graph:

Definition at line 268 of file daVinci_wrapper.c.

269 {
271  (void) printf("%s\n", read_answer_from_daVinci());
272  (void) printf("%s\n", read_answer_from_daVinci());
273 
274  /* Send the graph: */
275  send_command_to_daVinci("menu(file(open_graph(\"%s\")))",
276  graph_file_name);
277 }
void create_daVinci_new_context()

References create_daVinci_new_context(), printf(), read_answer_from_daVinci(), and send_command_to_daVinci().

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ start_daVinci_if_not_running()

void start_daVinci_if_not_running ( )

It is not necessary to start another daVinci:

Create the 2 pipes to communicate with daVinci.

Hum, need some portability adjustment for SVR4...

This is the child:

Connect the PIPS pipes to stdin and stdout of daVinci:

Hum, the PIPS parent will go on...

The parent:

Install the handler to monitor daVinci:

Wait for the OK stuff.

Definition at line 199 of file daVinci_wrapper.c.

200 {
201  int pips_output_fd[2], pips_input_fd[2];
202 
203  debug_on("DAVINCI_DEBUG_LEVEL");
204  if (daVinci_pid != 0) {
205  /* It is not necessary to start another daVinci: */
206  debug_off();
207  return;
208  }
209 
210  /* Create the 2 pipes to communicate with daVinci.
211 
212  Hum, need some portability adjustment for SVR4... */
213  if (pipe(pips_output_fd) != 0 || pipe(pips_input_fd) != 0) {
214  perror("fork");
215  pips_internal_error("Cannot create the 2 pipes.\n");
216  }
217 
218  daVinci_pid = fork();
219  pips_debug(5, "daVinci_pid = %d\n", daVinci_pid);
220 
221  if (daVinci_pid == -1) {
222  perror("fork");
223  pips_internal_error("Cannot fork a process.\n");
224  }
225 
226  if (daVinci_pid == 0) {
227  /* This is the child: */
228  /* Connect the PIPS pipes to stdin and stdout of daVinci: */
229  if (dup2(pips_output_fd[0], fileno(stdin)) == -1
230  || dup2(pips_input_fd[1], fileno(stdout)) == -1) {
231  perror("dup2");
232  pips_internal_error("Cannot dup file descriptors.\n");
233  }
234 
235  execlp("daVinci", "daVinci", "-pipe", NULL);
236  perror("execl of daVinci");
237  pips_internal_error("Cannot start the daVinci process.\n");
238  /* Hum, the PIPS parent will go on... */
239  }
240  else {
241  /* The parent: */
242  write_to_daVinci_stream = fdopen(pips_output_fd[1], "w");
243  if (write_to_daVinci_stream == NULL)
244  pips_internal_error("Cannot fdopen pips_output_fd[1].\n");
245 
246  read_from_daVinci_fd = pips_input_fd[0];
247 
248  /* Install the handler to monitor daVinci: */
249  old_SIGCHLD_handler = signal(SIGCHLD, monitor_daVinci);
250 
251  /* Wait for the OK stuff. */
253  }
254  debug_off();
255 }
static void parse_daVinci_answer()
static void monitor_daVinci(int sig, int code, struct sigcontext *scp, char *addr)
#define pips_internal_error
Definition: misc-local.h:149

References daVinci_pid, debug_off, debug_on, monitor_daVinci(), old_SIGCHLD_handler, parse_daVinci_answer(), pips_debug, pips_internal_error, read_from_daVinci_fd, and write_to_daVinci_stream.

Referenced by create_daVinci_new_context().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ daVinci_current_context

int daVinci_current_context = 0

The daVinci context control:

Definition at line 49 of file daVinci_wrapper.c.

Referenced by parse_daVinci_answer().

◆ daVinci_next_context_to_create

int daVinci_next_context_to_create = 0

Definition at line 50 of file daVinci_wrapper.c.

Referenced by create_daVinci_new_context().

◆ daVinci_pid

pid_t daVinci_pid = 0

All the stuff to use the graph viewer daVinci from PIPS.

Ronan.nosp@m..Ker.nosp@m.yell@.nosp@m.cri..nosp@m.ensmp.nosp@m..fr To monitor if we have already running daVinci:

Definition at line 46 of file daVinci_wrapper.c.

Referenced by monitor_daVinci(), and start_daVinci_if_not_running().

◆ old_SIGCHLD_handler

void( * old_SIGCHLD_handler) () ( ) = NULL

To process some eventual handler somewhere else:

Definition at line 53 of file daVinci_wrapper.c.

Referenced by monitor_daVinci(), and start_daVinci_if_not_running().

◆ read_from_daVinci_fd

int read_from_daVinci_fd

Definition at line 57 of file daVinci_wrapper.c.

Referenced by read_answer_from_daVinci(), and start_daVinci_if_not_running().

◆ write_to_daVinci_stream

FILE* write_to_daVinci_stream

The pipes to communicate with daVinci:

Definition at line 56 of file daVinci_wrapper.c.

Referenced by send_command_to_daVinci(), and start_daVinci_if_not_running().