/* * Cflow2VCG * Copyright (C) 2001 Guilhem BONNEFILLE * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "cflow2vcg.h" #include "write_vcg.h" #include "cflow_struct.h" #include "read_sun.h" #include "read_free.h" #define NBMAX 512 #define PROFONDEUR 30 /* Definition des categories de noeuds : - noeuds internes (definis dans les codes analyses) - noeuds externes (les autres : '<>') */ #define NOEUD_INT 1 #define NOEUD_EXT 2 typedef enum { INPUT_SUN, INPUT_FREE, INPUT_AUTO } INPUT_TYPE; static int niveau_courant = 0; static int tab_niveaux[PROFONDEUR]; static int *tab_noeud_int; ///< Tableau des noeuds internes static int nb_noeud_int; ///< Nombre de noeuds internes stockes static int *tab_noeud_ext; ///< Tableau des noeuds externes static int nb_noeud_ext; ///< Nombre de noeuds externes stockes /** Classe invisible */ int classe_inv = CLASS_NULL; /* */ static INPUT_TYPE input_type; void positionner_niveau(int numlig, int niveau) { niveau_courant = niveau - 1; tab_niveaux[niveau_courant] = numlig; } int niveau_pere() { if (niveau_courant >= 1) return tab_niveaux[niveau_courant - 1]; else return -1; } /** Ajout d'un element en redimensionnant le tableau si necessaire */ void tab_dyn_ajouter_elem(int nouveau, int taille_realloc, int **p_tab, int *p_nb) { /* Reallocation eventuelle du tableau */ if (*p_tab == NULL || *p_nb % taille_realloc == 0) { *p_tab = realloc(*p_tab, sizeof (int) * (*p_nb + taille_realloc)); if (*p_tab == NULL) { (void) fprintf(stderr, "Erreur allocation.\n"); exit(EXIT_FAILURE); } } /* Ajout de l'element */ (*p_tab)[*p_nb] = nouveau; (*p_nb)++; } /** Fonction de comparaison d'entier pour bsearch */ int int_compare(const void *elem1, const void *elem2) { int cmp; int entier1, entier2; entier1 = *(int *) elem1; entier2 = *(int *) elem2; if (entier1 == entier2) cmp = 0; else if (entier1 > entier2) cmp = 1; else cmp = -1; return cmp; } void *rechercher_parmi_interne(int noeud) { return bsearch(&noeud, tab_noeud_int, nb_noeud_int, sizeof(int), int_compare); } #define afficher_noeud_int(label,numlig,type,fichier,ligne) \ afficher_noeud((label),(numlig),type,fichier,ligne) #define afficher_noeud_ext(label,numlig) \ afficher_noeud((label),(numlig),"","",0) void usage(FILE * out, const char *progname) { (void) fprintf(out, "Usage: %s -h\n", progname); (void) fprintf(out, "Usage: %s -v\n", progname); (void) fprintf(out, "Usage: %s [ -i | -e ] [ -f i_format ] < file.cflow\n", progname); (void) fprintf(out, "\t-h: this help.\n"); (void) fprintf(out, "\t-v: version information.\n"); (void) fprintf(out, "\t-i: restrict to internal (defined) functions.\n"); (void) fprintf(out, "\t-e: restrict to external (used) functions (less usefull).\n"); (void) fprintf(out, "\t-f i_format: input format. Arg. should be sun or free.\n"); (void) fprintf(out, "\t by default, it will be automatic as possible.\n"); } void version (FILE * out) { /* Print some version informations */ #if (defined(PACKAGE) && defined(VERSION)) (void) fprintf(out, "%s %s\n", PACKAGE, VERSION); #else (void) fprintf(out, "No package-version available (due to generation).\n" "CVS/RCS informations: $RCSfile: cflow2vcg.c,v $ $Revision: 1.5 $\n"); #endif /* Copyright notice */ (void) fprintf(out, "Copyright (C) 2001 Guilhem BONNEFILLE\n" "This program comes with NO WARRANTY.\n" "You may redistribute copies of it under the terms of the\n" "GNU General Public License.\n" "For more information about these matters,\n" "see the files named COPYING.\n"); } int scan_line(const char *line, LINE_INFO * line_info) { int result = 0; switch (input_type) { case INPUT_SUN: result = scan_sun(line, line_info); break; case INPUT_FREE: result = scan_free(line, line_info); break; case INPUT_AUTO: /* Try to retrieve the format */ /* When scanning match, update the format */ if ((result = scan_sun(line, line_info)) == 1) input_type = INPUT_SUN; else if ((result = scan_free(line, line_info)) == 1) input_type = INPUT_FREE; else { (void) fputs("Error: input format not recognized.\n", stderr); (void) fputs(" Read interupted.\n", stderr); exit (EXIT_FAILURE); } break; } return result; } INPUT_TYPE get_input_type(const char *s_type) { if (strcmp (s_type, "sun") == 0) return INPUT_SUN; else if (strcmp (s_type, "free") == 0) return INPUT_FREE; else return INPUT_AUTO; } int main(int argc, char *argv[]) { int line_number; char ligne[NBMAX + 1]; /* ligne lue */ LINE_INFO line_info; int numligpere; int c; extern char *optarg; extern int optind; /* Default values */ input_type = INPUT_AUTO; /* User cmd */ while ((c = getopt(argc, argv, "ievhf:")) != EOF) switch (c) { case 'i': classe_inv = CLASS_EXT; break; case 'e': classe_inv = CLASS_INT; break; case 'f': input_type = get_input_type (optarg); break; case 'v': version(stdout); return EXIT_SUCCESS; break; case 'h': usage(stdout, argv[0]); return EXIT_SUCCESS; break; case '?': usage(stderr, argv[0]); return EXIT_FAILURE; break; } afficher_entete (); /* No line read */ line_number = 0; while (fgets(ligne, NBMAX, stdin) != NULL) { ligne[NBMAX] = '\0'; /* A new line is read */ line_number++; /* Scanning the current line */ if (scan_line(ligne, &line_info) == 0) { (void) fprintf(stderr, "Syntax error line %d\n", line_number); return EXIT_FAILURE; } positionner_niveau(line_info.id, line_info.depth); switch (line_info.type) { case EXTERNAL: /* Production du noeud */ tab_dyn_ajouter_elem(line_info.id, NBMAX, &tab_noeud_ext, &nb_noeud_ext); afficher_noeud_ext(line_info.fct, line_info.id); break; case INTERNAL: /* Production du noeud */ tab_dyn_ajouter_elem(line_info.id, NBMAX, &tab_noeud_int, &nb_noeud_int); afficher_noeud_int(line_info.fct, line_info.id, line_info.fct_type, line_info.src, line_info.line_src); break; } /* Creation d'un arc */ numligpere = niveau_pere(); if (numligpere != -1) afficher_arc(numligpere, line_info.id); } afficher_pied(); return EXIT_SUCCESS; }