]> git.llucax.com Git - z.facultad/75.42/calculadora.git/blob - tp2.c
145aa09c4f08f6fa21e42de03f420e377fc19ef4
[z.facultad/75.42/calculadora.git] / tp2.c
1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 2:
6  * Programa calculadora.
7  *
8  * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9  * Puede copiar, modificar y distribuir este programa bajo los términos de
10  * la licencia GPL (http://www.gnu.org/).
11  *
12  * Creado: mar sep 16 04:07:49 ART 2003
13  *
14  * $Id$
15  */
16
17 #include "dllist.h"
18 #include "parseerror.h"
19 #include "parser_variable.h"
20 #include "parser_equation.h"
21 #include "variable_list.h"
22 /* TODO separar #include "equation_list.h" */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "memdebug_debugger.h"
29
30 /** Tamaño del buffer de lectura de archivos. */
31 #define BUFFER_SIZE 4096
32
33 /**
34  * Imprime una explicación de como usar el programa.
35  *
36  * \param fh Archivo en donde imprimir el mensaje (ej: stdout o stderr).
37  */
38 void print_help(FILE* fh) {
39     fprintf(fh, "\n");
40     fprintf(fh, "Modo de uso:\n");
41     fprintf(fh, "  tp2 <arch_variables> <arch_ecuaciones>\n");
42 }
43
44 void print_menu(void) {
45     printf("Menu:\n");
46     printf("1. Listar variables.\n");
47     printf("2. Listar ecuaciones.\n");
48     printf("3. Evaluar ecuaciones.\n");
49     printf("4. Listar memoria.\n");
50     printf("5. Salir.\n");
51 }
52
53 char get_entrada(void) {
54     char buff[BUFFER_SIZE];
55     printf("Elija una opción: ");
56     fgets(buff, BUFFER_SIZE, stdin);
57     return buff[0];
58 }
59
60 void menu_loop(DLList* var_list, DLList* eq_list) {
61     char entrada;
62     print_menu();
63     entrada = get_entrada();
64     /* Mientras no sea '5' (salir), se mantiene en el loop. */
65     while (entrada != '5') {
66         /* Mientras la entrada sea inválida, muestra mensaje de error. */
67         while ((entrada < '1') || (entrada > '5')) {
68             printf("\n\n\n");
69             print_menu();
70             printf("Debe elegir un número entre 1 y 5!\n");
71             entrada = get_entrada();
72         }
73         printf("\n");
74         switch (entrada) {
75             case '1': /* Listar variables */
76                 printf("Lista de variables:\n");
77                 DLList_variable_print(var_list, stdout);
78                 break;
79             case '2': /* Listar ecuaciones */
80                 printf("Lista de ecuaciones:\n");
81                 DLList_equation_print(eq_list, stdout);
82                 break;
83             case '3': /* Evaluar ecuaciones */
84                 /* TODO */
85                 printf("Lista de variables después de evaluar:\n");
86                 break;
87             case '4': /* Listar memoria */
88                 printf("Lista de memoria alocada:\n");
89                 memdebug_list_print(stdout);
90                 break;
91             case '5': /* Sale */
92                 continue;
93         }
94         printf("\n\n");
95         print_menu();
96         entrada = get_entrada();
97     }
98 }
99
100 /**
101  * Programa principal.
102  * Este es el programa que se encarga de resolver el trabajo práctico.
103  *
104  * \param argc Cantidad de parámetros de línea de comandos ingresados.
105  * \param argv Parámetros de línea de comandos.
106  *
107  * \return EXIT_FAILURE si hubo un error, si no EXIT_SUCCESS.
108  */
109 int main(int argc, const char** argv) {
110     /* Declaración de variables. */
111     DLList* var_list = NULL;
112     DLList* eq_list = NULL;
113     ParseError* error;
114     char buff[BUFFER_SIZE];
115     int i;
116     FILE* fp;
117
118     if (argc != 3) {
119         print_help(stderr);
120         return EXIT_FAILURE;
121     }
122
123     /* Inicializo ParseError. */
124     if (!(error = ParseError_new())) {
125         fprintf(stderr, "Error: No se pudo alocar la memoria para el manejo "
126                 "de error.\n");
127         return EXIT_FAILURE;
128     }
129
130     /* Inicializo la lista de variables. */
131     if (!(var_list = DLList_new())) {
132         fprintf(stderr, "Error: No se pudo alocar la memoria para la lista "
133                 "de variables.\n");
134         return EXIT_FAILURE;
135     }
136     /* Abro archivo. */
137     fp = fopen(argv[1], "r");
138     if (!fp) {
139         fprintf(stderr, "Error: No se pudo abrir el archivo '%s'.\n", argv[1]);
140         return EXIT_FAILURE;
141     }
142     /* Parseo cada línea, mostrando mensaje por pantalla si hay error. */
143     for (i = 1; fgets(buff, BUFFER_SIZE, fp); i++) {
144         if (!parser_variable(buff, strlen(buff) - 1, var_list, error)) {
145             error->line = i;
146             fprintf(stderr, "%s: ", argv[1]);
147             ParseError_print(error, stderr);
148         }
149     }
150     /* Cierro archivo. */
151     fclose(fp);
152
153     /* Inicializo la lista de ecuaciones. */
154     if (!(eq_list = DLList_new())) {
155         fprintf(stderr, "Error: No se pudo alocar la memoria para la lista "
156                 "de ecuaciones.\n");
157         return EXIT_FAILURE;
158     }
159     /* Abro archivo. */
160     fp = fopen(argv[2], "r");
161     if (!fp) {
162         fprintf(stderr, "Error: No se pudo abrir el archivo '%s'.\n", argv[2]);
163         return EXIT_FAILURE;
164     }
165     /* Parseo cada línea, mostrando mensaje por pantalla si hay error. */
166     for (i = 1; fgets(buff, BUFFER_SIZE, fp); i++) {
167         if (!parser_equation(buff, strlen(buff) - 1, eq_list, error)) {
168             error->line = i;
169             fprintf(stderr, "%s: ", argv[2]);
170             ParseError_print(error, stderr);
171         }
172     }
173     /* Cierro archivo. */
174     fclose(fp);
175
176     /* Elimino el error de interpretación. */
177     ParseError_delete(error);
178
179     menu_loop(var_list, eq_list);
180
181     /* Elimino listas. */
182     DLList_variable_delete(var_list);
183     DLList_equation_delete(eq_list);
184
185     /* Veo si quedo memoria sin desalocar. */
186     memdebug_end();
187
188     /* Salió todo ok. */
189     return EXIT_SUCCESS;
190 }
191