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 258 of file daVinci_wrapper.c.

259 {
261  (void) printf("%s\n", read_answer_from_daVinci());
262  send_command_to_daVinci("multi(open_context(\"Context_%d\"))",
264 }
void start_daVinci_if_not_running()
int daVinci_next_context_to_create
int printf()
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()

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

+ Here is the call graph for this function:

◆ main()

main ( void  )

Definition at line 279 of file daVinci_wrapper.c.

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

References exit, printf(), read_answer_from_daVinci(), 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 161 of file daVinci_wrapper.c.

165 {
166  pid_t pid;
167  int statusp;
168 
169  debug_on("DAVINCI_DEBUG_LEVEL");
170  pid = waitpid(daVinci_pid, &statusp, WNOHANG);
171 
172  pips_debug(5, "waitpid -> %d\n", pid);
173 
174  if (pid == -1) {
175  /* Not about daVinci, pass to the old handler: */
176  debug_off();
177  ( * old_SIGCHLD_handler)(sig, code, scp, addr);
178  }
179 
180  /* If the calling process is stopped, pid = 0: */
181  if (pid != 0 && (statusp & 255) != 127) {
182  /* Well, daVinci is no longer here... */
183  pips_debug(5, "daVinci pid %d exited with status %x\n",
184  daVinci_pid, statusp);
185  daVinci_pid = 0;
186  /* Restore the old handler: */
187  (void) signal(SIGCHLD, old_SIGCHLD_handler);
188  old_SIGCHLD_handler = NULL;
189  }
190  else {
191  /* Else, the process may have stopped: nothing to do. */
192  }
193  debug_off();
194 }
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 115 of file daVinci_wrapper.c.

116 {
117  char * command = read_answer_from_daVinci();
118  char * buffer = malloc(strlen(command));
119 
120  for(;;) {
121  if (strcmp(command, "ok\001")) {
122  pips_debug(8, "\"ok\" parsed\n");
123  break;
124  }
125 
126  /* I love scanf-based parser... :-) */
127  if (sscanf(command, "context(\"Context_%d\")\001",
128  &daVinci_current_context) == 1) {
129  pips_debug(8, "Current context set to %d\n",
131  break;
132  }
133 
134  if (sscanf(command, "communication_error(\"%s\")\001",
135  buffer) == 1) {
136  user_warning("daVinci said...",
137  "communication_error(\"%s\")", buffer);
138  break;
139  }
140  }
141 }
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 59 of file daVinci_wrapper.c.

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

147 {
148  va_list some_arguments;
149 
150  va_start(some_arguments, command_format);
151  vfprintf(write_to_daVinci_stream, command_format, some_arguments);
152  va_end(some_arguments);
153 
154  /* A "\n" is used by daVinci to end commands: */
156  fflush(write_to_daVinci_stream);
157 }
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 267 of file daVinci_wrapper.c.

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

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

+ Here is the call 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 198 of file daVinci_wrapper.c.

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

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.

+ Here is the call graph for this function:

Variable Documentation

◆ daVinci_current_context

int daVinci_current_context = 0

The daVinci context control:

Definition at line 48 of file daVinci_wrapper.c.

◆ daVinci_next_context_to_create

int daVinci_next_context_to_create = 0

Definition at line 49 of file daVinci_wrapper.c.

◆ 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 45 of file daVinci_wrapper.c.

◆ old_SIGCHLD_handler

void( * old_SIGCHLD_handler) () ( ) = NULL

To process some eventual handler somewhere else:

Definition at line 52 of file daVinci_wrapper.c.

◆ read_from_daVinci_fd

int read_from_daVinci_fd

Definition at line 56 of file daVinci_wrapper.c.

◆ write_to_daVinci_stream

FILE* write_to_daVinci_stream

The pipes to communicate with daVinci:

Definition at line 55 of file daVinci_wrapper.c.