/* * This file contains the C functions for the Mathomatic API. * Refer to this, if you are going to use the Mathomatic code in other projects. * * Be sure and define "LIBRARY" when compiling the Mathomatic code for this. * And be sure to call clear_all() after completing each group of operations, * otherwise the equation spaces will fill up. * * Copyright (C) 1987-2009 George Gesslein II. */ #include "../includes.h" #include "mathomatic.h" /* * matho_init() - Initialize Mathomatic. * Call this only once before calling any Mathomatic code. * This must be called exactly once upon program startup and not again. * * Returns true if successful. * If this returns false, there was not enough memory * and Mathomatic cannot be used. */ int matho_init() { init_gvars(); gfp = stdout; if (!init_mem()) { return false; } signal(SIGFPE, fphandler); /* handle floating point exceptions, currently ignored */ return true; } /* * Process a Mathomatic command or input an expression into an equation space. * Input string is in "input", output string is stored in "*outputp". * * This function works just like typing something into the Mathomatic prompt. * * If this returns true (non-zero), the command or input was successful, * and the resulting expression output is stored in "*outputp". * That is a malloc()ed text string which must be free()d after use * to return the memory used by the string. * * If this returns false, the command or input failed and a text error * message is stored in "*outputp". The error message should NOT be free()d. * * This routine will set "*outputp" to NULL, if there is no resulting expression or message. * If there is an error, there will always be an error message string returned at "*outputp", * except when there is no input. */ int matho_process(char *input, const char **outputp) { int i; int rv; if (outputp) *outputp = NULL; result_str = NULL; error_str = NULL; warning_str = NULL; if (input == NULL) return false; input = strdup(input); if ((i = setjmp(jmp_save)) != 0) { clean_up(); /* Mathomatic processing was interrupted, so do a clean up. */ if (i == 14) { error(_("Expression too large.")); } if (outputp) { if (error_str) { *outputp = error_str; } else { *outputp = _("Processing was interrupted."); } } free_result_str(); free(input); return false; } set_error_level(input); rv = process(input); if (rv) { if (outputp) *outputp = result_str; } else { if (outputp) { if (error_str) { *outputp = error_str; } else { *outputp = _("Unknown error."); } } free_result_str(); } free(input); return rv; } /* * Parse an equation or expression and store in the next available equation space, * making it the current equation. * * Input string is in "input", output string is stored in "*outputp". * * Works the same as matho_process() above, except commands are not allowed, * so that variables are not confused with commands. * * Returns true (non-zero) if successful. */ int matho_parse(char *input, const char **outputp) { int i; int rv; if (outputp) *outputp = NULL; result_str = NULL; error_str = NULL; warning_str = NULL; if (input == NULL) return false; input = strdup(input); if ((i = setjmp(jmp_save)) != 0) { clean_up(); /* Mathomatic processing was interrupted, so do a clean up. */ if (i == 14) { error(_("Expression too large.")); } if (outputp) { if (error_str) { *outputp = error_str; } else { *outputp = _("Processing was interrupted."); } } free_result_str(); free(input); return false; } set_error_level(input); i = next_espace(); #if true /* set this true if you want to be able to enter single variable expressions with no solving */ rv = parse(i, input); #else rv = process_parse(i, input); #endif if (rv) { if (outputp) *outputp = result_str; } else { if (outputp) { if (error_str) { *outputp = error_str; } else { *outputp = _("Unknown error."); } } free_result_str(); } free(input); return rv; } /* * Floating point exception handler. * Usually doesn't work in most operating systems, so just ignore it. */ void fphandler(int sig) { /* error(_("Floating point exception.")); */ }