--- /dev/null
+/* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t:
+ *
+ * Taller de Programación (75.42).
+ *
+ * Ejercicio Número 2:
+ * Programa calculadora.
+ *
+ * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
+ * Puede copiar, modificar y distribuir este programa bajo los términos de
+ * la licencia GPL (http://www.gnu.org/).
+ *
+ * Creado: mar sep 16 04:07:49 ART 2003
+ *
+ * $Id$
+ */
+
+#include "dllist.h"
+#include "parseerror.h"
+#include "parser_variable.h"
+#include "parser_equation.h"
+#include "variable_list.h"
+/* TODO separar #include "equation_list.h" */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "memdebug_debugger.h"
+
+/** Tamaño del buffer de lectura de archivos. */
+#define BUFFER_SIZE 4096
+
+/**
+ * Imprime una explicación de como usar el programa.
+ *
+ * \param fh Archivo en donde imprimir el mensaje (ej: stdout o stderr).
+ */
+void print_help(FILE* fh) {
+ fprintf(fh, "\n");
+ fprintf(fh, "Modo de uso:\n");
+ fprintf(fh, " tp2 <arch_variables> <arch_ecuaciones>\n");
+}
+
+void print_menu(void) {
+ printf("Menu:\n");
+ printf("1. Listar variables.\n");
+ printf("2. Listar ecuaciones.\n");
+ printf("3. Evaluar ecuaciones.\n");
+ printf("4. Listar memoria.\n");
+ printf("5. Salir.\n");
+}
+
+char get_entrada(void) {
+ char buff[BUFFER_SIZE];
+ printf("Elija una opción: ");
+ fgets(buff, BUFFER_SIZE, stdin);
+ return buff[0];
+}
+
+void menu_loop(DLList* var_list, DLList* eq_list) {
+ char entrada;
+ print_menu();
+ entrada = get_entrada();
+ /* Mientras no sea '5' (salir), se mantiene en el loop. */
+ while (entrada != '5') {
+ /* Mientras la entrada sea inválida, muestra mensaje de error. */
+ while ((entrada < '1') || (entrada > '5')) {
+ printf("\n\n\n");
+ print_menu();
+ printf("Debe elegir un número entre 1 y 5!\n");
+ entrada = get_entrada();
+ }
+ printf("\n");
+ switch (entrada) {
+ case '1': /* Listar variables */
+ printf("Lista de variables:\n");
+ DLList_variable_print(var_list, stdout);
+ break;
+ case '2': /* Listar ecuaciones */
+ printf("Lista de ecuaciones:\n");
+ DLList_equation_print(eq_list, stdout);
+ break;
+ case '3': /* Evaluar ecuaciones */
+ /* TODO */
+ printf("Lista de variables después de evaluar:\n");
+ break;
+ case '4': /* Listar memoria */
+ printf("Lista de memoria alocada:\n");
+ memdebug_list_print(stdout);
+ break;
+ case '5': /* Sale */
+ continue;
+ }
+ printf("\n\n");
+ print_menu();
+ entrada = get_entrada();
+ }
+}
+
+/**
+ * Programa principal.
+ * Este es el programa que se encarga de resolver el trabajo práctico.
+ *
+ * \param argc Cantidad de parámetros de línea de comandos ingresados.
+ * \param argv Parámetros de línea de comandos.
+ *
+ * \return EXIT_FAILURE si hubo un error, si no EXIT_SUCCESS.
+ */
+int main(int argc, const char** argv) {
+ /* Declaración de variables. */
+ DLList* var_list = NULL;
+ DLList* eq_list = NULL;
+ ParseError* error;
+ char buff[BUFFER_SIZE];
+ int i;
+ FILE* fp;
+
+ if (argc != 3) {
+ print_help(stderr);
+ return EXIT_FAILURE;
+ }
+
+ /* Inicializo ParseError. */
+ if (!(error = ParseError_new())) {
+ fprintf(stderr, "Error: No se pudo alocar la memoria para el manejo "
+ "de error.\n");
+ return EXIT_FAILURE;
+ }
+
+ /* Inicializo la lista de variables. */
+ if (!(var_list = DLList_new())) {
+ fprintf(stderr, "Error: No se pudo alocar la memoria para la lista "
+ "de variables.\n");
+ return EXIT_FAILURE;
+ }
+ /* Abro archivo. */
+ fp = fopen(argv[1], "r");
+ if (!fp) {
+ fprintf(stderr, "Error: No se pudo abrir el archivo '%s'.\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+ /* Parseo cada línea, mostrando mensaje por pantalla si hay error. */
+ for (i = 1; fgets(buff, BUFFER_SIZE, fp); i++) {
+ if (!parser_variable(buff, strlen(buff) - 1, var_list, error)) {
+ error->line = i;
+ fprintf(stderr, "%s: ", argv[1]);
+ ParseError_print(error, stderr);
+ }
+ }
+ /* Cierro archivo. */
+ fclose(fp);
+
+ /* Inicializo la lista de ecuaciones. */
+ if (!(eq_list = DLList_new())) {
+ fprintf(stderr, "Error: No se pudo alocar la memoria para la lista "
+ "de ecuaciones.\n");
+ return EXIT_FAILURE;
+ }
+ /* Abro archivo. */
+ fp = fopen(argv[2], "r");
+ if (!fp) {
+ fprintf(stderr, "Error: No se pudo abrir el archivo '%s'.\n", argv[2]);
+ return EXIT_FAILURE;
+ }
+ /* Parseo cada línea, mostrando mensaje por pantalla si hay error. */
+ for (i = 1; fgets(buff, BUFFER_SIZE, fp); i++) {
+ if (!parser_equation(buff, strlen(buff) - 1, eq_list, error)) {
+ error->line = i;
+ fprintf(stderr, "%s: ", argv[2]);
+ ParseError_print(error, stderr);
+ }
+ }
+ /* Cierro archivo. */
+ fclose(fp);
+
+ /* Elimino el error de interpretación. */
+ ParseError_delete(error);
+
+ menu_loop(var_list, eq_list);
+
+ /* Elimino listas. */
+ DLList_variable_delete(var_list);
+ DLList_equation_delete(eq_list);
+
+ /* Veo si quedo memoria sin desalocar. */
+ memdebug_end();
+
+ /* Salió todo ok. */
+ return EXIT_SUCCESS;
+}
+