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