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