Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpLex.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Le module "lex.c" contient les procedures de gestion
33  * de l'analyse lexicale de l'analyseur lexicale "lex"
34  * d'un fichier source dont la grammaire possede
35  * les symboles terminaux suivants (ecrit en "LEX", UNIX) :
36  *
37  * Authors:
38  * Jean-Luc CORRE
39  *
40 *****************************************************************************/
41 
42 #include <visp3/core/vpConfig.h>
43 #include <visp3/core/vpException.h>
44 
45 #include "vpKeyword.h"
46 #include "vpMy.h"
47 #include "vpToken.h"
48 
49 #include <ctype.h>
50 #include <fcntl.h>
51 #include <math.h>
52 #include <stdarg.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #ifndef DOXYGEN_SHOULD_SKIP_THIS
57 
58 BEGIN_VISP_NAMESPACE
59 static void count(void);
60 static void next_source(void);
61 
62 void lexerr(const char *path, ...);
63 
64 /* Codes des symboles terminaux */
65 
66 #define NULT 0 /* caractere non valide */
67 #define EOBT 1 /* fin de buffer */
68 #define EOFT 2 /* fin de fichier */
69 #define EOLT 3 /* fin de ligne */
70 #define CMTT 4 /* commentaire */
71 #define IDNT 5 /* identificateur */
72 #define INTT 6 /* nombre entier */
73 #define FPTT 7 /* nombre flottant */
74 #define SGNT 8 /* signe +/- */
75 #define SPCT 9 /* caractere blanc */
76 #define STGT 10 /* caractere de chaine */
77 #define NBRT 11 /* nombre de codes */
78 
79 /* Drapeaux des caracteres */
80 
81 #define _NULT 0x00 /* caractere non valide */
82 #define _CMTT 0x01 /* commentaire */
83 #define _FPTT 0x02 /* nombre flottant */
84 #define _IDNT 0x04 /* identificateur */
85 #define _INTT 0x08 /* nombre entier */
86 #define _SGNT 0x10 /* signe +/- */
87 #define _STGT 0x20 /* caractere de chaine */
88 
89 /* Caracteres sentinelles */
90 
91 #define ASCII_NBR 128 /* nombre de codes ASCII*/
92 
93 #ifndef EOB
94 #define EOB (-2) /* fin de buffer */
95 #endif
96 #ifndef EOF
97 #define EOF (-1) /* fin de fichier */
98 #endif
99 #ifndef EOL
100 #define EOL 10 /* fin de ligne */
101 #endif
102 
103 #define CHAR_NBR 130 /* nombre de caracteres */
104 
105 /* Tests des drapeaux */
106 
107 #define isnult(c) (scantbl[c] == _NULT)
108 #define iscmtt(c) (scantbl[c] & _CMTT)
109 #define isfptt(c) (scantbl[c] & _FPTT)
110 #define isidnt(c) (scantbl[c] & _IDNT)
111 #define isintt(c) (scantbl[c] & _INTT)
112 #define issgnt(c) (scantbl[c] & _SGNT)
113 #define isstgt(c) (scantbl[c] & _STGT)
114 
115 /*
116  * Codes des messages d'erreur de l'analyseur lexicale.
117  */
118 #define E_UNKNOWN 0
119 #define E_SYMBOL 1
120 #define E_CMT_EOF 2
121 #define E_FLOAT 3
122 #define E_INT 4
123 #define E_KEYWORD 5
124 #define E_STG_EOF 6
125 #define E_STG_EOL 7
126 #define E_STRING 8
127 #define E_9 9
128 
129 const char *lex_errtbl[] = {/* table des messages d'erreur */
130  "error unknown",
131  "symbol undefined",
132  "unexpected EOF in comment",
133  "float expected",
134  "int expected",
135  "keyword expected",
136  "unexpected EOF in string or char constant",
137  "newline in string or char constant",
138  "string expected",
139  "" };
140 
141 char *mytext = NULL;
142 int mylength = 0;
143 int mylineno = 1;
144 unsigned int mycolumno = 0;
145 float myfloat = 0.0;
146 int myint = 0;
147 
148 static char *mysptr; /* tete de lecture de la ligne courante */
149 static char *myline; /* debut de la ligne courante */
150 static char *lastline; /* derniere ligne du buffer d'entree */
151 
152 static Byte *chtbl; /* premiers caracteres des terminaux */
153 static Byte *scantbl; /* caracteres suivants des terminaux */
154 
155 /*
156  * La procedure "open_lex" alloue et initialise les variables utilisees
157  * par l'analyseur lexical "lex".
158  */
159 void open_lex(void)
160 {
161  if ((chtbl = (Byte *)malloc(CHAR_NBR * sizeof(Byte))) == NULL ||
162  (scantbl = (Byte *)malloc(CHAR_NBR * sizeof(Byte))) == NULL) {
163  static char proc_name[] = "open_lex";
164  perror(proc_name);
165  throw vpException(vpException::fatalError, "Error in open_lex");
166  }
167  chtbl += 2; /* 2 sentinelles non affichables */
168  scantbl += 2;
169 
170  /* initialise les premiers caracteres des symboles terminaux */
171 
172  for (int i = 0; i < ASCII_NBR; i++) {
173  if (isalpha(i))
174  chtbl[i] = IDNT;
175  else if (isdigit(i))
176  chtbl[i] = INTT;
177  else if (isspace(i))
178  chtbl[i] = SPCT;
179  else
180  switch (i) {
181  case '"':
182  chtbl[i] = STGT;
183  break;
184  case '+':
185  case '-':
186  chtbl[i] = SGNT;
187  break;
188  case '.':
189  chtbl[i] = FPTT;
190  break;
191  case '/':
192  chtbl[i] = CMTT;
193  break;
194  case '_':
195  chtbl[i] = IDNT;
196  break;
197  default:
198  chtbl[i] = NULT;
199  break;
200  }
201  }
202 
203  /* Initialise les sentinelles comme des terminaux. */
204 
205  chtbl[EOB] = EOBT;
206  chtbl[EOF] = EOFT;
207  chtbl[EOL] = EOLT;
208 
209  /* Initialise les caracteres suivants des symboles terminaux. */
210 
211  for (int i = 0; i < ASCII_NBR; i++) {
212  if (isalpha(i))
213  scantbl[i] = _CMTT | _IDNT | _STGT;
214  else if (isdigit(i))
215  scantbl[i] = _CMTT | _IDNT | _INTT | _STGT;
216  else
217  switch (i) {
218  case '"':
219  scantbl[i] = _CMTT;
220  break;
221  case '+':
222  case '-':
223  scantbl[i] = _CMTT | _SGNT | _STGT;
224  break;
225  case '.':
226  scantbl[i] = _CMTT | _FPTT | _STGT;
227  break;
228  case '/':
229  scantbl[i] = _STGT;
230  break;
231  case '_':
232  scantbl[i] = _CMTT | _IDNT | _STGT;
233  break;
234  default:
235  scantbl[i] = _CMTT | _STGT;
236  break;
237  }
238  }
239 
240  /* Initialise les sentinelles comme des terminaux. */
241 
242  scantbl[EOB] = _NULT;
243  scantbl[EOF] = _NULT;
244  scantbl[EOL] = _NULT;
245 }
246 
247 /*
248  * La procedure "close_lex" libere les variables utilisees
249  * par l'analyseur lexical "lex".
250  */
251 void close_lex(void)
252 {
253  free((char *)(chtbl - 2)); /* voir "open_lex" pour "- 2" */
254  free((char *)(scantbl - 2));
255 }
256 
257 #define ECHO printf("%c", *(mysptr))
258 #define CURC (*((signed char *)mysptr)) /* caractere courant */
259 #define NEXTC (*((signed char *)mysptr + 1)) /* caractere suivant */
260 #define PREVC (*((signed char *)mysptr - 1)) /* caractere precedent */
261 
262 /*
263  * La procedure "lex" contient l'analyseur lexical.
264  * Note :
265  * La tete de lecture (mysptr) n'est pas systematiquement avancee apres
266  *lecture. Le caractere courant est celui sous la tete de lecture. Ainsi on
267  *accede de maniere symetrique aux caracteres precedent et suivant. Sortie :
268  * Code du symbole terminale analyse.
269  */
270 int lex(void)
271 {
272 lex_loop:
273 
274  for (; chtbl[(int)CURC] == SPCT; mysptr++) {
275  }; /* saute les espaces */
276 
277  switch (chtbl[(int)CURC]) {
278 
279  case NULT:
280  mytext = mysptr; /* sauvegarde le jeton */
281  mysptr++;
282  return (*mytext);
283  break;
284  case EOBT:
285  next_source();
286  goto lex_loop;
287  break;
288  case EOFT:
289  mytext = mysptr; /* sauvegarde le jeton */
290  return (T_EOF);
291  break;
292  case EOLT:
293  if (mysptr == lastline)
294  next_source();
295  else
296  mysptr++;
297  mylineno++;
298  myline = mysptr;
299  goto lex_loop;
300  break;
301  case CMTT:
302  mytext = mysptr; /* sauvegarde le jeton */
303  mysptr++;
304  if (CURC != '*')
305  return (*mytext);
306  mysptr++;
307  comment:
308  for (; iscmtt((int)CURC); mysptr++) {
309  };
310  switch (chtbl[(int)CURC]) {
311  case EOBT:
312  next_source();
313  goto comment;
314  break;
315  case EOFT:
316  lexerr("start", lex_errtbl[E_CMT_EOF], NULL);
317  return (T_EOF);
318  break;
319  case EOLT:
320  if (mysptr == lastline)
321  next_source();
322  else
323  mysptr++;
324  mylineno++;
325  myline = mysptr;
326  goto comment;
327  break;
328  case CMTT:
329  if (PREVC == '*') { /* veritable fin */
330  mysptr++;
331  goto lex_loop;
332  }
333  mysptr++; /* pseudo fin */
334  goto comment;
335  break;
336  }
337  break;
338  case IDNT:
339  mytext = mysptr; /* sauvegarde le jeton */
340  mysptr++;
341  for (; isidnt((int)CURC); mysptr++) {
342  };
343  mylength = (int)(mysptr - mytext);
344  return (get_symbol(mytext, mylength));
345  break;
346  case INTT:
347  mytext = mysptr; /* sauvegarde le jeton */
348  int_part:
349  myint = (int)(CURC - '0');
350  mysptr++;
351  for (; isintt((int)CURC); mysptr++)
352  myint = myint * 10 + (int)(CURC - '0');
353  switch (CURC) {
354  case '.': /* lecture fraction */
355  float_part:
356  mysptr++;
357  for (; isintt((int)CURC); mysptr++) {
358  };
359  if (CURC != 'E' && CURC != 'e') {
360  myfloat = (float)atof(mytext);
361  /* FC
362  printf("mytext %s, myfloat %f\n",mytext,myfloat);
363  */
364  return (T_FLOAT);
365  }
366  break;
367  case 'E': /* lecture exposant */
368  case 'e':
369  mysptr++;
370  if (isintt((int)CURC))
371  mysptr++;
372  else if (issgnt((int)CURC) && isintt((int)NEXTC))
373  mysptr += 2;
374  else {
375  mysptr--;
376  myfloat = (float)atof(mytext);
377  return (T_FLOAT);
378  }
379  for (; isintt((int)CURC); mysptr++) {
380  };
381  myfloat = (float)atof(mytext);
382  return (T_FLOAT);
383  break;
384  default:
385  if (*mytext == '-')
386  myint = -myint;
387  return (T_INT);
388  break;
389  }
390  break;
391  case FPTT:
392  mytext = mysptr; /* sauvegarde le jeton */
393  mysptr++;
394  if (!isintt((int)CURC)) /* pas de fraction */
395  return (*mytext);
396  goto float_part;
397  break;
398  case SGNT:
399  mytext = mysptr; /* sauvegarde le jeton */
400  mysptr++;
401  if (isintt((int)CURC))
402  goto int_part;
403  if (isfptt((int)CURC) && isintt((int)NEXTC))
404  goto float_part;
405  return (*mytext);
406  break;
407  case STGT:
408  mytext = mysptr; /* sauvegarde le jeton */
409  mysptr++;
410  string:
411  for (; isstgt((int)CURC); mysptr++) {
412  };
413  switch (chtbl[(int)CURC]) {
414  case EOBT:
415  next_source();
416  goto string;
417  break;
418  case EOFT:
419  lexerr("start", lex_errtbl[E_STG_EOF], NULL);
420  return ('\n');
421  break;
422  case EOLT:
423  lexerr("start", lex_errtbl[E_STG_EOL], NULL);
424  return ('\n');
425  break;
426  case STGT:
427  if (PREVC != '\\') { /* veritable fin */
428  mytext++;
429  mylength = (int)(mysptr - mytext);
430  mysptr++;
431  return (T_STRING);
432  }
433  mysptr++; /* pseudo fin */
434  goto string;
435  break;
436  }
437  break;
438  default:
439  ECHO;
440  mysptr++;
441  goto lex_loop;
442  break;
443  }
444  return (T_EOF);
445 }
446 
447 /*
448  * La procedure "lexecho" contient l'analyseur lexical "lex" :
449  * 1 Analyse le fichier source,
450  * 2 Affiche le fichier source sur le fichier "f",
451  * 3 Stoppe devant le jeton "token".
452  * Note :
453  * La tete de lecture (mysptr) n'est pas systematiquement avancee apres
454  *lecture. Le caractere courant est celui sous la tete de lecture. Ainsi on
455  *accede de maniere symetrique aux caracteres precedent et suivant. Entree :
456  * f Fichier en sortie.
457  * token Jeton de fin de rechercher.
458  * Sortie :
459  * Code du symbole terminale analyse.
460  */
461 int lexecho(FILE *f, int token)
462 {
463 lex_loop:
464  for (; chtbl[(int)CURC] == SPCT; mysptr++) /* saute les espaces */
465  fwrite(mysptr, 1, 1, f);
466 
467  switch (chtbl[(int)CURC]) {
468 
469  case NULT:
470  mytext = mysptr; /* sauvegarde le jeton */
471  mysptr++;
472  if (token != *mytext)
473  fwrite(mytext, 1, 1, f);
474  return (*mytext);
475  break;
476  case EOBT:
477  next_source();
478  goto lex_loop;
479  break;
480  case EOFT:
481  mytext = mysptr; /* sauvegarde le jeton */
482  return (T_EOF);
483  break;
484  case EOLT:
485  fwrite(mysptr, 1, 1, f);
486  if (mysptr == lastline)
487  next_source();
488  else
489  mysptr++;
490  mylineno++;
491  myline = mysptr;
492  goto lex_loop;
493  break;
494  case CMTT:
495  fwrite(mysptr, 1, 1, f);
496  mytext = mysptr; /* sauvegarde le jeton */
497  mysptr++;
498  if (CURC != '*')
499  return (*mytext);
500  fwrite(mysptr, 1, 1, f);
501  mysptr++;
502  comment:
503  for (; iscmtt((int)CURC); mysptr++)
504  fwrite(mysptr, 1, 1, f);
505  switch (chtbl[(int)CURC]) {
506  case EOBT:
507  next_source();
508  goto comment;
509  break;
510  case EOFT:
511  lexerr("start", lex_errtbl[E_CMT_EOF], NULL);
512  return (T_EOF);
513  break;
514  case EOLT:
515  fwrite(mysptr, 1, 1, f);
516  if (mysptr == lastline)
517  next_source();
518  else
519  mysptr++;
520  mylineno++;
521  myline = mysptr;
522  goto comment;
523  break;
524  case CMTT:
525  fwrite(mysptr, 1, 1, f);
526  if (PREVC == '*') { /* veritable fin */
527  mysptr++;
528  goto lex_loop;
529  }
530  mysptr++; /* pseudo fin */
531  goto comment;
532  break;
533  }
534  break;
535  case IDNT:
536  mytext = mysptr; /* sauvegarde le jeton */
537  mysptr++;
538  for (; isidnt((int)CURC); mysptr++) {
539  };
540  mylength = (int)(mysptr - mytext);
541  if (token != get_symbol(mytext, mylength))
542  fwrite(mytext, (size_t)mylength, 1, f);
543  return (get_symbol(mytext, mylength));
544  break;
545  case INTT:
546  mytext = mysptr; /* sauvegarde le jeton */
547  int_part:
548  mysptr++;
549  for (; isintt((int)CURC); mysptr++) {
550  };
551  switch (CURC) {
552  case '.': /* lecture fraction */
553  float_part:
554  mysptr++;
555  for (; isintt((int)CURC); mysptr++) {
556  };
557  if (CURC != 'E' && CURC != 'e') {
558  if (token != T_FLOAT)
559  fwrite(mytext, (size_t)(mysptr - mytext), 1, f);
560  return (T_FLOAT);
561  }
562  break;
563  case 'E': /* lecture exposant */
564  case 'e':
565  mysptr++;
566  if (isintt((int)CURC))
567  mysptr++;
568  else if (issgnt((int)CURC) && isintt((int)NEXTC))
569  mysptr += 2;
570  else {
571  mysptr--;
572  if (token != T_FLOAT)
573  fwrite(mytext, (size_t)(mysptr - mytext), 1, f);
574  return (T_FLOAT);
575  }
576  for (; isintt((int)CURC); mysptr++) {
577  };
578  if (token != T_FLOAT)
579  fwrite(mytext, (size_t)(mysptr - mytext), 1, f);
580  return (T_FLOAT);
581  break;
582  default:
583  if (token != T_INT)
584  fwrite(mytext, (size_t)(mysptr - mytext), 1, f);
585  return (T_INT);
586  break;
587  }
588  break;
589  case FPTT:
590  mytext = mysptr; /* sauvegarde le jeton */
591  mysptr++;
592  if (!isintt((int)CURC)) { /* pas de fraction */
593  if (token != *mytext)
594  fwrite(mytext, 1, 1, f);
595  return (*mytext);
596  }
597  goto float_part;
598  break;
599  case SGNT:
600  mytext = mysptr; /* sauvegarde le jeton */
601  mysptr++;
602  if (isintt((int)CURC))
603  goto int_part;
604  if (isfptt((int)CURC) && isintt((int)NEXTC))
605  goto float_part;
606  if (token != *mytext)
607  fwrite(mytext, 1, 1, f);
608  return (*mytext);
609  break;
610  case STGT:
611  fwrite(mysptr, 1, 1, f);
612  mytext = mysptr; /* sauvegarde le jeton */
613  mysptr++;
614  string:
615  for (; isstgt((int)CURC); mysptr++)
616  fwrite(mysptr, 1, 1, f);
617  switch (chtbl[(int)CURC]) {
618  case EOBT:
619  next_source();
620  goto comment;
621  break;
622  case EOFT:
623  lexerr("start", lex_errtbl[E_STG_EOF], NULL);
624  return (T_EOF);
625  break;
626  case EOLT:
627  lexerr("start", lex_errtbl[E_STG_EOL], NULL);
628  return ('\n');
629  break;
630  case STGT:
631  fwrite(mysptr, 1, 1, f);
632  if (PREVC != '\\') { /* veritable fin */
633  mytext++;
634  mylength = (int)(mysptr - mytext);
635  mysptr++;
636  return (T_STRING);
637  }
638  mysptr++; /* pseudo fin */
639  goto string;
640  break;
641  }
642  break;
643  default:
644  fwrite(mysptr, 1, 1, f);
645  mysptr++;
646  goto lex_loop;
647  break;
648  }
649  return (T_EOF);
650 }
651 
652 #undef BUFSIZE
653 #undef LINESIZE
654 #undef TEXTSIZE
655 
656 #define BUFSIZE (BUFSIZ << 5)
657 #define LINESIZE (BUFSIZ - 1)
658 #define TEXTSIZE (1 + LINESIZE + BUFSIZE + 1)
659 
660 static FILE *fds; /* descripteur du fichier source */
661 static char *source; /* nom du fichier du programme source */
662 static char *botbuf; /* fond du buffer d'entree du fichier */
663 static char *buf; /* base du buffer d'entree du fichier */
664 static char *topbuf; /* sommet du buffer d'entree du fichier */
665 
666 /*
667  * La procedure "unlex" recule la tete de lecture devant le dernier jeton.
668  */
669 void unlex(void) { mysptr = mytext; }
670 
671 /*
672  * La procedure "open_source" alloue et initialise les variables utilisees
673  * pour la gestion des entrees du programme source.
674  * Entree :
675  * fd Fichier du programme source.
676  * sptr Nom du fichier du programme source.
677  */
678 void open_source(FILE *fd, const char *str)
679 {
680  if ((source = (char *)malloc((strlen(str) + 1) * sizeof(char))) == NULL) {
681  static char proc_name[] = "open_source";
682  perror(proc_name);
683  throw vpException(vpException::fatalError, "Error in open_source");
684  }
685  strcpy(source, str);
686  if ((botbuf = (char *)malloc(TEXTSIZE * sizeof(char))) == NULL) {
687  static char proc_name[] = "open_source";
688  perror(proc_name);
689  throw vpException(vpException::fatalError, "Error in open_source");
690  }
691  fds = fd;
692  buf = botbuf + 1 + LINESIZE;
693  topbuf = buf + 1;
694  mylineno = 1;
695  next_source();
696 }
697 
698 /*
699  * La procedure "close_source" libere les variables utilisees pour la gestion
700  * des entrees du programme source.
701  */
702 void close_source(void)
703 {
704  free((char *)source);
705  free((char *)botbuf);
706 }
707 
708 /*
709  * La procedure "next_source" remplit le buffer courant.
710  */
711 static void next_source(void)
712 {
713  size_t size;
714  char *bot = buf;
715  char *top = topbuf;
716 
717  /* recopie la derniere ligne devant "buf" */
718 
719  *bot = EOL; /* evite le debordement de "buf" */
720  while ((*--bot = *--top) != EOL) {
721  };
722  myline = mysptr = bot + 1;
723 
724  size = fread(buf, sizeof(char), BUFSIZE, fds);
725  if (size == 0) {
726  topbuf = buf + 1;
727  *buf = EOF;
728  *topbuf = EOB; /* sentinelle de fin de fichier */
729  mysptr = buf;
730  }
731  else {
732  topbuf = buf + size;
733  *topbuf = EOB; /* sentinelle de fin de buffer */
734 
735  /* recherche de la derniere ligne */
736  top = topbuf;
737  while (*--top != EOL) {
738  };
739  lastline = top;
740  }
741 }
742 
743 /*
744  * ERR_STACK : Pile des messages d'erreur.
745  * La pile est geree par les procedures "poperr", "popuperr" et "pusherr".
746  * Les messages sont affiches par les procedures "count" et "lexerr".
747  */
748 #define ERR_STACK_MAX 32
749 
750 static const char *err_stack[ERR_STACK_MAX];
751 static int size_stack = 0;
752 
753 /*
754  * La procedure "count" calcule la distance en espaces entre
755  * le premier caractere "*mytext" et le caractere de debut de ligne "*myline".
756  */
757 static void count(void)
758 {
759  char *str;
760 
761  mycolumno = 0;
762  for (str = myline; str <= mytext; str++) {
763  (*str == '\t') ? mycolumno += 8 - (mycolumno % 8) : mycolumno++;
764  }
765 }
766 
767 /*
768  * La procedure "lexerr" affiche les messages d'erreur.
769  * 1 elle affiche la ligne d'erreur du fichier source.
770  * 2 elle indique la position de l'erreur dans la ligne.
771  * 3 elle affiche les messages d'erreur contenus dans la pile.
772  * 4 elle affiche les messages d'erreur en parametre.
773  * Entree :
774  * va_list Liste de messages d'erreur terminee par NULL.
775  */
776 
777 // lexerr (va_alist)
778 // va_dcl
779 
780 void lexerr(const char *path, ...)
781 {
782  va_list ap;
783  char *cp;
784  int i;
785 
786  /* Pointe sur le caractere fautif. */
787 
788  count();
789  // write (STDERR, myline, mysptr - myline);
790  fprintf(stderr, "\n%*c\n\"%s\", line %d:\n", mycolumno, '^', source, mylineno);
791 
792  /* Affiche les messages d'erreur de la pile. */
793 
794  for (i = 0; i < size_stack; i++)
795  fprintf(stderr, "%s", err_stack[i]);
796 
797  /* Affiche les messages d'erreur en parametres. */
798 
799  va_start(ap, path);
800  while ((cp = (char *)va_arg(ap, char *)) != NULL)
801  fprintf(stderr, "%s", cp);
802  fprintf(stderr, "\n");
803  va_end(ap);
804 
805  throw vpException(vpException::fatalError, "Error in lexerr");
806 }
807 
808 /*
809  * La procedure "poperr" depile le message d'erreur du sommet de pile.
810  */
811 void poperr(void)
812 {
813  if (--size_stack < 0) {
814  static char proc_name[] = "poperr";
815  fprintf(stderr, "%s: error stack underflow\n", proc_name);
816  throw vpException(vpException::fatalError, "Error in poperr");
817  }
818 }
819 
820 /*
821  * La procedure "popup_error" remplace le message d'erreur du sommet de pile.
822  */
823 void popuperr(const char *str)
824 {
825  if (size_stack <= 0) {
826  static const char proc_name[] = "popuerr";
827  fprintf(stderr, "%s: error stack underflow\n", proc_name);
828  throw vpException(vpException::fatalError, "Error in popuperr");
829  }
830  err_stack[size_stack - 1] = str;
831 }
832 
833 /*
834  * La procedure "pusherr" empile le message d'erreur.
835  */
836 void pusherr(const char *str)
837 {
838  if (size_stack >= ERR_STACK_MAX) {
839  static const char proc_name[] = "pusherr";
840  fprintf(stderr, "%s: error stack overflow\n", proc_name);
841  throw vpException(vpException::fatalError, "Error in pusherr");
842  }
843  err_stack[size_stack++] = str;
844 }
845 END_VISP_NAMESPACE
846 #endif
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ fatalError
Fatal error.
Definition: vpException.h:72