From 0b512b8c06510cbed814de21d4b9ebda30d7681d Mon Sep 17 00:00:00 2001 From: mingodad Date: Sun, 22 Sep 2019 19:09:46 +0200 Subject: [PATCH 1/3] Made reentrant by moving all globals/static variables to a struct and passing it where needed --- am.c | 748 ++++++------- am.h | 28 +- blt.h | 2 +- cmds.c | 2785 +++++++++++++++++++++++----------------------- complex.c | 125 ++- diff.c | 523 +++++---- externs.h | 265 +++-- factor.c | 424 ++++--- factor_int.c | 211 ++-- gcd.c | 76 +- globals.c | 249 ++--- help.c | 861 +++++++------- includes.h | 2 +- integrate.c | 535 +++++---- lib/example.c | 16 +- lib/lib.c | 100 +- lib/mathomatic.h | 25 +- lib/testmain.c | 19 +- list.c | 567 +++++----- main.c | 201 ++-- parse.c | 198 ++-- poly.c | 1143 ++++++++++--------- proto.h | 458 ++++---- simplify.c | 1015 ++++++++--------- solve.c | 706 ++++++------ super.c | 256 +++-- unfactor.c | 239 ++-- 27 files changed, 5762 insertions(+), 6015 deletions(-) diff --git a/am.c b/am.c index a08797d..37403df 100644 --- a/am.c +++ b/am.c @@ -34,25 +34,25 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. * but really can go to any file you wish. */ void -display_startup_message(fp) -FILE *fp; /* output file pointer */ +display_startup_message(MathoMatic* mathomatic, FILE *fp) +//FILE *fp; /* output file pointer */ { long es_size; #if SECURE fprintf(fp, _("Secure ")); #else - if (security_level >= 2) + if (mathomatic->security_level >= 2) fprintf(fp, _("Secure ")); - else if (security_level == -1) + else if (mathomatic->security_level == -1) fprintf(fp, "m4 "); #endif fprintf(fp, "Mathomatic version %s\n", VERSION); - if (html_flag) + if (mathomatic->html_flag) fprintf(fp, "Copyright © 1987-2012 George Gesslein II.\n"); else fprintf(fp, "Copyright (C) 1987-2012 George Gesslein II.\n"); - es_size = (long) n_tokens * sizeof(token_type) * 2L / 1000L; + es_size = (long) mathomatic->n_tokens * sizeof(token_type) * 2L / 1000L; if (es_size >= 1000) { fprintf(fp, _("%d equation spaces available in RAM; %ld megabytes per equation space.\n"), N_EQUATIONS, (es_size + 500L) / 1000L); @@ -66,14 +66,14 @@ FILE *fp; /* output file pointer */ * Standard function to report an error to the user. */ void -error(str) -const char *str; /* constant string to display */ +error(MathoMatic* mathomatic, const char *str) +//const char *str; /* constant string to display */ { - error_str = str; /* save reference to str, must be a constant string, temporary strings don't work */ + mathomatic->error_str = str; /* save reference to str, must be a constant string, temporary strings don't work */ #if !SILENT && !LIBRARY - set_color(2); /* set color to red */ + set_color(mathomatic, 2); /* set color to red */ printf("%s\n", str); - default_color(false); /* restore to default color */ + default_color(mathomatic, false); /* restore to default color */ #endif } @@ -81,13 +81,13 @@ const char *str; /* constant string to display */ * Reset last call to error(), as if it didn't happen. */ void -reset_error(void) +reset_error(MathoMatic* mathomatic) { #if !SILENT && !LIBRARY - if (error_str) + if (mathomatic->error_str) printf(_("Forgetting previous error.\n")); #endif - error_str = NULL; + mathomatic->error_str = NULL; } /* @@ -95,21 +95,21 @@ reset_error(void) * A warning is less serious than an error. */ void -warning(str) -const char *str; /* constant string to display */ +warning(MathoMatic* mathomatic, const char *str) +//const char *str; /* constant string to display */ { int already_warned = false; - if (warning_str) { - if (strcmp(str, warning_str) == 0) + if (mathomatic->warning_str) { + if (strcmp(str, mathomatic->warning_str) == 0) already_warned = true; } - warning_str = str; /* save reference to str, must be a constant string, temporary strings don't work */ + mathomatic->warning_str = str; /* save reference to str, must be a constant string, temporary strings don't work */ #if !SILENT && !LIBRARY - if (!already_warned && debug_level >= -1) { - set_color(1); /* set color to yellow */ + if (!already_warned && mathomatic->debug_level >= -1) { + set_color(mathomatic, 1); /* set color to yellow */ printf("Warning: %s\n", str); - default_color(false); /* restore to default color */ + default_color(mathomatic, false); /* restore to default color */ } #endif } @@ -120,9 +120,9 @@ const char *str; /* constant string to display */ * There is no return. */ void -error_huge(void) +error_huge(MathoMatic* mathomatic) { - longjmp(jmp_save, 14); + longjmp(mathomatic->jmp_save, 14); } /* @@ -131,11 +131,11 @@ error_huge(void) * There is no return. */ void -error_bug(str) -const char *str; /* constant string to display */ +error_bug(MathoMatic* mathomatic, const char *str) +//const char *str; /* constant string to display */ { /* Return and display the passed error message in str. */ - error(str); /* str must be a constant string, temporary strings don't work */ + error(mathomatic, str); /* str must be a constant string, temporary strings don't work */ #if SILENT || LIBRARY printf("%s\n", str); #endif @@ -144,7 +144,7 @@ const char *str; /* constant string to display */ #if !LIBRARY printf(_("Type \"help bugs\" for info on how to report bugs found in this program.\n")); #endif - longjmp(jmp_save, 13); /* Abort the current operation with the critical error number 13. */ + longjmp(mathomatic->jmp_save, 13); /* Abort the current operation with the critical error number 13. */ } /* @@ -153,22 +153,22 @@ const char *str; /* constant string to display */ * There is no return if an error message is displayed. */ void -check_err(void) +check_err(MathoMatic* mathomatic) { switch (errno) { case EDOM: errno = 0; - if (domain_check) { - domain_check = false; + if (mathomatic->domain_check) { + mathomatic->domain_check = false; } else { - error(_("Domain error in constant.")); - longjmp(jmp_save, 2); + error(mathomatic, _("Domain error in constant.")); + longjmp(mathomatic->jmp_save, 2); } break; case ERANGE: errno = 0; - error(_("Floating point constant out of range.")); - longjmp(jmp_save, 2); + error(mathomatic, _("Floating point constant out of range.")); + longjmp(mathomatic->jmp_save, 2); break; } } @@ -179,7 +179,7 @@ check_err(void) * Return true if the global integers screen_columns and/or screen_rows were set. */ int -get_screen_size(void) +get_screen_size(MathoMatic* mathomatic) { int rv = false; @@ -190,17 +190,17 @@ get_screen_size(void) ws.ws_row = 0; if (ioctl(1, TIOCGWINSZ, &ws) >= 0) { if (ws.ws_col > 0) { - screen_columns = ws.ws_col; + mathomatic->screen_columns = ws.ws_col; rv = true; } if (ws.ws_row > 0) { - screen_rows = ws.ws_row; + mathomatic->screen_rows = ws.ws_row; rv = true; } } #else - screen_columns = STANDARD_SCREEN_COLUMNS; - screen_rows = STANDARD_SCREEN_ROWS; + mathomatic->screen_columns = STANDARD_SCREEN_COLUMNS; + mathomatic->screen_rows = STANDARD_SCREEN_ROWS; rv = true; #endif return rv; @@ -213,24 +213,24 @@ get_screen_size(void) * Return true with vscreen[] allocated to TEXT_ROWS*current_columns characters if successful. */ int -malloc_vscreen(void) +malloc_vscreen(MathoMatic* mathomatic) { int i; - if (current_columns == 0 || ((screen_columns > 0) ? (current_columns != screen_columns) : (current_columns != TEXT_COLUMNS))) { - if (screen_columns > 0) { - current_columns = screen_columns; + if (mathomatic->current_columns == 0 || ((mathomatic->screen_columns > 0) ? (mathomatic->current_columns != mathomatic->screen_columns) : (mathomatic->current_columns != TEXT_COLUMNS))) { + if (mathomatic->screen_columns > 0) { + mathomatic->current_columns = mathomatic->screen_columns; } else { - current_columns = TEXT_COLUMNS; + mathomatic->current_columns = TEXT_COLUMNS; } for (i = 0; i < TEXT_ROWS; i++) { - if (vscreen[i]) { - free(vscreen[i]); + if (mathomatic->vscreen[i]) { + free(mathomatic->vscreen[i]); } - vscreen[i] = malloc(current_columns + 1); - if (vscreen[i] == NULL) { - error(_("Out of memory (can't malloc(3)).")); - current_columns = 0; + mathomatic->vscreen[i] = malloc(mathomatic->current_columns + 1); + if (mathomatic->vscreen[i] == NULL) { + error(mathomatic, _("Out of memory (can't malloc(3)).")); + mathomatic->current_columns = 0; return false; } } @@ -250,20 +250,20 @@ malloc_vscreen(void) * Returns true if successful, otherwise Mathomatic cannot be used. */ int -init_mem(void) +init_mem(MathoMatic* mathomatic) { - if (n_tokens <= 0) + if (mathomatic->n_tokens <= 0) return false; - if ((scratch = (token_type *) malloc(((n_tokens * 3) / 2) * sizeof(token_type))) == NULL - || (tes = (token_type *) malloc(n_tokens * sizeof(token_type))) == NULL - || (tlhs = (token_type *) malloc(n_tokens * sizeof(token_type))) == NULL - || (trhs = (token_type *) malloc(n_tokens * sizeof(token_type))) == NULL) { + if ((mathomatic->scratch = (token_type *) malloc(((mathomatic->n_tokens * 3) / 2) * sizeof(token_type))) == NULL + || (mathomatic->tes = (token_type *) malloc(mathomatic->n_tokens * sizeof(token_type))) == NULL + || (mathomatic->tlhs = (token_type *) malloc(mathomatic->n_tokens * sizeof(token_type))) == NULL + || (mathomatic->trhs = (token_type *) malloc(mathomatic->n_tokens * sizeof(token_type))) == NULL) { return false; } - if (alloc_next_espace() < 0) { /* make sure there is at least 1 equation space */ + if (alloc_next_espace(mathomatic) < 0) { /* make sure there is at least 1 equation space */ return false; } - clear_all(); + clear_all(mathomatic); return true; } @@ -278,36 +278,36 @@ init_mem(void) * Inclusion of this routine was requested by Tam Hanna for use with Symbian OS. */ void -free_mem(void) +free_mem(MathoMatic* mathomatic) { int i; - clear_all(); + clear_all(mathomatic); - free(scratch); - free(tes); - free(tlhs); - free(trhs); + free(mathomatic->scratch); + free(mathomatic->tes); + free(mathomatic->tlhs); + free(mathomatic->trhs); for (i = 0; i < N_EQUATIONS; i++) { - if (lhs[i]) { - free(lhs[i]); - lhs[i] = NULL; + if (mathomatic->lhs[i]) { + free(mathomatic->lhs[i]); + mathomatic->lhs[i] = NULL; } - if (rhs[i]) { - free(rhs[i]); - rhs[i] = NULL; + if (mathomatic->rhs[i]) { + free(mathomatic->rhs[i]); + mathomatic->rhs[i] = NULL; } } - n_equations = 0; + mathomatic->n_equations = 0; for (i = 0; i < TEXT_ROWS; i++) { - if (vscreen[i]) { - free(vscreen[i]); - vscreen[i] = NULL; + if (mathomatic->vscreen[i]) { + free(mathomatic->vscreen[i]); + mathomatic->vscreen[i] = NULL; } } - current_columns = 0; + mathomatic->current_columns = 0; } #endif @@ -319,23 +319,23 @@ free_mem(void) * Always returns true, or doesn't return on error. */ int -check_gvars(void) +check_gvars(MathoMatic* mathomatic) { - if (!(domain_check == false && - high_prec == false && - partial_flag == true && - symb_flag == false && - sign_cmp_flag == false && - approximate_roots == false)) - error_bug("Global vars got changed!"); - - if (!(zero_token.level == 1 && - zero_token.kind == CONSTANT && - zero_token.token.constant == 0.0 && - one_token.level == 1 && - one_token.kind == CONSTANT && - one_token.token.constant == 1.0)) - error_bug("Global constants got changed!"); + if (!(mathomatic->domain_check == false && + mathomatic->high_prec == false && + mathomatic->partial_flag == true && + mathomatic->symb_flag == false && + mathomatic->sign_cmp_flag == false && + mathomatic->approximate_roots == false)) + error_bug(mathomatic, "Global vars got changed!"); + + if (!(mathomatic->zero_token.level == 1 && + mathomatic->zero_token.kind == CONSTANT && + mathomatic->zero_token.token.constant == 0.0 && + mathomatic->one_token.level == 1 && + mathomatic->one_token.kind == CONSTANT && + mathomatic->one_token.token.constant == 1.0)) + error_bug(mathomatic, "Global constants got changed!"); return true; } @@ -347,48 +347,48 @@ check_gvars(void) * This is also called when processing is aborted with a longjmp(3). */ void -init_gvars(void) +init_gvars(MathoMatic* mathomatic) { - domain_check = false; - high_prec = false; - partial_flag = true; - symb_flag = false; - sign_cmp_flag = false; - approximate_roots = false; - repeat_flag = false; + mathomatic->domain_check = false; + mathomatic->high_prec = false; + mathomatic->partial_flag = true; + mathomatic->symb_flag = false; + mathomatic->sign_cmp_flag = false; + mathomatic->approximate_roots = false; + mathomatic->repeat_flag = false; /* initialize the universal and often used constant "0" expression */ - zero_token.level = 1; - zero_token.kind = CONSTANT; - zero_token.token.constant = 0.0; + mathomatic->zero_token.level = 1; + mathomatic->zero_token.kind = CONSTANT; + mathomatic->zero_token.token.constant = 0.0; /* initialize the universal and often used constant "1" expression */ - one_token.level = 1; - one_token.kind = CONSTANT; - one_token.token.constant = 1.0; + mathomatic->one_token.level = 1; + mathomatic->one_token.kind = CONSTANT; + mathomatic->one_token.token.constant = 1.0; } /* * Clean up when processing is unexpectedly interrupted or terminated. */ void -clean_up(void) +clean_up(MathoMatic* mathomatic) { int i; - init_gvars(); /* reset the global variables to the default */ - if (gfp != default_out) { /* reset the output file to default */ + init_gvars(mathomatic); /* reset the global variables to the default */ + if (mathomatic->gfp != mathomatic->default_out) { /* reset the output file to default */ #if !SECURE - if (gfp != stdout && gfp != stderr) - fclose(gfp); + if (mathomatic->gfp != stdout && mathomatic->gfp != stderr) + fclose(mathomatic->gfp); #endif - gfp = default_out; + mathomatic->gfp = mathomatic->default_out; } - gfp_filename = NULL; - for (i = 0; i < n_equations; i++) { - if (n_lhs[i] <= 0) { - n_lhs[i] = 0; - n_rhs[i] = 0; + mathomatic->gfp_filename = NULL; + for (i = 0; i < mathomatic->n_equations; i++) { + if (mathomatic->n_lhs[i] <= 0) { + mathomatic->n_lhs[i] = 0; + mathomatic->n_rhs[i] = 0; } } } @@ -398,21 +398,21 @@ clean_up(void) * so that the next sign variables returned by next_sign() will be unique. */ void -set_sign_array(void) +set_sign_array(MathoMatic* mathomatic) { int i, j; - CLEAR_ARRAY(sign_array); - for (i = 0; i < n_equations; i++) { - if (n_lhs[i] > 0) { - for (j = 0; j < n_lhs[i]; j += 2) { - if (lhs[i][j].kind == VARIABLE && (lhs[i][j].token.variable & VAR_MASK) == SIGN) { - sign_array[(lhs[i][j].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; + CLEAR_ARRAY(mathomatic->sign_array); + for (i = 0; i < mathomatic->n_equations; i++) { + if (mathomatic->n_lhs[i] > 0) { + for (j = 0; j < mathomatic->n_lhs[i]; j += 2) { + if (mathomatic->lhs[i][j].kind == VARIABLE && (mathomatic->lhs[i][j].token.variable & VAR_MASK) == SIGN) { + mathomatic->sign_array[(mathomatic->lhs[i][j].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; } } - for (j = 0; j < n_rhs[i]; j += 2) { - if (rhs[i][j].kind == VARIABLE && (rhs[i][j].token.variable & VAR_MASK) == SIGN) { - sign_array[(rhs[i][j].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; + for (j = 0; j < mathomatic->n_rhs[i]; j += 2) { + if (mathomatic->rhs[i][j].kind == VARIABLE && (mathomatic->rhs[i][j].token.variable & VAR_MASK) == SIGN) { + mathomatic->sign_array[(mathomatic->rhs[i][j].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; } } } @@ -424,20 +424,19 @@ set_sign_array(void) * Mark it used. */ int -next_sign(vp) -long *vp; +next_sign(MathoMatic* mathomatic, long *vp) { int i; for (i = 0;; i++) { - if (i >= ARR_CNT(sign_array)) { + if (i >= ARR_CNT(mathomatic->sign_array)) { /* out of unique sign variables */ *vp = SIGN; return false; } - if (!sign_array[i]) { + if (!mathomatic->sign_array[i]) { *vp = SIGN + (((long) i) << VAR_SHIFT); - sign_array[i] = true; + mathomatic->sign_array[i] = true; break; } } @@ -449,23 +448,23 @@ long *vp; * Similar to a restart. */ void -clear_all(void) +clear_all(MathoMatic* mathomatic) { int i; /* select first equation space */ - cur_equation = 0; + mathomatic->cur_equation = 0; /* erase all equation spaces by setting their length to zero */ - CLEAR_ARRAY(n_lhs); - CLEAR_ARRAY(n_rhs); + CLEAR_ARRAY(mathomatic->n_lhs); + CLEAR_ARRAY(mathomatic->n_rhs); /* forget all variables names */ - for (i = 0; var_names[i]; i++) { - free(var_names[i]); - var_names[i] = NULL; + for (i = 0; mathomatic->var_names[i]; i++) { + free(mathomatic->var_names[i]); + mathomatic->var_names[i] = NULL; } /* reset everything to a known state */ - CLEAR_ARRAY(sign_array); - init_gvars(); + CLEAR_ARRAY(mathomatic->sign_array); + init_gvars(mathomatic); } /* @@ -473,24 +472,24 @@ clear_all(void) * zeroing and allocating if necessary. */ int -alloc_espace(i) -int i; /* equation space number */ +alloc_espace(MathoMatic* mathomatic, int i) +//int i; /* equation space number */ { if (i < 0 || i >= N_EQUATIONS) return false; - n_lhs[i] = 0; - n_rhs[i] = 0; - if (lhs[i] && rhs[i]) + mathomatic->n_lhs[i] = 0; + mathomatic->n_rhs[i] = 0; + if (mathomatic->lhs[i] && mathomatic->rhs[i]) return true; /* already allocated */ - if (lhs[i] || rhs[i]) + if (mathomatic->lhs[i] || mathomatic->rhs[i]) return false; /* something is wrong */ - lhs[i] = (token_type *) malloc(n_tokens * sizeof(token_type)); - if (lhs[i] == NULL) + mathomatic->lhs[i] = (token_type *) malloc(mathomatic->n_tokens * sizeof(token_type)); + if (mathomatic->lhs[i] == NULL) return false; - rhs[i] = (token_type *) malloc(n_tokens * sizeof(token_type)); - if (rhs[i] == NULL) { - free(lhs[i]); - lhs[i] = NULL; + mathomatic->rhs[i] = (token_type *) malloc(mathomatic->n_tokens * sizeof(token_type)); + if (mathomatic->rhs[i] == NULL) { + free(mathomatic->lhs[i]); + mathomatic->lhs[i] = NULL; return false; } return true; @@ -503,21 +502,21 @@ int i; /* equation space number */ * Returns true if successful. */ int -alloc_to_espace(en) -int en; /* equation space number */ +alloc_to_espace(MathoMatic* mathomatic, int en) +//int en; /* equation space number */ { if (en < 0 || en >= N_EQUATIONS) return false; for (;;) { - if (en < n_equations) + if (en < mathomatic->n_equations) return true; - if (n_equations >= N_EQUATIONS) + if (mathomatic->n_equations >= N_EQUATIONS) return false; - if (!alloc_espace(n_equations)) { - warning(_("Memory is exhausted.")); + if (!alloc_espace(mathomatic, mathomatic->n_equations)) { + warning(mathomatic, _("Memory is exhausted.")); return false; } - n_equations++; + mathomatic->n_equations++; } } @@ -527,32 +526,32 @@ int en; /* equation space number */ * Returns empty equation space number ready for use or -1 on error. */ int -alloc_next_espace(void) +alloc_next_espace(MathoMatic* mathomatic) { int i, n; - for (n = cur_equation, i = 0;; n = (n + 1) % N_EQUATIONS, i++) { + for (n = mathomatic->cur_equation, i = 0;; n = (n + 1) % N_EQUATIONS, i++) { if (i >= N_EQUATIONS) return -1; - if (n >= n_equations) { - n = n_equations; - if (!alloc_espace(n)) { - warning(_("Memory is exhausted.")); - for (n = 0; n < n_equations; n++) { - if (n_lhs[n] == 0) { - n_rhs[n] = 0; + if (n >= mathomatic->n_equations) { + n = mathomatic->n_equations; + if (!alloc_espace(mathomatic, n)) { + warning(mathomatic, _("Memory is exhausted.")); + for (n = 0; n < mathomatic->n_equations; n++) { + if (mathomatic->n_lhs[n] == 0) { + mathomatic->n_rhs[n] = 0; return n; } } return -1; } - n_equations++; + mathomatic->n_equations++; return n; } - if (n_lhs[n] == 0) + if (mathomatic->n_lhs[n] == 0) break; } - n_rhs[n] = 0; + mathomatic->n_rhs[n] = 0; return n; } @@ -560,32 +559,32 @@ alloc_next_espace(void) * Return the number of the next empty equation space, otherwise don't return. */ int -next_espace(void) +next_espace(MathoMatic* mathomatic) { int i, j; long answer_v = 0; /* Mathomatic answer variable */ - i = alloc_next_espace(); + i = alloc_next_espace(mathomatic); if (i < 0) { #if !SILENT printf(_("Deleting old numeric calculations to free up equation spaces.\n")); #endif - parse_var(&answer_v, "answer"); /* convert to a Mathomatic variable */ - for (j = 0; j < n_equations; j++) { - if (n_lhs[j] == 1 && lhs[j][0].kind == VARIABLE - && lhs[j][0].token.variable == answer_v) { + parse_var(mathomatic, &answer_v, "answer"); /* convert to a Mathomatic variable */ + for (j = 0; j < mathomatic->n_equations; j++) { + if (mathomatic->n_lhs[j] == 1 && mathomatic->lhs[j][0].kind == VARIABLE + && mathomatic->lhs[j][0].token.variable == answer_v) { /* delete calculation from memory */ - n_lhs[j] = 0; - n_rhs[j] = 0; + mathomatic->n_lhs[j] = 0; + mathomatic->n_rhs[j] = 0; } } - i = alloc_next_espace(); + i = alloc_next_espace(mathomatic); if (i < 0) { - error(_("Out of free equation spaces.")); + error(mathomatic, _("Out of free equation spaces.")); #if !SILENT printf(_("Use the clear command on unnecessary equations and try again.\n")); #endif - longjmp(jmp_save, 3); /* do not return */ + longjmp(mathomatic->jmp_save, 3); /* do not return */ } } return i; @@ -596,35 +595,35 @@ next_espace(void) * "dest" is overwritten. */ void -copy_espace(src, dest) -int src, dest; /* equation space numbers */ +copy_espace(MathoMatic* mathomatic, int src, int dest) +//int src, dest; /* equation space numbers */ { if (src == dest) { #if DEBUG - error_bug("Internal error: copy_espace() source and destination the same."); + error_bug(mathomatic, "Internal error: copy_espace() source and destination the same."); #endif return; } - blt(lhs[dest], lhs[src], n_lhs[src] * sizeof(token_type)); - n_lhs[dest] = n_lhs[src]; - blt(rhs[dest], rhs[src], n_rhs[src] * sizeof(token_type)); - n_rhs[dest] = n_rhs[src]; + blt(mathomatic->lhs[dest], mathomatic->lhs[src], mathomatic->n_lhs[src] * sizeof(token_type)); + mathomatic->n_lhs[dest] = mathomatic->n_lhs[src]; + blt(mathomatic->rhs[dest], mathomatic->rhs[src], mathomatic->n_rhs[src] * sizeof(token_type)); + mathomatic->n_rhs[dest] = mathomatic->n_rhs[src]; } /* * Return true if equation space "i" is a valid equation solved for a normal variable. */ int -solved_equation(i) -int i; +solved_equation(MathoMatic* mathomatic, int i) +//int i; { - if (empty_equation_space(i)) + if (empty_equation_space(mathomatic, i)) return false; - if (n_rhs[i] <= 0) + if (mathomatic->n_rhs[i] <= 0) return false; - if (n_lhs[i] != 1 || lhs[i][0].kind != VARIABLE || (lhs[i][0].token.variable & VAR_MASK) <= SIGN) + if (mathomatic->n_lhs[i] != 1 || mathomatic->lhs[i][0].kind != VARIABLE || (mathomatic->lhs[i][0].token.variable & VAR_MASK) <= SIGN) return false; - if (found_var(rhs[i], n_rhs[i], lhs[i][0].token.variable)) + if (found_var(mathomatic->rhs[i], mathomatic->n_rhs[i], mathomatic->lhs[i][0].token.variable)) return false; return true; } @@ -655,17 +654,17 @@ long v; /* standard Mathomatic variable */ * Return true if variable "v" exists in equation space "i". */ int -var_in_equation(i, v) -int i; /* equation space number */ -long v; /* standard Mathomatic variable */ +var_in_equation(MathoMatic* mathomatic, int i, long v) +//int i; /* equation space number */ +//long v; /* standard Mathomatic variable */ { - if (empty_equation_space(i)) + if (empty_equation_space(mathomatic, i)) return false; - if (found_var(lhs[i], n_lhs[i], v)) + if (found_var(mathomatic->lhs[i], mathomatic->n_lhs[i], v)) return true; - if (n_rhs[i] <= 0) + if (mathomatic->n_rhs[i] <= 0) return false; - if (found_var(rhs[i], n_rhs[i], v)) + if (found_var(mathomatic->rhs[i], mathomatic->n_rhs[i], v)) return true; return false; } @@ -678,27 +677,27 @@ long v; /* standard Mathomatic variable */ * If found, return true with cur_equation set to the equation space the variable is found in. */ int -search_all_for_var(v, forward_direction) -long v; -int forward_direction; +search_all_for_var(MathoMatic* mathomatic, long v, int forward_direction) +//long v; +//int forward_direction; { int i, n; - i = cur_equation; - for (n = 0; n < n_equations; n++) { + i = mathomatic->cur_equation; + for (n = 0; n < mathomatic->n_equations; n++) { if (forward_direction) { - if (i >= (n_equations - 1)) + if (i >= (mathomatic->n_equations - 1)) i = 0; else i++; } else { if (i <= 0) - i = n_equations - 1; + i = mathomatic->n_equations - 1; else i--; } - if (var_in_equation(i, v)) { - cur_equation = i; + if (var_in_equation(mathomatic, i, v)) { + mathomatic->cur_equation = i; return true; } } @@ -709,27 +708,27 @@ int forward_direction; * Replace all occurrences of variable from_v with to_v in an equation space. */ void -rename_var_in_es(en, from_v, to_v) -int en; /* equation space number */ -long from_v, to_v; /* Mathomatic variables */ +rename_var_in_es(MathoMatic* mathomatic, int en, long from_v, long to_v) +//int en; /* equation space number */ +//long from_v, to_v; /* Mathomatic variables */ { int i; - if (empty_equation_space(en)) { + if (empty_equation_space(mathomatic, en)) { #if DEBUG - error_bug("Invalid or empty equation number given to rename_var_in_es()."); + error_bug(mathomatic, "Invalid or empty equation number given to rename_var_in_es()."); #else return; #endif } - for (i = 0; i < n_lhs[en]; i += 2) - if (lhs[en][i].kind == VARIABLE - && lhs[en][i].token.variable == from_v) - lhs[en][i].token.variable = to_v; - for (i = 0; i < n_rhs[en]; i += 2) - if (rhs[en][i].kind == VARIABLE - && rhs[en][i].token.variable == from_v) - rhs[en][i].token.variable = to_v; + for (i = 0; i < mathomatic->n_lhs[en]; i += 2) + if (mathomatic->lhs[en][i].kind == VARIABLE + && mathomatic->lhs[en][i].token.variable == from_v) + mathomatic->lhs[en][i].token.variable = to_v; + for (i = 0; i < mathomatic->n_rhs[en]; i += 2) + if (mathomatic->rhs[en][i].kind == VARIABLE + && mathomatic->rhs[en][i].token.variable == from_v) + mathomatic->rhs[en][i].token.variable = to_v; } /* @@ -738,12 +737,12 @@ long from_v, to_v; /* Mathomatic variables */ * Return true if something was substituted. */ int -subst_var_with_exp(equation, np, expression, len, v) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to equation side length */ -token_type *expression; /* expression pointer */ -int len; /* expression length */ -long v; /* variable to substitute with expression */ +subst_var_with_exp(MathoMatic* mathomatic, token_type *equation, int *np, token_type *expression, int len, long v) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to equation side length */ +//token_type *expression; /* expression pointer */ +//int len; /* expression length */ +//long v; /* variable to substitute with expression */ { int j, k; int level; @@ -754,8 +753,8 @@ long v; /* variable to substitute with expression */ for (j = *np - 1; j >= 0; j--) { if (equation[j].kind == VARIABLE && equation[j].token.variable == v) { level = equation[j].level; - if (*np + len - 1 > n_tokens) { - error_huge(); + if (*np + len - 1 > mathomatic->n_tokens) { + error_huge(mathomatic); } if (len > 1) { blt(&equation[j+len], &equation[j+1], (*np - (j + 1)) * sizeof(token_type)); @@ -768,8 +767,8 @@ long v; /* variable to substitute with expression */ } } if (substituted) { - if (is_integer_var(v) && !is_integer_expr(expression, len)) { - warning(_("Substituting integer variable with non-integer expression.")); + if (is_integer_var(mathomatic, v) && !is_integer_expr(mathomatic, expression, len)) { + warning(mathomatic, _("Substituting integer variable with non-integer expression.")); } } return substituted; @@ -779,16 +778,16 @@ long v; /* variable to substitute with expression */ * Return the base (minimum) parentheses level encountered in a Mathomatic "expression". */ int -min_level(expression, n) -token_type *expression; /* expression pointer */ -int n; /* expression length */ +min_level(MathoMatic* mathomatic, token_type *expression, int n) +//token_type *expression; /* expression pointer */ +//int n; /* expression length */ { int min1; token_type *p1, *ep; #if DEBUG if (expression == NULL) - error_bug("NULL pointer passed to min_level()."); + error_bug(mathomatic, "NULL pointer passed to min_level()."); #endif switch (n) { case 1: @@ -797,7 +796,7 @@ int n; /* expression length */ return expression[1].level; default: if (n <= 0 || (n & 1) != 1) - error_bug("Invalid expression length in call to min_level()."); + error_bug(mathomatic, "Invalid expression length in call to min_level()."); break; } min1 = expression[1].level; @@ -817,19 +816,18 @@ int n; /* expression length */ * Return -1 on error. */ int -get_default_en(cp) -char *cp; +get_default_en(MathoMatic* mathomatic, char *cp) { int i; if (*cp == '\0') { - i = cur_equation; + i = mathomatic->cur_equation; } else { i = decstrtol(cp, &cp) - 1; - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return -1; } - if (not_defined(i)) { + if (not_defined(mathomatic, i)) { return -1; } return i; @@ -842,27 +840,27 @@ char *cp; * Return true if successful. */ int -get_expr(equation, np) -token_type *equation; /* where the parsed expression is stored (equation side) */ -int *np; /* pointer to the returned parsed expression length */ +get_expr(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* where the parsed expression is stored (equation side) */ +//int *np; /* pointer to the returned parsed expression length */ { char buf[DEFAULT_N_TOKENS]; char *cp; #if LIBRARY - snprintf(buf, sizeof(buf), "#%+d", pull_number); - pull_number++; - cp = parse_expr(equation, np, buf, true); - if (extra_characters(cp)) + snprintf(buf, sizeof(buf), "#%+d", mathomatic->pull_number); + mathomatic->pull_number++; + cp = parse_expr(mathomatic, equation, np, buf, true); + if (extra_characters(mathomatic, cp)) return false; return(cp && *np > 0); #else for (;;) { - if ((cp = get_string(buf, sizeof(buf))) == NULL) { + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) { return false; } - cp = parse_expr(equation, np, cp, true); - if (cp && !extra_characters(cp)) { + cp = parse_expr(mathomatic, equation, np, cp, true); + if (cp && !extra_characters(mathomatic, cp)) { break; } } @@ -876,22 +874,22 @@ int *np; /* pointer to the returned parsed expression length */ * Return true if successful. */ int -prompt_var(vp) -long *vp; /* pointer to the returned variable */ +prompt_var(MathoMatic* mathomatic, long *vp) +//long *vp; /* pointer to the returned variable */ { char buf[MAX_CMD_LEN]; char *cp; for (;;) { - my_strlcpy(prompt_str, _("Enter variable: "), sizeof(prompt_str)); - if ((cp = get_string(buf, sizeof(buf))) == NULL) { + my_strlcpy(mathomatic->prompt_str, _("Enter variable: "), sizeof(mathomatic->prompt_str)); + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) { return false; } if (*cp == '\0') { return false; } - cp = parse_var2(vp, cp); - if (cp == NULL || extra_characters(cp)) { + cp = parse_var2(mathomatic, vp, cp); + if (cp == NULL || extra_characters(mathomatic, cp)) { continue; } return true; @@ -902,18 +900,18 @@ long *vp; /* pointer to the returned variable */ * Return true and display a message if equation "i" is undefined. */ int -not_defined(i) -int i; /* equation space number */ +not_defined(MathoMatic* mathomatic, int i) +//int i; /* equation space number */ { - if (i < 0 || i >= n_equations) { - error(_("Invalid equation number.")); + if (i < 0 || i >= mathomatic->n_equations) { + error(mathomatic, _("Invalid equation number.")); return true; } - if (n_lhs[i] <= 0) { - if (i == cur_equation) { - error(_("Current equation space is empty.")); + if (mathomatic->n_lhs[i] <= 0) { + if (i == mathomatic->cur_equation) { + error(mathomatic, _("Current equation space is empty.")); } else { - error(_("Equation space is empty.")); + error(mathomatic, _("Equation space is empty.")); } return true; } @@ -926,17 +924,17 @@ int i; /* equation space number */ * Return true and display a message if the current equation space is empty or not defined. */ int -current_not_defined(void) +current_not_defined(MathoMatic* mathomatic) { int i; - i = cur_equation; - if (i < 0 || i >= n_equations) { - error(_("Current equation number out of range; reset to 1.")); - i = cur_equation = 0; + i = mathomatic->cur_equation; + if (i < 0 || i >= mathomatic->n_equations) { + error(mathomatic, _("Current equation number out of range; reset to 1.")); + i = mathomatic->cur_equation = 0; } - if (n_lhs[i] <= 0) { - error(_("No current equation or expression.")); + if (mathomatic->n_lhs[i] <= 0) { + error(mathomatic, _("No current equation or expression.")); return true; } return false; @@ -950,12 +948,12 @@ current_not_defined(void) * Returns "string" if successful or NULL on error. */ char * -get_string(string, n) -char *string; /* storage for input string */ -int n; /* maximum size of "string" in bytes */ +get_string(MathoMatic* mathomatic, char *string, int n) +//char *string; /* storage for input string */ +//int n; /* maximum size of "string" in bytes */ { #if LIBRARY - error(_("Library usage error. Input requested, possibly due to missing command-line argument.")); + error(mathomatic, _("Library usage error. Input requested, possibly due to missing command-line argument.")); return NULL; #else int i; @@ -965,62 +963,62 @@ int n; /* maximum size of "string" in bytes */ #if DEBUG if (string == NULL) - error_bug("NULL pointer passed to get_string()."); + error_bug(mathomatic, "NULL pointer passed to get_string()."); #endif - if (quiet_mode) { - prompt_str[0] = '\0'; /* don't display a prompt */ + if (mathomatic->quiet_mode) { + mathomatic->prompt_str[0] = '\0'; /* don't display a prompt */ } - input_column = strlen(prompt_str); + mathomatic->input_column = strlen(mathomatic->prompt_str); fflush(NULL); /* flush everything before gathering input */ #if READLINE || EDITLINE - if (readline_enabled) { - cp = readline(prompt_str); + if (mathomatic->readline_enabled) { + cp = readline(mathomatic->prompt_str); if (cp == NULL) { - if (!quiet_mode) + if (!mathomatic->quiet_mode) printf(_("\nEnd of input.\n")); exit_program(0); } my_strlcpy(string, cp, n); - if (skip_space(cp)[0] && (last_history_string == NULL || strcmp(last_history_string, cp))) { + if (skip_space(cp)[0] && (mathomatic->last_history_string == NULL || strcmp(mathomatic->last_history_string, cp))) { add_history(cp); - last_history_string = cp; + mathomatic->last_history_string = cp; } else { free(cp); } } else { - printf("%s", prompt_str); + printf("%s", mathomatic->prompt_str); fflush(stdout); if (fgets(string, n, stdin) == NULL) { - if (!quiet_mode) + if (!mathomatic->quiet_mode) printf(_("\nEnd of input.\n")); exit_program(0); } } #else - printf("%s", prompt_str); + printf("%s", mathomatic->prompt_str); fflush(stdout); if (fgets(string, n, stdin) == NULL) { - if (!quiet_mode) + if (!mathomatic->quiet_mode) printf(_("\nEnd of input.\n")); exit_program(0); } #endif - if (abort_flag) { - abort_flag = false; - longjmp(jmp_save, 13); + if (mathomatic->abort_flag) { + mathomatic->abort_flag = false; + longjmp(mathomatic->jmp_save, 13); } /* Fix an fgets() peculiarity: */ i = strlen(string) - 1; if (i >= 0 && string[i] == '\n') { string[i] = '\0'; } - if ((gfp != stdout && gfp != stderr) || (echo_input && !quiet_mode)) { + if ((mathomatic->gfp != stdout && mathomatic->gfp != stderr) || (mathomatic->echo_input && !mathomatic->quiet_mode)) { /* Input that is prompted for is now included in the redirected output of a command to a file, making redirection like logging. */ - fprintf(gfp, "%s%s\n", prompt_str, string); + fprintf(mathomatic->gfp, "%s%s\n", mathomatic->prompt_str, string); } - set_error_level(string); - abort_flag = false; + set_error_level(mathomatic, string); + mathomatic->abort_flag = false; return string; #endif } @@ -1032,7 +1030,7 @@ int n; /* maximum size of "string" in bytes */ * Return false if "n" or not interactive. */ int -get_yes_no(void) +get_yes_no(MathoMatic* mathomatic) { char *cp; char buf[MAX_CMD_LEN]; @@ -1043,7 +1041,7 @@ get_yes_no(void) } #endif for (;;) { - if ((cp = get_string(buf, sizeof(buf))) == NULL) { + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) { return false; } str_tolower(cp); @@ -1064,35 +1062,35 @@ get_yes_no(void) * Return true if successful. */ int -return_result(en) -int en; /* equation space number the result is in */ +return_result(MathoMatic* mathomatic, int en) +//int en; /* equation space number the result is in */ { - if (empty_equation_space(en)) { + if (empty_equation_space(mathomatic, en)) { return false; } #if LIBRARY - make_fractions_and_group(en); - if (factor_int_flag) { - factor_int_equation(en); + make_fractions_and_group(mathomatic, en); + if (mathomatic->factor_int_flag) { + factor_int_equation(mathomatic, en); } - free_result_str(); + free_result_str(mathomatic); #if 1 /* Set this to 1 to allow display2d to decide library output mode. */ - if (display2d) { - result_str = flist_equation_string(en); - if (result_str == NULL) - result_str = list_equation(en, false); + if (mathomatic->display2d) { + mathomatic->result_str = flist_equation_string(mathomatic, en); + if (mathomatic->result_str == NULL) + mathomatic->result_str = list_equation(mathomatic, en, false); } else { - result_str = list_equation(en, false); + mathomatic->result_str = list_equation(mathomatic, en, false); } #else /* For feeding command output to the next command's input only. */ - result_str = list_equation(en, false); + mathomatic->result_str = list_equation(mathomatic, en, false); #endif - result_en = en; - if (gfp == stdout) { - return(result_str != NULL); + mathomatic->result_en = en; + if (mathomatic->gfp == stdout) { + return(mathomatic->result_str != NULL); } #endif - return(list_sub(en) != 0); + return(list_sub(mathomatic, en) != 0); } /* @@ -1100,13 +1098,13 @@ int en; /* equation space number the result is in */ * in the symbolic math library. */ void -free_result_str(void) +free_result_str(MathoMatic* mathomatic) { - if (result_str) { - free(result_str); - result_str = NULL; + if (mathomatic->result_str) { + free(mathomatic->result_str); + mathomatic->result_str = NULL; } - result_en = -1; + mathomatic->result_en = -1; } /* @@ -1130,9 +1128,7 @@ char *cp; * and ending equation number in "*jp". */ int -get_range(cpp, ip, jp) -char **cpp; -int *ip, *jp; +get_range(MathoMatic* mathomatic, char **cpp, int *ip, int *jp) { int i; char *cp; @@ -1142,8 +1138,8 @@ int *ip, *jp; if (is_all(cp)) { cp = skip_param(cp); *ip = 0; - *jp = n_equations - 1; - while (*jp > 0 && n_lhs[*jp] == 0) + *jp = mathomatic->n_equations - 1; + while (*jp > 0 && mathomatic->n_lhs[*jp] == 0) (*jp)--; } else { if (*cp == '0') { @@ -1152,11 +1148,11 @@ int *ip, *jp; if (isdigit(*cp)) { *ip = strtol(cp, &cp, 10) - 1; } else { - *ip = cur_equation; + *ip = mathomatic->cur_equation; } if (*cp != '-') { if (*cp == '\0' || *cp == ',' || isspace(*cp)) { - if (not_defined(*ip)) { + if (not_defined(mathomatic, *ip)) { return false; } *jp = *ip; @@ -1164,18 +1160,18 @@ int *ip, *jp; return true; } else { use_current: - *jp = *ip = cur_equation; + *jp = *ip = mathomatic->cur_equation; #if 1 - rv = !empty_equation_space(cur_equation); /* don't display error message */ + rv = !empty_equation_space(mathomatic, mathomatic->cur_equation); /* don't display error message */ if (rv) { - debug_string(1, _("Defaulting to the current equation space.")); + debug_string(mathomatic, 1, _("Defaulting to the current equation space.")); } else { - debug_string(1, _("Defaulting to current empty equation space.")); + debug_string(mathomatic, 1, _("Defaulting to current empty equation space.")); } #else - rv = !current_not_defined(); /* display an error message if error */ + rv = !current_not_defined(mathomatic); /* display an error message if error */ if (rv) { - debug_string(1, _("Defaulting to the current equation space.")); + debug_string(mathomatic, 1, _("Defaulting to the current equation space.")); } #endif return rv; @@ -1188,13 +1184,13 @@ int *ip, *jp; if (isdigit(*cp)) { *jp = strtol(cp, &cp, 10) - 1; } else { - *jp = cur_equation; + *jp = mathomatic->cur_equation; } if (*cp && !isspace(*cp)) { goto use_current; } if (*ip < 0 || *ip >= N_EQUATIONS || *jp < 0 || *jp >= N_EQUATIONS) { - error(_("Invalid equation number (out of range).")); + error(mathomatic, _("Invalid equation number (out of range).")); return false; } if (*jp < *ip) { @@ -1205,12 +1201,12 @@ int *ip, *jp; } cp = skip_comma_space(cp); for (i = *ip; i <= *jp; i++) { - if (n_lhs[i] > 0) { + if (mathomatic->n_lhs[i] > 0) { *cpp = cp; return true; } } - error(_("No expressions defined in specified range.")); + error(mathomatic, _("No expressions defined in specified range.")); return false; } @@ -1222,14 +1218,14 @@ int *ip, *jp; * Otherwise just returns false indicating everything is OK. */ int -extra_characters(cp) -char *cp; /* command line string */ +extra_characters(MathoMatic* mathomatic, char *cp) +//char *cp; /* command line string */ { if (cp) { cp = skip_comma_space(cp); if (*cp) { printf(_("\nError: \"%s\" not required on input line.\n"), cp); - error(_("Extra characters or unrecognized argument.")); + error(mathomatic, _("Extra characters or unrecognized argument.")); return true; } } @@ -1241,14 +1237,12 @@ char *cp; /* command line string */ * otherwise display an error message and return false. */ int -get_range_eol(cpp, ip, jp) -char **cpp; -int *ip, *jp; +get_range_eol(MathoMatic* mathomatic, char **cpp, int *ip, int *jp) { - if (!get_range(cpp, ip, jp)) { + if (!get_range(mathomatic, cpp, ip, jp)) { return false; } - if (extra_characters(*cpp)) { + if (extra_characters(mathomatic, *cpp)) { return false; } return true; @@ -1346,7 +1340,7 @@ char *cp1, *cp2; #if DEBUG if (cp1 == NULL || cp2 == NULL) - error_bug("NULL pointer passed to strcmp_tospace()."); + error_bug(mathomatic, "NULL pointer passed to strcmp_tospace()."); #endif for (cp1a = cp1; *cp1a && !isdelimiter(*cp1a); cp1a++) ; @@ -1383,11 +1377,11 @@ int level; /* parentheses level number to check */ * Return the number of level 1 additive type operators. */ int -level1_plus_count(p1, n1) -token_type *p1; /* expression pointer */ -int n1; /* expression length */ +level1_plus_count(MathoMatic* mathomatic, token_type *p1, int n1) +//token_type *p1; /* expression pointer */ +//int n1; /* expression length */ { - return level_plus_count(p1, n1, min_level(p1, n1)); + return level_plus_count(p1, n1, min_level(mathomatic, p1, n1)); } /* @@ -1531,11 +1525,10 @@ int n1; /* expression length */ * Display a warning and return true if passed double is 0. */ int -check_divide_by_zero(denominator) -double denominator; +check_divide_by_zero(MathoMatic* mathomatic, double denominator) { if (denominator == 0) { - warning(_("Division by zero.")); + warning(mathomatic, _("Division by zero.")); return true; } return false; @@ -1572,9 +1565,9 @@ char *cp; /* string containing filename to modify */ * otherwise return true. */ int -load_rc(return_true_if_no_file, ofp) -int return_true_if_no_file; -FILE *ofp; /* if non-NULL, display each line as read in to this file */ +load_rc(MathoMatic* mathomatic, int return_true_if_no_file, FILE *ofp) +//int return_true_if_no_file; +//FILE *ofp; /* if non-NULL, display each line as read in to this file */ { FILE *fp = NULL; char buf[MAX_CMD_LEN]; @@ -1583,40 +1576,40 @@ FILE *ofp; /* if non-NULL, display each line as read in to this file */ cp = getenv("HOME"); if (cp) { - snprintf(rc_file, sizeof(rc_file), "%s/%s", cp, ".mathomaticrc"); - fp = fopen(rc_file, "r"); + snprintf(mathomatic->rc_file, sizeof(mathomatic->rc_file), "%s/%s", cp, ".mathomaticrc"); + fp = fopen(mathomatic->rc_file, "r"); } #if CYGWIN || MINGW if (fp == NULL && cp) { - snprintf(rc_file, sizeof(rc_file), "%s/%s", cp, "mathomatic.rc"); - fp = fopen(rc_file, "r"); + snprintf(mathomatic->rc_file, sizeof(mathomatic->rc_file), "%s/%s", cp, "mathomatic.rc"); + fp = fopen(mathomatic->rc_file, "r"); } if (fp == NULL && dir_path) { - snprintf(rc_file, sizeof(rc_file), "%s/%s", dir_path, "mathomatic.rc"); - fp = fopen(rc_file, "r"); + snprintf(mathomatic->rc_file, sizeof(mathomatic->rc_file), "%s/%s", dir_path, "mathomatic.rc"); + fp = fopen(mathomatic->rc_file, "r"); } #endif if (fp == NULL) { if (return_true_if_no_file) { return true; } else { - perror(rc_file); + perror(mathomatic->rc_file); return false; } } - if (!quiet_mode && !eoption) { - printf(_("Loading startup set options from \"%s\".\n"), rc_file); + if (!mathomatic->quiet_mode && !mathomatic->eoption) { + printf(_("Loading startup set options from \"%s\".\n"), mathomatic->rc_file); } while ((cp = fgets(buf, sizeof(buf), fp)) != NULL) { if (ofp) fprintf(ofp, "%s", cp); - set_error_level(cp); - if (!set_options(cp, true)) + set_error_level(mathomatic, cp); + if (!set_options(mathomatic, cp, true)) rv = false; } if (fclose(fp)) { rv = false; - perror(rc_file); + perror(mathomatic->rc_file); } return rv; } @@ -1629,18 +1622,17 @@ FILE *ofp; /* if non-NULL, display each line as read in to this file */ * otherwise return true. */ int -display_rc(ofp) -FILE *ofp; +display_rc(MathoMatic* mathomatic, FILE *ofp) { FILE *fp = NULL; char buf[MAX_CMD_LEN]; char *cp; int rv = true; - printf(_("Displaying startup set options from \"%s\":\n\n"), rc_file); - fp = fopen(rc_file, "r"); + printf(_("Displaying startup set options from \"%s\":\n\n"), mathomatic->rc_file); + fp = fopen(mathomatic->rc_file, "r"); if (fp == NULL) { - perror(rc_file); + perror(mathomatic->rc_file); return false; } while ((cp = fgets(buf, sizeof(buf), fp)) != NULL) { @@ -1648,7 +1640,7 @@ FILE *ofp; } if (fclose(fp)) { rv = false; - perror(rc_file); + perror(mathomatic->rc_file); } return rv; } diff --git a/am.h b/am.h index d2ea960..2f6b5d3 100644 --- a/am.h +++ b/am.h @@ -170,20 +170,20 @@ enum language_list { /* Debugging macros: */ #if SILENT -#define list_esdebug(level, en) { ; } /* Display an equation space. */ -#define list_tdebug(level) { ; } /* Display the temporary equation (e.g.: when solving). */ -#define side_debug(level, p1, n1) { ; } /* Display any expression. */ -#define debug_string(level, str) { ; } /* Display any ASCII string. */ +#define list_esdebug(mathomatic, level, en) { ; } /* Display an equation space. */ +#define list_tdebug(mathomatic, level) { ; } /* Display the temporary equation (e.g.: when solving). */ +#define side_debug(mathomatic, level, p1, n1) { ; } /* Display any expression. */ +#define debug_string(mathomatic, level, str) { ; } /* Display any ASCII string. */ #else -#define list_esdebug(level, en) list_debug(level, lhs[en], n_lhs[en], rhs[en], n_rhs[en]) -#define list_tdebug(level) list_debug(level, tlhs, n_tlhs, trhs, n_trhs) -#define side_debug(level, p1, n1) list_debug(level, p1, n1, NULL, 0) -#define debug_string(level, str) { if (debug_level >= (level)) fprintf(gfp, "%s\n", str); } +#define list_esdebug(mathomatic, level, en) list_debug(mathomatic, level, mathomatic->lhs[en], mathomatic->n_lhs[en], mathomatic->rhs[en], mathomatic->n_rhs[en]) +#define list_tdebug(mathomatic, level) list_debug(mathomatic, level, mathomatic->tlhs, mathomatic->n_tlhs, mathomatic->trhs, mathomatic->n_trhs) +#define side_debug(mathomatic, level, p1, n1) list_debug(mathomatic, level, p1, n1, NULL, 0) +#define debug_string(mathomatic, level, str) { if (mathomatic->debug_level >= (level)) fprintf(mathomatic->gfp, "%s\n", str); } #endif /* The correct ways to determine if equation number "en" (origin 0) contains an expression or equation. */ -#define empty_equation_space(en) ((en) < 0 || (en) >= n_equations || n_lhs[(en)] <= 0) -#define equation_space_is_equation(en) ((en) >= 0 && (en) < n_equations && n_lhs[(en)] > 0 && n_rhs[(en)] > 0) +#define empty_equation_space(mathomatic, en) ((en) < 0 || (en) >= mathomatic->n_equations || mathomatic->n_lhs[(en)] <= 0) +#define equation_space_is_equation(mathomatic, en) ((en) >= 0 && (en) < mathomatic->n_equations && mathomatic->n_lhs[(en)] > 0 && mathomatic->n_rhs[(en)] > 0) /* * The following are macros for displaying help text. @@ -192,10 +192,10 @@ enum language_list { * This is helpful when the output device has less than 80 text character columns. */ #if NOT80COLUMNS -#define SP(str) fprintf(gfp, "%s ", str) /* display part of a paragraph, separated with spaces (Space Paragraph) */ -#define EP(str) fprintf(gfp, "%s\n", str) /* display the end of a paragraph (End Paragraph) */ +#define SP(mathomatic, str) fprintf(mathomatic->gfp, "%s ", str) /* display part of a paragraph, separated with spaces (Space Paragraph) */ +#define EP(mathomatic, str) fprintf(mathomatic->gfp, "%s\n", str) /* display the end of a paragraph (End Paragraph) */ #else /* Otherwise the following only works nicely with 80 column or wider screens; */ /* all strings passed to it should be less than 80 columns if possible, so it doesn't wrap around. */ -#define SP(str) fprintf(gfp, "%s\n", str) -#define EP(str) fprintf(gfp, "%s\n", str) +#define SP(mathomatic, str) fprintf(mathomatic->gfp, "%s\n", str) +#define EP(mathomatic, str) fprintf(mathomatic->gfp, "%s\n", str) #endif diff --git a/blt.h b/blt.h index 7922972..5655e93 100644 --- a/blt.h +++ b/blt.h @@ -40,7 +40,7 @@ int cnt; if (cnt == 0) { return dest; } else { - error_bug("blt() cnt < 0"); + error_bug(mathomatic, "blt() cnt < 0"); } } if (src == dest) { diff --git a/cmds.c b/cmds.c index 22304b1..3bb62ab 100644 --- a/cmds.c +++ b/cmds.c @@ -32,13 +32,10 @@ enum spf_function { FOR_COMMAND }; -static int sum_product(char *cp, enum spf_function current_function); -static int complex_func(char *cp, int imag_flag); -static int elim_sub(int i, long v); +static int sum_product(MathoMatic* mathomatic, char *cp, enum spf_function current_function); +static int complex_func(MathoMatic* mathomatic, char *cp, int imag_flag); +static int elim_sub(MathoMatic* mathomatic, int i, long v); -/* Global variables for the optimize command. */ -static int opt_en[N_EQUATIONS+1]; -static int last_temp_var = 0; #if SHELL_OUT /* @@ -47,10 +44,10 @@ static int last_temp_var = 0; * All command functions like this return true if successful, or false for failure. */ int -plot_cmd(cp) -char *cp; /* the command-line argument */ +plot_cmd(MathoMatic* mathomatic, char *cp) +//char *cp; /* the command-line argument */ { -#define APPEND(str) { if (strlen(str) + cl1_len < sizeof(cl1)) { strcpy(&cl1[cl1_len], str); cl1_len += strlen(str); } else warning(_("Expression too large to plot; omitted.")); } +#define APPEND(str) { if (strlen(str) + cl1_len < sizeof(cl1)) { strcpy(&cl1[cl1_len], str); cl1_len += strlen(str); } else warning(mathomatic, _("Expression too large to plot; omitted.")); } int i1, i2; int start, stop; @@ -63,53 +60,53 @@ char *cp; /* the command-line argument */ int ev; /* exit value */ int cur_equation_flag = false; - if (security_level > 0) { - show_usage = false; - error(_("Command disabled by security level.")); + if (mathomatic->security_level > 0) { + mathomatic->show_usage = false; + error(mathomatic, _("Command disabled by security level.")); return false; } - if (!parse_var(&vx, "x")) { + if (!parse_var(mathomatic, &vx, "x")) { return false; } do { cp1 = cp; - if (!get_range(&cp, &start, &stop)) { - reset_error(); + if (!get_range(mathomatic, &cp, &start, &stop)) { + reset_error(mathomatic); break; } if (cp != cp1 || first_time) { if (cp == cp1) - cur_equation_flag = (!empty_equation_space(cur_equation)); + cur_equation_flag = (!empty_equation_space(mathomatic, mathomatic->cur_equation)); for (i1 = start; i1 <= stop; i1++) { - if (i1 != cur_equation) { + if (i1 != mathomatic->cur_equation) { cur_equation_flag = false; } - if (n_lhs[i1] > 0) { + if (mathomatic->n_lhs[i1] > 0) { v = 0; - if (n_rhs[i1]) { - equation = rhs[i1]; - np = &n_rhs[i1]; + if (mathomatic->n_rhs[i1]) { + equation = mathomatic->rhs[i1]; + np = &mathomatic->n_rhs[i1]; } else { - equation = lhs[i1]; - np = &n_lhs[i1]; + equation = mathomatic->lhs[i1]; + np = &mathomatic->n_lhs[i1]; } if (!no_vars(equation, *np, &v) && v) { - if (strcmp(var_name(v), "x") && strcmp(var_name(v), "t")) { - list_var(v, 0); - fprintf(gfp, _("#%d: Renaming variable %s to x for gnuplot.\n"), i1 + 1, var_str); - rename_var_in_es(i1, v, vx); + if (strcmp(var_name(mathomatic, v), "x") && strcmp(var_name(mathomatic, v), "t")) { + list_var(mathomatic, v, 0); + fprintf(mathomatic->gfp, _("#%d: Renaming variable %s to x for gnuplot.\n"), i1 + 1, mathomatic->var_str); + rename_var_in_es(mathomatic, i1, v, vx); } } - if (n_rhs[i1] && !solved_equation(i1)) { - warning(_("Not a normally solved equation, plotting the RHS only.")); + if (mathomatic->n_rhs[i1] && !solved_equation(mathomatic, i1)) { + warning(mathomatic, _("Not a normally solved equation, plotting the RHS only.")); } for (i2 = 0; i2 < *np; i2 += 2) { if (equation[i2].kind == VARIABLE && (equation[i2].token.variable & VAR_MASK) == SIGN) { - warning(_("Plot expression contains sign variables; try \"simplify sign\" before plotting.")); + warning(mathomatic, _("Plot expression contains sign variables; try \"simplify sign\" before plotting.")); break; } } - exp_str = list_expression(equation, *np, 3); + exp_str = list_expression(mathomatic, equation, *np, 3); if (exp_str == NULL) return false; if (cl1_len) { @@ -124,12 +121,12 @@ char *cp; /* the command-line argument */ } while (*cp && cp != cp1); cl1[cl1_len] = '\0'; if (cl1_len == 0 && *cp == '\0') { - error(_("No plot expression specified.")); + error(mathomatic, _("No plot expression specified.")); return false; } for (cl2_len = 0, i2 = 0; cp[i2]; i2++) { if ((cl2_len + 2) >= sizeof(cl2)) { - error(_("Command-line too long.")); + error(mathomatic, _("Command-line too long.")); return false; } switch (cp[i2]) { @@ -148,18 +145,18 @@ char *cp; /* the command-line argument */ cl2[cl2_len] = '\0'; if (cl1_len && cl2_len && cl2[cl2_len-1] != ',') { if (cur_equation_flag) { - snprintf(prompt_str, sizeof(prompt_str), _("Do you want to plot the current equation, too (y/n)? ")); - if (!get_yes_no()) { + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("Do you want to plot the current equation, too (y/n)? ")); + if (!get_yes_no(mathomatic)) { cl1_len = 0; cl1[cl1_len] = '\0'; } } if (cl1_len) { - snprintf(prompt_str, sizeof(prompt_str), _("Does the plot command-line consist of any expressions (y/n)? ")); - if (get_yes_no()) { - fprintf(gfp, _("Appending a comma to the command-line.\n")); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("Does the plot command-line consist of any expressions (y/n)? ")); + if (get_yes_no(mathomatic)) { + fprintf(mathomatic->gfp, _("Appending a comma to the command-line.\n")); if ((cl2_len + 2) >= sizeof(cl2)) { - error(_("Command-line too long.")); + error(mathomatic, _("Command-line too long.")); return false; } cl2[cl2_len++] = ','; @@ -168,27 +165,27 @@ char *cp; /* the command-line argument */ } } if (strchr(cl2, 'y') || strchr(cl1, 'y')) { - fprintf(gfp, _("Performing 3D surface plot...\n")); + fprintf(mathomatic->gfp, _("Performing 3D surface plot...\n")); #if MINGW - len = snprintf(cl, sizeof(cl), "gnuplot -persist -e \"%s; splot %s %s\"", plot_prefix, cl2, cl1); + len = snprintf(cl, sizeof(cl), "gnuplot -persist -e \"%s; splot %s %s\"", mathomatic->plot_prefix, cl2, cl1); #else - len = snprintf(cl, sizeof(cl), "echo '%s; splot %s %s'|gnuplot -persist", plot_prefix, cl2, cl1); + len = snprintf(cl, sizeof(cl), "echo '%s; splot %s %s'|gnuplot -persist", mathomatic->plot_prefix, cl2, cl1); #endif } else { - fprintf(gfp, _("Performing 2D plot...\n")); + fprintf(mathomatic->gfp, _("Performing 2D plot...\n")); #if MINGW - len = snprintf(cl, sizeof(cl), "gnuplot -persist -e \"%s; plot %s %s\"", plot_prefix, cl2, cl1); + len = snprintf(cl, sizeof(cl), "gnuplot -persist -e \"%s; plot %s %s\"", mathomatic->plot_prefix, cl2, cl1); #else - len = snprintf(cl, sizeof(cl), "echo '%s; plot %s %s'|gnuplot -persist", plot_prefix, cl2, cl1); + len = snprintf(cl, sizeof(cl), "echo '%s; plot %s %s'|gnuplot -persist", mathomatic->plot_prefix, cl2, cl1); #endif } if (len >= sizeof(cl)) { - error(_("gnuplot command-line too long.")); + error(mathomatic, _("gnuplot command-line too long.")); return false; } - ev = shell_out(cl); + ev = shell_out(mathomatic, cl); if (ev) { - error(_("Possible error running gnuplot.")); + error(mathomatic, _("Possible error running gnuplot.")); printf(_("Decimal exit value = %d\n"), ev); if (ev == 256 || ev == 1) { printf(_("Try separating each expression with a comma.\n")); @@ -205,8 +202,8 @@ char *cp; /* the command-line argument */ * All commands return true if successful. */ int -version_cmd(cp) -char *cp; /* the command-line argument */ +version_cmd(MathoMatic* mathomatic, char *cp) +//char *cp; /* the command-line argument */ { int rv = true; /* return value */ int status_flag = false; @@ -215,29 +212,29 @@ char *cp; /* the command-line argument */ status_flag = true; cp = skip_param(cp); } - if (extra_characters(cp)) /* Make sure nothing else is on the command-line. */ + if (extra_characters(mathomatic, cp)) /* Make sure nothing else is on the command-line. */ return false; #if LIBRARY - free_result_str(); - result_str = strdup(VERSION); + free_result_str(mathomatic); + mathomatic->result_str = strdup(VERSION); #endif if (status_flag) { - rv = version_report(); + rv = version_report(mathomatic); } else { #if !SILENT || !LIBRARY - fprintf(gfp, _("Mathomatic version %s\n"), VERSION); + fprintf(mathomatic->gfp, _("Mathomatic version %s\n"), VERSION); #endif } if (status_flag) { - debug_string(0, "\nMathomatic is GNU LGPL version 2.1 licensed software,\n" + debug_string(mathomatic, 0, "\nMathomatic is GNU LGPL version 2.1 licensed software,\n" "meaning it is free software that comes with no warranty.\n" "Type \"help license\" for the copyright and license."); - EP(_("\nFor all new stuff, visit the Mathomatic website: www.mathomatic.org")); + EP(mathomatic, ("\nFor all new stuff, visit the Mathomatic website: www.mathomatic.org")); } #if LIBRARY - return(rv && result_str != NULL); + return(rv && mathomatic->result_str != NULL); #else return rv; #endif @@ -247,9 +244,9 @@ char *cp; /* the command-line argument */ * Return the maximum amount of memory (in bytes) that this program will use. */ long -max_memory_usage(void) +max_memory_usage(MathoMatic* mathomatic) { - return((long) (N_EQUATIONS + 3L) * (long) n_tokens * sizeof(token_type) * 2L); + return((long) (N_EQUATIONS + 3L) * (long) mathomatic->n_tokens * sizeof(token_type) * 2L); } /* @@ -258,8 +255,7 @@ max_memory_usage(void) * Return true if successful. */ int -show_status(ofp) -FILE *ofp; +show_status(FILE *ofp) { #if SHOW_RESOURCES struct rusage usage_local; @@ -286,149 +282,149 @@ FILE *ofp; * Display version and status info. */ int -version_report(void) +version_report(MathoMatic* mathomatic) { long l; - fprintf(gfp, _("Mathomatic version %s\n"), VERSION); - fprintf(gfp, _("The last main prompt return value is %d (meaning "), previous_return_value); - switch (previous_return_value) { + fprintf(mathomatic->gfp, _("Mathomatic version %s\n"), VERSION); + fprintf(mathomatic->gfp, _("The last main prompt return value is %d (meaning "), mathomatic->previous_return_value); + switch (mathomatic->previous_return_value) { case 0: - fprintf(gfp, _("failure).\n")); + fprintf(mathomatic->gfp, _("failure).\n")); break; default: - fprintf(gfp, _("success).\n")); + fprintf(mathomatic->gfp, _("success).\n")); break; } - show_status(gfp); - fprintf(gfp, _("\nCompile-time defines used: ")); + show_status(mathomatic->gfp); + fprintf(mathomatic->gfp, _("\nCompile-time defines used: ")); #if linux - fprintf(gfp, "linux "); + fprintf(mathomatic->gfp, "linux "); #endif #if sun - fprintf(gfp, "sun "); + fprintf(mathomatic->gfp, "sun "); #endif #if UNIX - fprintf(gfp, "UNIX "); + fprintf(mathomatic->gfp, "UNIX "); #endif #if CYGWIN - fprintf(gfp, "CYGWIN "); + fprintf(mathomatic->gfp, "CYGWIN "); #endif #if MINGW - fprintf(gfp, "MINGW "); + fprintf(mathomatic->gfp, "MINGW "); #endif #if HANDHELD - fprintf(gfp, "HANDHELD "); + fprintf(mathomatic->gfp, "HANDHELD "); #endif #if EDITLINE - fprintf(gfp, "EDITLINE "); + fprintf(mathomatic->gfp, "EDITLINE "); #endif #if READLINE - fprintf(gfp, "READLINE "); + fprintf(mathomatic->gfp, "READLINE "); #endif #if SILENT - fprintf(gfp, "SILENT "); + fprintf(mathomatic->gfp, "SILENT "); #endif #if LIBRARY - fprintf(gfp, "LIBRARY "); + fprintf(mathomatic->gfp, "LIBRARY "); #endif #if SECURE - fprintf(gfp, "SECURE "); + fprintf(mathomatic->gfp, "SECURE "); #endif #if TIMEOUT_SECONDS - fprintf(gfp, "TIMEOUT_SECONDS=%d ", TIMEOUT_SECONDS); + fprintf(mathomatic->gfp, "TIMEOUT_SECONDS=%d ", TIMEOUT_SECONDS); #endif #if I18N - fprintf(gfp, "I18N "); + fprintf(mathomatic->gfp, "I18N "); #endif #if NO_COLOR - fprintf(gfp, "NO_COLOR "); + fprintf(mathomatic->gfp, "NO_COLOR "); #endif #if BOLD_COLOR - fprintf(gfp, "BOLD_COLOR "); + fprintf(mathomatic->gfp, "BOLD_COLOR "); #endif #if WIN32_CONSOLE_COLORS - fprintf(gfp, "WIN32_CONSOLE_COLORS "); + fprintf(mathomatic->gfp, "WIN32_CONSOLE_COLORS "); #endif #if NOGAMMA - fprintf(gfp, "NOGAMMA "); + fprintf(mathomatic->gfp, "NOGAMMA "); #endif #if USE_TGAMMA - fprintf(gfp, "USE_TGAMMA "); + fprintf(mathomatic->gfp, "USE_TGAMMA "); #endif #if DEBUG - fprintf(gfp, "DEBUG "); + fprintf(mathomatic->gfp, "DEBUG "); #endif #if VALGRIND - fprintf(gfp, "VALGRIND "); + fprintf(mathomatic->gfp, "VALGRIND "); #endif #if SHOW_RESOURCES - fprintf(gfp, "SHOW_RESOURCES "); + fprintf(mathomatic->gfp, "SHOW_RESOURCES "); #endif - fprintf(gfp, "\nsizeof(int) = %u bytes, sizeof(long) = %u bytes.\n", (unsigned) sizeof(int), (unsigned) sizeof(long)); - fprintf(gfp, "sizeof(double) = %u bytes, maximum double precision = %d decimal digits.\n", (unsigned) sizeof(double), DBL_DIG); + fprintf(mathomatic->gfp, "\nsizeof(int) = %u bytes, sizeof(long) = %u bytes.\n", (unsigned) sizeof(int), (unsigned) sizeof(long)); + fprintf(mathomatic->gfp, "sizeof(double) = %u bytes, maximum double precision = %d decimal digits.\n", (unsigned) sizeof(double), DBL_DIG); #ifdef __VERSION__ #ifdef __GNUC__ - fprintf(gfp, "GNU "); + fprintf(mathomatic->gfp, "GNU "); #endif - fprintf(gfp, _("C Compiler version: %s\n"), __VERSION__); + fprintf(mathomatic->gfp, _("C Compiler version: %s\n"), __VERSION__); #endif - fprintf(gfp, _("\n%d equation spaces currently allocated.\n"), n_equations); - fprintf(gfp, _("The current expression array size is %d tokens,\n"), n_tokens); - l = max_memory_usage() / 1000L; + fprintf(mathomatic->gfp, _("\n%d equation spaces currently allocated.\n"), mathomatic->n_equations); + fprintf(mathomatic->gfp, _("The current expression array size is %d tokens,\n"), mathomatic->n_tokens); + l = max_memory_usage(mathomatic) / 1000L; if (l >= 10000L) { - fprintf(gfp, _("making the maximum memory usage approximately %ld megabytes.\n"), l / 1000L); + fprintf(mathomatic->gfp, _("making the maximum memory usage approximately %ld megabytes.\n"), l / 1000L); } else { - fprintf(gfp, _("making the maximum memory usage approximately %ld kilobytes.\n"), l); + fprintf(mathomatic->gfp, _("making the maximum memory usage approximately %ld kilobytes.\n"), l); } #if SECURE - fprintf(gfp, _("Compiled for maximum security.\n")); + fprintf(mathomatic->gfp, _("Compiled for maximum security.\n")); #else - fprintf(gfp, _("The current security level is %d"), security_level); - switch (security_level) { + fprintf(mathomatic->gfp, _("The current security level is %d"), mathomatic->security_level); + switch (mathomatic->security_level) { case -1: - fprintf(gfp, _(", meaning you are running m4 Mathomatic.\n")); + fprintf(mathomatic->gfp, _(", meaning you are running m4 Mathomatic.\n")); break; case 0: - fprintf(gfp, _(", no security, meaning users are unrestricted.\n")); + fprintf(mathomatic->gfp, _(", no security, meaning users are unrestricted.\n")); break; case 1: case 2: - fprintf(gfp, _(", some security.\n")); + fprintf(mathomatic->gfp, _(", some security.\n")); break; case 3: - fprintf(gfp, _(", high security.\n")); + fprintf(mathomatic->gfp, _(", high security.\n")); break; case 4: - fprintf(gfp, _(", maximum security.\n")); + fprintf(mathomatic->gfp, _(", maximum security.\n")); break; default: - fprintf(gfp, _(", unknown meaning.\n")); + fprintf(mathomatic->gfp, _(", unknown meaning.\n")); break; } #endif #if READLINE || EDITLINE #if READLINE - fprintf(gfp, _("\nreadline is compiled in and ")); + fprintf(mathomatic->gfp, _("\nreadline is compiled in and ")); #else - fprintf(gfp, _("\neditline is compiled in and ")); + fprintf(mathomatic->gfp, _("\neditline is compiled in and ")); #endif - if (readline_enabled) { - fprintf(gfp, _("activated.\n")); + if (mathomatic->readline_enabled) { + fprintf(mathomatic->gfp, _("activated.\n")); } else { - fprintf(gfp, _("deactivated.\n")); + fprintf(mathomatic->gfp, _("deactivated.\n")); } #elif !LIBRARY && !HANDHELD #if MINGW - SP(_("\nreadline is not compiled in, however some of its functionality")); - SP(_("already exists in the Windows console for any")); - EP(_("Windows console program (like Mathomatic).")); + SP(mathomatic, ("\nreadline is not compiled in, however some of its functionality")); + SP(mathomatic, ("already exists in the Windows console for any")); + EP(mathomatic, ("Windows console program (like Mathomatic).")); #else - SP(_("\nreadline is not compiled in.")); - SP(_("Please notify the package maintainer that readline")); - EP(_("should be compiled into Mathomatic, with \"make READLINE=1\".")); + SP(mathomatic, ("\nreadline is not compiled in.")); + SP(mathomatic, ("Please notify the package maintainer that readline")); + EP(mathomatic, ("should be compiled into Mathomatic, with \"make READLINE=1\".")); #endif #endif return true; @@ -444,8 +440,7 @@ version_report(void) * or the result contains infinity or NaN). */ int -solve_cmd(cp) -char *cp; +solve_cmd(MathoMatic* mathomatic, char *cp) { int i, j, k; int start, stop; @@ -465,12 +460,12 @@ char *cp; verify_flag = 2; cp = skip_param(cp); } - if (!get_range(&cp, &start, &stop)) { - warning(_("No equations to solve.")); + if (!get_range(mathomatic, &cp, &start, &stop)) { + warning(mathomatic, _("No equations to solve.")); return false; } - i = next_espace(); - repeat_flag = true; + i = next_espace(mathomatic); + mathomatic->repeat_flag = true; if (strcmp_tospace(cp, "verify") == 0) { verify_flag = 1; cp = skip_param(cp); @@ -485,116 +480,116 @@ char *cp; } } if (*cp == '\0') { - my_strlcpy(prompt_str, _("Enter variable to solve for: "), sizeof(prompt_str)); - if ((cp = get_string(buf, sizeof(buf))) == NULL) { + my_strlcpy(mathomatic->prompt_str, _("Enter variable to solve for: "), sizeof(mathomatic->prompt_str)); + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) { return false; } cp_start = cp; } - input_column += (cp - cp_start); - if ((cp = parse_equation(i, cp)) == NULL) { + mathomatic->input_column += (cp - cp_start); + if ((cp = parse_equation(mathomatic, i, cp)) == NULL) { return false; } if (verify_flag) { - if (n_lhs[i] != 1 || n_rhs[i] != 0 || (lhs[i][0].kind != VARIABLE - && (lhs[i][0].kind != CONSTANT || lhs[i][0].token.constant != 0.0))) { - error(_("Can only verify for a single solve variable or identities after solving for 0.")); + if (mathomatic->n_lhs[i] != 1 || mathomatic->n_rhs[i] != 0 || (mathomatic->lhs[i][0].kind != VARIABLE + && (mathomatic->lhs[i][0].kind != CONSTANT || mathomatic->lhs[i][0].token.constant != 0.0))) { + error(mathomatic, _("Can only verify for a single solve variable or identities after solving for 0.")); goto fail; } - want = lhs[i][0]; + want = mathomatic->lhs[i][0]; } - show_usage = false; + mathomatic->show_usage = false; for (k = start; k <= stop; k++) { - if (k == i || n_lhs[k] <= 0 || n_rhs[k] <= 0) { + if (k == i || mathomatic->n_lhs[k] <= 0 || mathomatic->n_rhs[k] <= 0) { continue; } last_solve_successful = false; - cur_equation = k; + mathomatic->cur_equation = k; did_something = true; if (verify_flag) { pre_v = 0; - fprintf(gfp, _("Solving equation #%d for "), cur_equation + 1); - list_proc(&want, 1, false); + fprintf(mathomatic->gfp, _("Solving equation #%d for "), mathomatic->cur_equation + 1); + list_proc(mathomatic, &want, 1, false); if (verify_flag == 2) { - fprintf(gfp, " with required "); + fprintf(mathomatic->gfp, " with required "); } else { - fprintf(gfp, " with "); + fprintf(mathomatic->gfp, " with "); } if (want.kind == VARIABLE) { - fprintf(gfp, "verification...\n"); - if (solved_equation(cur_equation)) { - pre_v = lhs[cur_equation][0].token.variable; + fprintf(mathomatic->gfp, "verification...\n"); + if (solved_equation(mathomatic, mathomatic->cur_equation)) { + pre_v = mathomatic->lhs[mathomatic->cur_equation][0].token.variable; } } else { - fprintf(gfp, "identity verification...\n"); + fprintf(mathomatic->gfp, "identity verification...\n"); } - copy_espace(cur_equation, i); - if (solve_sub(&want, 1, lhs[cur_equation], &n_lhs[cur_equation], rhs[cur_equation], &n_rhs[cur_equation]) > 0) { - simpa_repeat(cur_equation, true, false); /* Solve result should be quick simplified. */ + copy_espace(mathomatic, mathomatic->cur_equation, i); + if (solve_sub(mathomatic, &want, 1, mathomatic->lhs[mathomatic->cur_equation], &mathomatic->n_lhs[mathomatic->cur_equation], mathomatic->rhs[mathomatic->cur_equation], &mathomatic->n_rhs[mathomatic->cur_equation]) > 0) { + simpa_repeat(mathomatic, mathomatic->cur_equation, true, false); /* Solve result should be quick simplified. */ last_solve_successful = true; - debug_string(0, _("Solve and \"repeat simplify quick\" successful:")); - if (!return_result(cur_equation)) { /* Display the simplified solve result. */ + debug_string(mathomatic, 0, _("Solve and \"repeat simplify quick\" successful:")); + if (!return_result(mathomatic, mathomatic->cur_equation)) { /* Display the simplified solve result. */ goto fail; } if (want.kind == VARIABLE) { - if (!solved_equation(cur_equation) || lhs[cur_equation][0].token.variable != want.token.variable) { - error(_("Result not a properly solved equation, so cannot verify.")); + if (!solved_equation(mathomatic, mathomatic->cur_equation) || mathomatic->lhs[mathomatic->cur_equation][0].token.variable != want.token.variable) { + error(mathomatic, _("Result not a properly solved equation, so cannot verify.")); continue; } if (pre_v && pre_v == want.token.variable) { - warning(_("Equation was already solved, so no need to verify solutions.")); + warning(mathomatic, _("Equation was already solved, so no need to verify solutions.")); continue; } } else { - copy_espace(cur_equation, i); + copy_espace(mathomatic, mathomatic->cur_equation, i); } plural_flag = false; - for (j = 0; j < n_rhs[cur_equation]; j += 2) { - if (rhs[cur_equation][j].kind == VARIABLE && (rhs[cur_equation][j].token.variable & VAR_MASK) == SIGN) { + for (j = 0; j < mathomatic->n_rhs[mathomatic->cur_equation]; j += 2) { + if (mathomatic->rhs[mathomatic->cur_equation][j].kind == VARIABLE && (mathomatic->rhs[mathomatic->cur_equation][j].token.variable & VAR_MASK) == SIGN) { plural_flag = true; break; } } if (want.kind == VARIABLE) { - subst_var_with_exp(lhs[i], &n_lhs[i], rhs[cur_equation], n_rhs[cur_equation], want.token.variable); - subst_var_with_exp(rhs[i], &n_rhs[i], rhs[cur_equation], n_rhs[cur_equation], want.token.variable); + subst_var_with_exp(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->rhs[mathomatic->cur_equation], mathomatic->n_rhs[mathomatic->cur_equation], want.token.variable); + subst_var_with_exp(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], mathomatic->rhs[mathomatic->cur_equation], mathomatic->n_rhs[mathomatic->cur_equation], want.token.variable); } once_through = false; - calc_simp(lhs[i], &n_lhs[i]); - calc_simp(rhs[i], &n_rhs[i]); + calc_simp(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i]); + calc_simp(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); check_result: - contains_infinity = (exp_contains_infinity(lhs[i], n_lhs[i]) - || exp_contains_infinity(rhs[i], n_rhs[i])); - if (se_compare(lhs[i], n_lhs[i], rhs[i], n_rhs[i], &diff_sign) && (want.kind != VARIABLE || !diff_sign)) { + contains_infinity = (exp_contains_infinity(mathomatic->lhs[i], mathomatic->n_lhs[i]) + || exp_contains_infinity(mathomatic->rhs[i], mathomatic->n_rhs[i])); + if (se_compare(mathomatic, mathomatic->lhs[i], mathomatic->n_lhs[i], mathomatic->rhs[i], mathomatic->n_rhs[i], &diff_sign) && (want.kind != VARIABLE || !diff_sign)) { if (want.kind != VARIABLE) { - fprintf(gfp, _("This equation is an identity.\n")); + fprintf(mathomatic->gfp, _("This equation is an identity.\n")); } else if (plural_flag) - fprintf(gfp, _("All solutions verified.\n")); + fprintf(mathomatic->gfp, _("All solutions verified.\n")); else - fprintf(gfp, _("Solution verified.\n")); + fprintf(mathomatic->gfp, _("Solution verified.\n")); if (contains_infinity) { - error(_("Solution might be incorrect because it contains infinity or NaN.")); + error(mathomatic, _("Solution might be incorrect because it contains infinity or NaN.")); if (rv) rv = 2; } } else { if (!contains_infinity && once_through < 2) { - symb_flag = symblify; - simpa_repeat(i, once_through ? false : true, once_through ? true : false); /* Simplify to compare equation sides. */ - symb_flag = false; + mathomatic->symb_flag = mathomatic->symblify; + simpa_repeat(mathomatic, i, once_through ? false : true, once_through ? true : false); /* Simplify to compare equation sides. */ + mathomatic->symb_flag = false; once_through++; goto check_result; } if (contains_infinity) { - error(_("Solution might be incorrect because it contains infinity or NaN.")); + error(mathomatic, _("Solution might be incorrect because it contains infinity or NaN.")); } else { if (want.kind != VARIABLE) { - error(_("This equation is NOT an identity.")); + error(mathomatic, _("This equation is NOT an identity.")); } else if (plural_flag) - error(_("Unable to verify all solutions.")); + error(mathomatic, _("Unable to verify all solutions.")); else - error(_("Unable to verify solution.")); + error(mathomatic, _("Unable to verify solution.")); } if (verify_flag == 2) rv = 0; @@ -602,13 +597,13 @@ char *cp; rv = 2; } } else { - printf(_("Solve failed for equation space #%d.\n"), cur_equation + 1); + printf(_("Solve failed for equation space #%d.\n"), mathomatic->cur_equation + 1); rv = 0; } } else { - if (solve_espace(i, cur_equation)) { + if (solve_espace(mathomatic, i, mathomatic->cur_equation)) { last_solve_successful = true; - if (!return_result(cur_equation)) { + if (!return_result(mathomatic, mathomatic->cur_equation)) { goto fail; } } else { @@ -618,18 +613,18 @@ char *cp; } if (did_something) { if (last_solve_successful && verify_flag) { - debug_string(1, "Verification identity:"); - list_esdebug(1, i); + debug_string(mathomatic, 1, "Verification identity:"); + list_esdebug(mathomatic, 1, i); } } else { printf(_("No work done.\n")); } - n_lhs[i] = 0; - n_rhs[i] = 0; + mathomatic->n_lhs[i] = 0; + mathomatic->n_rhs[i] = 0; return rv; fail: - n_lhs[i] = 0; - n_rhs[i] = 0; + mathomatic->n_lhs[i] = 0; + mathomatic->n_rhs[i] = 0; return 0; } @@ -637,39 +632,35 @@ char *cp; * The sum command. */ int -sum_cmd(cp) -char *cp; +sum_cmd(MathoMatic* mathomatic, char *cp) { - return sum_product(cp, SUM_COMMAND); + return sum_product(mathomatic, cp, SUM_COMMAND); } /* * The product command. */ int -product_cmd(cp) -char *cp; +product_cmd(MathoMatic* mathomatic, char *cp) { - return sum_product(cp, PRODUCT_COMMAND); + return sum_product(mathomatic, cp, PRODUCT_COMMAND); } /* * The for command. */ int -for_cmd(cp) -char *cp; +for_cmd(MathoMatic* mathomatic, char *cp) { - return sum_product(cp, FOR_COMMAND); + return sum_product(mathomatic, cp, FOR_COMMAND); } /* * Common function for the sum and product commands. */ static int -sum_product(cp, current_function) -char *cp; /* the command-line */ -enum spf_function current_function; +sum_product(MathoMatic* mathomatic, char *cp, enum spf_function current_function) +//char *cp; /* the command-line */ { int i; long v = 0; /* Mathomatic variable */ @@ -680,36 +671,36 @@ enum spf_function current_function; int count_down; /* if true, count down, otherwise count up */ char *cp1, buf[MAX_CMD_LEN]; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - result_equation = next_espace(); - if (n_rhs[cur_equation]) { - ns = n_rhs[cur_equation]; - source = rhs[cur_equation]; - dest = rhs[result_equation]; + result_equation = next_espace(mathomatic); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + ns = mathomatic->n_rhs[mathomatic->cur_equation]; + source = mathomatic->rhs[mathomatic->cur_equation]; + dest = mathomatic->rhs[result_equation]; } else { - ns = n_lhs[cur_equation]; - source = lhs[cur_equation]; - dest = lhs[result_equation]; + ns = mathomatic->n_lhs[mathomatic->cur_equation]; + source = mathomatic->lhs[mathomatic->cur_equation]; + dest = mathomatic->lhs[result_equation]; } if (*cp) { - cp = parse_var2(&v, cp); + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } } if (no_vars(source, ns, &v)) { - error(_("Current expression contains no variables.")); + error(mathomatic, _("Current expression contains no variables.")); return false; } if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } if (!found_var(source, ns, v)) { - error(_("Specified variable not found.")); + error(mathomatic, _("Specified variable not found.")); return false; } if (*cp) { @@ -718,18 +709,18 @@ enum spf_function current_function; } cp1 = cp; } else { - list_var(v, 0); - snprintf(prompt_str, sizeof(prompt_str), "%s = ", var_str); - if ((cp1 = get_string(buf, sizeof(buf))) == NULL) + list_var(mathomatic, v, 0); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), "%s = ", mathomatic->var_str); + if ((cp1 = get_string(mathomatic, buf, sizeof(buf))) == NULL) return false; } start = strtod(cp1, &cp); if (cp1 == cp || !isfinite(start)) { - error(_("Number expected.")); + error(mathomatic, _("Number expected.")); return false; } if (fabs(start) >= MAX_K_INTEGER) { - error(_("Number too large.")); + error(mathomatic, _("Number too large.")); return false; } cp = skip_comma_space(cp); @@ -739,17 +730,17 @@ enum spf_function current_function; if (*cp) { cp1 = cp; } else { - my_strlcpy(prompt_str, _("To: "), sizeof(prompt_str)); - if ((cp1 = get_string(buf, sizeof(buf))) == NULL) + my_strlcpy(mathomatic->prompt_str, _("To: "), sizeof(mathomatic->prompt_str)); + if ((cp1 = get_string(mathomatic, buf, sizeof(buf))) == NULL) return false; } end = strtod(cp1, &cp); if (cp1 == cp || !isfinite(end)) { - error(_("Number expected.")); + error(mathomatic, _("Number expected.")); return false; } if (fabs(end) >= MAX_K_INTEGER) { - error(_("Number too large.")); + error(mathomatic, _("Number too large.")); return false; } cp = skip_comma_space(cp); @@ -760,37 +751,37 @@ enum spf_function current_function; cp1 = cp; step = fabs(strtod(cp1, &cp)); if (cp1 == cp || !isfinite(step) || step <= 0.0 || step >= MAX_K_INTEGER) { - error(_("Invalid step.")); + error(mathomatic, _("Invalid step.")); return false; } } - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; count_down = (end < start); if (fmod(fabs(start - end) / step, 1.0) != 0.0) { - warning(_("End value not reached.")); + warning(mathomatic, _("End value not reached.")); } if (current_function == PRODUCT_COMMAND) { - dest[0] = one_token; + dest[0] = mathomatic->one_token; } else { - dest[0] = zero_token; + dest[0] = mathomatic->zero_token; } n = 1; for (; count_down ? (start >= end) : (start <= end); count_down ? (start -= step) : (start += step)) { - if (n + 1 + ns > n_tokens) { - error_huge(); + if (n + 1 + ns > mathomatic->n_tokens) { + error_huge(mathomatic); } - blt(tlhs, source, ns * sizeof(token_type)); - n_tlhs = ns; - for (i = 0; i < n_tlhs; i += 2) { - if (tlhs[i].kind == VARIABLE && tlhs[i].token.variable == v) { - tlhs[i].kind = CONSTANT; - tlhs[i].token.constant = start; + blt(mathomatic->tlhs, source, ns * sizeof(token_type)); + mathomatic->n_tlhs = ns; + for (i = 0; i < mathomatic->n_tlhs; i += 2) { + if (mathomatic->tlhs[i].kind == VARIABLE && mathomatic->tlhs[i].token.variable == v) { + mathomatic->tlhs[i].kind = CONSTANT; + mathomatic->tlhs[i].token.constant = start; } } if (current_function != FOR_COMMAND) { - for (i = 0; i < n_tlhs; i++) { - tlhs[i].level++; + for (i = 0; i < mathomatic->n_tlhs; i++) { + mathomatic->tlhs[i].level++; } for (i = 0; i < n; i++) { dest[i].level++; @@ -811,29 +802,29 @@ enum spf_function current_function; n = 0; break; } - blt(&dest[n], tlhs, n_tlhs * sizeof(token_type)); - n += n_tlhs; - calc_simp(dest, &n); + blt(&dest[n], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + n += mathomatic->n_tlhs; + calc_simp(mathomatic, dest, &n); if (current_function == FOR_COMMAND) { - list_var(v, 0); - fprintf(gfp, "%s = %.*g: ", var_str, precision, start); - list_factor(dest, &n, false); - fprintf(gfp, "\n"); + list_var(mathomatic, v, 0); + fprintf(mathomatic->gfp, "%s = %.*g: ", mathomatic->var_str, mathomatic->precision, start); + list_factor(mathomatic, dest, &n, false); + fprintf(mathomatic->gfp, "\n"); } else { - side_debug(1, dest, n); + side_debug(mathomatic, 1, dest, n); } } if (current_function == FOR_COMMAND) { return true; } else { - if (n_rhs[cur_equation]) { - n_rhs[result_equation] = n; - blt(lhs[result_equation], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_lhs[result_equation] = n_lhs[cur_equation]; + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + mathomatic->n_rhs[result_equation] = n; + blt(mathomatic->lhs[result_equation], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_lhs[result_equation] = mathomatic->n_lhs[mathomatic->cur_equation]; } else { - n_lhs[result_equation] = n; + mathomatic->n_lhs[result_equation] = n; } - return return_result(result_equation); + return return_result(mathomatic, result_equation); } } @@ -843,17 +834,17 @@ enum spf_function current_function; * It should be called repeatedly until it returns false. */ static int -find_more(equation, np, en) -token_type *equation; /* expression to search */ -int *np; /* pointer to length of expression */ -int en; /* equation space number */ +find_more(MathoMatic* mathomatic, token_type *equation, int *np, int en) +//token_type *equation; /* expression to search */ +//int *np; /* pointer to length of expression */ +//int en; /* equation space number */ { int i, j, k; int level; int diff_sign; int found_se; /* found sub-expression flag */ - if (*np <= 0 || !solved_equation(en)) { + if (*np <= 0 || !solved_equation(mathomatic, en)) { return false; } for (level = 1, found_se = true; found_se; level++) { @@ -865,7 +856,7 @@ int en; /* equation space number */ } found_se = true; k = i - 1; - if (se_compare(&equation[k], j - k, rhs[en], n_rhs[en], &diff_sign)) { + if (se_compare(mathomatic, &equation[k], j - k, mathomatic->rhs[en], mathomatic->n_rhs[en], &diff_sign)) { if (diff_sign) { blt(&equation[i+2], &equation[j], (*np - j) * sizeof(token_type)); *np -= (j - (i + 2)); @@ -884,7 +875,7 @@ int en; /* equation space number */ } equation[k].level = level; equation[k].kind = VARIABLE; - equation[k].token.variable = lhs[en][0].token.variable; + equation[k].token.variable = mathomatic->lhs[en][0].token.variable; return true; } } @@ -899,9 +890,7 @@ int en; /* equation space number */ * It should be called repeatedly until it returns false. */ static int -opt_es(equation, np) -token_type *equation; -int *np; +opt_es(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j, k, i1, i2, jj1, k1; int level, level1; @@ -938,22 +927,22 @@ int *np; continue; k1 = i1 - 1; if ((jj1 - k1) >= OPT_MIN_SIZE - && se_compare(&equation[k], j - k, &equation[k1], jj1 - k1, &diff_sign)) { - snprintf(var_name_buf, sizeof(var_name_buf), "temp%.0d", last_temp_var); - if (parse_var(&v, var_name_buf) == NULL) { + && se_compare(mathomatic, &equation[k], j - k, &equation[k1], jj1 - k1, &diff_sign)) { + snprintf(var_name_buf, sizeof(var_name_buf), "temp%.0d", mathomatic->last_temp_var); + if (parse_var(mathomatic, &v, var_name_buf) == NULL) { return false; /* can't create "temp" variable */ } - last_temp_var++; - if (last_temp_var < 0) { - last_temp_var = 0; + mathomatic->last_temp_var++; + if (mathomatic->last_temp_var < 0) { + mathomatic->last_temp_var = 0; } - i2 = next_espace(); - lhs[i2][0].level = 1; - lhs[i2][0].kind = VARIABLE; - lhs[i2][0].token.variable = v; - n_lhs[i2] = 1; - blt(rhs[i2], &equation[k], (j - k) * sizeof(token_type)); - n_rhs[i2] = j - k; + i2 = next_espace(mathomatic); + mathomatic->lhs[i2][0].level = 1; + mathomatic->lhs[i2][0].kind = VARIABLE; + mathomatic->lhs[i2][0].token.variable = v; + mathomatic->n_lhs[i2] = 1; + blt(mathomatic->rhs[i2], &equation[k], (j - k) * sizeof(token_type)); + mathomatic->n_rhs[i2] = j - k; if (diff_sign) { blt(&equation[i1+2], &equation[jj1], (*np - jj1) * sizeof(token_type)); *np -= (jj1 - (i1 + 2)); @@ -978,19 +967,19 @@ int *np; equation[k].level = level; equation[k].kind = VARIABLE; equation[k].token.variable = v; - while (find_more(equation, np, i2)) + while (find_more(mathomatic, equation, np, i2)) ; - simp_loop(rhs[i2], &n_rhs[i2]); - simp_loop(equation, np); + simp_loop(mathomatic, mathomatic->rhs[i2], &mathomatic->n_rhs[i2]); + simp_loop(mathomatic, equation, np); for (i = 0;; i++) { if (i >= N_EQUATIONS) { - error_bug("Too many optimized equations."); + error_bug(mathomatic, "Too many optimized equations."); } - if (opt_en[i] < 0) + if (mathomatic->opt_en[i] < 0) break; } - opt_en[i] = i2; - opt_en[i+1] = -1; + mathomatic->opt_en[i] = i2; + mathomatic->opt_en[i+1] = -1; return true; } } @@ -1004,8 +993,7 @@ int *np; * The optimize command. */ int -optimize_cmd(cp) -char *cp; +optimize_cmd(MathoMatic* mathomatic, char *cp) { int i, j, k, i1; int start, stop; @@ -1013,15 +1001,15 @@ char *cp; int start_en; int diff_sign; - if (!get_range_eol(&cp, &start, &stop)) { + if (!get_range_eol(mathomatic, &cp, &start, &stop)) { return false; } - opt_en[0] = -1; + mathomatic->opt_en[0] = -1; start_en = 0; for (j = i = start; i <= stop; i++) { - if (n_lhs[i]) { + if (mathomatic->n_lhs[i]) { j = i; - simp_equation(i); + simp_equation(mathomatic, i); } } stop = j; @@ -1030,7 +1018,7 @@ char *cp; for (i = start; i <= stop; i++) { for (j = start; j <= stop; j++) { if (i != j) { - while (find_more(rhs[i], &n_rhs[i], j)) { + while (find_more(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], j)) { flag = true; rv = true; } @@ -1039,80 +1027,80 @@ char *cp; } } while (flag); for (i = start; i <= stop; i++) { - if (n_lhs[i] == 0) + if (mathomatic->n_lhs[i] == 0) continue; do { flag = false; - simp_equation(i); - for (j = 0; opt_en[j] >= 0; j++) { - if (i != opt_en[j]) { - simp_equation(opt_en[j]); - while (find_more(lhs[i], &n_lhs[i], opt_en[j])) + simp_equation(mathomatic, i); + for (j = 0; mathomatic->opt_en[j] >= 0; j++) { + if (i != mathomatic->opt_en[j]) { + simp_equation(mathomatic, mathomatic->opt_en[j]); + while (find_more(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->opt_en[j])) flag = true; - while (find_more(rhs[i], &n_rhs[i], opt_en[j])) + while (find_more(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], mathomatic->opt_en[j])) flag = true; } } } while (flag); - while (opt_es(lhs[i], &n_lhs[i])) { + while (opt_es(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i])) { rv = true; } - while (opt_es(rhs[i], &n_rhs[i])) { + while (opt_es(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i])) { rv = true; } if (rv) { - for (i1 = start_en; opt_en[i1] >= 0; i1++) { - for (j = start_en; opt_en[j] >= 0; j++) { - for (k = j + 1; opt_en[k] >= 0; k++) { - while (find_more(rhs[opt_en[k]], &n_rhs[opt_en[k]], opt_en[j])) + for (i1 = start_en; mathomatic->opt_en[i1] >= 0; i1++) { + for (j = start_en; mathomatic->opt_en[j] >= 0; j++) { + for (k = j + 1; mathomatic->opt_en[k] >= 0; k++) { + while (find_more(mathomatic, mathomatic->rhs[mathomatic->opt_en[k]], &mathomatic->n_rhs[mathomatic->opt_en[k]], mathomatic->opt_en[j])) ; - while (find_more(rhs[opt_en[j]], &n_rhs[opt_en[j]], opt_en[k])) + while (find_more(mathomatic, mathomatic->rhs[mathomatic->opt_en[j]], &mathomatic->n_rhs[mathomatic->opt_en[j]], mathomatic->opt_en[k])) ; } } - while (opt_es(rhs[opt_en[i1]], &n_rhs[opt_en[i1]])) + while (opt_es(mathomatic, mathomatic->rhs[mathomatic->opt_en[i1]], &mathomatic->n_rhs[mathomatic->opt_en[i1]])) ; } /* Remove equation if identity, otherwise display. */ - for (; opt_en[start_en] >= 0; start_en++) { - k = opt_en[start_en]; - if (se_compare(lhs[k], n_lhs[k], rhs[k], n_rhs[k], &diff_sign) && !diff_sign) { - n_lhs[k] = 0; - n_rhs[k] = 0; + for (; mathomatic->opt_en[start_en] >= 0; start_en++) { + k = mathomatic->opt_en[start_en]; + if (se_compare(mathomatic, mathomatic->lhs[k], mathomatic->n_lhs[k], mathomatic->rhs[k], mathomatic->n_rhs[k], &diff_sign) && !diff_sign) { + mathomatic->n_lhs[k] = 0; + mathomatic->n_rhs[k] = 0; } else - list_sub(k); + list_sub(mathomatic, k); } - if (se_compare(lhs[i], n_lhs[i], rhs[i], n_rhs[i], &diff_sign) && !diff_sign) { - n_lhs[i] = 0; - n_rhs[i] = 0; + if (se_compare(mathomatic, mathomatic->lhs[i], mathomatic->n_lhs[i], mathomatic->rhs[i], mathomatic->n_rhs[i], &diff_sign) && !diff_sign) { + mathomatic->n_lhs[i] = 0; + mathomatic->n_rhs[i] = 0; } } } if (rv) { for (i = start; i <= stop; i++) { - if (n_lhs[i] == 0) + if (mathomatic->n_lhs[i] == 0) continue; skip_flag = false; do { flag = false; - simp_equation(i); - for (j = 0; opt_en[j] >= 0; j++) { - if (i != opt_en[j]) { - simp_equation(opt_en[j]); - while (find_more(lhs[i], &n_lhs[i], opt_en[j])) + simp_equation(mathomatic, i); + for (j = 0; mathomatic->opt_en[j] >= 0; j++) { + if (i != mathomatic->opt_en[j]) { + simp_equation(mathomatic, mathomatic->opt_en[j]); + while (find_more(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->opt_en[j])) flag = true; - while (find_more(rhs[i], &n_rhs[i], opt_en[j])) + while (find_more(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], mathomatic->opt_en[j])) flag = true; } else skip_flag = true; } } while (flag); if (!skip_flag) - list_sub(i); + list_sub(mathomatic, i); } } if (!rv) { - error(_("Unable to find any repeated expressions.")); + error(mathomatic, _("Unable to find any repeated expressions.")); } return rv; } @@ -1122,23 +1110,22 @@ char *cp; * The push command. */ int -push_cmd(cp) -char *cp; +push_cmd(MathoMatic* mathomatic, char *cp) { int start, stop; int k; char *cp1, *cp_start; cp_start = cp; - if (!readline_enabled) { - error(_("Readline is currently turned off.")); + if (!mathomatic->readline_enabled) { + error(mathomatic, _("Readline is currently turned off.")); return false; } do { cp1 = cp; - if (!get_range(&cp, &start, &stop)) { + if (!get_range(mathomatic, &cp, &start, &stop)) { if (*cp_start) { - reset_error(); + reset_error(mathomatic); } goto push_text; } @@ -1146,11 +1133,11 @@ char *cp; goto push_text; } for (k = start; k <= stop; k++) { - if (n_lhs[k]) { - if (push_en(k)) { - debug_string(0, _("Expression pushed. Press the UP key to access.")); + if (mathomatic->n_lhs[k]) { + if (push_en(mathomatic, k)) { + debug_string(mathomatic, 0, _("Expression pushed. Press the UP key to access.")); } else { - error(_("Expression push failed.")); + error(mathomatic, _("Expression push failed.")); return false; } } @@ -1161,8 +1148,8 @@ char *cp; push_text: if (*cp_start) { add_history(cp_start); - last_history_string = NULL; - debug_string(0, _("Text string pushed. Press the UP key to access.")); + mathomatic->last_history_string = NULL; + debug_string(mathomatic, 0, _("Text string pushed. Press the UP key to access.")); return true; } return false; @@ -1174,20 +1161,20 @@ char *cp; * Return true if successful. */ int -push_en(en) -int en; /* equation space number to push */ +push_en(MathoMatic* mathomatic, int en) +//int en; /* equation space number to push */ { char *cp; - if (!readline_enabled) + if (!mathomatic->readline_enabled) return false; - high_prec = true; - cp = list_equation(en, false); - high_prec = false; + mathomatic->high_prec = true; + cp = list_equation(mathomatic, en, false); + mathomatic->high_prec = false; if (cp == NULL) return false; add_history(cp); - last_history_string = cp; + mathomatic->last_history_string = cp; return true; } #endif @@ -1198,13 +1185,13 @@ int en; /* equation space number to push */ * Return true if successful. */ int -output_current_directory(ofp) -FILE *ofp; /* output file pointer */ +output_current_directory(MathoMatic* mathomatic, FILE *ofp) +//FILE *ofp; /* output file pointer */ { #if !SECURE char buf[MAX_CMD_LEN]; - if (security_level < 3 && ofp) { + if (mathomatic->security_level < 3 && ofp) { if (getcwd(buf, sizeof(buf))) { fprintf(ofp, "directory %s\n", buf); return true; @@ -1217,9 +1204,7 @@ FILE *ofp; /* output file pointer */ } int -fprintf_escaped(ofp, cp) -FILE *ofp; -char *cp; +fprintf_escaped(FILE *ofp, char *cp) { int len = 0; @@ -1238,80 +1223,79 @@ char *cp; * If all_set_options, include options you don't want to save. */ void -output_options(ofp, all_set_options) -FILE *ofp; /* output file pointer */ -int all_set_options; +output_options(MathoMatic* mathomatic, FILE *ofp, int all_set_options) +//FILE *ofp; /* output file pointer */ { if (ofp == NULL) return; - fprintf(ofp, "precision = %d digits\n", precision); + fprintf(ofp, "precision = %d digits\n", mathomatic->precision); - if (!autosolve) { + if (!mathomatic->autosolve) { fprintf(ofp, "no "); } fprintf(ofp, "autosolve\n"); - if (!autocalc) { + if (!mathomatic->autocalc) { fprintf(ofp, "no "); } fprintf(ofp, "autocalc\n"); - if (!autodelete) { + if (!mathomatic->autodelete) { fprintf(ofp, "no "); } fprintf(ofp, "autodelete\n"); - if (!autoselect) { + if (!mathomatic->autoselect) { fprintf(ofp, "no "); } fprintf(ofp, "autoselect\n"); #if !SILENT - fprintf(ofp, "debug_level = %d\n", debug_level); + fprintf(ofp, "debug_level = %d\n", mathomatic->debug_level); #endif - if (!case_sensitive_flag) { + if (!mathomatic->case_sensitive_flag) { fprintf(ofp, "no "); } fprintf(ofp, "case_sensitive\n"); - if (all_set_options && html_flag) { - if (html_flag == 2) { + if (all_set_options && mathomatic->html_flag) { + if (mathomatic->html_flag == 2) { fprintf(ofp, "all html "); } else { fprintf(ofp, "html "); } } - if (color_flag == 2) { + if (mathomatic->color_flag == 2) { fprintf(ofp, "alternative "); } - if (bold_colors && color_flag) { + if (mathomatic->bold_colors && mathomatic->color_flag) { fprintf(ofp, "bold color"); } else { - if (!color_flag) { + if (!mathomatic->color_flag) { fprintf(ofp, "no color"); } else { fprintf(ofp, "no bold color"); } } - if (text_color >= 0) { - fprintf(ofp, " %d", text_color); + if (mathomatic->text_color >= 0) { + fprintf(ofp, " %d", mathomatic->text_color); } fprintf(ofp, "\n"); - if (!display2d) { + if (!mathomatic->display2d) { fprintf(ofp, "no "); } fprintf(ofp, "display2d\n"); if (all_set_options) { - fprintf(ofp, "columns = %d, ", screen_columns); - fprintf(ofp, "rows = %d\n", screen_rows); + fprintf(ofp, "columns = %d, ", mathomatic->screen_columns); + fprintf(ofp, "rows = %d\n", mathomatic->screen_rows); } fprintf(ofp, "fractions_display_mode = "); - switch (fractions_display) { + switch (mathomatic->fractions_display) { case 0: fprintf(ofp, "none\n"); break; @@ -1323,25 +1307,25 @@ int all_set_options; break; } - if (quiet_mode) { + if (mathomatic->quiet_mode) { fprintf(ofp, "no "); } fprintf(ofp, "prompt\n"); #if 0 - if (!preserve_surds) { + if (!mathomatic->preserve_surds) { fprintf(ofp, "no "); } fprintf(ofp, "preserve_surds\n"); #endif - if (!rationalize_denominators) { + if (!mathomatic->rationalize_denominators) { fprintf(ofp, "no "); } fprintf(ofp, "rationalize_denominators\n"); fprintf(ofp, "modulus_mode = "); - switch (modulus_mode) { + switch (mathomatic->modulus_mode) { case 0: fprintf(ofp, "C\n"); break; @@ -1356,36 +1340,35 @@ int all_set_options; break; } - if (finance_option < 0) { + if (mathomatic->finance_option < 0) { fprintf(ofp, "no fixed_point\n"); } else { - fprintf(ofp, "fixed_point = %d\n", finance_option); + fprintf(ofp, "fixed_point = %d\n", mathomatic->finance_option); } - if (!factor_int_flag) { + if (!mathomatic->factor_int_flag) { fprintf(ofp, "no "); } fprintf(ofp, "factor_integers\n"); - if (right_associative_power) { /* option is hardly ever used */ + if (mathomatic->right_associative_power) { /* option is hardly ever used */ fprintf(ofp, "right_associative_power\n"); } #if SHELL_OUT fprintf(ofp, "plot_prefix = "); - fprintf_escaped(ofp, plot_prefix); + fprintf_escaped(ofp, mathomatic->plot_prefix); fprintf(ofp, "\n"); #endif - fprintf(ofp, "special_variable_characters = %s\n", special_variable_characters); + fprintf(ofp, "special_variable_characters = %s\n", mathomatic->special_variable_characters); } /* * Skip over a yes/no indicator and return true if *cpp pointed to a negative word. */ int -skip_no(cpp) -char **cpp; +skip_no(char **cpp) { if (strcmp_tospace(*cpp, "no") == 0 || strcmp_tospace(*cpp, "not") == 0 @@ -1410,20 +1393,19 @@ char **cpp; * Return true if successful. */ int -save_set_options(cp) -char *cp; +save_set_options(MathoMatic* mathomatic, char *cp) { FILE *fp; int pre_existing; - if (rc_file[0] == '\0') { - error(_("Set options startup file name not set; contact the developer.")); + if (mathomatic->rc_file[0] == '\0') { + error(mathomatic, _("Set options startup file name not set; contact the developer.")); return false; } - pre_existing = (access(rc_file, F_OK) == 0); - if ((fp = fopen(rc_file, "w")) == NULL) { - perror(rc_file); - error(_("Unable to write to set options startup file.")); + pre_existing = (access(mathomatic->rc_file, F_OK) == 0); + if ((fp = fopen(mathomatic->rc_file, "w")) == NULL) { + perror(mathomatic->rc_file); + error(mathomatic, _("Unable to write to set options startup file.")); return false; } fprintf(fp, "; Mathomatic set options loaded at startup,\n"); @@ -1432,16 +1414,16 @@ char *cp; if (cp && *cp) { fprintf(fp, "%s\n", cp); } else { - output_options(fp, false); + output_options(mathomatic, fp, false); } if (fclose(fp) == 0) { if (pre_existing) - printf(_("Startup file \"%s\" overwritten with set options.\n"), rc_file); + printf(_("Startup file \"%s\" overwritten with set options.\n"), mathomatic->rc_file); else - printf(_("Set options saved in startup file \"%s\".\n"), rc_file); + printf(_("Set options saved in startup file \"%s\".\n"), mathomatic->rc_file); } else { - perror(rc_file); - error(_("Error saving set options.")); + perror(mathomatic->rc_file); + error(mathomatic, _("Error saving set options.")); return false; } return true; @@ -1454,15 +1436,13 @@ char *cp; * Return false if error. */ int -set_options(cp, loading_startup_file) -char *cp; -int loading_startup_file; +set_options(MathoMatic* mathomatic, char *cp, int loading_startup_file) { int i; int negate; char *cp1 = NULL, *option_string; - show_usage = false; /* this command gives enough usage information */ + mathomatic->show_usage = false; /* this command gives enough usage information */ try_next_param: cp = skip_comma_space(cp); if (*cp == '\0') { @@ -1471,25 +1451,25 @@ int loading_startup_file; if (strncasecmp(cp, "directory", 3) == 0) { cp = skip_param(cp); #if !SECURE - if (security_level < 3) { + if (mathomatic->security_level < 3) { if (*cp == '\0') { cp1 = getenv("HOME"); if (cp1 == NULL) { - error(_("HOME environment variable not set.")); + error(mathomatic, _("HOME environment variable not set.")); return false; } cp = cp1; } if (chdir(cp)) { perror(cp); - error(_("Error changing directory.")); + error(mathomatic, _("Error changing directory.")); return false; } printf(_("Current working directory changed to ")); - return output_current_directory(stdout); + return output_current_directory(mathomatic, stdout); } #endif - error(_("Option disabled by security level.")); + error(mathomatic, _("Option disabled by security level.")); return false; } negate = skip_no(&cp); @@ -1498,134 +1478,134 @@ int loading_startup_file; #if !SILENT if (strncasecmp(option_string, "debug", 5) == 0) { if (negate) { - debug_level = 0; + mathomatic->debug_level = 0; } else { i = decstrtol(cp, &cp1); if (cp1 == NULL || cp == cp1) { - error(_("Please specify the debug level number from -2 to 6.")); + error(mathomatic, _("Please specify the debug level number from -2 to 6.")); return false; } cp = cp1; - debug_level = i; + mathomatic->debug_level = i; } goto try_next_param; } #endif if (strncasecmp(option_string, "special", 7) == 0) { if (negate) { - special_variable_characters[0] = '\0'; + mathomatic->special_variable_characters[0] = '\0'; } else { for (i = 0; cp[i]; i++) { if (is_mathomatic_operator(cp[i])) { - error(_("Invalid character in list, character is a Mathomatic operator.")); + error(mathomatic, _("Invalid character in list, character is a Mathomatic operator.")); return false; } } - my_strlcpy(special_variable_characters, cp, sizeof(special_variable_characters)); + my_strlcpy(mathomatic->special_variable_characters, cp, sizeof(mathomatic->special_variable_characters)); } return true; } #if SHELL_OUT if (strncasecmp(option_string, "plot_prefix", 4) == 0) { if (negate) { - plot_prefix[0] = '\0'; + mathomatic->plot_prefix[0] = '\0'; } else { - my_strlcpy(plot_prefix, cp, sizeof(plot_prefix)); + my_strlcpy(mathomatic->plot_prefix, cp, sizeof(mathomatic->plot_prefix)); } return true; } #endif if (strncasecmp(option_string, "rows", 3) == 0) { if (negate) { - screen_rows = 0; + mathomatic->screen_rows = 0; } else { if (*cp == '\0') { - printf(_("Current screen rows is %d.\n"), screen_rows); + printf(_("Current screen rows is %d.\n"), mathomatic->screen_rows); goto check_return; } i = decstrtol(cp, &cp1); if (i < 0 || cp1 == NULL || cp == cp1) { - error(_("Please specify how tall the screen is; 0 = no pagination.")); + error(mathomatic, _("Please specify how tall the screen is; 0 = no pagination.")); return false; } cp = cp1; - screen_rows = i; + mathomatic->screen_rows = i; } goto try_next_param; } if (strncasecmp(option_string, "columns", 6) == 0) { if (negate) { - screen_columns = 0; + mathomatic->screen_columns = 0; } else { if (*cp == '\0') { - if (!get_screen_size()) { - error(_("OS failed to return screen size.")); + if (!get_screen_size(mathomatic)) { + error(mathomatic, _("OS failed to return screen size.")); return false; } goto check_return; } i = decstrtol(cp, &cp1); if (i < 0 || cp1 == NULL || cp == cp1) { - error(_("Please specify how wide the screen is; 0 = no limit.")); + error(mathomatic, _("Please specify how wide the screen is; 0 = no limit.")); return false; } cp = cp1; - screen_columns = i; + mathomatic->screen_columns = i; } goto try_next_param; } if (strncasecmp(option_string, "wide", 4) == 0) { if (negate) { - if (!get_screen_size() || screen_columns == 0) { - error(_("OS failed to return screen size.")); + if (!get_screen_size(mathomatic) || mathomatic->screen_columns == 0) { + error(mathomatic, _("OS failed to return screen size.")); return false; } } else { - screen_columns = 0; - screen_rows = 0; + mathomatic->screen_columns = 0; + mathomatic->screen_rows = 0; } goto try_next_param; } if (strncasecmp(option_string, "precision", 4) == 0) { i = decstrtol(cp, &cp1); if (i < 0 || i > 15 || cp1 == NULL || cp == cp1) { - error(_("Please specify a display precision between 0 and 15 digits.")); + error(mathomatic, _("Please specify a display precision between 0 and 15 digits.")); return false; } - precision = i; + mathomatic->precision = i; return true; } if (strcmp_tospace(option_string, "auto") == 0) { - autosolve = autocalc = autoselect = !negate; + mathomatic->autosolve = mathomatic->autocalc = mathomatic->autoselect = !negate; goto try_next_param; } if (strncasecmp(option_string, "autosolve", 9) == 0) { - autosolve = !negate; + mathomatic->autosolve = !negate; goto try_next_param; } if (strncasecmp(option_string, "autocalc", 8) == 0) { - autocalc = !negate; + mathomatic->autocalc = !negate; goto try_next_param; } if (strncasecmp(option_string, "autodelete", 7) == 0) { - autodelete = !negate; + mathomatic->autodelete = !negate; goto try_next_param; } if (strncasecmp(option_string, "autoselect", 10) == 0) { - autoselect = !negate; + mathomatic->autoselect = !negate; goto try_next_param; } if (strncasecmp(option_string, "case", 4) == 0) { - case_sensitive_flag = !negate; + mathomatic->case_sensitive_flag = !negate; goto try_next_param; } if (strncasecmp(option_string, "display2d", 7) == 0) { - display2d = !negate; + mathomatic->display2d = !negate; goto try_next_param; } if (strncasecmp(option_string, "fractions", 4) == 0) { if (negate) { - fractions_display = 0; + mathomatic->fractions_display = 0; } else { i = decstrtol(cp, &cp1); if (cp == cp1) { @@ -1641,58 +1621,58 @@ int loading_startup_file; } } if (cp1 == NULL || cp == cp1 || i < 0 || i > 2) { - error(_("Please specify the fractions display mode number (0, 1, or 2).")); + error(mathomatic, _("Please specify the fractions display mode number (0, 1, or 2).")); printf(_("0 means do not display any constants as fractions,\n")); printf(_("1 means display some constants as \"simple\" fractions,\n")); printf(_("2 means display some constants as \"mixed\" or simple fractions.\n")); - printf(_("Current value is %d.\n"), fractions_display); + printf(_("Current value is %d.\n"), mathomatic->fractions_display); return false; } cp = cp1; - fractions_display = i; + mathomatic->fractions_display = i; } goto try_next_param; } if (strncasecmp(option_string, "prompt", 6) == 0) { - quiet_mode = negate; + mathomatic->quiet_mode = negate; goto try_next_param; } if (strncasecmp(option_string, "demo", 4) == 0) { - demo_mode = !negate; + mathomatic->demo_mode = !negate; goto try_next_param; } if (strncasecmp(option_string, "html", 4) == 0) { #if !SECURE - if (security_level > 0) { + if (mathomatic->security_level > 0) { #endif - error(_("Option disabled by security level.")); + error(mathomatic, _("Option disabled by security level.")); return false; #if !SECURE } #endif - reset_attr(); + reset_attr(mathomatic); if (is_all(cp)) { cp = skip_param(cp); if (negate) - html_flag = 0; + mathomatic->html_flag = 0; else - html_flag = 2; + mathomatic->html_flag = 2; } else { - html_flag = !negate; + mathomatic->html_flag = !negate; } goto try_next_param; } if (strncasecmp(option_string, "preserve_surds", 13) == 0) { - preserve_surds = !negate; + mathomatic->preserve_surds = !negate; goto try_next_param; } if (strncasecmp(option_string, "rationalize", 11) == 0) { - rationalize_denominators = !negate; + mathomatic->rationalize_denominators = !negate; goto try_next_param; } if (strncasecmp(option_string, "modulus_mode", 3) == 0) { if (negate) { - error(_("Modulus mode cannot be turned off.")); + error(mathomatic, _("Modulus mode cannot be turned off.")); return false; } else { i = decstrtol(cp, &cp1); @@ -1709,15 +1689,15 @@ int loading_startup_file; } } if (cp1 == NULL || cp == cp1 || i < 0 || i > 2) { - error(_("Please specify the modulus mode number (0, 1, or 2).")); + error(mathomatic, _("Please specify the modulus mode number (0, 1, or 2).")); printf(_("* \"C\" and \"Java\" programming language mode 0:\n")); printf(_(" 0 means modulus operator (dividend %% divisor) result has same sign as dividend;\n")); printf(_("* \"Python\" programming language mode 1:\n")); printf(_(" 1 means computed result always has same sign as the divisor;\n")); printf(_("* Mathematically correct mode 2 for perfect simplification:\n")); printf(_(" 2 means the result is always \"positive\" or zero (\"normal\" mode).\n\n")); - printf(_("The current value is %d ("), modulus_mode); - switch (modulus_mode) { + printf(_("The current value is %d ("), mathomatic->modulus_mode); + switch (mathomatic->modulus_mode) { case 0: printf("C"); break; @@ -1735,37 +1715,37 @@ int loading_startup_file; return false; } cp = cp1; - modulus_mode = i; + mathomatic->modulus_mode = i; } goto try_next_param; } if (strncasecmp(option_string, "color", 5) == 0) { - reset_attr(); - if (color_flag != 2 || negate) { - color_flag = !negate; + reset_attr(mathomatic); + if (mathomatic->color_flag != 2 || negate) { + mathomatic->color_flag = !negate; } i = decstrtol(cp, &cp1); if (cp1 && cp != cp1) { - text_color = i; + mathomatic->text_color = i; cp = cp1; } else { - text_color = -1; + mathomatic->text_color = -1; } goto try_next_param; } if (strncasecmp(option_string, "alternative", 3) == 0) { - reset_attr(); - color_flag = (!negate) + 1; + reset_attr(mathomatic); + mathomatic->color_flag = (!negate) + 1; goto try_next_param; } if (strncasecmp(option_string, "bold", 4) == 0) { - reset_attr(); - bold_colors = !negate; + reset_attr(mathomatic); + mathomatic->bold_colors = !negate; goto try_next_param; } if (strncasecmp(option_string, "fixed", 3) == 0) { if (negate) { - finance_option = -1; + mathomatic->finance_option = -1; } else { i = decstrtol(cp, &cp1); if (cp1 == NULL) { @@ -1775,28 +1755,28 @@ int loading_startup_file; if (*cp1 == '\0') { i = 2; } else { - error(_("Please specify the number of digits to display after the decimal point.")); + error(mathomatic, _("Please specify the number of digits to display after the decimal point.")); return false; } } if (i < -1 || i > 100) { - error(_("Range is -1 to 100; Sets rounded display with fixed number of trailing digits.")); + error(mathomatic, _("Range is -1 to 100; Sets rounded display with fixed number of trailing digits.")); return false; } if (i == 0) { - warning("Setting rounded, integer-only display."); + warning(mathomatic, "Setting rounded, integer-only display."); } cp = cp1; - finance_option = i; + mathomatic->finance_option = i; } goto try_next_param; } if (strncasecmp(option_string, "factor_integers", 6) == 0) { - factor_int_flag = !negate; + mathomatic->factor_int_flag = !negate; goto try_next_param; } if (strncasecmp(option_string, "right_associative_power", 5) == 0) { - right_associative_power = !negate; + mathomatic->right_associative_power = !negate; goto try_next_param; } if (strcmp_tospace(option_string, "load") == 0) { @@ -1809,26 +1789,26 @@ int loading_startup_file; printf(_("Ignoring recursive \"set load\".\n")); return true; } - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; - if (security_level <= 3) { - if (load_rc(false, gfp)) { - fprintf(gfp, _("\nEnd of file.\n")); + if (mathomatic->security_level <= 3) { + if (load_rc(mathomatic, false, mathomatic->gfp)) { + fprintf(mathomatic->gfp, _("\nEnd of file.\n")); return true; } else { - error(_("Error loading startup set options.")); + error(mathomatic, _("Error loading startup set options.")); return false; } } #endif - error(_("Option disabled by security level.")); + error(mathomatic, _("Option disabled by security level.")); return false; } if (strcmp_tospace(option_string, "save") == 0) { #if !SECURE - if (security_level < 2) { - if (rc_file[0] == '\0') { - error(_("Set options startup file name not set; contact the developer.")); + if (mathomatic->security_level < 2) { + if (mathomatic->rc_file[0] == '\0') { + error(mathomatic, _("Set options startup file name not set; contact the developer.")); return false; } if (loading_startup_file) { @@ -1836,32 +1816,32 @@ int loading_startup_file; return false; } if (negate) { - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; - if (unlink(rc_file) == 0) { - printf(_("Set options startup file \"%s\" removed.\n"), rc_file); + if (unlink(mathomatic->rc_file) == 0) { + printf(_("Set options startup file \"%s\" removed.\n"), mathomatic->rc_file); printf(_("Factory default options will be used on next startup of Mathomatic.\n")); return true; } else { - perror(rc_file); - error(_("Set options startup file cannot be removed.")); + perror(mathomatic->rc_file); + error(mathomatic, _("Set options startup file cannot be removed.")); return false; } } else { - if (save_set_options(cp)) { - if (load_rc(false, gfp)) { - fprintf(gfp, _("\nNew startup set options loaded.\n")); + if (save_set_options(mathomatic, cp)) { + if (load_rc(mathomatic, false, mathomatic->gfp)) { + fprintf(mathomatic->gfp, _("\nNew startup set options loaded.\n")); return true; } else { - error(_("Error loading new startup set options.")); - fprintf(gfp, _("Correct or type \"set no save\" to remove.\n")); + error(mathomatic, _("Error loading new startup set options.")); + fprintf(mathomatic->gfp, _("Correct or type \"set no save\" to remove.\n")); } } return false; } } #endif - error(_("Option disabled by security level.")); + error(mathomatic, _("Option disabled by security level.")); return false; } if (strcmp_tospace(option_string, "set") == 0) { @@ -1869,11 +1849,11 @@ int loading_startup_file; goto try_next_param; } printf(_("\nCannot process set string \"%s\".\n"), option_string); - error(_("Unknown set option.")); + error(mathomatic, _("Unknown set option.")); return false; check_return: - extra_characters(cp); + extra_characters(mathomatic, cp); return true; } @@ -1881,22 +1861,21 @@ int loading_startup_file; * The set command. */ int -set_cmd(cp) -char *cp; +set_cmd(MathoMatic* mathomatic, char *cp) { int rv; if (*cp == '\0') { - fprintf(gfp, _("Options are set as follows:\n\n")); + fprintf(mathomatic->gfp, _("Options are set as follows:\n\n")); - output_options(gfp, true); + output_options(mathomatic, mathomatic->gfp, true); - output_current_directory(gfp); + output_current_directory(mathomatic, mathomatic->gfp); return true; } - rv = set_options(cp, false); + rv = set_options(mathomatic, cp, false); if (rv) { - debug_string(0, _("Success.")); + debug_string(mathomatic, 0, _("Success.")); } return rv; } @@ -1905,35 +1884,34 @@ char *cp; * The echo command. */ int -echo_cmd(cp) -char *cp; +echo_cmd(MathoMatic* mathomatic, char *cp) { int i; int len = 0; int width, height; - if (repeat_flag) { + if (mathomatic->repeat_flag) { if (*cp) { - if (screen_columns) - width = screen_columns; + if (mathomatic->screen_columns) + width = mathomatic->screen_columns; else width = TEXT_COLUMNS; while ((len + strlen(cp)) < width) { - fprintf(gfp, "%s", cp); + fprintf(mathomatic->gfp, "%s", cp); len += strlen(cp); } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } else { - if (screen_rows) - height = screen_rows; + if (mathomatic->screen_rows) + height = mathomatic->screen_rows; else height = TEXT_ROWS; for (i = 0; i < height; i++) { - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } } } else { - fprintf(gfp, "%s\n", cp); + fprintf(mathomatic->gfp, "%s\n", cp); } return true; } @@ -1942,8 +1920,7 @@ char *cp; * The pause command. */ int -pause_cmd(cp) -char *cp; +pause_cmd(MathoMatic* mathomatic, char *cp) { #if LIBRARY return true; @@ -1951,17 +1928,17 @@ char *cp; char *cp1; char buf[MAX_CMD_LEN]; - if (test_mode || demo_mode) { + if (mathomatic->test_mode || mathomatic->demo_mode) { return true; } - show_usage = false; + mathomatic->show_usage = false; if (*cp == '\0') { cp = _("Please press the Enter key"); } - set_color(3); /* make color blue, to show that this is not part of the surrounding text */ - snprintf(prompt_str, sizeof(prompt_str), "==== %s: ", cp); - cp1 = get_string(buf, sizeof(buf)); - default_color(false); + set_color(mathomatic, 3); /* make color blue, to show that this is not part of the surrounding text */ + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), "==== %s: ", cp); + cp1 = get_string(mathomatic, buf, sizeof(buf)); + default_color(mathomatic, false); if (cp1 == NULL) { return false; } @@ -1979,8 +1956,7 @@ char *cp; * The copy command. */ int -copy_cmd(cp) -char *cp; +copy_cmd(MathoMatic* mathomatic, char *cp) { int i, j, k; int i1; @@ -1989,8 +1965,8 @@ char *cp; int select_flag = false; /* select the first equation space copied to */ CLEAR_ARRAY(exists); - for (i1 = 0; i1 < n_equations; i1++) { - if (n_lhs[i1] > 0) { + for (i1 = 0; i1 < mathomatic->n_equations; i1++) { + if (mathomatic->n_lhs[i1] > 0) { exists[i1] = true; } } @@ -2000,22 +1976,22 @@ char *cp; } do { cp1 = cp; - if (!get_range(&cp, &i, &j)) { + if (!get_range(mathomatic, &cp, &i, &j)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid equation number range.")); + error(mathomatic, _("Invalid equation number range.")); return false; } for (i1 = i; i1 <= j; i1++) { if (exists[i1]) { - k = next_espace(); - copy_espace(i1, k); - if (!return_result(k)) { + k = next_espace(mathomatic); + copy_espace(mathomatic, i1, k); + if (!return_result(mathomatic, k)) { return false; } if (select_flag) { - cur_equation = k; + mathomatic->cur_equation = k; select_flag = false; } } @@ -2028,9 +2004,9 @@ char *cp; * Common function for the imaginary and real commands. */ static int -complex_func(cp, imag_flag) -char *cp; /* the command-line */ -int imag_flag; /* if true, copy the imaginary part, otherwise copy the real part */ +complex_func(MathoMatic* mathomatic, char *cp, int imag_flag) +//char *cp; /* the command-line */ +//int imag_flag; /* if true, copy the imaginary part, otherwise copy the real part */ { int i, j, k; int beg; @@ -2039,39 +2015,39 @@ int imag_flag; /* if true, copy the imaginary part, otherwise copy the real part int n1, *nps, *np; long v = IMAGINARY; /* separation variable */ - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - solved = solved_equation(cur_equation); - i = cur_equation; - j = next_espace(); - if (n_rhs[i]) { - source = rhs[i]; - nps = &n_rhs[i]; - dest = rhs[j]; - np = &n_rhs[j]; + solved = solved_equation(mathomatic, mathomatic->cur_equation); + i = mathomatic->cur_equation; + j = next_espace(mathomatic); + if (mathomatic->n_rhs[i]) { + source = mathomatic->rhs[i]; + nps = &mathomatic->n_rhs[i]; + dest = mathomatic->rhs[j]; + np = &mathomatic->n_rhs[j]; } else { - source = lhs[i]; - nps = &n_lhs[i]; - dest = lhs[j]; - np = &n_lhs[j]; + source = mathomatic->lhs[i]; + nps = &mathomatic->n_lhs[i]; + dest = mathomatic->lhs[j]; + np = &mathomatic->n_lhs[j]; } if (*cp) { - cp = parse_var2(&v, cp); + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; } - simp_loop(source, nps); - uf_simp(source, nps); - factorv(source, nps, v); - partial_flag = false; - uf_simp(source, nps); - partial_flag = true; + simp_loop(mathomatic, source, nps); + uf_simp(mathomatic, source, nps); + factorv(mathomatic, source, nps, v); + mathomatic->partial_flag = false; + uf_simp(mathomatic, source, nps); + mathomatic->partial_flag = true; n1 = 1; - dest[0] = zero_token; + dest[0] = mathomatic->zero_token; has_imag = has_real = false; for (beg = k = 0; beg < *nps; beg = k, k++) { for (found_imag = false; k < *nps; k++) { @@ -2096,48 +2072,46 @@ int imag_flag; /* if true, copy the imaginary part, otherwise copy the real part } } if (!has_imag || !has_real) { - warning(_("Expression was not a mix.")); + warning(mathomatic, _("Expression was not a mix.")); } do { - simp_loop(dest, &n1); - } while (factor_plus(dest, &n1, v, 0.0)); - simp_divide(dest, &n1); - if (n_rhs[i]) { - blt(lhs[j], lhs[i], n_lhs[i] * sizeof(token_type)); - n_lhs[j] = n_lhs[i]; + simp_loop(mathomatic, dest, &n1); + } while (factor_plus(mathomatic, dest, &n1, v, 0.0)); + simp_divide(mathomatic, dest, &n1); + if (mathomatic->n_rhs[i]) { + blt(mathomatic->lhs[j], mathomatic->lhs[i], mathomatic->n_lhs[i] * sizeof(token_type)); + mathomatic->n_lhs[j] = mathomatic->n_lhs[i]; if (solved) { - if (list_var(lhs[j][0].token.variable, 0) < (MAX_VAR_LEN - 5)) { + if (list_var(mathomatic, mathomatic->lhs[j][0].token.variable, 0) < (MAX_VAR_LEN - 5)) { if (imag_flag) - strcat(var_str, "_imag"); + strcat(mathomatic->var_str, "_imag"); else - strcat(var_str, "_real"); - parse_var(&lhs[j][0].token.variable, var_str); + strcat(mathomatic->var_str, "_real"); + parse_var(mathomatic, &mathomatic->lhs[j][0].token.variable, mathomatic->var_str); } } } *np = n1; - cur_equation = j; - return return_result(cur_equation); + mathomatic->cur_equation = j; + return return_result(mathomatic, mathomatic->cur_equation); } /* * The real command. */ int -real_cmd(cp) -char *cp; +real_cmd(MathoMatic* mathomatic, char *cp) { - return complex_func(cp, false); + return complex_func(mathomatic, cp, false); } /* * The imaginary command. */ int -imaginary_cmd(cp) -char *cp; +imaginary_cmd(MathoMatic* mathomatic, char *cp) { - return complex_func(cp, true); + return complex_func(mathomatic, cp, true); } #if !LIBRARY @@ -2145,8 +2119,7 @@ char *cp; * The tally command. */ int -tally_cmd(cp) -char *cp; +tally_cmd(MathoMatic* mathomatic, char *cp) { int i, k, first, last; double count = 0.0; @@ -2154,128 +2127,128 @@ char *cp; long v; char *cp1; - if (!parse_var(&v, "total")) { + if (!parse_var(mathomatic, &v, "total")) { return false; } if (strcmp_tospace(cp, "average") == 0) { arithmetic_mean = true; cp = skip_param(cp); } - trhs[0] = zero_token; - n_trhs = 1; + mathomatic->trhs[0] = mathomatic->zero_token; + mathomatic->n_trhs = 1; if (*cp) { do { cp1 = cp; - if (!get_range(&cp, &first, &last)) { + if (!get_range(mathomatic, &cp, &first, &last)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (k = first; k <= last; k++) { - if (n_lhs[k] <= 0) + if (mathomatic->n_lhs[k] <= 0) continue; - if (n_rhs[k] > 0) { - if ((n_trhs + 1 + n_rhs[k]) > n_tokens) { - error_huge(); + if (mathomatic->n_rhs[k] > 0) { + if ((mathomatic->n_trhs + 1 + mathomatic->n_rhs[k]) > mathomatic->n_tokens) { + error_huge(mathomatic); } - for (i = 0; i < n_trhs; i++) { - trhs[i].level++; + for (i = 0; i < mathomatic->n_trhs; i++) { + mathomatic->trhs[i].level++; } - trhs[n_trhs].kind = OPERATOR; - trhs[n_trhs].level = 1; - trhs[n_trhs].token.operatr = PLUS; - n_trhs++; - blt(&trhs[n_trhs], rhs[k], n_rhs[k] * sizeof(token_type)); - n_trhs += n_rhs[k]; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; + mathomatic->trhs[mathomatic->n_trhs].level = 1; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = PLUS; + mathomatic->n_trhs++; + blt(&mathomatic->trhs[mathomatic->n_trhs], mathomatic->rhs[k], mathomatic->n_rhs[k] * sizeof(token_type)); + mathomatic->n_trhs += mathomatic->n_rhs[k]; } else { - if ((n_trhs + 1 + n_lhs[k]) > n_tokens) { - error_huge(); + if ((mathomatic->n_trhs + 1 + mathomatic->n_lhs[k]) > mathomatic->n_tokens) { + error_huge(mathomatic); } - for (i = 0; i < n_trhs; i++) { - trhs[i].level++; + for (i = 0; i < mathomatic->n_trhs; i++) { + mathomatic->trhs[i].level++; } - trhs[n_trhs].kind = OPERATOR; - trhs[n_trhs].level = 1; - trhs[n_trhs].token.operatr = PLUS; - n_trhs++; - blt(&trhs[n_trhs], lhs[k], n_lhs[k] * sizeof(token_type)); - n_trhs += n_lhs[k]; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; + mathomatic->trhs[mathomatic->n_trhs].level = 1; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = PLUS; + mathomatic->n_trhs++; + blt(&mathomatic->trhs[mathomatic->n_trhs], mathomatic->lhs[k], mathomatic->n_lhs[k] * sizeof(token_type)); + mathomatic->n_trhs += mathomatic->n_lhs[k]; } - for (i++; i < n_trhs; i++) { - trhs[i].level++; + for (i++; i < mathomatic->n_trhs; i++) { + mathomatic->trhs[i].level++; } - calc_simp(trhs, &n_trhs); + calc_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); count++; } } while (*cp); } - if (extra_characters(cp)) { + if (extra_characters(mathomatic, cp)) { return false; } for (;; count++) { - fprintf(gfp, _("total = ")); - list_proc(trhs, n_trhs, false); - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, _("total = ")); + list_proc(mathomatic, mathomatic->trhs, mathomatic->n_trhs, false); + fprintf(mathomatic->gfp, "\n"); if (count > 0) { if (arithmetic_mean) { /* calculate and display the average */ - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; - if ((n_tlhs + 2) > n_tokens) { - error_huge(); + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; + if ((mathomatic->n_tlhs + 2) > mathomatic->n_tokens) { + error_huge(mathomatic); } - for (i = 0; i < n_tlhs; i++) { - tlhs[i].level++; + for (i = 0; i < mathomatic->n_tlhs; i++) { + mathomatic->tlhs[i].level++; } - tlhs[n_tlhs].kind = OPERATOR; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].token.operatr = DIVIDE; - n_tlhs++; - tlhs[n_tlhs].kind = CONSTANT; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].token.constant = count; - n_tlhs++; - calc_simp(tlhs, &n_tlhs); - fprintf(gfp, _("count = %.0f, average = "), count); - list_proc(tlhs, n_tlhs, false); - fprintf(gfp, "\n"); - } - } - fprintf(gfp, "\n"); - my_strlcpy(prompt_str, _("Enter value to add: "), sizeof(prompt_str)); - if (!get_expr(tlhs, &n_tlhs)) { + mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; + mathomatic->n_tlhs++; + mathomatic->tlhs[mathomatic->n_tlhs].kind = CONSTANT; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].token.constant = count; + mathomatic->n_tlhs++; + calc_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + fprintf(mathomatic->gfp, _("count = %.0f, average = "), count); + list_proc(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs, false); + fprintf(mathomatic->gfp, "\n"); + } + } + fprintf(mathomatic->gfp, "\n"); + my_strlcpy(mathomatic->prompt_str, _("Enter value to add: "), sizeof(mathomatic->prompt_str)); + if (!get_expr(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) { break; } - if ((n_trhs + 1 + n_tlhs) > n_tokens) { - error_huge(); + if ((mathomatic->n_trhs + 1 + mathomatic->n_tlhs) > mathomatic->n_tokens) { + error_huge(mathomatic); } - for (i = 0; i < n_tlhs; i++) { - tlhs[i].level++; + for (i = 0; i < mathomatic->n_tlhs; i++) { + mathomatic->tlhs[i].level++; } - for (i = 0; i < n_trhs; i++) { - trhs[i].level++; + for (i = 0; i < mathomatic->n_trhs; i++) { + mathomatic->trhs[i].level++; } - trhs[n_trhs].kind = OPERATOR; - trhs[n_trhs].level = 1; - trhs[n_trhs].token.operatr = PLUS; - n_trhs++; - blt(&trhs[n_trhs], tlhs, n_tlhs * sizeof(token_type)); - n_trhs += n_tlhs; - calc_simp(trhs, &n_trhs); + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; + mathomatic->trhs[mathomatic->n_trhs].level = 1; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = PLUS; + mathomatic->n_trhs++; + blt(&mathomatic->trhs[mathomatic->n_trhs], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_trhs += mathomatic->n_tlhs; + calc_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); } - fprintf(gfp, _("End.\n")); + fprintf(mathomatic->gfp, _("End.\n")); if (count > 0) { - i = next_espace(); - lhs[i][0].level = 1; - lhs[i][0].kind = VARIABLE; - lhs[i][0].token.variable = v; - n_lhs[i] = 1; - blt(rhs[i], trhs, n_trhs * sizeof(token_type)); - n_rhs[i] = n_trhs; - cur_equation = i; - return return_result(cur_equation); + i = next_espace(mathomatic); + mathomatic->lhs[i][0].level = 1; + mathomatic->lhs[i][0].kind = VARIABLE; + mathomatic->lhs[i][0].token.variable = v; + mathomatic->n_lhs[i] = 1; + blt(mathomatic->rhs[i], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_rhs[i] = mathomatic->n_trhs; + mathomatic->cur_equation = i; + return return_result(mathomatic, mathomatic->cur_equation); } return true; } @@ -2286,8 +2259,7 @@ char *cp; * The calculate command. */ int -calculate_cmd(cp) -char *cp; +calculate_cmd(MathoMatic* mathomatic, char *cp) { int i, k1, k; int first, last; @@ -2308,50 +2280,50 @@ char *cp; } break; } - if (!get_range(&cp, &first, &last)) { + if (!get_range(mathomatic, &cp, &first, &last)) { return false; } if (*cp) { - cp = parse_var2(&it_v, cp); + cp = parse_var2(mathomatic, &it_v, cp); if (cp == NULL) { return false; } if (*cp == '\0') { - my_strlcpy(prompt_str, _("Enter maximum number of iterations: "), sizeof(prompt_str)); - if ((cp = get_string(buf, sizeof(buf))) == NULL) + my_strlcpy(mathomatic->prompt_str, _("Enter maximum number of iterations: "), sizeof(mathomatic->prompt_str)); + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) return false; } iterations = decstrtol(cp, &cp); if (*cp || iterations < 0) { - error(_("Positive integer required.")); + error(mathomatic, _("Positive integer required.")); return false; } if (iterations == 0) { - warning(_("Feedback calculation will be iterated until convergence.")); + warning(mathomatic, _("Feedback calculation will be iterated until convergence.")); iterations = LONG_MAX - 1L; } } - if (extra_characters(cp)) { + if (extra_characters(mathomatic, cp)) { return false; } calc_again: value_entered = false; for (i = first; i <= last; i++) { - if (n_rhs[i]) { - source = rhs[i]; - n = n_rhs[i]; + if (mathomatic->n_rhs[i]) { + source = mathomatic->rhs[i]; + n = mathomatic->n_rhs[i]; } else { - source = lhs[i]; - n = n_lhs[i]; + source = mathomatic->lhs[i]; + n = mathomatic->n_lhs[i]; } if (it_v) { if (!found_var(source, n, it_v)) { - debug_string((first == last) ? 0 : 1, _("Specified feedback variable not found.")); + debug_string(mathomatic, (first == last) ? 0 : 1, _("Specified feedback variable not found.")); continue; } } - n_trhs = n; - blt(trhs, source, n_trhs * sizeof(token_type)); + mathomatic->n_trhs = n; + blt(mathomatic->trhs, source, mathomatic->n_trhs * sizeof(token_type)); last_v = 0; for (;;) { v = -1; @@ -2368,62 +2340,62 @@ char *cp; if ((v & VAR_MASK) <= SIGN || v == it_v) { continue; } - if (test_mode || demo_mode) + if (mathomatic->test_mode || mathomatic->demo_mode) continue; - list_var(v, 0); - snprintf(prompt_str, sizeof(prompt_str), _("Enter %s: "), var_str); - if (!get_expr(tlhs, &n_tlhs)) { + list_var(mathomatic, v, 0); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("Enter %s: "), mathomatic->var_str); + if (!get_expr(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) { continue; } value_entered = true; /* Disguise all variables in the entered expression by making them negative. */ /* That way they won't be improperly substituted in the future. */ - for (k1 = 0; k1 < n_tlhs; k1 += 2) - if (tlhs[k1].kind == VARIABLE) - tlhs[k1].token.variable = -tlhs[k1].token.variable; - subst_var_with_exp(trhs, &n_trhs, tlhs, n_tlhs, v); + for (k1 = 0; k1 < mathomatic->n_tlhs; k1 += 2) + if (mathomatic->tlhs[k1].kind == VARIABLE) + mathomatic->tlhs[k1].token.variable = -mathomatic->tlhs[k1].token.variable; + subst_var_with_exp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, mathomatic->tlhs, mathomatic->n_tlhs, v); } /* Restore disguised variables: */ - for (k1 = 0; k1 < n_trhs; k1 += 2) - if (trhs[k1].kind == VARIABLE && trhs[k1].token.variable < 0) - trhs[k1].token.variable = -trhs[k1].token.variable; + for (k1 = 0; k1 < mathomatic->n_trhs; k1 += 2) + if (mathomatic->trhs[k1].kind == VARIABLE && mathomatic->trhs[k1].token.variable < 0) + mathomatic->trhs[k1].token.variable = -mathomatic->trhs[k1].token.variable; if (it_v) { /* Handle the iteration option, where the simplified result is repeatedly plugged into variable it_v. */ - list_var(it_v, 0); - snprintf(prompt_str, sizeof(prompt_str), _("Enter initial %s: "), var_str); - while (!get_expr(tes, &n_tes)) { + list_var(mathomatic, it_v, 0); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("Enter initial %s: "), mathomatic->var_str); + while (!get_expr(mathomatic, mathomatic->tes, &mathomatic->n_tes)) { printf("Aborted.\n"); - return repeat_flag; + return mathomatic->repeat_flag; } value_entered = true; - calc_simp(tes, &n_tes); - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; + calc_simp(mathomatic, mathomatic->tes, &mathomatic->n_tes); + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; for (l = 0;; l++) { if (l >= iterations) { - fprintf(gfp, _("%ld feedback iterations performed.\n"), l); + fprintf(mathomatic->gfp, _("%ld feedback iterations performed.\n"), l); break; } - side_debug(1, tes, n_tes); - blt(trhs, tlhs, n_tlhs * sizeof(token_type)); - n_trhs = n_tlhs; - subst_var_with_exp(trhs, &n_trhs, tes, n_tes, it_v); - calc_simp(trhs, &n_trhs); - if (se_compare(trhs, n_trhs, tes, n_tes, &diff_sign) && !diff_sign) { - fprintf(gfp, _("Convergence reached after %ld iterations.\n"), l + 1); + side_debug(mathomatic, 1, mathomatic->tes, mathomatic->n_tes); + blt(mathomatic->trhs, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_trhs = mathomatic->n_tlhs; + subst_var_with_exp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, mathomatic->tes, mathomatic->n_tes, it_v); + calc_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + if (se_compare(mathomatic, mathomatic->trhs, mathomatic->n_trhs, mathomatic->tes, mathomatic->n_tes, &diff_sign) && !diff_sign) { + fprintf(mathomatic->gfp, _("Convergence reached after %ld iterations.\n"), l + 1); break; } - blt(tes, trhs, n_trhs * sizeof(token_type)); - n_tes = n_trhs; + blt(mathomatic->tes, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tes = mathomatic->n_trhs; } } - calc_simp(trhs, &n_trhs); + calc_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); /* Now substitute all sign variables with +1 and -1. */ CLEAR_ARRAY(sa_mark); - for (k1 = 0; k1 < n_trhs; k1 += 2) { - if (trhs[k1].kind == VARIABLE && (trhs[k1].token.variable & VAR_MASK) == SIGN) { - sa_mark[(trhs[k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; + for (k1 = 0; k1 < mathomatic->n_trhs; k1 += 2) { + if (mathomatic->trhs[k1].kind == VARIABLE && (mathomatic->trhs[k1].token.variable & VAR_MASK) == SIGN) { + sa_mark[(mathomatic->trhs[k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; } } for (k1 = 0, k = 0; k1 < ARR_CNT(sa_mark); k1++) { @@ -2433,67 +2405,67 @@ char *cp; } counter_max = (1L << k) - 1L; if (counter_max) { - fprintf(gfp, _("There are %ld solutions.\n"), counter_max + 1); + fprintf(mathomatic->gfp, _("There are %ld solutions.\n"), counter_max + 1); } for (counter = 0; counter <= counter_max; counter++) { - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; for (k1 = 0, k = 0; k1 < ARR_CNT(sa_mark); k1++) { if (sa_mark[k1]) { sa_value[k1] = (((1L << k) & counter) != 0); k++; } } - for (k1 = 0; k1 < n_tlhs; k1 += 2) { - if (tlhs[k1].kind == VARIABLE && (tlhs[k1].token.variable & VAR_MASK) == SIGN) { - if (sa_value[(tlhs[k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK]) { - tlhs[k1].kind = CONSTANT; - tlhs[k1].token.constant = -1.0; + for (k1 = 0; k1 < mathomatic->n_tlhs; k1 += 2) { + if (mathomatic->tlhs[k1].kind == VARIABLE && (mathomatic->tlhs[k1].token.variable & VAR_MASK) == SIGN) { + if (sa_value[(mathomatic->tlhs[k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK]) { + mathomatic->tlhs[k1].kind = CONSTANT; + mathomatic->tlhs[k1].token.constant = -1.0; } else { - tlhs[k1].kind = CONSTANT; - tlhs[k1].token.constant = 1.0; + mathomatic->tlhs[k1].kind = CONSTANT; + mathomatic->tlhs[k1].token.constant = 1.0; } } } for (k1 = 0, k = false; k1 < ARR_CNT(sa_mark); k1++) { if (sa_mark[k1]) { if (k) { - fprintf(gfp, ", "); + fprintf(mathomatic->gfp, ", "); } else { - fprintf(gfp, _("\nSolution number %ld with "), counter + 1); + fprintf(mathomatic->gfp, _("\nSolution number %ld with "), counter + 1); } - list_var((long) SIGN + (((long) k1) << VAR_SHIFT), 0); - fprintf(gfp, "%s = ", var_str); + list_var(mathomatic, (long) SIGN + (((long) k1) << VAR_SHIFT), 0); + fprintf(mathomatic->gfp, "%s = ", mathomatic->var_str); if (sa_value[k1]) { - fprintf(gfp, "-1"); + fprintf(mathomatic->gfp, "-1"); } else { - fprintf(gfp, "1"); + fprintf(mathomatic->gfp, "1"); } k = true; } } if (k) - fprintf(gfp, ":\n"); - calc_simp(tlhs, &n_tlhs); + fprintf(mathomatic->gfp, ":\n"); + calc_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); if (factor_flag) { - mid_simp_side(tlhs, &n_tlhs); + mid_simp_side(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); } - fprintf(gfp, " "); - if (n_rhs[i]) { - list_proc(lhs[i], n_lhs[i], false); - fprintf(gfp, " = "); + fprintf(mathomatic->gfp, " "); + if (mathomatic->n_rhs[i]) { + list_proc(mathomatic, mathomatic->lhs[i], mathomatic->n_lhs[i], false); + fprintf(mathomatic->gfp, " = "); } - list_factor(tlhs, &n_tlhs, factor_flag); - if (fractions_display && n_tlhs <= 9 && make_fractions(tlhs, &n_tlhs)) { - group_proc(tlhs, &n_tlhs); - fprintf(gfp, ", with fractions it is: "); - list_factor(tlhs, &n_tlhs, factor_flag); + list_factor(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, factor_flag); + if (mathomatic->fractions_display && mathomatic->n_tlhs <= 9 && make_fractions(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) { + group_proc(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + fprintf(mathomatic->gfp, ", with fractions it is: "); + list_factor(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, factor_flag); } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } } - if (value_entered && repeat_flag) { - fprintf(gfp, "Repeating:\n"); + if (value_entered && mathomatic->repeat_flag) { + fprintf(mathomatic->gfp, "Repeating:\n"); goto calc_again; } return true; @@ -2504,8 +2476,7 @@ char *cp; * The clear command. */ int -clear_cmd(cp) -char *cp; +clear_cmd(MathoMatic* mathomatic, char *cp) { int i, j; char *cp1; @@ -2513,19 +2484,19 @@ char *cp; do { cp1 = cp; if (is_all(cp)) { - clear_all(); + clear_all(mathomatic); return true; } else { - if (!get_range(&cp, &i, &j)) { + if (!get_range(mathomatic, &cp, &i, &j)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (; i <= j; i++) { - n_lhs[i] = 0; - n_rhs[i] = 0; + mathomatic->n_lhs[i] = 0; + mathomatic->n_rhs[i] = 0; } } } while (*cp); @@ -2536,22 +2507,20 @@ char *cp; * Compare the Right Hand Sides of two equation spaces. */ static int -compare_rhs(i, j, diff_signp) -int i, j; -int *diff_signp; +compare_rhs(MathoMatic* mathomatic, int i, int j, int *diff_signp) { int rv; /* First, test the compare function by comparing with self: */ - rv = se_compare(rhs[i], n_rhs[i], rhs[i], n_rhs[i], diff_signp); + rv = se_compare(mathomatic, mathomatic->rhs[i], mathomatic->n_rhs[i], mathomatic->rhs[i], mathomatic->n_rhs[i], diff_signp); if (!rv || *diff_signp) { - error(_("Too many terms to compare.")); + error(mathomatic, _("Too many terms to compare.")); return false; } /* Now do the requested compare: */ - sign_cmp_flag = true; - rv = se_compare(rhs[i], n_rhs[i], rhs[j], n_rhs[j], diff_signp); - sign_cmp_flag = false; + mathomatic->sign_cmp_flag = true; + rv = se_compare(mathomatic, mathomatic->rhs[i], mathomatic->n_rhs[i], mathomatic->rhs[j], mathomatic->n_rhs[j], diff_signp); + mathomatic->sign_cmp_flag = false; return rv; } @@ -2562,23 +2531,23 @@ int *diff_signp; * Return 1 if identical. Return -1 if they are expressions that differ only in sign. */ int -compare_es(i, j) -int i, j; /* equation space numbers */ +compare_es(MathoMatic* mathomatic, int i, int j) +//int i, j; /* equation space numbers */ { int rv; int diff_sign_lhs, diff_sign_rhs; - if (n_lhs[i] == 0 || n_lhs[j] == 0) + if (mathomatic->n_lhs[i] == 0 || mathomatic->n_lhs[j] == 0) return false; /* empty equation space */ - if ((n_rhs[i] == 0) != (n_rhs[j] == 0)) + if ((mathomatic->n_rhs[i] == 0) != (mathomatic->n_rhs[j] == 0)) return false; /* mix of expression and equation */ /* Compare the two left hand sides: */ - sign_cmp_flag = true; - rv = se_compare(lhs[i], n_lhs[i], lhs[j], n_lhs[j], &diff_sign_lhs); - sign_cmp_flag = false; + mathomatic->sign_cmp_flag = true; + rv = se_compare(mathomatic, mathomatic->lhs[i], mathomatic->n_lhs[i], mathomatic->lhs[j], mathomatic->n_lhs[j], &diff_sign_lhs); + mathomatic->sign_cmp_flag = false; if (!rv) return false; - if (n_rhs[i] == 0 && n_rhs[j] == 0) { + if (mathomatic->n_rhs[i] == 0 && mathomatic->n_rhs[j] == 0) { /* two expressions, not equations */ if (diff_sign_lhs) return -1; @@ -2586,9 +2555,9 @@ int i, j; /* equation space numbers */ return 1; } /* They are equations, so compare the two right hand sides: */ - sign_cmp_flag = true; - rv = se_compare(rhs[i], n_rhs[i], rhs[j], n_rhs[j], &diff_sign_rhs); - sign_cmp_flag = false; + mathomatic->sign_cmp_flag = true; + rv = se_compare(mathomatic, mathomatic->rhs[i], mathomatic->n_rhs[i], mathomatic->rhs[j], mathomatic->n_rhs[j], &diff_sign_rhs); + mathomatic->sign_cmp_flag = false; if (!rv) return false; return(diff_sign_lhs == diff_sign_rhs); @@ -2598,8 +2567,7 @@ int i, j; /* equation space numbers */ * The compare command. */ int -compare_cmd(cp) -char *cp; +compare_cmd(MathoMatic* mathomatic, char *cp) { int i, j; int diff_sign; @@ -2620,204 +2588,204 @@ char *cp; cp = skip_param(cp); } i = decstrtol(cp, &cp) - 1; - if (not_defined(i)) { + if (not_defined(mathomatic, i)) { return false; } if (strcmp_tospace(cp, "with") == 0) { cp = skip_param(cp); } - if ((j = get_default_en(cp)) < 0) { + if ((j = get_default_en(mathomatic, cp)) < 0) { return false; } if (i == j) { - error(_("Cannot compare an expression with itself.")); + error(mathomatic, _("Cannot compare an expression with itself.")); return false; } - show_usage = false; - fprintf(gfp, _("Comparing #%d with #%d...\n"), i + 1, j + 1); - simp_equation(i); - simp_equation(j); - if (n_rhs[i] == 0 || n_rhs[j] == 0) { - if (n_rhs[i] == 0 && n_rhs[j] == 0) { - switch (compare_es(i, j)) { + mathomatic->show_usage = false; + fprintf(mathomatic->gfp, _("Comparing #%d with #%d...\n"), i + 1, j + 1); + simp_equation(mathomatic, i); + simp_equation(mathomatic, j); + if (mathomatic->n_rhs[i] == 0 || mathomatic->n_rhs[j] == 0) { + if (mathomatic->n_rhs[i] == 0 && mathomatic->n_rhs[j] == 0) { + switch (compare_es(mathomatic, i, j)) { case 1: - fprintf(gfp, _("Expressions are identical.\n")); + fprintf(mathomatic->gfp, _("Expressions are identical.\n")); return true; case -1: - error(_("Expressions differ only in sign (times -1).")); + error(mathomatic, _("Expressions differ only in sign (times -1).")); return false; } if (approx) { - debug_string(0, _("Approximating both expressions...")); - approximate(lhs[i], &n_lhs[i]); - approximate(lhs[j], &n_lhs[j]); - switch (compare_es(i, j)) { + debug_string(mathomatic, 0, _("Approximating both expressions...")); + approximate(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i]); + approximate(mathomatic, mathomatic->lhs[j], &mathomatic->n_lhs[j]); + switch (compare_es(mathomatic, i, j)) { case 1: - fprintf(gfp, _("Expressions are identical.\n")); + fprintf(mathomatic->gfp, _("Expressions are identical.\n")); return true; case -1: - error(_("Expressions differ only in sign (times -1).")); + error(mathomatic, _("Expressions differ only in sign (times -1).")); return false; } } - debug_string(0, _("Simplifying both expressions...")); - symb_flag = symb; - simpa_repeat_side(lhs[i], &n_lhs[i], false, true); - simpa_repeat_side(lhs[j], &n_lhs[j], false, true); - symb_flag = false; + debug_string(mathomatic, 0, _("Simplifying both expressions...")); + mathomatic->symb_flag = symb; + simpa_repeat_side(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i], false, true); + simpa_repeat_side(mathomatic, mathomatic->lhs[j], &mathomatic->n_lhs[j], false, true); + mathomatic->symb_flag = false; if (approx) { - approximate(lhs[i], &n_lhs[i]); - approximate(lhs[j], &n_lhs[j]); + approximate(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i]); + approximate(mathomatic, mathomatic->lhs[j], &mathomatic->n_lhs[j]); } - switch (compare_es(i, j)) { + switch (compare_es(mathomatic, i, j)) { case 1: - fprintf(gfp, _("Expressions are identical.\n")); + fprintf(mathomatic->gfp, _("Expressions are identical.\n")); return true; case -1: - error(_("Expressions differ only in sign (times -1).")); + error(mathomatic, _("Expressions differ only in sign (times -1).")); return false; } #if !SILENT - if (debug_level >= 0) { - list_sub(i); - list_sub(j); + if (mathomatic->debug_level >= 0) { + list_sub(mathomatic, i); + list_sub(mathomatic, j); } #endif - uf_simp(lhs[i], &n_lhs[i]); - uf_simp(lhs[j], &n_lhs[j]); + uf_simp(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i]); + uf_simp(mathomatic, mathomatic->lhs[j], &mathomatic->n_lhs[j]); if (approx) { - approximate(lhs[i], &n_lhs[i]); - approximate(lhs[j], &n_lhs[j]); + approximate(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i]); + approximate(mathomatic, mathomatic->lhs[j], &mathomatic->n_lhs[j]); } - switch (compare_es(i, j)) { + switch (compare_es(mathomatic, i, j)) { case 1: - fprintf(gfp, _("Expressions are identical.\n")); + fprintf(mathomatic->gfp, _("Expressions are identical.\n")); return true; case -1: - error(_("Expressions differ only in sign (times -1).")); + error(mathomatic, _("Expressions differ only in sign (times -1).")); return false; } - fprintf(gfp, _("Expressions differ.\n")); + fprintf(mathomatic->gfp, _("Expressions differ.\n")); return false; } - error(_("Cannot compare an equation with a non-equation.")); + error(mathomatic, _("Cannot compare an equation with a non-equation.")); return false; } - if (compare_es(i, j) > 0) { - fprintf(gfp, _("Equations are identical.\n")); + if (compare_es(mathomatic, i, j) > 0) { + fprintf(mathomatic->gfp, _("Equations are identical.\n")); return true; } - if (solved_equation(i) && solved_equation(j)) { - if (compare_rhs(i, j, &diff_sign)) { + if (solved_equation(mathomatic, i) && solved_equation(mathomatic, j)) { + if (compare_rhs(mathomatic, i, j, &diff_sign)) { goto times_neg1; } if (approx) { - debug_string(0, _("Approximating both equations...")); - approximate(rhs[i], &n_rhs[i]); - approximate(rhs[j], &n_rhs[j]); - if (compare_rhs(i, j, &diff_sign)) { + debug_string(mathomatic, 0, _("Approximating both equations...")); + approximate(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + approximate(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); + if (compare_rhs(mathomatic, i, j, &diff_sign)) { goto times_neg1; } } - debug_string(0, _("Simplifying both equations...")); - symb_flag = symb; - simpa_repeat_side(rhs[i], &n_rhs[i], false, true); - simpa_repeat_side(rhs[j], &n_rhs[j], false, true); - symb_flag = false; + debug_string(mathomatic, 0, _("Simplifying both equations...")); + mathomatic->symb_flag = symb; + simpa_repeat_side(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], false, true); + simpa_repeat_side(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j], false, true); + mathomatic->symb_flag = false; if (approx) { - approximate(rhs[i], &n_rhs[i]); - approximate(rhs[j], &n_rhs[j]); + approximate(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + approximate(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); } - if (compare_rhs(i, j, &diff_sign)) { + if (compare_rhs(mathomatic, i, j, &diff_sign)) { goto times_neg1; } #if !SILENT - if (debug_level >= 0) { - list_sub(i); - list_sub(j); + if (mathomatic->debug_level >= 0) { + list_sub(mathomatic, i); + list_sub(mathomatic, j); } #endif - uf_simp(rhs[i], &n_rhs[i]); - uf_simp(rhs[j], &n_rhs[j]); + uf_simp(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + uf_simp(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); if (approx) { - approximate(rhs[i], &n_rhs[i]); - approximate(rhs[j], &n_rhs[j]); + approximate(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + approximate(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); } - if (compare_rhs(i, j, &diff_sign)) { + if (compare_rhs(mathomatic, i, j, &diff_sign)) { goto times_neg1; } } - debug_string(0, _("Solving both equations for zero and expanding...")); - if (solve_sub(&zero_token, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) + debug_string(mathomatic, 0, _("Solving both equations for zero and expanding...")); + if (solve_sub(mathomatic, &mathomatic->zero_token, 1, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->rhs[i], &mathomatic->n_rhs[i]) <= 0) return false; - if (solve_sub(&zero_token, 1, lhs[j], &n_lhs[j], rhs[j], &n_rhs[j]) <= 0) + if (solve_sub(mathomatic, &mathomatic->zero_token, 1, mathomatic->lhs[j], &mathomatic->n_lhs[j], mathomatic->rhs[j], &mathomatic->n_rhs[j]) <= 0) return false; - if (compare_rhs(i, j, &diff_sign)) { - fprintf(gfp, _("Equations are identical.\n")); + if (compare_rhs(mathomatic, i, j, &diff_sign)) { + fprintf(mathomatic->gfp, _("Equations are identical.\n")); return true; } - uf_simp(rhs[i], &n_rhs[i]); - uf_simp(rhs[j], &n_rhs[j]); - if (compare_rhs(i, j, &diff_sign)) { - fprintf(gfp, _("Equations are identical.\n")); + uf_simp(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + uf_simp(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); + if (compare_rhs(mathomatic, i, j, &diff_sign)) { + fprintf(mathomatic->gfp, _("Equations are identical.\n")); return true; } if (approx) { - debug_string(0, _("Approximating both equations...")); - approximate(rhs[i], &n_rhs[i]); - approximate(rhs[j], &n_rhs[j]); - if (compare_rhs(i, j, &diff_sign)) { - fprintf(gfp, _("Equations are identical.\n")); + debug_string(mathomatic, 0, _("Approximating both equations...")); + approximate(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + approximate(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); + if (compare_rhs(mathomatic, i, j, &diff_sign)) { + fprintf(mathomatic->gfp, _("Equations are identical.\n")); return true; } } - debug_string(0, _("Simplifying both equations...")); - symb_flag = symb; - simpa_repeat_side(rhs[i], &n_rhs[i], false, false); - simpa_repeat_side(rhs[j], &n_rhs[j], false, false); - symb_flag = false; + debug_string(mathomatic, 0, _("Simplifying both equations...")); + mathomatic->symb_flag = symb; + simpa_repeat_side(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], false, false); + simpa_repeat_side(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j], false, false); + mathomatic->symb_flag = false; if (approx) { - approximate(rhs[i], &n_rhs[i]); - approximate(rhs[j], &n_rhs[j]); + approximate(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + approximate(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); } - if (compare_rhs(i, j, &diff_sign)) { - fprintf(gfp, _("Equations are identical.\n")); + if (compare_rhs(mathomatic, i, j, &diff_sign)) { + fprintf(mathomatic->gfp, _("Equations are identical.\n")); return true; } - if (solve_sub(&zero_token, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) + if (solve_sub(mathomatic, &mathomatic->zero_token, 1, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->rhs[i], &mathomatic->n_rhs[i]) <= 0) return false; - if (solve_sub(&zero_token, 1, lhs[j], &n_lhs[j], rhs[j], &n_rhs[j]) <= 0) + if (solve_sub(mathomatic, &mathomatic->zero_token, 1, mathomatic->lhs[j], &mathomatic->n_lhs[j], mathomatic->rhs[j], &mathomatic->n_rhs[j]) <= 0) return false; - uf_simp(rhs[i], &n_rhs[i]); - uf_simp(rhs[j], &n_rhs[j]); + uf_simp(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + uf_simp(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); if (approx) { - approximate(rhs[i], &n_rhs[i]); - approximate(rhs[j], &n_rhs[j]); + approximate(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + approximate(mathomatic, mathomatic->rhs[j], &mathomatic->n_rhs[j]); } - if (compare_rhs(i, j, &diff_sign)) { - fprintf(gfp, _("Equations are identical.\n")); + if (compare_rhs(mathomatic, i, j, &diff_sign)) { + fprintf(mathomatic->gfp, _("Equations are identical.\n")); return true; } - fprintf(gfp, _("Equations differ.\n")); + fprintf(mathomatic->gfp, _("Equations differ.\n")); return false; times_neg1: - if (!diff_sign && lhs[i][0].token.variable == lhs[j][0].token.variable) { - fprintf(gfp, _("Equations are identical.\n")); + if (!diff_sign && mathomatic->lhs[i][0].token.variable == mathomatic->lhs[j][0].token.variable) { + fprintf(mathomatic->gfp, _("Equations are identical.\n")); return true; } - fprintf(gfp, _("Variable ")); - list_proc(lhs[i], n_lhs[i], false); - fprintf(gfp, _(" in the first equation\nis equal to ")); + fprintf(mathomatic->gfp, _("Variable ")); + list_proc(mathomatic, mathomatic->lhs[i], mathomatic->n_lhs[i], false); + fprintf(mathomatic->gfp, _(" in the first equation\nis equal to ")); if (diff_sign) { - fprintf(gfp, "-"); + fprintf(mathomatic->gfp, "-"); } - list_proc(lhs[j], n_lhs[j], false); - fprintf(gfp, _(" in the second equation.\n")); + list_proc(mathomatic, mathomatic->lhs[j], mathomatic->n_lhs[j], false); + fprintf(mathomatic->gfp, _(" in the second equation.\n")); #if LIBRARY if (diff_sign) - error(_("RHS appears negated.")); + error(mathomatic, _("RHS appears negated.")); else - error(_("Different LHS variable name, otherwise the same.")); + error(mathomatic, _("Different LHS variable name, otherwise the same.")); return false; #else return 2; @@ -2831,19 +2799,18 @@ char *cp; * Return true if a fraction was displayed. */ int -display_fraction(value) -double value; +display_fraction(MathoMatic* mathomatic, double value) { double d4, d5; int rv = false; - f_to_fraction(value, &d4, &d5); - fprintf(gfp, "%.*g", precision, value); + f_to_fraction(mathomatic, value, &d4, &d5); + fprintf(mathomatic->gfp, "%.*g", mathomatic->precision, value); if (d5 != 1.0) { - fprintf(gfp, " = %.*g/%.*g", precision, d4, precision, d5); + fprintf(mathomatic->gfp, " = %.*g/%.*g", mathomatic->precision, d4, mathomatic->precision, d5); rv = true; } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); return rv; } @@ -2851,8 +2818,7 @@ double value; * The divide command. */ int -divide_cmd(cp) -char *cp; +divide_cmd(MathoMatic* mathomatic, char *cp) { long v = 0, v_tmp; /* Mathomatic variables */ int i, j; @@ -2862,26 +2828,26 @@ char *cp; char *cp_start; cp_start = cp; - pull_number = -1; /* Operands are last two entered expressions when using library. */ - if (*cp && isvarchar(*cp)) { - cp = parse_var(&v, cp); + mathomatic->pull_number = -1; /* Operands are last two entered expressions when using library. */ + if (*cp && isvarchar(mathomatic, *cp)) { + cp = parse_var(mathomatic, &v, cp); if (cp == NULL || (*cp && !isspace(*cp) && *cp != ',')) { if (cp == NULL) { - reset_error(); + reset_error(mathomatic); } cp = cp_start; v = 0; } else { cp = skip_comma_space(cp); - SP(_("You have entered a base variable.")); - EP(_("Polynomial division will be based on this variable.")); - point_flag = false; + SP(mathomatic, ("You have entered a base variable.")); + EP(mathomatic, ("Polynomial division will be based on this variable.")); + mathomatic->point_flag = false; } } - i = next_espace(); + i = next_espace(mathomatic); if (*cp) { - input_column += (cp - cp_start); - cp = parse_expr(rhs[i], &nright, cp, false); + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->rhs[i], &nright, cp, false); if (cp == NULL || nright <= 0) { return false; } @@ -2889,138 +2855,138 @@ char *cp; if (*cp) { cp_start = cp; cp = skip_comma_space(cp); - input_column += (cp - cp_start); - cp = parse_expr(lhs[i], &nleft, cp, false); - if (cp == NULL || extra_characters(cp) || nleft <= 0) { + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->lhs[i], &nleft, cp, false); + if (cp == NULL || extra_characters(mathomatic, cp) || nleft <= 0) { return false; } } do_repeat_prompt: /* prompt for the two operands */ - my_strlcpy(prompt_str, _("Enter dividend: "), sizeof(prompt_str)); - if (nright == 0 && !get_expr(rhs[i], &nright)) { - return repeat_flag; + my_strlcpy(mathomatic->prompt_str, _("Enter dividend: "), sizeof(mathomatic->prompt_str)); + if (nright == 0 && !get_expr(mathomatic, mathomatic->rhs[i], &nright)) { + return mathomatic->repeat_flag; } - my_strlcpy(prompt_str, _("Enter divisor: "), sizeof(prompt_str)); - if (nleft == 0 && !get_expr(lhs[i], &nleft)) { - return repeat_flag; + my_strlcpy(mathomatic->prompt_str, _("Enter divisor: "), sizeof(mathomatic->prompt_str)); + if (nleft == 0 && !get_expr(mathomatic, mathomatic->lhs[i], &nleft)) { + return mathomatic->repeat_flag; } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); /* simplify and expand the operand expressions */ #if 1 - simp_loop(rhs[i], &nright); - uf_simp(rhs[i], &nright); - simp_loop(lhs[i], &nleft); - uf_simp(lhs[i], &nleft); + simp_loop(mathomatic, mathomatic->rhs[i], &nright); + uf_simp(mathomatic, mathomatic->rhs[i], &nright); + simp_loop(mathomatic, mathomatic->lhs[i], &nleft); + uf_simp(mathomatic, mathomatic->lhs[i], &nleft); #else /* approximates, too */ - calc_simp(rhs[i], &nright); - calc_simp(lhs[i], &nleft); + calc_simp(mathomatic, mathomatic->rhs[i], &nright); + calc_simp(mathomatic, mathomatic->lhs[i], &nleft); #endif /* if division by zero, display a warning */ - if (get_constant(lhs[i], nleft, &d2)) { - check_divide_by_zero(d2); + if (get_constant(mathomatic, mathomatic->lhs[i], nleft, &d2)) { + check_divide_by_zero(mathomatic, d2); } /* Do constant division if 2 normal numbers were entered */ - if (get_constant(rhs[i], nright, &d1) && get_constant(lhs[i], nleft, &d2)) { - fprintf(gfp, _("Result of numerical division:\n")); - d3 = gcd_verified(d1, d2); + if (get_constant(mathomatic, mathomatic->rhs[i], nright, &d1) && get_constant(mathomatic, mathomatic->lhs[i], nleft, &d2)) { + fprintf(mathomatic->gfp, _("Result of numerical division:\n")); + d3 = gcd_verified(mathomatic, d1, d2); d4 = modf(d1 / d2, &d5); - fprintf(gfp, "%.*g/%.*g = %.*g", precision, d1, precision, d2, precision, d1 / d2); + fprintf(mathomatic->gfp, "%.*g/%.*g = %.*g", mathomatic->precision, d1, mathomatic->precision, d2, mathomatic->precision, d1 / d2); if (d3 != 0.0 && d3 != 1.0 && (d2 / d3) != 1.0) { if ((d1 / d2) < 0) { - fprintf(gfp, " = -%.*g/%.*g", precision, fabs(d1 / d3), precision, fabs(d2 / d3)); + fprintf(mathomatic->gfp, " = -%.*g/%.*g", mathomatic->precision, fabs(d1 / d3), mathomatic->precision, fabs(d2 / d3)); } else { - fprintf(gfp, " = %.*g/%.*g", precision, fabs(d1 / d3), precision, fabs(d2 / d3)); + fprintf(mathomatic->gfp, " = %.*g/%.*g", mathomatic->precision, fabs(d1 / d3), mathomatic->precision, fabs(d2 / d3)); } } if (d3 != 0 && d4 != 0 && d5 != 0) { if ((d1 / d2) < 0) { - fprintf(gfp, " = -(%.*g + (%.*g/%.*g))", precision, fabs(d5), precision, fabs(d4 * (d2 / d3)), precision, fabs(d2 / d3)); + fprintf(mathomatic->gfp, " = -(%.*g + (%.*g/%.*g))", mathomatic->precision, fabs(d5), mathomatic->precision, fabs(d4 * (d2 / d3)), mathomatic->precision, fabs(d2 / d3)); } else { - fprintf(gfp, " = %.*g + (%.*g/%.*g)", precision, fabs(d5), precision, fabs(d4 * (d2 / d3)), precision, fabs(d2 / d3)); + fprintf(mathomatic->gfp, " = %.*g + (%.*g/%.*g)", mathomatic->precision, fabs(d5), mathomatic->precision, fabs(d4 * (d2 / d3)), mathomatic->precision, fabs(d2 / d3)); } } - fprintf(gfp, _("\nQuotient: %.*g, Remainder: %.*g\n"), precision, d5, precision, d4 * d2); + fprintf(mathomatic->gfp, _("\nQuotient: %.*g, Remainder: %.*g\n"), mathomatic->precision, d5, mathomatic->precision, d4 * d2); d1 = fabs(d1); d2 = fabs(d2); if (d3 == 0.0) { - fprintf(gfp, _("No GCD found.\n")); - if (repeat_flag) + fprintf(mathomatic->gfp, _("No GCD found.\n")); + if (mathomatic->repeat_flag) goto do_repeat; return true; } - fprintf(gfp, "GCD = "); - if (d3 >= 4.0 && factor_one(d3) && !is_prime()) { - display_unique(); + fprintf(mathomatic->gfp, "GCD = "); + if (d3 >= 4.0 && factor_one(mathomatic, d3) && !is_prime(mathomatic)) { + display_unique(mathomatic); } else { - display_fraction(d3); + display_fraction(mathomatic, d3); } lcm = (d1 * d2) / d3; - fprintf(gfp, "LCM = "); - if (lcm >= 4.0 && factor_one(lcm) && !is_prime()) { - display_unique(); + fprintf(mathomatic->gfp, "LCM = "); + if (lcm >= 4.0 && factor_one(mathomatic, lcm) && !is_prime(mathomatic)) { + display_unique(mathomatic); } else { - display_fraction(lcm); + display_fraction(mathomatic, lcm); } - if (repeat_flag) + if (mathomatic->repeat_flag) goto do_repeat; return true; } /* else do complex number division if 2 complex numbers were entered */ - if (parse_complex(rhs[i], nright, &c1) && parse_complex(lhs[i], nleft, &c2)) { - fprintf(gfp, _("Result of complex number division:\n")); + if (parse_complex(mathomatic, mathomatic->rhs[i], nright, &c1) && parse_complex(mathomatic, mathomatic->lhs[i], nleft, &c2)) { + fprintf(mathomatic->gfp, _("Result of complex number division:\n")); c3 = complex_div(c1, c2); - fprintf(gfp, "%.*g %+.*g*i\n\n", precision, c3.re, precision, c3.im); - if (repeat_flag) + fprintf(mathomatic->gfp, "%.*g %+.*g*i\n\n", mathomatic->precision, c3.re, mathomatic->precision, c3.im); + if (mathomatic->repeat_flag) goto do_repeat; return true; } /* else do polynomial division and univariate GCD display */ v_tmp = v; - if (poly_div(rhs[i], nright, lhs[i], nleft, &v_tmp)) { - simp_divide(tlhs, &n_tlhs); - simp_divide(trhs, &n_trhs); - list_var(v_tmp, 0); - fprintf(gfp, _("Polynomial division successful using base variable %s.\n"), var_str); - fprintf(gfp, _("The quotient is:\n")); - fractions_and_group(tlhs, &n_tlhs); - list_factor(tlhs, &n_tlhs, false); - fprintf(gfp, _("\n\nThe remainder is:\n")); - fractions_and_group(trhs, &n_trhs); - list_factor(trhs, &n_trhs, false); - fprintf(gfp, "\n"); + if (poly_div(mathomatic, mathomatic->rhs[i], nright, mathomatic->lhs[i], nleft, &v_tmp)) { + simp_divide(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + simp_divide(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + list_var(mathomatic, v_tmp, 0); + fprintf(mathomatic->gfp, _("Polynomial division successful using base variable %s.\n"), mathomatic->var_str); + fprintf(mathomatic->gfp, _("The quotient is:\n")); + fractions_and_group(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + list_factor(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, false); + fprintf(mathomatic->gfp, _("\n\nThe remainder is:\n")); + fractions_and_group(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + list_factor(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, false); + fprintf(mathomatic->gfp, "\n"); } else { - SP(_("Polynomial division failed,")); - SP(_("because the given polynomials cannot be divided in the given order,")); - EP(_("according to the rules of polynomial division.")); + SP(mathomatic, ("Polynomial division failed,")); + SP(mathomatic, ("because the given polynomials cannot be divided in the given order,")); + EP(mathomatic, ("according to the rules of polynomial division.")); } - fprintf(gfp, "\n"); - j = poly_gcd(rhs[i], nright, lhs[i], nleft, v); + fprintf(mathomatic->gfp, "\n"); + j = poly_gcd(mathomatic, mathomatic->rhs[i], nright, mathomatic->lhs[i], nleft, v); if (j == 0) { - j = poly_gcd(lhs[i], nleft, rhs[i], nright, v); + j = poly_gcd(mathomatic, mathomatic->lhs[i], nleft, mathomatic->rhs[i], nright, v); } if (j > 0) { - simp_divide(trhs, &n_trhs); - fprintf(gfp, _("Polynomial GCD (after %d Euclidean algorithm iterations):\n"), j); - fractions_and_group(trhs, &n_trhs); - list_factor(trhs, &n_trhs, false); - fprintf(gfp, "\n"); - blt(tes, trhs, n_trhs * sizeof(token_type)); - n_tes = n_trhs; - if (poly_factor(tes, &n_tes, true)) { - simp_loop(tes, &n_tes); - fprintf(gfp, _("Polynomial GCD (after quick polynomial factoring):\n")); - fractions_and_group(tes, &n_tes); - list_factor(tes, &n_tes, false); - fprintf(gfp, "\n"); + simp_divide(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + fprintf(mathomatic->gfp, _("Polynomial GCD (after %d Euclidean algorithm iterations):\n"), j); + fractions_and_group(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + list_factor(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, false); + fprintf(mathomatic->gfp, "\n"); + blt(mathomatic->tes, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tes = mathomatic->n_trhs; + if (poly_factor(mathomatic, mathomatic->tes, &mathomatic->n_tes, true)) { + simp_loop(mathomatic, mathomatic->tes, &mathomatic->n_tes); + fprintf(mathomatic->gfp, _("Polynomial GCD (after quick polynomial factoring):\n")); + fractions_and_group(mathomatic, mathomatic->tes, &mathomatic->n_tes); + list_factor(mathomatic, mathomatic->tes, &mathomatic->n_tes, false); + fprintf(mathomatic->gfp, "\n"); } } else { - SP(_("No additive univariate polynomial GCD found.")); - SP(_("This does not mean there is no GCD; it could be multivariate,")); - EP(_("or contain too much floating point round-off error.")); + SP(mathomatic, ("No additive univariate polynomial GCD found.")); + SP(mathomatic, ("This does not mean there is no GCD; it could be multivariate,")); + EP(mathomatic, ("or contain too much floating point round-off error.")); } - if (repeat_flag) + if (mathomatic->repeat_flag) goto do_repeat; return true; @@ -3034,8 +3000,7 @@ char *cp; * The eliminate command. */ int -eliminate_cmd(cp) -char *cp; +eliminate_cmd(MathoMatic* mathomatic, char *cp) { long v, last_v, v1, va[MAX_VARS]; /* Mathomatic variables */ int vc = 0; /* variable count */ @@ -3046,12 +3011,12 @@ char *cp; char buf[MAX_CMD_LEN]; CLEAR_ARRAY(used); - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } if (*cp == '\0') { - my_strlcpy(prompt_str, _("Enter variables to eliminate: "), sizeof(prompt_str)); - cp = get_string(buf, sizeof(buf)); + my_strlcpy(mathomatic->prompt_str, _("Enter variables to eliminate: "), sizeof(mathomatic->prompt_str)); + cp = get_string(mathomatic, buf, sizeof(buf)); if (cp == NULL || *cp == '\0') { return false; } @@ -3067,19 +3032,19 @@ char *cp; last_v = 0; for (;;) { v1 = -1; - for (i = 0; i < n_lhs[cur_equation]; i += 2) { - if (lhs[cur_equation][i].kind == VARIABLE - && lhs[cur_equation][i].token.variable > last_v) { - if (v1 == -1 || lhs[cur_equation][i].token.variable < v1) { - v1 = lhs[cur_equation][i].token.variable; + for (i = 0; i < mathomatic->n_lhs[mathomatic->cur_equation]; i += 2) { + if (mathomatic->lhs[mathomatic->cur_equation][i].kind == VARIABLE + && mathomatic->lhs[mathomatic->cur_equation][i].token.variable > last_v) { + if (v1 == -1 || mathomatic->lhs[mathomatic->cur_equation][i].token.variable < v1) { + v1 = mathomatic->lhs[mathomatic->cur_equation][i].token.variable; } } } - for (i = 0; i < n_rhs[cur_equation]; i += 2) { - if (rhs[cur_equation][i].kind == VARIABLE - && rhs[cur_equation][i].token.variable > last_v) { - if (v1 == -1 || rhs[cur_equation][i].token.variable < v1) { - v1 = rhs[cur_equation][i].token.variable; + for (i = 0; i < mathomatic->n_rhs[mathomatic->cur_equation]; i += 2) { + if (mathomatic->rhs[mathomatic->cur_equation][i].kind == VARIABLE + && mathomatic->rhs[mathomatic->cur_equation][i].token.variable > last_v) { + if (v1 == -1 || mathomatic->rhs[mathomatic->cur_equation][i].token.variable < v1) { + v1 = mathomatic->rhs[mathomatic->cur_equation][i].token.variable; } } } @@ -3095,12 +3060,12 @@ char *cp; } goto next_var; } - cp = parse_var2(&v, cp); + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } } else { - if (repeat_flag) { + if (mathomatic->repeat_flag) { if (success_flag) { success_flag = false; cp = cp_start; @@ -3108,9 +3073,9 @@ char *cp; } } if (did_something) { - did_something = return_result(cur_equation); + did_something = return_result(mathomatic, mathomatic->cur_equation); } else { - error(_("No substitutions made.")); + error(mathomatic, _("No substitutions made.")); } return did_something; } @@ -3120,37 +3085,37 @@ char *cp; if (*cp == '#') cp++; i = decstrtol(cp, &cp) - 1; - if (not_defined(i)) { + if (not_defined(mathomatic, i)) { return false; } } - if (!var_in_equation(cur_equation, v)) { + if (!var_in_equation(mathomatic, mathomatic->cur_equation, v)) { #if !SILENT - if (!repeat_flag) { - list_var(v, 0); - printf(_("Variable %s not found in current equation.\n"), var_str); + if (!mathomatic->repeat_flag) { + list_var(mathomatic, v, 0); + printf(_("Variable %s not found in current equation.\n"), mathomatic->var_str); } #endif goto next_var; } if (using_flag) { - if (!elim_sub(i, v)) + if (!elim_sub(mathomatic, i, v)) goto next_var; } else { n = 1; - i = cur_equation; + i = mathomatic->cur_equation; for (;; n++) { - if (n >= n_equations) { + if (n >= mathomatic->n_equations) { goto next_var; } if (i <= 0) - i = n_equations - 1; + i = mathomatic->n_equations - 1; else i--; if (used[i]) continue; - if (n_lhs[i] && n_rhs[i] && var_in_equation(i, v)) { - if (elim_sub(i, v)) + if (mathomatic->n_lhs[i] && mathomatic->n_rhs[i] && var_in_equation(mathomatic, i, v)) { + if (elim_sub(mathomatic, i, v)) break; } } @@ -3166,39 +3131,39 @@ char *cp; * into all occurrences of v in the current equation, then simplify. */ static int -elim_sub(i, v) -int i; /* equation number */ -long v; /* Mathomatic variable */ +elim_sub(MathoMatic* mathomatic, int i, long v) +//int i; /* equation number */ +//long v; /* Mathomatic variable */ { token_type want; int solved; - if (i == cur_equation) { - error(_("Error: source and destination are the same.")); + if (i == mathomatic->cur_equation) { + error(mathomatic, _("Error: source and destination are the same.")); return false; } - solved = (solved_equation(i) && lhs[i][0].token.variable == v); + solved = (solved_equation(mathomatic, i) && mathomatic->lhs[i][0].token.variable == v); #if !SILENT - list_var(v, 0); + list_var(mathomatic, v, 0); if (solved) { - fprintf(gfp, _("Eliminating variable %s using solved equation #%d...\n"), var_str, i + 1); + fprintf(mathomatic->gfp, _("Eliminating variable %s using solved equation #%d...\n"), mathomatic->var_str, i + 1); } else { - fprintf(gfp, _("Solving equation #%d for %s and substituting into the current equation...\n"), i + 1, var_str); + fprintf(mathomatic->gfp, _("Solving equation #%d for %s and substituting into the current equation...\n"), i + 1, mathomatic->var_str); } #endif if (!solved) { want.level = 1; want.kind = VARIABLE; want.token.variable = v; - if (solve_sub(&want, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) { - error(_("Solve failed.")); + if (solve_sub(mathomatic, &want, 1, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->rhs[i], &mathomatic->n_rhs[i]) <= 0) { + error(mathomatic, _("Solve failed.")); return false; } } - subst_var_with_exp(rhs[cur_equation], &n_rhs[cur_equation], rhs[i], n_rhs[i], v); - subst_var_with_exp(lhs[cur_equation], &n_lhs[cur_equation], rhs[i], n_rhs[i], v); + subst_var_with_exp(mathomatic, mathomatic->rhs[mathomatic->cur_equation], &mathomatic->n_rhs[mathomatic->cur_equation], mathomatic->rhs[i], mathomatic->n_rhs[i], v); + subst_var_with_exp(mathomatic, mathomatic->lhs[mathomatic->cur_equation], &mathomatic->n_lhs[mathomatic->cur_equation], mathomatic->rhs[i], mathomatic->n_rhs[i], v); - simp_equation(cur_equation); + simp_equation(mathomatic, mathomatic->cur_equation); return true; } @@ -3210,8 +3175,7 @@ long v; /* Mathomatic variable */ * Return number of expressions displayed. */ int -display_cmd(cp) -char *cp; +display_cmd(MathoMatic* mathomatic, char *cp) { int i, j; char *cp1; @@ -3219,7 +3183,7 @@ char *cp; int factor_flag = false, displayed = 0; int orig_fractions_display_mode, new_fractions_display_mode; - new_fractions_display_mode = orig_fractions_display_mode = fractions_display; + new_fractions_display_mode = orig_fractions_display_mode = mathomatic->fractions_display; for (;; cp = skip_param(cp)) { if (strncasecmp(cp, "factor", 4) == 0) { factor_flag = true; @@ -3237,43 +3201,43 @@ char *cp; } do { cp1 = cp; - if (!get_range(&cp, &i, &j)) { + if (!get_range(mathomatic, &cp, &i, &j)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (; i <= j; i++) { - if (n_lhs[i] > 0) { - blt(save_save, jmp_save, sizeof(jmp_save)); - if (setjmp(jmp_save) != 0) { /* trap errors */ - fractions_display = orig_fractions_display_mode; - blt(jmp_save, save_save, sizeof(jmp_save)); + if (mathomatic->n_lhs[i] > 0) { + blt(save_save, mathomatic->jmp_save, sizeof(mathomatic->jmp_save)); + if (setjmp(mathomatic->jmp_save) != 0) { /* trap errors */ + mathomatic->fractions_display = orig_fractions_display_mode; + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); printf("Skipping equation number %d.\n", i + 1); continue; } - fractions_display = new_fractions_display_mode; - make_fractions_and_group(i); - fractions_display = orig_fractions_display_mode; - if (factor_flag || factor_int_flag) { - factor_int_equation(i); + mathomatic->fractions_display = new_fractions_display_mode; + make_fractions_and_group(mathomatic, i); + mathomatic->fractions_display = orig_fractions_display_mode; + if (factor_flag || mathomatic->factor_int_flag) { + factor_int_equation(mathomatic, i); } - blt(jmp_save, save_save, sizeof(jmp_save)); + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); #if LIBRARY - free_result_str(); - result_str = flist_equation_string(i); - if (result_str == NULL) - result_str = list_equation(i, false); - if (result_str) - result_en = i; - if (gfp != stdout) { - if (flist_equation(i) > 0) { + free_result_str(mathomatic); + mathomatic->result_str = flist_equation_string(mathomatic, i); + if (mathomatic->result_str == NULL) + mathomatic->result_str = list_equation(mathomatic, i, false); + if (mathomatic->result_str) + mathomatic->result_en = i; + if (mathomatic->gfp != stdout) { + if (flist_equation(mathomatic, i) > 0) { displayed++; } } #else - if (flist_equation(i) > 0) { + if (flist_equation(mathomatic, i) > 0) { displayed++; } #endif @@ -3281,7 +3245,7 @@ char *cp; } } while (*cp); #if LIBRARY - return(result_str != NULL); + return(mathomatic->result_str != NULL); #else return(displayed); #endif @@ -3291,8 +3255,7 @@ char *cp; * The list command. */ int -list_cmd(cp) -char *cp; +list_cmd(MathoMatic* mathomatic, char *cp) { int k; int first, last; @@ -3324,20 +3287,20 @@ char *cp; } #if SHELL_OUT if (primes_flag) { - if (gfp && gfp_filename && gfp_filename[0]) { - if (snprintf(cl, sizeof(cl), "matho-primes -u %s >%s%s", cp, gfp_append_flag ? ">" : "", gfp_filename) >= sizeof(cl)) { - error(_("Command-line too long.")); + if (mathomatic->gfp && mathomatic->gfp_filename && mathomatic->gfp_filename[0]) { + if (snprintf(cl, sizeof(cl), "matho-primes -u %s >%s%s", cp, mathomatic->gfp_append_flag ? ">" : "", mathomatic->gfp_filename) >= sizeof(cl)) { + error(mathomatic, _("Command-line too long.")); return false; } - clean_up(); /* end any redirection */ + clean_up(mathomatic); /* end any redirection */ } else { if (snprintf(cl, sizeof(cl), "matho-primes -u %s", cp) >= sizeof(cl)) { - error(_("Command-line too long.")); + error(mathomatic, _("Command-line too long.")); return false; } } - if ((ev = shell_out(cl))) { - error(_("Abnormal termination of matho-primes.")); + if ((ev = shell_out(mathomatic, cl))) { + error(mathomatic, _("Abnormal termination of matho-primes.")); printf(_("Decimal exit value = %d, shell command-line = %s\n"), ev, cl); return false; } @@ -3346,28 +3309,28 @@ char *cp; #endif do { cp1 = cp; - if (!get_range(&cp, &first, &last)) { + if (!get_range(mathomatic, &cp, &first, &last)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (k = first; k <= last; k++) { - if (n_lhs[k] <= 0) + if (mathomatic->n_lhs[k] <= 0) continue; #if LIBRARY - free_result_str(); - result_str = list_equation(k, export_flag); - if (result_str) - result_en = k; + free_result_str(mathomatic); + mathomatic->result_str = list_equation(mathomatic, k, export_flag); + if (mathomatic->result_str) + mathomatic->result_en = k; else return false; - if (gfp == stdout) { + if (mathomatic->gfp == stdout) { continue; } #endif - list1_sub(k, export_flag); + list1_sub(mathomatic, k, export_flag); } } while (*cp); return true; @@ -3377,8 +3340,7 @@ char *cp; * The code command. */ int -code_cmd(cp) -char *cp; +code_cmd(MathoMatic* mathomatic, char *cp) { int i, j, k; int li, ri; @@ -3407,62 +3369,62 @@ char *cp; } do { cp1 = cp; - if (!get_range(&cp, &i, &j)) { + if (!get_range(mathomatic, &cp, &i, &j)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (k = i; k <= j; k++) { - if (n_lhs[k] <= 0) + if (mathomatic->n_lhs[k] <= 0) continue; - if (n_rhs[k] == 0 || n_lhs[k] != 1 || lhs[k][0].kind != VARIABLE) { - warning(_("Can't make assignment statement because this is not an equation.")); - } else if (!solved_equation(k)) { - warning(_("Equation is not solved for a normal variable.")); + if (mathomatic->n_rhs[k] == 0 || mathomatic->n_lhs[k] != 1 || mathomatic->lhs[k][0].kind != VARIABLE) { + warning(mathomatic, _("Can't make assignment statement because this is not an equation.")); + } else if (!solved_equation(mathomatic, k)) { + warning(mathomatic, _("Equation is not solved for a normal variable.")); } - simp_i(lhs[k], &n_lhs[k]); + simp_i(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); if (int_flag) { /* factor_constants() for more accurate integer results. */ do { - simp_loop(lhs[k], &n_lhs[k]); - } while (factor_constants(lhs[k], &n_lhs[k], 6)); + simp_loop(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); + } while (factor_constants(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k], 6)); /* Turn the power operator into the multiply operator, if raised to the power of a constant. */ - uf_repeat_always(lhs[k], &n_lhs[k]); + uf_repeat_always(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); } - if (n_rhs[k] > 0) { - simp_i(rhs[k], &n_rhs[k]); + if (mathomatic->n_rhs[k] > 0) { + simp_i(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); if (int_flag) { /* factor_constants() for more accurate integer results. */ do { - simp_loop(rhs[k], &n_rhs[k]); - } while (factor_constants(rhs[k], &n_rhs[k], 6)); + simp_loop(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); + } while (factor_constants(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k], 6)); /* Turn the power operator into the multiply operator, if raised to the power of a constant. */ - uf_repeat_always(rhs[k], &n_rhs[k]); + uf_repeat_always(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); } } - make_fractions_and_group(k); + make_fractions_and_group(mathomatic, k); if (int_flag) { - if ((!(li = int_expr(lhs[k], n_lhs[k])) || !(ri = int_expr(rhs[k], n_rhs[k])))) { - warning(_("Not an integer expression, but this rounded code may possibly work:")); + if ((!(li = int_expr(mathomatic->lhs[k], mathomatic->n_lhs[k])) || !(ri = int_expr(mathomatic->rhs[k], mathomatic->n_rhs[k])))) { + warning(mathomatic, _("Not an integer expression, but this rounded code may possibly work:")); } else if (li < 0 || ri < 0) { - warning(_("This integer expression contains non-integer divides:")); + warning(mathomatic, _("This integer expression contains non-integer divides:")); } } #if LIBRARY - free_result_str(); - result_str = string_code_equation(k, language, int_flag); - if (result_str) - result_en = k; + free_result_str(mathomatic); + mathomatic->result_str = string_code_equation(mathomatic, k, language, int_flag); + if (mathomatic->result_str) + mathomatic->result_en = k; else return false; - if (gfp == stdout) { + if (mathomatic->gfp == stdout) { displayed = true; continue; } #endif - if (list_code_equation(k, language, int_flag) > 0) { + if (list_code_equation(mathomatic, k, language, int_flag) > 0) { displayed = true; } } @@ -3491,8 +3453,7 @@ sort_type *p1, *p2; * The variables command. */ int -variables_cmd(cp) -char *cp; +variables_cmd(MathoMatic* mathomatic, char *cp) { int start, stop; int k; @@ -3533,22 +3494,22 @@ char *cp; range_start = cp; do { cp1 = cp; - if (!get_range(&cp, &start, &stop)) { + if (!get_range(mathomatic, &cp, &start, &stop)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (k = start; k <= stop; k++) { - if (n_lhs[k] <= 0) + if (mathomatic->n_lhs[k] <= 0) continue; - if (n_rhs[k] > 0) { - p1 = rhs[k]; - n1 = n_rhs[k]; + if (mathomatic->n_rhs[k] > 0) { + p1 = mathomatic->rhs[k]; + n1 = mathomatic->n_rhs[k]; } else { - p1 = lhs[k]; - n1 = n_lhs[k]; + p1 = mathomatic->lhs[k]; + n1 = mathomatic->n_lhs[k]; } for (i1 = 0; i1 < n1; i1 += 2) { if (p1[i1].kind == VARIABLE && p1[i1].token.variable == IMAGINARY) { @@ -3559,11 +3520,11 @@ char *cp; } } } while (*cp); - show_usage = false; + mathomatic->show_usage = false; last_v = 0; for (vc = 0;;) { if (vc >= ARR_CNT(va)) { - error(_("Too many variables to list.")); + error(mathomatic, _("Too many variables to list.")); return false; } cnt = 0; @@ -3571,19 +3532,19 @@ char *cp; cp = range_start; do { cp1 = cp; - if (!get_range(&cp, &start, &stop)) { + if (!get_range(mathomatic, &cp, &start, &stop)) { return false; } #if DEBUG if (*cp && cp == cp1) { - error_bug("Bug in variables command."); + error_bug(mathomatic, "Bug in variables command."); } #endif for (k = start; k <= stop; k++) { - if (n_lhs[k] <= 0) + if (mathomatic->n_lhs[k] <= 0) continue; - p1 = lhs[k]; - n1 = n_lhs[k]; + p1 = mathomatic->lhs[k]; + n1 = mathomatic->n_lhs[k]; for (i1 = 0; i1 < n1; i1 += 2) { if (p1[i1].kind == VARIABLE && p1[i1].token.variable > last_v) { if (v1 == -1 || p1[i1].token.variable < v1) { @@ -3594,8 +3555,8 @@ char *cp; } } } - p1 = rhs[k]; - n1 = n_rhs[k]; + p1 = mathomatic->rhs[k]; + n1 = mathomatic->n_rhs[k]; for (i1 = 0; i1 < n1; i1 += 2) { if (p1[i1].kind == VARIABLE && p1[i1].token.variable > last_v) { if (v1 == -1 || p1[i1].token.variable < v1) { @@ -3617,7 +3578,7 @@ char *cp; } if (vc <= 0) { if (lang_code == 0) { - error(_("Expression is numeric. No normal variables found.")); + error(mathomatic, _("Expression is numeric. No normal variables found.")); return false; } else { return true; @@ -3631,54 +3592,54 @@ char *cp; if ((va[i1].v & VAR_MASK) >= SIGN) { rv = true; } - n_tabs = list_var(va[i1].v, lang_code ? lang_code : -5); + n_tabs = list_var(mathomatic, va[i1].v, lang_code ? lang_code : -5); if (lang_code) { - if (strpbrk(var_str, "[]()")) + if (strpbrk(mathomatic->var_str, "[]()")) array_element_flag = true; if (imag_flag) { for (k = 0;; k++) { - if (k >= n_equations) { + if (k >= mathomatic->n_equations) { not_complex = true; break; } - if (imag_array[k] && n_lhs[k] == 1 - && lhs[k][0].kind == VARIABLE && lhs[k][0].token.variable == va[i1].v) { - fprintf(gfp, "_Complex "); + if (imag_array[k] && mathomatic->n_lhs[k] == 1 + && mathomatic->lhs[k][0].kind == VARIABLE && mathomatic->lhs[k][0].token.variable == va[i1].v) { + fprintf(mathomatic->gfp, "_Complex "); n_tabs += 8; break; } } } - if (int_flag || is_integer_var(va[i1].v) || (va[i1].v & VAR_MASK) == SIGN) { - fprintf(gfp, "int%s%s;", (n_tabs + 1)/8 ? "\t" : "\t\t", var_str); + if (int_flag || is_integer_var(mathomatic, va[i1].v) || (va[i1].v & VAR_MASK) == SIGN) { + fprintf(mathomatic->gfp, "int%s%s;", (n_tabs + 1)/8 ? "\t" : "\t\t", mathomatic->var_str); } else { - fprintf(gfp, "double%s%s;", (n_tabs + 1)/8 ? "\t" : "\t\t", var_str); + fprintf(mathomatic->gfp, "double%s%s;", (n_tabs + 1)/8 ? "\t" : "\t\t", mathomatic->var_str); } if (n_tabs >= 7) n_tabs -= 7; } else { - fprintf(gfp, "%s", var_str); + fprintf(mathomatic->gfp, "%s", mathomatic->var_str); } if (count_flag) { if ((n_tabs / 8) == 0) { - fprintf(gfp, "\t"); + fprintf(mathomatic->gfp, "\t"); } - fprintf(gfp, _("\t/* count = %d */\n"), va[i1].count); + fprintf(mathomatic->gfp, _("\t/* count = %d */\n"), va[i1].count); } else { - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } } if (lang_code && imag_flag && not_complex && rv) { printf("\n"); - warning(_("Some variables might need to be of the complex number type.")); + warning(mathomatic, _("Some variables might need to be of the complex number type.")); printf(_("Manual adjustments may be necessary\n")); printf(_("because of the appearance of the imaginary unit (i).\n")); } if (!rv) { - error(_("Expressions are all numeric. No variables found.")); + error(mathomatic, _("Expressions are all numeric. No variables found.")); } if (array_element_flag) { - warning(_("Some defined variables were array elements or functions, requiring manual definition.")); + warning(mathomatic, _("Some defined variables were array elements or functions, requiring manual definition.")); rv = false; } return rv; @@ -3688,8 +3649,7 @@ char *cp; * The approximate command. */ int -approximate_cmd(cp) -char *cp; +approximate_cmd(MathoMatic* mathomatic, char *cp) { int start, stop; int k; @@ -3697,20 +3657,20 @@ char *cp; do { cp1 = cp; - if (!get_range(&cp, &start, &stop)) { + if (!get_range(mathomatic, &cp, &start, &stop)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (k = start; k <= stop; k++) { - if (n_lhs[k]) { - approximate(lhs[k], &n_lhs[k]); - if (n_rhs[k]) { - approximate(rhs[k], &n_rhs[k]); + if (mathomatic->n_lhs[k]) { + approximate(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); + if (mathomatic->n_rhs[k]) { + approximate(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); } - if (!return_result(k)) { + if (!return_result(mathomatic, k)) { return false; } } @@ -3723,8 +3683,7 @@ char *cp; * The replace command. */ int -replace_cmd(cp) -char *cp; +replace_cmd(MathoMatic* mathomatic, char *cp) { int i, j; long last_v, v, va[MAX_VARS]; /* Mathomatic variables */ @@ -3734,51 +3693,51 @@ char *cp; int diff_sign; cp_start = cp; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - i = cur_equation; + i = mathomatic->cur_equation; for (vc = 0; *cp; vc++) { if (strcmp_tospace(cp, "with") == 0) { if (vc) { - repeat_flag = false; + mathomatic->repeat_flag = false; break; } } if (vc >= ARR_CNT(va)) { - error(_("Too many variables specified.")); + error(mathomatic, _("Too many variables specified.")); return false; } - cp = parse_var2(&va[vc], cp); + cp = parse_var2(mathomatic, &va[vc], cp); if (cp == NULL) { return false; } - if (!var_in_equation(i, va[vc])) { - error(_("Variable not found.")); + if (!var_in_equation(mathomatic, i, va[vc])) { + error(mathomatic, _("Variable not found.")); return false; } } replace_again: - n_tlhs = n_lhs[i]; - blt(tlhs, lhs[i], n_tlhs * sizeof(token_type)); - n_trhs = n_rhs[i]; - blt(trhs, rhs[i], n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_lhs[i]; + blt(mathomatic->tlhs, mathomatic->lhs[i], mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_trhs = mathomatic->n_rhs[i]; + blt(mathomatic->trhs, mathomatic->rhs[i], mathomatic->n_trhs * sizeof(token_type)); value_entered = false; last_v = 0; for (;;) { v = -1; - for (j = 0; j < n_lhs[i]; j += 2) { - if (lhs[i][j].kind == VARIABLE) { - if (lhs[i][j].token.variable > last_v - && (v == -1 || lhs[i][j].token.variable < v)) - v = lhs[i][j].token.variable; + for (j = 0; j < mathomatic->n_lhs[i]; j += 2) { + if (mathomatic->lhs[i][j].kind == VARIABLE) { + if (mathomatic->lhs[i][j].token.variable > last_v + && (v == -1 || mathomatic->lhs[i][j].token.variable < v)) + v = mathomatic->lhs[i][j].token.variable; } } - for (j = 0; j < n_rhs[i]; j += 2) { - if (rhs[i][j].kind == VARIABLE) { - if (rhs[i][j].token.variable > last_v - && (v == -1 || rhs[i][j].token.variable < v)) - v = rhs[i][j].token.variable; + for (j = 0; j < mathomatic->n_rhs[i]; j += 2) { + if (mathomatic->rhs[i][j].kind == VARIABLE) { + if (mathomatic->rhs[i][j].token.variable > last_v + && (v == -1 || mathomatic->rhs[i][j].token.variable < v)) + v = mathomatic->rhs[i][j].token.variable; } } if (v == -1) { @@ -3798,59 +3757,59 @@ char *cp; return false; } cp1 = skip_param(cp); - input_column += (cp1 - cp_start); - if ((cp1 = parse_expr(tes, &n_tes, cp1, true)) == NULL || n_tes <= 0) { + mathomatic->input_column += (cp1 - cp_start); + if ((cp1 = parse_expr(mathomatic, mathomatic->tes, &mathomatic->n_tes, cp1, true)) == NULL || mathomatic->n_tes <= 0) { return false; } goto do_this; } } - list_var(v, 0); - snprintf(prompt_str, sizeof(prompt_str), _("Enter %s: "), var_str); - if (!get_expr(tes, &n_tes)) { + list_var(mathomatic, v, 0); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("Enter %s: "), mathomatic->var_str); + if (!get_expr(mathomatic, mathomatic->tes, &mathomatic->n_tes)) { continue; } value_entered = true; do_this: /* Disguise all variables in the entered expression by making them negative; */ /* That way they won't be improperly substituted later, allowing variable interchange. */ - for (j = 0; j < n_tes; j += 2) { - if (tes[j].kind == VARIABLE) { - tes[j].token.variable = -tes[j].token.variable; + for (j = 0; j < mathomatic->n_tes; j += 2) { + if (mathomatic->tes[j].kind == VARIABLE) { + mathomatic->tes[j].token.variable = -mathomatic->tes[j].token.variable; } } - subst_var_with_exp(tlhs, &n_tlhs, tes, n_tes, v); - subst_var_with_exp(trhs, &n_trhs, tes, n_tes, v); + subst_var_with_exp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, mathomatic->tes, mathomatic->n_tes, v); + subst_var_with_exp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, mathomatic->tes, mathomatic->n_tes, v); } /* Restore disguised variables: */ - for (j = 0; j < n_tlhs; j += 2) - if (tlhs[j].kind == VARIABLE && tlhs[j].token.variable < 0) - tlhs[j].token.variable = -tlhs[j].token.variable; - for (j = 0; j < n_trhs; j += 2) - if (trhs[j].kind == VARIABLE && trhs[j].token.variable < 0) - trhs[j].token.variable = -trhs[j].token.variable; - if (repeat_flag) { - calc_simp(tlhs, &n_tlhs); - if (n_trhs) { - calc_simp(trhs, &n_trhs); - if (se_compare(tlhs, n_tlhs, trhs, n_trhs, &diff_sign) && !diff_sign) { - fprintf(gfp, _("The result is an identity:\n")); - } - } - list_tdebug(-10); + for (j = 0; j < mathomatic->n_tlhs; j += 2) + if (mathomatic->tlhs[j].kind == VARIABLE && mathomatic->tlhs[j].token.variable < 0) + mathomatic->tlhs[j].token.variable = -mathomatic->tlhs[j].token.variable; + for (j = 0; j < mathomatic->n_trhs; j += 2) + if (mathomatic->trhs[j].kind == VARIABLE && mathomatic->trhs[j].token.variable < 0) + mathomatic->trhs[j].token.variable = -mathomatic->trhs[j].token.variable; + if (mathomatic->repeat_flag) { + calc_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + if (mathomatic->n_trhs) { + calc_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + if (se_compare(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs, mathomatic->trhs, mathomatic->n_trhs, &diff_sign) && !diff_sign) { + fprintf(mathomatic->gfp, _("The result is an identity:\n")); + } + } + list_tdebug(mathomatic, -10); if (value_entered) { - fprintf(gfp, "Repeating:\n"); + fprintf(mathomatic->gfp, "Repeating:\n"); goto replace_again; } else { return true; } } - n_lhs[i] = n_tlhs; - blt(lhs[i], tlhs, n_tlhs * sizeof(token_type)); - n_rhs[i] = n_trhs; - blt(rhs[i], trhs, n_trhs * sizeof(token_type)); - simp_equation(i); - return return_result(i); + mathomatic->n_lhs[i] = mathomatic->n_tlhs; + blt(mathomatic->lhs[i], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_rhs[i] = mathomatic->n_trhs; + blt(mathomatic->rhs[i], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + simp_equation(mathomatic, i); + return return_result(mathomatic, i); } /* @@ -3859,8 +3818,7 @@ char *cp; * Returns number of expressions simplified. */ int -simplify_cmd(cp) -char *cp; +simplify_cmd(MathoMatic* mathomatic, char *cp) { int i, i1; int first, last; @@ -3895,25 +3853,25 @@ char *cp; } do { cp1 = cp; - if (!get_range(&cp, &first, &last)) { + if (!get_range(mathomatic, &cp, &first, &last)) { return false; } if (*cp && cp == cp1) { - error(_("Invalid argument. Expecting equation number or range.")); + error(mathomatic, _("Invalid argument. Expecting equation number or range.")); return false; } for (i = first; i <= last; i++) { - if (n_lhs[i] <= 0) + if (mathomatic->n_lhs[i] <= 0) continue; number_simplified++; - symb_flag = symb; + mathomatic->symb_flag = symb; if (quickest_flag) { - simp_equation(i); + simp_equation(mathomatic, i); } else { - simpa_repeat(i, quick_flag, frac_flag); + simpa_repeat(mathomatic, i, quick_flag, frac_flag); } - symb_flag = false; - if (!return_result(i)) { + mathomatic->symb_flag = false; + if (!return_result(mathomatic, i)) { return false; } if (!sign_flag) @@ -3921,14 +3879,14 @@ char *cp; /* Now substitute all sign variables with +1 and -1. */ CLEAR_ARRAY(previous_solution_number); CLEAR_ARRAY(sa_mark); - for (k1 = 0; k1 < n_lhs[i]; k1 += 2) { - if (lhs[i][k1].kind == VARIABLE && (lhs[i][k1].token.variable & VAR_MASK) == SIGN) { - sa_mark[(lhs[i][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; + for (k1 = 0; k1 < mathomatic->n_lhs[i]; k1 += 2) { + if (mathomatic->lhs[i][k1].kind == VARIABLE && (mathomatic->lhs[i][k1].token.variable & VAR_MASK) == SIGN) { + sa_mark[(mathomatic->lhs[i][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; } } - for (k1 = 0; k1 < n_rhs[i]; k1 += 2) { - if (rhs[i][k1].kind == VARIABLE && (rhs[i][k1].token.variable & VAR_MASK) == SIGN) { - sa_mark[(rhs[i][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; + for (k1 = 0; k1 < mathomatic->n_rhs[i]; k1 += 2) { + if (mathomatic->rhs[i][k1].kind == VARIABLE && (mathomatic->rhs[i][k1].token.variable & VAR_MASK) == SIGN) { + sa_mark[(mathomatic->rhs[i][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK] = true; } } for (k1 = 0, k = 0; k1 < ARR_CNT(sa_mark); k1++) { @@ -3940,77 +3898,77 @@ char *cp; continue; counter_max = (1L << k) - 1L; if (counter_max) { - fprintf(gfp, _("There are %ld possible solutions.\n"), counter_max + 1); + fprintf(mathomatic->gfp, _("There are %ld possible solutions.\n"), counter_max + 1); } for (counter = 0; counter <= counter_max; counter++) { - i1 = next_espace(); - copy_espace(i, i1); + i1 = next_espace(mathomatic); + copy_espace(mathomatic, i, i1); for (k1 = 0, k = 0; k1 < ARR_CNT(sa_mark); k1++) { if (sa_mark[k1]) { sa_value[k1] = (((1L << k) & counter) != 0); k++; } } - for (k1 = 0; k1 < n_lhs[i1]; k1 += 2) { - if (lhs[i1][k1].kind == VARIABLE && (lhs[i1][k1].token.variable & VAR_MASK) == SIGN) { - if (sa_value[(lhs[i1][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK]) { - lhs[i1][k1].kind = CONSTANT; - lhs[i1][k1].token.constant = -1.0; + for (k1 = 0; k1 < mathomatic->n_lhs[i1]; k1 += 2) { + if (mathomatic->lhs[i1][k1].kind == VARIABLE && (mathomatic->lhs[i1][k1].token.variable & VAR_MASK) == SIGN) { + if (sa_value[(mathomatic->lhs[i1][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK]) { + mathomatic->lhs[i1][k1].kind = CONSTANT; + mathomatic->lhs[i1][k1].token.constant = -1.0; } else { - lhs[i1][k1].kind = CONSTANT; - lhs[i1][k1].token.constant = 1.0; + mathomatic->lhs[i1][k1].kind = CONSTANT; + mathomatic->lhs[i1][k1].token.constant = 1.0; } } } - for (k1 = 0; k1 < n_rhs[i1]; k1 += 2) { - if (rhs[i1][k1].kind == VARIABLE && (rhs[i1][k1].token.variable & VAR_MASK) == SIGN) { - if (sa_value[(rhs[i1][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK]) { - rhs[i1][k1].kind = CONSTANT; - rhs[i1][k1].token.constant = -1.0; + for (k1 = 0; k1 < mathomatic->n_rhs[i1]; k1 += 2) { + if (mathomatic->rhs[i1][k1].kind == VARIABLE && (mathomatic->rhs[i1][k1].token.variable & VAR_MASK) == SIGN) { + if (sa_value[(mathomatic->rhs[i1][k1].token.variable >> VAR_SHIFT) & SUBSCRIPT_MASK]) { + mathomatic->rhs[i1][k1].kind = CONSTANT; + mathomatic->rhs[i1][k1].token.constant = -1.0; } else { - rhs[i1][k1].kind = CONSTANT; - rhs[i1][k1].token.constant = 1.0; + mathomatic->rhs[i1][k1].kind = CONSTANT; + mathomatic->rhs[i1][k1].token.constant = 1.0; } } } for (k1 = 0, k = false; k1 < ARR_CNT(sa_mark); k1++) { if (sa_mark[k1]) { if (k) { - fprintf(gfp, ", "); + fprintf(mathomatic->gfp, ", "); } else { - fprintf(gfp, _("Solution number %ld with "), counter + 1); + fprintf(mathomatic->gfp, _("Solution number %ld with "), counter + 1); } - list_var((long) SIGN + (((long) k1) << VAR_SHIFT), 0); - fprintf(gfp, "%s = ", var_str); + list_var(mathomatic, (long) SIGN + (((long) k1) << VAR_SHIFT), 0); + fprintf(mathomatic->gfp, "%s = ", mathomatic->var_str); if (sa_value[k1]) { - fprintf(gfp, "-1"); + fprintf(mathomatic->gfp, "-1"); } else { - fprintf(gfp, "1"); + fprintf(mathomatic->gfp, "1"); } k = true; } } if (k) - fprintf(gfp, ":\n"); - symb_flag = symb; + fprintf(mathomatic->gfp, ":\n"); + mathomatic->symb_flag = symb; if (quickest_flag) { - simp_equation(i1); + simp_equation(mathomatic, i1); } else { - simpa_repeat(i1, quick_flag, frac_flag); + simpa_repeat(mathomatic, i1, quick_flag, frac_flag); } - symb_flag = false; + mathomatic->symb_flag = false; for (k1 = 0; k1 < ARR_CNT(previous_solution_number); k1++) { if (previous_solution_number[k1]) { - if (compare_es(k1, i1) > 0) { - n_lhs[i1] = 0; - n_rhs[i1] = 0; - fprintf(gfp, _("is identical to solution number %ld.\n"), previous_solution_number[k1]); + if (compare_es(mathomatic, k1, i1) > 0) { + mathomatic->n_lhs[i1] = 0; + mathomatic->n_rhs[i1] = 0; + fprintf(mathomatic->gfp, _("is identical to solution number %ld.\n"), previous_solution_number[k1]); break; } } } - if (n_lhs[i1]) { - list_sub(i1); + if (mathomatic->n_lhs[i1]) { + list_sub(mathomatic, i1); previous_solution_number[i1] = counter + 1; } } @@ -4022,7 +3980,7 @@ char *cp; } if (total_number_of_solutions > 0) { number_simplified += total_number_of_solutions; - fprintf(gfp, _("%d unique solutions stored in equation spaces for this expression (#%d).\n"), total_number_of_solutions, i + 1); + fprintf(mathomatic->gfp, _("%d unique solutions stored in equation spaces for this expression (#%d).\n"), total_number_of_solutions, i + 1); } } } while (*cp); @@ -4033,8 +3991,7 @@ char *cp; * The factor command. */ int -factor_cmd(cp) -char *cp; +factor_cmd(MathoMatic* mathomatic, char *cp) { int first, last; int i1; @@ -4053,24 +4010,24 @@ char *cp; if (strcmp_tospace(cp, "number") == 0) { cp = skip_param(cp); } else if (strcmp_tospace(cp, "numbers") == 0) { - repeat_flag = true; + mathomatic->repeat_flag = true; cp = skip_param(cp); } else { if (strcmp_tospace(cp, "power") == 0) { power_flag = true; cp = skip_param(cp); } - valid_range = get_range(&cp, &first, &last); + valid_range = get_range(mathomatic, &cp, &first, &last); if (!valid_range) { #if LIBRARY /* be consistent */ return false; #else /* be helpful */ if (*cp == '-' || isdigit(*cp)) { - reset_error(); + reset_error(mathomatic); printf(_("Factoring integers on command-line instead:\n")); - point_flag = false; + mathomatic->point_flag = false; } else { - extra_characters(cp); + extra_characters(mathomatic, cp); return false; } #endif @@ -4078,7 +4035,7 @@ char *cp; } if (!valid_range) { #if LIBRARY - repeat_flag = false; + mathomatic->repeat_flag = false; #endif do { if (*cp == '\0') { @@ -4086,8 +4043,8 @@ char *cp; #if LIBRARY return false; #else - my_strlcpy(prompt_str, _("Enter integers to factor: "), sizeof(prompt_str)); - cp = get_string(buf, sizeof(buf)); + my_strlcpy(mathomatic->prompt_str, _("Enter integers to factor: "), sizeof(mathomatic->prompt_str)); + cp = get_string(mathomatic, buf, sizeof(buf)); if (cp == NULL) return false; cp_start = cp; @@ -4114,61 +4071,61 @@ char *cp; } } else { try_parsing: - input_column += (cp1 - cp_start); - cp = parse_expr(tes, &n_tes, cp1, false); + mathomatic->input_column += (cp1 - cp_start); + cp = parse_expr(mathomatic, mathomatic->tes, &mathomatic->n_tes, cp1, false); if (cp == NULL) goto retry; cp_start = cp; - if (n_tes <= 0) + if (mathomatic->n_tes <= 0) return rv; - calc_simp(tes, &n_tes); - if (n_tes != 1 || tes[0].kind != CONSTANT || !isfinite(tes[0].token.constant)) { - error(_("Integer expected.")); + calc_simp(mathomatic, mathomatic->tes, &mathomatic->n_tes); + if (mathomatic->n_tes != 1 || mathomatic->tes[0].kind != CONSTANT || !isfinite(mathomatic->tes[0].token.constant)) { + error(mathomatic, _("Integer expected.")); goto retry; } - ed = d = tes[0].token.constant; + ed = d = mathomatic->tes[0].token.constant; } } cp = skip_comma_space(cp); count_down = (ed < d); for (; count_down ? (d >= ed) : (d <= ed); count_down ? (d -= 1.0) : (d += 1.0)) { if (d == 0) { - fprintf(gfp, _("0 can be evenly divided by any number.\n")); + fprintf(mathomatic->gfp, _("0 can be evenly divided by any number.\n")); continue; } - if (!factor_one(d)) { - error(_("Number too large to factor or not an integer.")); + if (!factor_one(mathomatic, d)) { + error(mathomatic, _("Number too large to factor or not an integer.")); rv = false; break; } #if !SILENT - if (is_prime() && debug_level >= 0) { - fprintf(gfp, _("Prime number: ")); + if (is_prime(mathomatic) && mathomatic->debug_level >= 0) { + fprintf(mathomatic->gfp, _("Prime number: ")); } #endif - if (!display_unique()) + if (!display_unique(mathomatic)) rv = false; } } - } while (repeat_flag); + } while (mathomatic->repeat_flag); return rv; } if (power_flag) { - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; for (i1 = first; i1 <= last; i1++) { - if (n_lhs[i1]) { + if (mathomatic->n_lhs[i1]) { /* factor_power(lhs[i1], &n_lhs[i1]); */ do { - simp_loop(lhs[i1], &n_lhs[i1]); - } while (factor_power(lhs[i1], &n_lhs[i1])); - if (n_rhs[i1]) { + simp_loop(mathomatic, mathomatic->lhs[i1], &mathomatic->n_lhs[i1]); + } while (factor_power(mathomatic, mathomatic->lhs[i1], &mathomatic->n_lhs[i1])); + if (mathomatic->n_rhs[i1]) { /* factor_power(rhs[i1], &n_rhs[i1]); */ do { - simp_loop(rhs[i1], &n_rhs[i1]); - } while (factor_power(rhs[i1], &n_rhs[i1])); + simp_loop(mathomatic, mathomatic->rhs[i1], &mathomatic->n_rhs[i1]); + } while (factor_power(mathomatic, mathomatic->rhs[i1], &mathomatic->n_rhs[i1])); } - if (!return_result(i1)) + if (!return_result(mathomatic, i1)) return false; } } @@ -4176,41 +4133,41 @@ char *cp; do { v = 0; if (*cp) { - if ((cp = parse_var2(&v, cp)) == NULL) { + if ((cp = parse_var2(mathomatic, &v, cp)) == NULL) { return false; } } if (v) { found = false; for (i1 = first; i1 <= last; i1++) { - if (var_in_equation(i1, v)) { + if (var_in_equation(mathomatic, i1, v)) { found = true; break; } } if (!found) { - warning(_("Specified variable not found.")); + warning(mathomatic, _("Specified variable not found.")); } } for (i1 = first; i1 <= last; i1++) { #if 0 if (v == 0) { - if (n_lhs[i1]) { - simp_loop(lhs[i1], &n_lhs[i1]); - poly_factor(lhs[i1], &n_lhs[i1], true); - if (n_rhs[i1]) { - simp_loop(rhs[i1], &n_rhs[i1]); - poly_factor(rhs[i1], &n_rhs[i1], true); + if (mathomatic->n_lhs[i1]) { + simp_loop(mathomatic, mathomatic->lhs[i1], &mathomatic->n_lhs[i1]); + poly_factor(mathomatic, mathomatic->lhs[i1], &mathomatic->n_lhs[i1], true); + if (mathomatic->n_rhs[i1]) { + simp_loop(mathomatic, mathomatic->rhs[i1], &mathomatic->n_rhs[i1]); + poly_factor(mathomatic, mathomatic->rhs[i1], &mathomatic->n_rhs[i1], true); } } } #endif - simpv_equation(i1, v); + simpv_equation(mathomatic, i1, v); } } while (*cp); for (i1 = first; i1 <= last; i1++) { - if (n_lhs[i1]) { - if (!return_result(i1)) + if (mathomatic->n_lhs[i1]) { + if (!return_result(mathomatic, i1)) return false; } } @@ -4224,22 +4181,22 @@ char *cp; * Return the total number of terms. */ int -display_term_count(en) -int en; /* equation space number */ +display_term_count(MathoMatic* mathomatic, int en) +//int en; /* equation space number */ { int left_count = 0, right_count = 0; - if (empty_equation_space(en)) + if (empty_equation_space(mathomatic, en)) return 0; - left_count = level1_plus_count(lhs[en], n_lhs[en]) + 1; - if (n_rhs[en]) { - right_count = level1_plus_count(rhs[en], n_rhs[en]) + 1; - fprintf(gfp, "#%d: LHS consists of %d term%s; ", en + 1, left_count, (left_count == 1) ? "" : "s"); - fprintf(gfp, "RHS consists of %d term%s.\n", right_count, (right_count == 1) ? "" : "s"); + left_count = level1_plus_count(mathomatic, mathomatic->lhs[en], mathomatic->n_lhs[en]) + 1; + if (mathomatic->n_rhs[en]) { + right_count = level1_plus_count(mathomatic, mathomatic->rhs[en], mathomatic->n_rhs[en]) + 1; + fprintf(mathomatic->gfp, "#%d: LHS consists of %d term%s; ", en + 1, left_count, (left_count == 1) ? "" : "s"); + fprintf(mathomatic->gfp, "RHS consists of %d term%s.\n", right_count, (right_count == 1) ? "" : "s"); } else { - fprintf(gfp, "#%d: ", en + 1); + fprintf(mathomatic->gfp, "#%d: ", en + 1); } - fprintf(gfp, "Expression consists of a total of %d term%s.\n", left_count + right_count, ((left_count + right_count) == 1) ? "" : "s"); + fprintf(mathomatic->gfp, "Expression consists of a total of %d term%s.\n", left_count + right_count, ((left_count + right_count) == 1) ? "" : "s"); return(left_count + right_count); } @@ -4247,8 +4204,7 @@ int en; /* equation space number */ * The unfactor command. */ int -unfactor_cmd(cp) -char *cp; +unfactor_cmd(MathoMatic* mathomatic, char *cp) { int first, last; int k; @@ -4273,77 +4229,75 @@ char *cp; } break; } - if (!get_range_eol(&cp, &first, &last)) { + if (!get_range_eol(mathomatic, &cp, &first, &last)) { return false; } - partial_flag = !fraction_flag; + mathomatic->partial_flag = !fraction_flag; if (power_flag) { for (k = first; k <= last; k++) { - if (n_lhs[k] <= 0) + if (mathomatic->n_lhs[k] <= 0) continue; if (quick_flag) { - uf_power(lhs[k], &n_lhs[k]); + uf_power(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); } else { - uf_allpower(lhs[k], &n_lhs[k]); + uf_allpower(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); } - elim_loop(lhs[k], &n_lhs[k]); - if (n_rhs[k]) { + elim_loop(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); + if (mathomatic->n_rhs[k]) { if (quick_flag) { - uf_power(rhs[k], &n_rhs[k]); + uf_power(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); } else { - uf_allpower(rhs[k], &n_rhs[k]); + uf_allpower(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); } - elim_loop(rhs[k], &n_rhs[k]); + elim_loop(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); } - if (!return_result(k)) { - partial_flag = true; + if (!return_result(mathomatic, k)) { + mathomatic->partial_flag = true; return false; } if (count_flag) { - display_term_count(k); + display_term_count(mathomatic, k); } } } else { for (k = first; k <= last; k++) { - if (n_lhs[k] <= 0) + if (mathomatic->n_lhs[k] <= 0) continue; if (quick_flag) { - uf_tsimp(lhs[k], &n_lhs[k]); - if (n_rhs[k]) { - uf_tsimp(rhs[k], &n_rhs[k]); + uf_tsimp(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); + if (mathomatic->n_rhs[k]) { + uf_tsimp(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); } } else { - uf_simp(lhs[k], &n_lhs[k]); - if (n_rhs[k]) { - uf_simp(rhs[k], &n_rhs[k]); + uf_simp(mathomatic, mathomatic->lhs[k], &mathomatic->n_lhs[k]); + if (mathomatic->n_rhs[k]) { + uf_simp(mathomatic, mathomatic->rhs[k], &mathomatic->n_rhs[k]); } } - if (!return_result(k)) { - partial_flag = true; + if (!return_result(mathomatic, k)) { + mathomatic->partial_flag = true; return false; } if (count_flag) { - display_term_count(k); + display_term_count(mathomatic, k); } } } - partial_flag = true; + mathomatic->partial_flag = true; return true; } int -div_loc_find(expression, n) -token_type *expression; -int n; +div_loc_find(MathoMatic* mathomatic, token_type *expression, int n) { int k, div_loc; int level; - level = min_level(expression, n); + level = min_level(mathomatic, expression, n); for (k = 1, div_loc = -1; k < n; k += 2) { if (expression[k].level == level && expression[k].token.operatr == DIVIDE) { if (div_loc >= 0) { - error_bug("Expression not grouped."); + error_bug(mathomatic, "Expression not grouped."); } div_loc = k; } @@ -4355,8 +4309,7 @@ int n; * The fraction command. */ int -fraction_cmd(cp) -char *cp; +fraction_cmd(MathoMatic* mathomatic, char *cp) { int i, div_loc; int first, last; @@ -4373,45 +4326,45 @@ char *cp; } break; } - if (!get_range_eol(&cp, &first, &last)) { + if (!get_range_eol(mathomatic, &cp, &first, &last)) { return false; } - show_usage = false; + mathomatic->show_usage = false; for (i = first; i <= last; i++) { - if (n_lhs[i]) { + if (mathomatic->n_lhs[i]) { was_fraction = false; - simple_frac_repeat_side(lhs[i], &n_lhs[i]); - div_loc = div_loc_find(lhs[i], n_lhs[i]); + simple_frac_repeat_side(mathomatic, mathomatic->lhs[i], &mathomatic->n_lhs[i]); + div_loc = div_loc_find(mathomatic, mathomatic->lhs[i], mathomatic->n_lhs[i]); if (div_loc > 0) { was_fraction = true; if (num_flag && !den_flag) { - n_lhs[i] = div_loc; + mathomatic->n_lhs[i] = div_loc; } else if (den_flag && !num_flag) { - blt(&lhs[i][0], &lhs[i][div_loc+1], (n_lhs[i] - (div_loc + 1)) * sizeof(token_type)); - n_lhs[i] -= (div_loc + 1); + blt(&mathomatic->lhs[i][0], &mathomatic->lhs[i][div_loc+1], (mathomatic->n_lhs[i] - (div_loc + 1)) * sizeof(token_type)); + mathomatic->n_lhs[i] -= (div_loc + 1); } } - if (n_rhs[i]) { - simple_frac_repeat_side(rhs[i], &n_rhs[i]); - div_loc = div_loc_find(rhs[i], n_rhs[i]); + if (mathomatic->n_rhs[i]) { + simple_frac_repeat_side(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i]); + div_loc = div_loc_find(mathomatic, mathomatic->rhs[i], mathomatic->n_rhs[i]); if (div_loc > 0) { was_fraction = true; if (num_flag && !den_flag) { - n_rhs[i] = div_loc; + mathomatic->n_rhs[i] = div_loc; } else if (den_flag && !num_flag) { - blt(&rhs[i][0], &rhs[i][div_loc+1], (n_rhs[i] - (div_loc + 1)) * sizeof(token_type)); - n_rhs[i] -= (div_loc + 1); + blt(&mathomatic->rhs[i][0], &mathomatic->rhs[i][div_loc+1], (mathomatic->n_rhs[i] - (div_loc + 1)) * sizeof(token_type)); + mathomatic->n_rhs[i] -= (div_loc + 1); } } } if ((num_flag || den_flag) && !was_fraction) { - warning(_("Expression is not an algebraic fraction.")); + warning(mathomatic, _("Expression is not an algebraic fraction.")); if (den_flag) { - error(_("Could not extract denominator.")); + error(mathomatic, _("Could not extract denominator.")); return false; } } - if (!return_result(i)) + if (!return_result(mathomatic, i)) return false; } } @@ -4423,14 +4376,13 @@ char *cp; * The quit command. */ int -quit_cmd(cp) -char *cp; +quit_cmd(MathoMatic* mathomatic, char *cp) { int ev = 0; if (*cp) { ev = decstrtol(cp, &cp); - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; } exit_program(ev); @@ -4443,21 +4395,20 @@ char *cp; * The read command. */ int -read_cmd(cp) -char *cp; +read_cmd(MathoMatic* mathomatic, char *cp) { int rv; - if (security_level >= 3) { - show_usage = false; - error(_("Command disabled by security level.")); + if (mathomatic->security_level >= 3) { + mathomatic->show_usage = false; + error(mathomatic, _("Command disabled by security level.")); return false; } - if (!repeat_flag || *cp == '\0') { - return read_file(cp); + if (!mathomatic->repeat_flag || *cp == '\0') { + return read_file(mathomatic, cp); } do { - rv = read_file(cp); + rv = read_file(mathomatic, cp); } while (rv); return rv; } @@ -4468,8 +4419,7 @@ char *cp; * Return true if successful. */ int -read_file(cp) -char *cp; +read_file(MathoMatic* mathomatic, char *cp) { int rv; FILE *fp; @@ -4487,36 +4437,36 @@ char *cp; #else lister = "ls -C"; #endif - if (gfp && gfp_filename && gfp_filename[0]) { - if (snprintf(cl, sizeof(cl), "%s >%s%s", lister, gfp_append_flag ? ">" : "", gfp_filename) >= sizeof(cl)) { - error(_("Command-line too long.")); + if (mathomatic->gfp && mathomatic->gfp_filename && mathomatic->gfp_filename[0]) { + if (snprintf(cl, sizeof(cl), "%s >%s%s", lister, mathomatic->gfp_append_flag ? ">" : "", mathomatic->gfp_filename) >= sizeof(cl)) { + error(mathomatic, _("Command-line too long.")); return false; } - clean_up(); /* end any redirection */ + clean_up(mathomatic); /* end any redirection */ } else { if (snprintf(cl, sizeof(cl), "%s", lister) >= sizeof(cl)) { - error(_("Command-line too long.")); + error(mathomatic, _("Command-line too long.")); return false; } } #if !MINGW printf(_("Listing contents of ")); - output_current_directory(stdout); + output_current_directory(mathomatic, stdout); printf("\n"); #endif - if ((ev = shell_out(cl))) { - error(_("Error executing directory lister.")); + if ((ev = shell_out(mathomatic, cl))) { + error(mathomatic, _("Error executing directory lister.")); printf(_("Decimal exit value = %d, shell command-line = %s\n"), ev, cl); return false; } return true; #else - error(_("No file name specified.")); + error(mathomatic, _("No file name specified.")); return false; #endif } if (snprintf(buf, sizeof(buf), "%s.in", cp) >= sizeof(buf)) { - error(_("File name too long.")); + error(mathomatic, _("File name too long.")); return false; } fp = fopen(buf, "r"); @@ -4525,16 +4475,16 @@ char *cp; fp = fopen(buf, "r"); if (fp == NULL) { if (chdir(buf)) { - error(_("Can't open requested file to read or change directory to.")); + error(mathomatic, _("Can't open requested file to read or change directory to.")); return false; } else { printf(_("Current working directory changed to ")); - return output_current_directory(stdout); + return output_current_directory(mathomatic, stdout); } } } - rv = read_sub(fp, buf); - show_usage = false; + rv = read_sub(mathomatic, fp, buf); + mathomatic->show_usage = false; if (fclose(fp)) { perror(buf); rv = 1; @@ -4542,13 +4492,13 @@ char *cp; if (rv == 100) return(true); #if !SILENT - if (!quiet_mode) { + if (!mathomatic->quiet_mode) { if (rv) { - if (!demo_mode) { + if (!mathomatic->demo_mode) { printf(_("Reading of script file \"%s\" aborted due to failure return status\n"), buf); printf(_("of a command or expression parsing, or some other error listed above.\n")); } - } else if (debug_level >= 0) { + } else if (mathomatic->debug_level >= 0) { printf(_("Successfully finished reading script file \"%s\".\n"), buf); } } @@ -4562,9 +4512,9 @@ char *cp; * Return zero if no error, non-zero if read aborted. */ int -read_sub(fp, filename) -FILE *fp; /* open Mathomatic input file */ -char *filename; /* filename of fp */ +read_sub(MathoMatic* mathomatic, FILE *fp, char *filename) +//FILE *fp; /* open Mathomatic input file */ +//char *filename; /* filename of fp */ { int rv; jmp_buf save_save; @@ -4574,42 +4524,41 @@ char *filename; /* filename of fp */ if (fp == NULL) { return -1; } - blt(save_save, jmp_save, sizeof(jmp_save)); - if ((rv = setjmp(jmp_save)) != 0) { /* trap errors */ - clean_up(); + blt(save_save, mathomatic->jmp_save, sizeof(mathomatic->jmp_save)); + if ((rv = setjmp(mathomatic->jmp_save)) != 0) { /* trap errors */ + clean_up(mathomatic); if (rv == 14) { - error(_("Expression too large.")); + error(mathomatic, _("Expression too large.")); } - previous_return_value = 0; + mathomatic->previous_return_value = 0; } else { - while ((cp = fgets((char *) tlhs, n_tokens * sizeof(token_type), fp)) != NULL) { + while ((cp = fgets((char *) mathomatic->tlhs, mathomatic->n_tokens * sizeof(token_type), fp)) != NULL) { if (*cp) { something_there = true; } - if (!display_process(cp)) { - longjmp(jmp_save, 3); /* jump to the above error trap */ + if (!display_process(mathomatic, cp)) { + longjmp(mathomatic->jmp_save, 3); /* jump to the above error trap */ } } if (!something_there) { if (chdir(filename)) { - error(_("Empty file (no script to read).")); + error(mathomatic, _("Empty file (no script to read).")); rv = 1; } else { printf(_("Current directory changed to ")); - output_current_directory(stdout); + output_current_directory(mathomatic, stdout); rv = 100; } } } - blt(jmp_save, save_save, sizeof(jmp_save)); + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); return rv; } #endif #if SHELL_OUT static int -edit_sub(cp) -char *cp; +edit_sub(MathoMatic* mathomatic, char *cp) { char cl[MAX_CMD_LEN]; /* command-line */ char *cp1; @@ -4623,20 +4572,20 @@ char *cp; #else cp1 = "nano"; #endif - warning("EDITOR environment variable not set; using default text editor."); + warning(mathomatic, "EDITOR environment variable not set; using default text editor."); } if (snprintf(cl, sizeof(cl), "%s %s", cp1, cp) >= sizeof(cl)) { - error(_("Editor command-line too long.")); + error(mathomatic, _("Editor command-line too long.")); return false; } - if ((ev = shell_out(cl))) { - error("Error executing editor, check EDITOR environment variable."); + if ((ev = shell_out(mathomatic, cl))) { + error(mathomatic, "Error executing editor, check EDITOR environment variable."); printf(_("Decimal exit value = %d, shell command-line = %s\n"), ev, cl); return false; } - clear_all(); - if (!read_cmd(cp)) { - if (pause_cmd(_("Prepare to rerun the editor, or type \"quit\""))) { + clear_all(mathomatic); + if (!read_cmd(mathomatic, cp)) { + if (pause_cmd(mathomatic, _("Prepare to rerun the editor, or type \"quit\""))) { goto edit_again; } } @@ -4647,8 +4596,7 @@ char *cp; * The edit command. */ int -edit_cmd(cp) -char *cp; +edit_cmd(MathoMatic* mathomatic, char *cp) { FILE *fp; #if !MINGW @@ -4657,23 +4605,23 @@ char *cp; int rv; char tmp_file[MAX_CMD_LEN]; - show_usage = false; - if (security_level) { - if (security_level < 0) { - error(_("Running the editor is not possible with m4.")); + mathomatic->show_usage = false; + if (mathomatic->security_level) { + if (mathomatic->security_level < 0) { + error(mathomatic, _("Running the editor is not possible with m4.")); } else { - error(_("Command disabled by security level.")); + error(mathomatic, _("Command disabled by security level.")); } return false; } - clean_up(); /* end any redirection */ + clean_up(mathomatic); /* end any redirection */ if (*cp == '\0') { #if MINGW my_strlcpy(tmp_file, "mathomatic.tmp", sizeof(tmp_file)); fp = fopen(tmp_file, "w+"); if (fp == NULL) { perror(tmp_file); - error(_("Can't create temporary file.")); + error(mathomatic, _("Can't create temporary file.")); return false; } #else @@ -4681,35 +4629,35 @@ char *cp; fd = mkstemp(tmp_file); if (fd < 0 || (fp = fdopen(fd, "w+")) == NULL) { perror(tmp_file); - error(_("Can't create temporary file.")); + error(mathomatic, _("Can't create temporary file.")); return false; } #endif - gfp = fp; - high_prec = true; - list_cmd("all"); - high_prec = false; - gfp = default_out; + mathomatic->gfp = fp; + mathomatic->high_prec = true; + list_cmd(mathomatic, "all"); + mathomatic->high_prec = false; + mathomatic->gfp = mathomatic->default_out; rv = !ferror(fp); if (fclose(fp) || !rv) { rv = false; perror(tmp_file); - error(_("Writing temporary file failed.")); + error(mathomatic, _("Writing temporary file failed.")); } else { - rv = edit_sub(tmp_file); + rv = edit_sub(mathomatic, tmp_file); } if (unlink(tmp_file)) { perror(tmp_file); } return rv; } else { - show_usage = true; + mathomatic->show_usage = true; if (access(cp, R_OK | W_OK)) { perror(cp); - error(_("You can only edit existing/writable files or all equation spaces.")); + error(mathomatic, _("You can only edit existing/writable files or all equation spaces.")); return false; } - return edit_sub(cp); + return edit_sub(mathomatic, cp); } } #endif @@ -4719,21 +4667,20 @@ char *cp; * The save command. */ int -save_cmd(cp) -char *cp; +save_cmd(MathoMatic* mathomatic, char *cp) { FILE *fp; int rv, space_flag = false, error_flag; char *cp1; - if (security_level >= 2) { - show_usage = false; - error(_("Command disabled by security level.")); + if (mathomatic->security_level >= 2) { + mathomatic->show_usage = false; + error(mathomatic, _("Command disabled by security level.")); return false; } - clean_up(); /* end any redirection */ + clean_up(mathomatic); /* end any redirection */ if (*cp == '\0') { - error(_("No file name specified; nothing was saved.")); + error(mathomatic, _("No file name specified; nothing was saved.")); return false; } for (cp1 = cp; *cp1; cp1++) { @@ -4745,18 +4692,18 @@ char *cp; if (access(cp, F_OK) == 0) { if (access(cp, W_OK)) { perror(cp); - error(_("Specified save file is not writable; choose a different file name.")); + error(mathomatic, _("Specified save file is not writable; choose a different file name.")); return false; } - snprintf(prompt_str, sizeof(prompt_str), _("File \"%s\" exists, overwrite (y/n)? "), cp); - if (!get_yes_no()) { - error(_("File not overwritten; nothing was saved.")); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("File \"%s\" exists, overwrite (y/n)? "), cp); + if (!get_yes_no(mathomatic)) { + error(mathomatic, _("File not overwritten; nothing was saved.")); return false; } } else if (space_flag) { - snprintf(prompt_str, sizeof(prompt_str), _("File name \"%s\" contains space characters, create anyways (y/n)? "), cp); - if (!get_yes_no()) { - error(_("Save command aborted; nothing was saved.")); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("File name \"%s\" contains space characters, create anyways (y/n)? "), cp); + if (!get_yes_no(mathomatic)) { + error(mathomatic, _("Save command aborted; nothing was saved.")); return false; } } @@ -4764,14 +4711,14 @@ char *cp; fp = fopen(cp, "w"); if (fp == NULL) { perror(cp); - error(_("Cannot create specified save file; nothing was saved.")); + error(mathomatic, _("Cannot create specified save file; nothing was saved.")); return false; } - gfp = fp; - high_prec = true; - rv = list_cmd("all"); - high_prec = false; - gfp = default_out; + mathomatic->gfp = fp; + mathomatic->high_prec = true; + rv = list_cmd(mathomatic, "all"); + mathomatic->high_prec = false; + mathomatic->gfp = mathomatic->default_out; error_flag = ferror(fp); if (fclose(fp) || error_flag) { rv = false; @@ -4782,7 +4729,7 @@ char *cp; printf(_("All expressions saved in file \"%s\".\n"), cp); #endif } else { - error(_("Error encountered while saving expressions.")); + error(mathomatic, _("Error encountered while saving expressions.")); } return rv; } diff --git a/complex.c b/complex.c index 3b6e9e3..d3e4239 100644 --- a/complex.c +++ b/complex.c @@ -41,8 +41,7 @@ double x, y, *radiusp, *thetap; * The roots command. */ int -roots_cmd(cp) -char *cp; +roots_cmd(MathoMatic * mathomatic, char *cp) { #define MAX_ROOT 10000.0 /* Root limit needed because more roots become more inaccurate and take longer to check. */ @@ -56,40 +55,40 @@ char *cp; do_repeat: if (*cp == '\0') { - my_strlcpy(prompt_str, _("Enter root (positive integer): "), sizeof(prompt_str)); - if ((cp = get_string(buf, sizeof(buf))) == NULL) + my_strlcpy(mathomatic->prompt_str, _("Enter root (positive integer): "), sizeof(mathomatic->prompt_str)); + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) return false; } root = strtod(cp, &cp); if ((*cp && *cp != ',' && !isspace(*cp)) || !isfinite(root) || root < 0.0 || root > MAX_ROOT || fmod(root, 1.0) != 0.0) { - error(_("Root invalid or out of range.")); + error(mathomatic, _("Root invalid or out of range.")); printf(_("Root must be a positive integer less than or equal to %.0f.\n"), MAX_ROOT); return false; } cp = skip_comma_space(cp); if (*cp == '\0') { - my_strlcpy(prompt_str, _("Enter real part (X): "), sizeof(prompt_str)); - if ((cp = get_string(buf, sizeof(buf))) == NULL) + my_strlcpy(mathomatic->prompt_str, _("Enter real part (X): "), sizeof(mathomatic->prompt_str)); + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) return false; } c.re = strtod(cp, &cp); if (*cp && *cp != ',' && !isspace(*cp)) { - error(_("Number expected.")); + error(mathomatic, _("Number expected.")); return false; } cp = skip_comma_space(cp); if (*cp == '\0') { - my_strlcpy(prompt_str, _("Enter imaginary part (Y): "), sizeof(prompt_str)); - if ((cp = get_string(buf, sizeof(buf))) == NULL) + my_strlcpy(mathomatic->prompt_str, _("Enter imaginary part (Y): "), sizeof(mathomatic->prompt_str)); + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL) return false; } c.im = strtod(cp, &cp); if (*cp) { - error(_("Number expected.")); + error(mathomatic, _("Number expected.")); return false; } if (c.re == 0.0 && c.im == 0.0) { - return repeat_flag; + return mathomatic->repeat_flag; } /* convert to polar coordinates */ errno = 0; @@ -97,14 +96,14 @@ char *cp; if (root) { radius_root = pow(radius, 1.0 / root); } - check_err(); - fprintf(gfp, _("\nThe polar coordinates are:\n%.*g amplitude and\n%.*g radians (%.*g degrees).\n\n"), - precision, radius, precision, theta, precision, theta * 180.0 / M_PI); + check_err(mathomatic); + fprintf(mathomatic->gfp, _("\nThe polar coordinates are:\n%.*g amplitude and\n%.*g radians (%.*g degrees).\n\n"), + mathomatic->precision, radius, mathomatic->precision, theta, mathomatic->precision, theta * 180.0 / M_PI); if (root) { if (c.im == 0.0) { - fprintf(gfp, _("The %.12g roots of (%.12g)^(1/%.12g) are:\n\n"), root, c.re, root); + fprintf(mathomatic->gfp, _("The %.12g roots of (%.12g)^(1/%.12g) are:\n\n"), root, c.re, root); } else { - fprintf(gfp, _("The %.12g roots of (%.12g%+.12g*i)^(1/%.12g) are:\n\n"), root, c.re, c.im, root); + fprintf(mathomatic->gfp, _("The %.12g roots of (%.12g%+.12g*i)^(1/%.12g) are:\n\n"), root, c.re, c.im, root); } for (k = 0.0; k < root; k += 1.0) { /* add constants to theta and convert back to rectangular coordinates */ @@ -112,14 +111,14 @@ char *cp; c2.im = radius_root * sin((theta + 2.0 * k * M_PI) / root); complex_fixup(&c2); if (c2.re || c2.im == 0.0) { - fprintf(gfp, "%.12g ", c2.re); + fprintf(mathomatic->gfp, "%.12g ", c2.re); } if (c2.im) { - fprintf(gfp, "%+.12g*i", c2.im); + fprintf(mathomatic->gfp, "%+.12g*i", c2.im); } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); #if !SILENT - if (debug_level <= 0) { + if (mathomatic->debug_level <= 0) { continue; } check = c2; @@ -138,7 +137,7 @@ char *cp; #endif } } - if (repeat_flag) + if (mathomatic->repeat_flag) goto do_repeat; return true; } @@ -152,9 +151,9 @@ char *cp; * Return true if the equation side was modified. */ int -complex_root_simp(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +complex_root_simp(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { int i, j; int level; @@ -170,12 +169,12 @@ int *np; /* pointer to length of equation side */ for (j = i + 2; j < *np && equation[j].level >= level; j += 2) ; len = j - (i + 1); - if (!parse_complex(&equation[i+1], len, &p)) + if (!parse_complex(mathomatic, &equation[i+1], len, &p)) continue; for (j = i - 1; j >= 0 && equation[j].level >= level; j--) ; j++; - if (!parse_complex(&equation[j], i - j, &c)) + if (!parse_complex(mathomatic, &equation[j], i - j, &c)) continue; if (c.im == 0.0 && p.im == 0.0) continue; @@ -186,8 +185,8 @@ int *np; /* pointer to length of equation side */ printf("(%.14g+%.14gi)^(%.14g+%.14gi) = %.14g+%.14gi\n", c.re, c.im, p.re, p.im, r.re, r.im); #endif - if (*np + 5 - (i - j) > n_tokens) { - error_huge(); + if (*np + 5 - (i - j) > mathomatic->n_tokens) { + error_huge(mathomatic); } if ((j + 5) != i) { blt(&equation[j+5], &equation[i], (*np - i) * sizeof(token_type)); @@ -217,7 +216,7 @@ int *np; /* pointer to length of equation side */ goto start_over; } if (modified) { - debug_string(1, _("Complex number roots approximated.")); + debug_string(mathomatic, 1, _("Complex number roots approximated.")); } return modified; } @@ -228,15 +227,15 @@ int *np; /* pointer to length of equation side */ * Return true if anything was approximated. */ int -approximate_complex_roots(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +approximate_complex_roots(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { int rv = false; for (;;) { - elim_loop(equation, np); - if (!complex_root_simp(equation, np)) + elim_loop(mathomatic, equation, np); + if (!complex_root_simp(mathomatic, equation, np)) break; rv = true; } @@ -250,10 +249,10 @@ int *np; /* pointer to length of equation side */ * Return true if successful, with the floating point constant returned in *dp. */ int -get_constant(p1, n, dp) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ -double *dp; /* pointer to returned double */ +get_constant(MathoMatic* mathomatic, token_type *p1, int n, double *dp) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ +//double *dp; /* pointer to returned double */ { int i, j; int level; @@ -262,7 +261,7 @@ double *dp; /* pointer to returned double */ #if DEBUG if (n < 1 || (n & 1) != 1) { - error_bug("Call to get_constant() has invalid expression length."); + error_bug(mathomatic, "Call to get_constant() has invalid expression length."); } #endif if (n == 1) { @@ -280,30 +279,30 @@ double *dp; /* pointer to returned double */ } } else if (n >= 3) { level = p1[1].level; - if (!get_constant(p1, 1, &d1)) + if (!get_constant(mathomatic, p1, 1, &d1)) return false; for (i = 1; i < n; i = j) { if (p1[i].kind != OPERATOR || p1[i].level > level) { #if DEBUG - error_bug("Possible error in get_constant()."); + error_bug(mathomatic, "Possible error in get_constant()."); #endif return false; } level = p1[i].level; for (j = i + 2; j < n && p1[j].level > level; j += 2) ; - if (!get_constant(&p1[i+1], j - (i + 1), &d2)) + if (!get_constant(mathomatic, &p1[i+1], j - (i + 1), &d2)) return false; - prev_approx_flag = approximate_roots; - approximate_roots = true; - if (calc(NULL, &d1, p1[i].token.operatr, d2)) { - approximate_roots = prev_approx_flag; - if (p1[i].token.operatr == POWER && !domain_check) + prev_approx_flag = mathomatic->approximate_roots; + mathomatic->approximate_roots = true; + if (calc(mathomatic, NULL, &d1, p1[i].token.operatr, d2)) { + mathomatic->approximate_roots = prev_approx_flag; + if (p1[i].token.operatr == POWER && !mathomatic->domain_check) return false; - domain_check = false; + mathomatic->domain_check = false; } else { - approximate_roots = prev_approx_flag; - domain_check = false; + mathomatic->approximate_roots = prev_approx_flag; + mathomatic->domain_check = false; return false; } } @@ -323,10 +322,10 @@ double *dp; /* pointer to returned double */ * If successful, return true with complex number in *cp. */ int -parse_complex(p1, n, cp) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ -complexs *cp; /* pointer to returned complex number */ +parse_complex(MathoMatic* mathomatic, token_type *p1, int n, complexs *cp) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ +//complexs *cp; /* pointer to returned complex number */ { int j, k; int imag_cnt = 0, times_cnt = 0; @@ -336,14 +335,14 @@ complexs *cp; /* pointer to returned complex number */ if (!exp_is_numeric(p1, n)) { return false; } - if (get_constant(p1, n, &c.re)) { + if (get_constant(mathomatic, p1, n, &c.re)) { c.im = 0.0; *cp = c; return true; } if (found_var(p1, n, IMAGINARY) != 1) return false; - level = min_level(p1, n); + level = min_level(mathomatic, p1, n); c.re = 0.0; c.im = 1.0; j = n - 1; @@ -353,13 +352,13 @@ complexs *cp; /* pointer to returned complex number */ if (k > 0) { #if DEBUG if (p1[k].level != level || p1[k].kind != OPERATOR) { - error_bug("Error in parse_complex()."); + error_bug(mathomatic, "Error in parse_complex()."); } #endif switch (p1[k].token.operatr) { case MINUS: case PLUS: - if (get_constant(&p1[k+1], j - k, &tmp.re)) { + if (get_constant(mathomatic, &p1[k+1], j - k, &tmp.re)) { if (p1[k].token.operatr == MINUS) c.re -= tmp.re; else @@ -394,7 +393,7 @@ complexs *cp; /* pointer to returned complex number */ if (p1[k-1].level != level2) return false; if (!(p1[k+1].kind == VARIABLE && p1[k+1].token.variable == IMAGINARY)) { - if (get_constant(&p1[k+1], 1, &tmp.im)) { + if (get_constant(mathomatic, &p1[k+1], 1, &tmp.im)) { if (p1[k].token.operatr == DIVIDE) c.im /= tmp.im; else @@ -420,7 +419,7 @@ complexs *cp; /* pointer to returned complex number */ } } if (!(p1[k+1].kind == VARIABLE && p1[k+1].token.variable == IMAGINARY)) { - if (get_constant(&p1[k+1], 1, &tmp.im)) { + if (get_constant(mathomatic, &p1[k+1], 1, &tmp.im)) { c.im *= tmp.im; } else return false; @@ -434,7 +433,7 @@ complexs *cp; /* pointer to returned complex number */ case PLUS: if (level != level2) return false; - if (get_constant(p1, j, &tmp.re)) { + if (get_constant(mathomatic, p1, j, &tmp.re)) { c.re += tmp.re; goto done; } @@ -447,7 +446,7 @@ complexs *cp; /* pointer to returned complex number */ done: if (imag_cnt != 1) { #if DEBUG - error_bug("Imaginary count wrong in parse_complex()."); + error_bug(mathomatic, "Imaginary count wrong in parse_complex()."); #else return false; #endif diff --git a/diff.c b/diff.c index 1b1d261..9feee5e 100644 --- a/diff.c +++ b/diff.c @@ -24,7 +24,7 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "includes.h" -static int d_recurse(token_type *equation, int *np, int loc, int level, long v); +static int d_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, long v); /* * Compute the derivative of an equation side, with respect to variable "v", @@ -36,14 +36,14 @@ static int d_recurse(token_type *equation, int *np, int loc, int level, long v); * The result must be simplified by the caller. */ int -differentiate(equation, np, v) -token_type *equation; /* pointer to source and destination equation side */ -int *np; /* pointer to the length of the equation side */ -long v; /* differentiation variable */ +differentiate(MathoMatic* mathomatic, token_type *equation, int *np, long v) +//token_type *equation; /* pointer to source and destination equation side */ +//int *np; /* pointer to the length of the equation side */ +//long v; /* differentiation variable */ { int i; - organize(equation, np); + organize(mathomatic, equation, np); /* First put every times and divide on a level by itself. */ for (i = 1; i < *np; i += 2) { switch (equation[i].token.operatr) { @@ -52,7 +52,7 @@ long v; /* differentiation variable */ binary_parenthesize(equation, *np, i); } } - return d_recurse(equation, np, 0, 1, v); + return d_recurse(mathomatic, equation, np, 0, 1, v); } /* @@ -67,10 +67,7 @@ long v; /* differentiation variable */ * Return false if it is beyond this program's capabilities or an error was encountered. */ static int -d_recurse(equation, np, loc, level, v) -token_type *equation; -int *np, loc, level; -long v; +d_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, long v) { int i, j; int n; @@ -102,7 +99,7 @@ long v; break; default: /* Oops. More than one operator on the same level in this expression. */ - error_bug("Internal error in d_recurse(): differentiating with unparenthesized operators is not allowed."); + error_bug(mathomatic, "Internal error in d_recurse(): differentiating with unparenthesized operators is not allowed."); return false; } op = equation[endloc].token.operatr; @@ -144,7 +141,7 @@ long v; /* and "u" and "v" are expressions. */ for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].kind != OPERATOR) { - if (!d_recurse(equation, np, i, level + 1, v)) + if (!d_recurse(mathomatic, equation, np, i, level + 1, v)) return false; i++; for (; i < *np && equation[i].level > level; i += 2) @@ -157,8 +154,8 @@ long v; d_times: /* Differentiate TIMES operator. */ /* Use product rule: d(u*v) = u*d(v) + v*d(u). */ - if (*np + 1 + (endloc - loc) > n_tokens) { - error_huge(); + if (*np + 1 + (endloc - loc) > mathomatic->n_tokens) { + error_huge(mathomatic); } for (i = loc; i < endloc; i++) equation[i].level++; @@ -167,14 +164,14 @@ long v; equation[endloc].level = level; equation[endloc].kind = OPERATOR; equation[endloc].token.operatr = PLUS; - if (!d_recurse(equation, np, endloc + (oploc - loc) + 2, level + 2, v)) + if (!d_recurse(mathomatic, equation, np, endloc + (oploc - loc) + 2, level + 2, v)) return false; - return(d_recurse(equation, np, loc, level + 2, v)); + return(d_recurse(mathomatic, equation, np, loc, level + 2, v)); d_divide: /* Differentiate DIVIDE operator. */ /* Use quotient rule: d(u/v) = (v*d(u) - u*d(v))/v^2. */ - if (*np + 3 + (endloc - loc) + (endloc - oploc) > n_tokens) { - error_huge(); + if (*np + 3 + (endloc - loc) + (endloc - oploc) > mathomatic->n_tokens) { + error_huge(mathomatic); } for (i = loc; i < endloc; i++) equation[i].level += 2; @@ -200,9 +197,9 @@ long v; equation[j].level = level + 1; equation[j].kind = CONSTANT; equation[j].token.constant = 2.0; - if (!d_recurse(equation, np, endloc + (oploc - loc) + 2, level + 3, v)) + if (!d_recurse(mathomatic, equation, np, endloc + (oploc - loc) + 2, level + 3, v)) return false; - return(d_recurse(equation, np, loc, level + 3, v)); + return(d_recurse(mathomatic, equation, np, loc, level + 3, v)); d_power: /* Differentiate POWER operator. */ /* Since we don't have symbolic logarithms, do all we can without them. */ @@ -210,11 +207,11 @@ long v; if (equation[i].kind == VARIABLE && ((v == MATCH_ANY && (equation[i].token.variable & VAR_MASK) > SIGN) || equation[i].token.variable == v)) { - if (parse_complex(&equation[loc], oploc - loc, &c)) { + if (parse_complex(mathomatic, &equation[loc], oploc - loc, &c)) { c = complex_log(c); n = (endloc - oploc) + 6; - if (*np + n > n_tokens) { - error_huge(); + if (*np + n > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[endloc+n], &equation[endloc], (*np - endloc) * sizeof(token_type)); *np += n; @@ -251,61 +248,60 @@ long v; for (i = loc; i < endloc; i++) { equation[i].level++; } - return(d_recurse(equation, np, n, level + 1, v)); + return(d_recurse(mathomatic, equation, np, n, level + 1, v)); } return false; } } - blt(scratch, &equation[oploc+1], (endloc - (oploc + 1)) * sizeof(token_type)); + blt(mathomatic->scratch, &equation[oploc+1], (endloc - (oploc + 1)) * sizeof(token_type)); n = endloc - (oploc + 1); - scratch[n].level = level; - scratch[n].kind = OPERATOR; - scratch[n].token.operatr = TIMES; + mathomatic->scratch[n].level = level; + mathomatic->scratch[n].kind = OPERATOR; + mathomatic->scratch[n].token.operatr = TIMES; n++; - if (n + (endloc - loc) + 2 > n_tokens) { - error_huge(); + if (n + (endloc - loc) + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } - blt(&scratch[n], &equation[loc], (endloc - loc) * sizeof(token_type)); + blt(&mathomatic->scratch[n], &equation[loc], (endloc - loc) * sizeof(token_type)); i = n; n += oploc + 1 - loc; for (; i < n; i++) - scratch[i].level++; + mathomatic->scratch[i].level++; n += endloc - (oploc + 1); for (; i < n; i++) - scratch[i].level += 2; - scratch[n].level = level + 2; - scratch[n].kind = OPERATOR; - scratch[n].token.operatr = MINUS; + mathomatic->scratch[i].level += 2; + mathomatic->scratch[n].level = level + 2; + mathomatic->scratch[n].kind = OPERATOR; + mathomatic->scratch[n].token.operatr = MINUS; n++; - scratch[n].level = level + 2; - scratch[n].kind = CONSTANT; - scratch[n].token.constant = 1.0; + mathomatic->scratch[n].level = level + 2; + mathomatic->scratch[n].kind = CONSTANT; + mathomatic->scratch[n].token.constant = 1.0; n++; - if (n + (oploc - loc) + 1 > n_tokens) { - error_huge(); + if (n + (oploc - loc) + 1 > mathomatic->n_tokens) { + error_huge(mathomatic); } - scratch[n].level = level; - scratch[n].kind = OPERATOR; - scratch[n].token.operatr = TIMES; + mathomatic->scratch[n].level = level; + mathomatic->scratch[n].kind = OPERATOR; + mathomatic->scratch[n].token.operatr = TIMES; n++; j = n; - blt(&scratch[n], &equation[loc], (oploc - loc) * sizeof(token_type)); + blt(&mathomatic->scratch[n], &equation[loc], (oploc - loc) * sizeof(token_type)); n += oploc - loc; - if (*np - (endloc - loc) + n > n_tokens) { - error_huge(); + if (*np - (endloc - loc) + n > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[loc+n], &equation[endloc], (*np - endloc) * sizeof(token_type)); *np += loc + n - endloc; - blt(&equation[loc], scratch, n * sizeof(token_type)); - return(d_recurse(equation, np, loc + j, level + 1, v)); + blt(&equation[loc], mathomatic->scratch, n * sizeof(token_type)); + return(d_recurse(mathomatic, equation, np, loc + j, level + 1, v)); } /* * The derivative command. */ int -derivative_cmd(cp) -char *cp; +derivative_cmd(MathoMatic* mathomatic, char *cp) { int i, len; long v = 0; /* Mathomatic variable */ @@ -314,28 +310,28 @@ char *cp; int n1, *nps, *np; int simplify_flag = true, solved; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - solved = solved_equation(cur_equation); + solved = solved_equation(mathomatic, mathomatic->cur_equation); if (strcmp_tospace(cp, "nosimplify") == 0) { simplify_flag = false; cp = skip_param(cp); } - i = next_espace(); - if (n_rhs[cur_equation]) { + i = next_espace(mathomatic); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { if (!solved) { - warning(_("Not a solved equation. Only the RHS will be differentiated.")); + warning(mathomatic, _("Not a solved equation. Only the RHS will be differentiated.")); } - source = rhs[cur_equation]; - nps = &n_rhs[cur_equation]; - dest = rhs[i]; - np = &n_rhs[i]; + source = mathomatic->rhs[mathomatic->cur_equation]; + nps = &mathomatic->n_rhs[mathomatic->cur_equation]; + dest = mathomatic->rhs[i]; + np = &mathomatic->n_rhs[i]; } else { - source = lhs[cur_equation]; - nps = &n_lhs[cur_equation]; - dest = lhs[i]; - np = &n_lhs[i]; + source = mathomatic->lhs[mathomatic->cur_equation]; + nps = &mathomatic->n_lhs[mathomatic->cur_equation]; + dest = mathomatic->lhs[i]; + np = &mathomatic->n_lhs[i]; } /* parse the command line or prompt: */ if (*cp) { @@ -343,8 +339,8 @@ char *cp; cp = skip_param(cp); v = MATCH_ANY; } else { - if (isvarchar(*cp)) { - cp = parse_var2(&v, cp); + if (isvarchar(mathomatic, *cp)) { + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } @@ -354,44 +350,44 @@ char *cp; order = decstrtol(cp, &cp); } if (order <= 0) { - error(_("The order must be a positive integer.")); + error(mathomatic, _("The order must be a positive integer.")); return false; } - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; } if (no_vars(source, *nps, &v)) { - warning(_("Current expression contains no variables; the derivative will be zero.")); + warning(mathomatic, _("Current expression contains no variables; the derivative will be zero.")); } else { if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } if (v && v != MATCH_ANY && !found_var(source, *nps, v)) { - warning(_("Specified variable not found; the derivative will be zero.")); + warning(mathomatic, _("Specified variable not found; the derivative will be zero.")); } } if (v == 0) { - error(_("No differentiation variable specified.")); + error(mathomatic, _("No differentiation variable specified.")); return false; } #if !SILENT - list_var(v, 0); - if (n_rhs[cur_equation]) { - fprintf(gfp, _("Differentiating the RHS with respect to %s"), var_str); + list_var(mathomatic, v, 0); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + fprintf(mathomatic->gfp, _("Differentiating the RHS with respect to %s"), mathomatic->var_str); } else { - fprintf(gfp, _("Differentiating with respect to %s"), var_str); + fprintf(mathomatic->gfp, _("Differentiating with respect to %s"), mathomatic->var_str); } if (order != 1) { - fprintf(gfp, _(" %ld times"), order); + fprintf(mathomatic->gfp, _(" %ld times"), order); } if (simplify_flag) { - fprintf(gfp, _(" and simplifying")); + fprintf(mathomatic->gfp, _(" and simplifying")); } else { - fprintf(gfp, _(" and not simplifying")); + fprintf(mathomatic->gfp, _(" and not simplifying")); } - fprintf(gfp, "...\n"); + fprintf(mathomatic->gfp, "...\n"); #endif blt(dest, source, *nps * sizeof(token_type)); n1 = *nps; @@ -399,46 +395,45 @@ char *cp; for (l1 = 0; l1 < order; l1++) { if (order != 1) { if (n1 == 1 && dest[0].kind == CONSTANT && dest[0].token.constant == 0.0) { - fprintf(gfp, _("0 reached after %ld derivatives taken.\n"), l1); + fprintf(mathomatic->gfp, _("0 reached after %ld derivatives taken.\n"), l1); order = l1; break; } } - if (!differentiate(dest, &n1, v)) { - error(_("Differentiation failed.")); + if (!differentiate(mathomatic, dest, &n1, v)) { + error(mathomatic, _("Differentiation failed.")); return false; } if (simplify_flag) { - simpa_repeat_side(dest, &n1, true, false); + simpa_repeat_side(mathomatic, dest, &n1, true, false); } else { - elim_loop(dest, &n1); + elim_loop(mathomatic, dest, &n1); } } *np = n1; - if (n_rhs[cur_equation]) { - blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_lhs[i] = n_lhs[cur_equation]; - if (solved && isvarchar('\'')) { - len = list_var(lhs[i][0].token.variable, 0); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + blt(mathomatic->lhs[i], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_lhs[i] = mathomatic->n_lhs[mathomatic->cur_equation]; + if (solved && isvarchar(mathomatic, '\'')) { + len = list_var(mathomatic, mathomatic->lhs[i][0].token.variable, 0); for (l1 = 0; l1 < order && len < (MAX_VAR_LEN - 1); l1++) { - var_str[len++] = '\''; + mathomatic->var_str[len++] = '\''; } - var_str[len] = '\0'; + mathomatic->var_str[len] = '\0'; if (l1 == order) { - parse_var(&lhs[i][0].token.variable, var_str); + parse_var(mathomatic, &mathomatic->lhs[i][0].token.variable, mathomatic->var_str); } } } - cur_equation = i; - return return_result(cur_equation); + mathomatic->cur_equation = i; + return return_result(mathomatic, mathomatic->cur_equation); } /* * The extrema command. */ int -extrema_cmd(cp) -char *cp; +extrema_cmd(MathoMatic* mathomatic, char *cp) { int i; long v = 0; /* Mathomatic variable */ @@ -447,24 +442,24 @@ char *cp; token_type *source; int n; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - i = next_espace(); - if (n_rhs[cur_equation]) { - if (!solved_equation(cur_equation)) { - error(_("The current equation is not solved for a variable.")); + i = next_espace(mathomatic); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + if (!solved_equation(mathomatic, mathomatic->cur_equation)) { + error(mathomatic, _("The current equation is not solved for a variable.")); return false; } - source = rhs[cur_equation]; - n = n_rhs[cur_equation]; + source = mathomatic->rhs[mathomatic->cur_equation]; + n = mathomatic->n_rhs[mathomatic->cur_equation]; } else { - source = lhs[cur_equation]; - n = n_lhs[cur_equation]; + source = mathomatic->lhs[mathomatic->cur_equation]; + n = mathomatic->n_lhs[mathomatic->cur_equation]; } if (*cp) { - if (isvarchar(*cp)) { - cp = parse_var2(&v, cp); + if (isvarchar(mathomatic, *cp)) { + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } @@ -473,62 +468,61 @@ char *cp; order = decstrtol(cp, &cp); } if (order <= 0) { - error(_("The order must be a positive integer.")); + error(mathomatic, _("The order must be a positive integer.")); return false; } - if (extra_characters(cp)) + if (extra_characters(mathomatic, cp)) return false; } - show_usage = false; + mathomatic->show_usage = false; if (no_vars(source, n, &v)) { - error(_("Current expression contains no variables.")); + error(mathomatic, _("Current expression contains no variables.")); return false; } if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } if (!found_var(source, n, v)) { - error(_("Specified variable not found; the derivative would be zero.")); + error(mathomatic, _("Specified variable not found; the derivative would be zero.")); return false; } - blt(rhs[i], source, n * sizeof(token_type)); + blt(mathomatic->rhs[i], source, n * sizeof(token_type)); /* take derivatives with respect to the specified variable and simplify: */ for (l1 = 0; l1 < order; l1++) { - if (!differentiate(rhs[i], &n, v)) { - error(_("Differentiation failed.")); + if (!differentiate(mathomatic, mathomatic->rhs[i], &n, v)) { + error(mathomatic, _("Differentiation failed.")); return false; } - simpa_repeat_side(rhs[i], &n, true, false); + simpa_repeat_side(mathomatic, mathomatic->rhs[i], &n, true, false); } - if (!found_var(rhs[i], n, v)) { - error(_("There are no solutions.")); + if (!found_var(mathomatic->rhs[i], n, v)) { + error(mathomatic, _("There are no solutions.")); return false; } - n_rhs[i] = n; + mathomatic->n_rhs[i] = n; /* set equal to zero: */ - n_lhs[i] = 1; - lhs[i][0] = zero_token; - cur_equation = i; + mathomatic->n_lhs[i] = 1; + mathomatic->lhs[i][0] = mathomatic->zero_token; + mathomatic->cur_equation = i; /* lastly, solve for the specified variable and simplify: */ want.level = 1; want.kind = VARIABLE; want.token.variable = v; - if (solve_sub(&want, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) { - error(_("Solve failed.")); + if (solve_sub(mathomatic, &want, 1, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->rhs[i], &mathomatic->n_rhs[i]) <= 0) { + error(mathomatic, _("Solve failed.")); return false; } - simpa_repeat_side(rhs[i], &n_rhs[i], false, false); - return return_result(cur_equation); + simpa_repeat_side(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], false, false); + return return_result(mathomatic, mathomatic->cur_equation); } /* * The taylor command. */ int -taylor_cmd(cp) -char *cp; +taylor_cmd(MathoMatic* mathomatic, char *cp) { long v = 0; /* Mathomatic variable */ int i, j, k, i1; @@ -543,37 +537,37 @@ char *cp; int simplify_flag = true; cp_start = cp; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } if (strcmp_tospace(cp, "nosimplify") == 0) { simplify_flag = false; cp = skip_param(cp); } - i = next_espace(); - blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_lhs[i] = n_lhs[cur_equation]; - n_rhs[i] = 0; - our = alloc_next_espace(); - n_lhs[i] = 0; + i = next_espace(mathomatic); + blt(mathomatic->lhs[i], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_lhs[i] = mathomatic->n_lhs[mathomatic->cur_equation]; + mathomatic->n_rhs[i] = 0; + our = alloc_next_espace(mathomatic); + mathomatic->n_lhs[i] = 0; if (our < 0) { - error(_("Out of free equation spaces.")); - show_usage = false; + error(mathomatic, _("Out of free equation spaces.")); + mathomatic->show_usage = false; return false; } - if (n_rhs[cur_equation]) { - source = rhs[cur_equation]; - nps = &n_rhs[cur_equation]; - dest = rhs[i]; - np = &n_rhs[i]; + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + source = mathomatic->rhs[mathomatic->cur_equation]; + nps = &mathomatic->n_rhs[mathomatic->cur_equation]; + dest = mathomatic->rhs[i]; + np = &mathomatic->n_rhs[i]; } else { - source = lhs[cur_equation]; - nps = &n_lhs[cur_equation]; - dest = lhs[i]; - np = &n_lhs[i]; + source = mathomatic->lhs[mathomatic->cur_equation]; + nps = &mathomatic->n_lhs[mathomatic->cur_equation]; + dest = mathomatic->lhs[i]; + np = &mathomatic->n_lhs[i]; } - if (*cp && isvarchar(*cp)) { - cp = parse_var2(&v, cp); + if (*cp && isvarchar(mathomatic, *cp)) { + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } @@ -581,55 +575,55 @@ char *cp; if (*cp) { order = decstrtol(cp, &cp1); if (cp1 != skip_param(cp) || order < 0) { - error(_("Positive integer required for order.")); + error(mathomatic, _("Positive integer required for order.")); return false; } cp = cp1; } - show_usage = false; + mathomatic->show_usage = false; no_vars(source, *nps, &v); if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } if (!found_var(source, *nps, v)) { - warning(_("Specified differentiation variable not found; the derivative will be 0.")); + warning(mathomatic, _("Specified differentiation variable not found; the derivative will be 0.")); } - blt(rhs[our], source, *nps * sizeof(token_type)); + blt(mathomatic->rhs[our], source, *nps * sizeof(token_type)); our_nrhs = *nps; /* Simplify and take the first derivative: */ - uf_simp(rhs[our], &our_nrhs); - if (!differentiate(rhs[our], &our_nrhs, v)) { - error(_("Differentiation failed.")); + uf_simp(mathomatic, mathomatic->rhs[our], &our_nrhs); + if (!differentiate(mathomatic, mathomatic->rhs[our], &our_nrhs, v)) { + error(mathomatic, _("Differentiation failed.")); return false; } if (*cp) { - input_column += (cp - cp_start); - cp = parse_expr(lhs[our], &our_nlhs, cp, true); - if (cp == NULL || extra_characters(cp) || our_nlhs <= 0) { - show_usage = true; + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->lhs[our], &our_nlhs, cp, true); + if (cp == NULL || extra_characters(mathomatic, cp) || our_nlhs <= 0) { + mathomatic->show_usage = true; return false; } } else { #if !SILENT - list_var(v, 0); - printf(_("Taylor series expansion around %s = point.\n"), var_str); + list_var(mathomatic, v, 0); + printf(_("Taylor series expansion around %s = point.\n"), mathomatic->var_str); #endif - my_strlcpy(prompt_str, _("Enter point (an expression; usually 0): "), sizeof(prompt_str)); - if (!get_expr(lhs[our], &our_nlhs)) { + my_strlcpy(mathomatic->prompt_str, _("Enter point (an expression; usually 0): "), sizeof(mathomatic->prompt_str)); + if (!get_expr(mathomatic, mathomatic->lhs[our], &our_nlhs)) { return false; } } if (order < 0) { - my_strlcpy(prompt_str, _("Enter order (number of derivatives to take): "), sizeof(prompt_str)); - if ((cp1 = get_string(buf, sizeof(buf))) == NULL) + my_strlcpy(mathomatic->prompt_str, _("Enter order (number of derivatives to take): "), sizeof(mathomatic->prompt_str)); + if ((cp1 = get_string(mathomatic, buf, sizeof(buf))) == NULL) return false; if (*cp1) { cp = NULL; order = decstrtol(cp1, &cp); if (cp == NULL || *cp || order < 0) { - error(_("Positive integer required for order.")); + error(mathomatic, _("Positive integer required for order.")); return false; } } else { @@ -640,18 +634,18 @@ char *cp; } } #if !SILENT - fprintf(gfp, _("Taylor series")); - if (n_rhs[cur_equation]) { - fprintf(gfp, _(" of the RHS")); + fprintf(mathomatic->gfp, _("Taylor series")); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + fprintf(mathomatic->gfp, _(" of the RHS")); } - list_var(v, 0); - fprintf(gfp, _(" with respect to %s"), var_str); + list_var(mathomatic, v, 0); + fprintf(mathomatic->gfp, _(" with respect to %s"), mathomatic->var_str); if (simplify_flag) { - fprintf(gfp, _(", simplified")); + fprintf(mathomatic->gfp, _(", simplified")); } else { - fprintf(gfp, _(", not simplified")); + fprintf(mathomatic->gfp, _(", not simplified")); } - fprintf(gfp, "...\n"); + fprintf(mathomatic->gfp, "...\n"); #endif n = 0; i1 = 0; @@ -661,20 +655,20 @@ char *cp; for (k = i1; k < n1; k += 2) { if (dest[k].kind == VARIABLE && dest[k].token.variable == v) { level = dest[k].level; - if ((n1 + our_nlhs - 1) > n_tokens) - error_huge(); + if ((n1 + our_nlhs - 1) > mathomatic->n_tokens) + error_huge(mathomatic); blt(&dest[k+our_nlhs], &dest[k+1], (n1 - (k + 1)) * sizeof(token_type)); n1 += our_nlhs - 1; j = k; - blt(&dest[k], lhs[our], our_nlhs * sizeof(token_type)); + blt(&dest[k], mathomatic->lhs[our], our_nlhs * sizeof(token_type)); k += our_nlhs; for (; j < k; j++) dest[j].level += level; k--; } } - if ((n1 + our_nlhs + 7) > n_tokens) - error_huge(); + if ((n1 + our_nlhs + 7) > mathomatic->n_tokens) + error_huge(mathomatic); for (k = i1; k < n1; k++) dest[k].level++; ep = &dest[n1]; @@ -691,7 +685,7 @@ char *cp; ep->token.operatr = MINUS; n1 += 3; j = n1; - blt(&dest[n1], lhs[our], our_nlhs * sizeof(token_type)); + blt(&dest[n1], mathomatic->lhs[our], our_nlhs * sizeof(token_type)); n1 += our_nlhs; for (; j < n1; j++) dest[j].level += 3; @@ -717,56 +711,55 @@ char *cp; for (; i1 < n1; i1++) dest[i1].level++; if (simplify_flag) { - uf_simp(dest, &n1); + uf_simp(mathomatic, dest, &n1); } - side_debug(1, dest, n1); + side_debug(mathomatic, 1, dest, n1); if (exp_contains_infinity(dest, n1)) { - error(_("Result invalid because it contains infinity or NaN.")); + error(mathomatic, _("Result invalid because it contains infinity or NaN.")); return false; } if (n < order) { if (n > 0) { - if (!differentiate(rhs[our], &our_nrhs, v)) { - error(_("Differentiation failed.")); + if (!differentiate(mathomatic, mathomatic->rhs[our], &our_nrhs, v)) { + error(mathomatic, _("Differentiation failed.")); return false; } } /* symb_flag = symblify; */ - simpa_repeat_side(rhs[our], &our_nrhs, true, false /* was true */); + simpa_repeat_side(mathomatic, mathomatic->rhs[our], &our_nrhs, true, false /* was true */); /* symb_flag = false; */ - if (our_nrhs != 1 || rhs[our][0].kind != CONSTANT || rhs[our][0].token.constant != 0.0) { + if (our_nrhs != 1 || mathomatic->rhs[our][0].kind != CONSTANT || mathomatic->rhs[our][0].token.constant != 0.0) { i1 = n1; - if ((i1 + 1 + our_nrhs) > n_tokens) - error_huge(); + if ((i1 + 1 + our_nrhs) > mathomatic->n_tokens) + error_huge(mathomatic); for (j = 0; j < i1; j++) dest[j].level++; dest[i1].level = 1; dest[i1].kind = OPERATOR; dest[i1].token.operatr = PLUS; i1++; - blt(&dest[i1], rhs[our], our_nrhs * sizeof(token_type)); + blt(&dest[i1], mathomatic->rhs[our], our_nrhs * sizeof(token_type)); n1 = i1 + our_nrhs; n++; goto loop_again; } } #if !SILENT - fprintf(gfp, _("%ld non-zero derivative%s applied.\n"), n, (n == 1) ? "" : "s"); + fprintf(mathomatic->gfp, _("%ld non-zero derivative%s applied.\n"), n, (n == 1) ? "" : "s"); #endif - if (n_rhs[cur_equation]) { - n_lhs[i] = n_lhs[cur_equation]; + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + mathomatic->n_lhs[i] = mathomatic->n_lhs[mathomatic->cur_equation]; } *np = n1; - cur_equation = i; - return return_result(cur_equation); + mathomatic->cur_equation = i; + return return_result(mathomatic, mathomatic->cur_equation); } /* * The limit command. */ int -limit_cmd(cp) -char *cp; +limit_cmd(MathoMatic* mathomatic, char *cp) { int i; long v = 0; /* Mathomatic variable */ @@ -774,120 +767,120 @@ char *cp; char *cp_start; cp_start = cp; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - i = next_espace(); - if (n_rhs[cur_equation] == 0) { + i = next_espace(mathomatic); + if (mathomatic->n_rhs[mathomatic->cur_equation] == 0) { /* make expression into an equation: */ - blt(rhs[cur_equation], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_rhs[cur_equation] = n_lhs[cur_equation]; - n_lhs[cur_equation] = 1; - lhs[cur_equation][0].level = 1; - lhs[cur_equation][0].kind = VARIABLE; - parse_var(&lhs[cur_equation][0].token.variable, "limit"); - } - if (!solved_equation(cur_equation)) { - error(_("The current equation is not solved for a variable.")); + blt(mathomatic->rhs[mathomatic->cur_equation], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_rhs[mathomatic->cur_equation] = mathomatic->n_lhs[mathomatic->cur_equation]; + mathomatic->n_lhs[mathomatic->cur_equation] = 1; + mathomatic->lhs[mathomatic->cur_equation][0].level = 1; + mathomatic->lhs[mathomatic->cur_equation][0].kind = VARIABLE; + parse_var(mathomatic, &mathomatic->lhs[mathomatic->cur_equation][0].token.variable, "limit"); + } + if (!solved_equation(mathomatic, mathomatic->cur_equation)) { + error(mathomatic, _("The current equation is not solved for a variable.")); return false; } - solved_v = lhs[cur_equation][0]; + solved_v = mathomatic->lhs[mathomatic->cur_equation][0]; /* parse the command line or prompt: */ if (*cp) { - cp = parse_var2(&v, cp); + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } } - show_usage = false; - if (no_vars(rhs[cur_equation], n_rhs[cur_equation], &v)) { - warning(_("Current expression contains no variables; that is the answer.")); - return return_result(cur_equation); + mathomatic->show_usage = false; + if (no_vars(mathomatic->rhs[mathomatic->cur_equation], mathomatic->n_rhs[mathomatic->cur_equation], &v)) { + warning(mathomatic, _("Current expression contains no variables; that is the answer.")); + return return_result(mathomatic, mathomatic->cur_equation); } if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } - if (!found_var(rhs[cur_equation], n_rhs[cur_equation], v)) { - warning(_("Limit variable not found; answer is original expression.")); - return return_result(cur_equation); + if (!found_var(mathomatic->rhs[mathomatic->cur_equation], mathomatic->n_rhs[mathomatic->cur_equation], v)) { + warning(mathomatic, _("Limit variable not found; answer is original expression.")); + return return_result(mathomatic, mathomatic->cur_equation); } if (*cp == '=') { cp = skip_space(cp + 1); } if (*cp) { - input_column += (cp - cp_start); - cp = parse_expr(tes, &n_tes, cp, true); - if (cp == NULL || extra_characters(cp) || n_tes <= 0) { - show_usage = true; + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->tes, &mathomatic->n_tes, cp, true); + if (cp == NULL || extra_characters(mathomatic, cp) || mathomatic->n_tes <= 0) { + mathomatic->show_usage = true; return false; } } else { - list_var(v, 0); - snprintf(prompt_str, sizeof(prompt_str), _("as %s goes to: "), var_str); - if (!get_expr(tes, &n_tes)) { + list_var(mathomatic, v, 0); + snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), _("as %s goes to: "), mathomatic->var_str); + if (!get_expr(mathomatic, mathomatic->tes, &mathomatic->n_tes)) { return false; } } - simp_loop(tes, &n_tes); + simp_loop(mathomatic, mathomatic->tes, &mathomatic->n_tes); #if !SILENT - list_var(v, 0); - fprintf(gfp, _("Taking the limit as %s goes to "), var_str); - list_proc(tes, n_tes, false); - fprintf(gfp, "\n"); + list_var(mathomatic, v, 0); + fprintf(mathomatic->gfp, _("Taking the limit as %s goes to "), mathomatic->var_str); + list_proc(mathomatic, mathomatic->tes, mathomatic->n_tes, false); + fprintf(mathomatic->gfp, "\n"); #endif /* copy the current equation to a new equation space, then simplify and work on the copy: */ - copy_espace(cur_equation, i); - simpa_side(rhs[i], &n_rhs[i], false, false); + copy_espace(mathomatic, mathomatic->cur_equation, i); + simpa_side(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], false, false); /* see if the limit expression is positive infinity: */ - if (n_tes == 1 && tes[0].kind == CONSTANT && tes[0].token.constant == INFINITY) { + if (mathomatic->n_tes == 1 && mathomatic->tes[0].kind == CONSTANT && mathomatic->tes[0].token.constant == INFINITY) { /* To take the limit to positive infinity, */ /* replace infinity with zero and replace the limit variable with its reciprocal: */ - n_tes = 1; - tes[0] = zero_token; - tlhs[0] = one_token; - tlhs[1].level = 1; - tlhs[1].kind = OPERATOR; - tlhs[1].token.operatr = DIVIDE; - tlhs[2].level = 1; - tlhs[2].kind = VARIABLE; - tlhs[2].token.variable = v; - n_tlhs = 3; - subst_var_with_exp(rhs[i], &n_rhs[i], tlhs, n_tlhs, v); + mathomatic->n_tes = 1; + mathomatic->tes[0] = mathomatic->zero_token; + mathomatic->tlhs[0] = mathomatic->one_token; + mathomatic->tlhs[1].level = 1; + mathomatic->tlhs[1].kind = OPERATOR; + mathomatic->tlhs[1].token.operatr = DIVIDE; + mathomatic->tlhs[2].level = 1; + mathomatic->tlhs[2].kind = VARIABLE; + mathomatic->tlhs[2].token.variable = v; + mathomatic->n_tlhs = 3; + subst_var_with_exp(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], mathomatic->tlhs, mathomatic->n_tlhs, v); } /* General limit taking, solve for the limit variable: */ - debug_string(0, _("Solving...")); + debug_string(mathomatic, 0, _("Solving...")); want.level = 1; want.kind = VARIABLE; want.token.variable = v; - if (solve_sub(&want, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) { - error(_("Can't take the limit because solve failed.")); + if (solve_sub(mathomatic, &want, 1, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->rhs[i], &mathomatic->n_rhs[i]) <= 0) { + error(mathomatic, _("Can't take the limit because solve failed.")); return false; } /* replace the limit variable (LHS) with the limit expression: */ - blt(lhs[i], tes, n_tes * sizeof(token_type)); - n_lhs[i] = n_tes; + blt(mathomatic->lhs[i], mathomatic->tes, mathomatic->n_tes * sizeof(token_type)); + mathomatic->n_lhs[i] = mathomatic->n_tes; /* simplify the RHS: */ - symb_flag = symblify; - simpa_side(rhs[i], &n_rhs[i], false, false); - symb_flag = false; - if (exp_contains_nan(rhs[i], n_rhs[i])) { - error(_("Unable to take limit; result contains NaN (Not a Number).")); + mathomatic->symb_flag = mathomatic->symblify; + simpa_side(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], false, false); + mathomatic->symb_flag = false; + if (exp_contains_nan(mathomatic->rhs[i], mathomatic->n_rhs[i])) { + error(mathomatic, _("Unable to take limit; result contains NaN (Not a Number).")); return false; } /* solve back for the original variable: */ - if (solve_sub(&solved_v, 1, lhs[i], &n_lhs[i], rhs[i], &n_rhs[i]) <= 0) { - error(_("Can't take the limit because solve failed.")); + if (solve_sub(mathomatic, &solved_v, 1, mathomatic->lhs[i], &mathomatic->n_lhs[i], mathomatic->rhs[i], &mathomatic->n_rhs[i]) <= 0) { + error(mathomatic, _("Can't take the limit because solve failed.")); return false; } /* simplify before returning the result: */ - simpa_side(rhs[i], &n_rhs[i], false, false); - if (exp_contains_nan(rhs[i], n_rhs[i])) { - error(_("Unable to take limit; result contains NaN (Not a Number).")); + simpa_side(mathomatic, mathomatic->rhs[i], &mathomatic->n_rhs[i], false, false); + if (exp_contains_nan(mathomatic->rhs[i], mathomatic->n_rhs[i])) { + error(mathomatic, _("Unable to take limit; result contains NaN (Not a Number).")); return false; } - return return_result(i); + return return_result(mathomatic, i); } diff --git a/externs.h b/externs.h index f712488..17580a6 100644 --- a/externs.h +++ b/externs.h @@ -22,115 +22,156 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. */ -extern int n_tokens; -extern int n_equations; -extern int cur_equation; - -extern token_type *lhs[N_EQUATIONS]; -extern token_type *rhs[N_EQUATIONS]; - -extern int n_lhs[N_EQUATIONS]; -extern int n_rhs[N_EQUATIONS]; - -extern token_type *tlhs; -extern token_type *trhs; -extern token_type *tes; - -extern int n_tlhs; -extern int n_trhs; -extern int n_tes; - -extern token_type *scratch; - -extern token_type zero_token; -extern token_type one_token; - -extern int precision; -extern int case_sensitive_flag; -extern int factor_int_flag; -extern int display2d; -extern int fractions_display; -extern int approximate_roots; -extern int preserve_surds; -extern int rationalize_denominators; -extern int modulus_mode; -extern volatile int screen_columns; -extern volatile int screen_rows; -extern int finance_option; -extern int autosolve; -extern int autocalc; -extern int autodelete; -extern int autoselect; -extern char special_variable_characters[256]; -extern char plot_prefix[256]; -extern int factor_out_all_numeric_gcds; -extern int right_associative_power; -extern int power_starstar; -#if !SILENT -extern int debug_level; -#endif -extern int domain_check; -extern int color_flag; -extern int bold_colors; -extern int text_color; -extern int cur_color; -extern int html_flag; -extern int readline_enabled; -extern int partial_flag; -extern int symb_flag; -extern int symblify; -extern int high_prec; -extern int input_column; -extern int sign_cmp_flag; -extern double small_epsilon; -extern double epsilon; - -extern char *prog_name; -extern char *var_names[MAX_VAR_NAMES]; -extern char var_str[MAX_VAR_LEN+80]; -extern char prompt_str[MAX_PROMPT_LEN]; -#if !SECURE -extern char rc_file[MAX_CMD_LEN]; -#endif - -#if CYGWIN || MINGW -extern char *dir_path; -#endif -#if READLINE || EDITLINE -extern char *last_history_string; -#endif -#if READLINE -extern char *history_filename; -extern char history_filename_storage[MAX_CMD_LEN]; -#endif - -extern double unique[]; -extern int ucnt[]; -extern int uno; - -extern int previous_return_value; -extern sign_array_type sign_array; -extern FILE *default_out; -extern FILE *gfp; -extern char *gfp_filename; -extern int gfp_append_flag; -extern jmp_buf jmp_save; -extern int eoption; -extern int test_mode; -extern int demo_mode; -extern int quiet_mode; -extern int echo_input; -extern volatile int abort_flag; -extern int pull_number; -extern int security_level; -extern int repeat_flag; -extern int show_usage; -extern int point_flag; - -extern char *result_str; -extern int result_en; -extern const char *error_str; -extern const char *warning_str; - -extern char *vscreen[TEXT_ROWS]; -extern int current_columns; +#ifndef MATHO_EXTERNS_H +#define MATHO_EXTERNS_H + +typedef struct { + int n_tokens; /* maximum size of expressions, must only be set during startup */ + int n_equations; /* number of equation spaces allocated */ + int cur_equation; /* current equation space number (origin 0) */ + + /* expression storage pointers and current length variables (they go together) */ + token_type *lhs[N_EQUATIONS]; /* The Left Hand Sides of equation spaces */ + token_type *rhs[N_EQUATIONS]; /* The Right Hand Sides of equation spaces */ + + int n_lhs[N_EQUATIONS]; /* number of tokens in each lhs[], 0 means equation space is empty */ + int n_rhs[N_EQUATIONS]; /* number of tokens in each rhs[], 0 means not an equation */ + + token_type *tlhs; /* LHS during solve and temporary storage for expressions, quotient for poly_div() and smart_div(). */ + token_type *trhs; /* RHS during solve and temporary storage for expressions, remainder for poly_div() and smart_div(). */ + token_type *tes; /* Temporary Equation Side, used in commands, simpa_repeat_side(), simple_frac_repeat_side(), etc. */ + token_type *scratch; /* Very temporary storage for expressions, used only in low level routines for expression manipulation. */ + + int n_tlhs; /* number of tokens in tlhs */ + int n_trhs; /* number of tokens in trhs */ + int n_tes; /* number of tokens in tes */ + + + token_type zero_token; /* the universal constant 0.0 as an expression */ + token_type one_token; /* the universal constant 1.0 as an expression */ + + /* Set options with their initial values. */ + int precision; /* the display precision for doubles (number of digits) */ + int case_sensitive_flag; /* "set case_sensitive" flag */ + int factor_int_flag; /* factor integers when displaying expressions */ + int display2d; /* "set no display2d" to allow feeding the output to the input */ + int fractions_display; /* "set fraction" mode */ + int preserve_surds; /* set option to preserve roots like (2^.5) */ + int rationalize_denominators; /* try to rationalize denominators if true */ + int modulus_mode; /* true for mathematically correct modulus */ + volatile int screen_columns; /* screen width of the terminal; 0 = infinite */ + volatile int screen_rows; /* screen height of the terminal; 0 = infinite */ + int finance_option; /* for displaying dollars and cents */ + int autosolve; /* Allows solving by typing the variable name at the main prompt */ + int autocalc; /* Allows automatically calculating a numerical expression */ + int autodelete; /* Automatically deletes the previous calculated numerical expression when a new one is entered */ + int autoselect; /* Allows selecting equation spaces by typing the number */ + char special_variable_characters[256]; /* user defined characters for variable names, '\0' terminated */ + /* allow backslash in variable names for Latex compatibility */ + char plot_prefix[256]; /* prefix fed into gnuplot before the plot command */ + int factor_out_all_numeric_gcds; /* if true, factor out the GCD of rational coefficients */ + int right_associative_power; /* if true, evaluate power operators right to left */ + int power_starstar; /* if true, display power operator as "**", otherwise "^" */ + #if !SILENT + int debug_level; /* current debug level */ + #endif + int domain_check; + int color_flag; /* "set color" flag; 0 for no color, 1 for color, 2 for alternative color output mode */ + int bold_colors; /* bold_colors must be 0 or 1; 0 is dim */ + int text_color; /* Current normal text color, -1 for no color */ + int cur_color; /* memory of current color on the terminal */ + int html_flag; /* 1 for HTML mode on all standard output; 2 for HTML mode on all output, even redirected output */ + + /* double precision floating point epsilon constants for number comparisons for equivalency */ + double small_epsilon; /* for ignoring small, floating point round-off errors */ + double epsilon; /* for ignoring larger, accumulated round-off errors */ + + /* string variables */ + char *prog_name; /* name of this program */ + char *var_names[MAX_VAR_NAMES]; /* index for storage of variable name strings */ + char var_str[MAX_VAR_LEN+80]; /* temp storage for listing a variable name */ + char prompt_str[MAX_PROMPT_LEN]; /* temp storage for the prompt string */ + #if !SECURE + char rc_file[MAX_CMD_LEN]; /* pathname for the set options startup file */ + #endif + + #if CYGWIN || MINGW + char *dir_path; /* directory path to the executable */ + #endif + #if READLINE || EDITLINE + char *last_history_string; /* To prevent repeated, identical entries. Must not point to temporary string. */ + #endif + #if READLINE + char *history_filename; + char history_filename_storage[MAX_CMD_LEN]; + #endif + + /* The following are for integer factoring (filled by factor_one()): */ + double unique[64]; /* storage for the unique prime factors */ + int ucnt[64]; /* number of times the factor occurs */ + int uno; /* number of unique factors stored in unique[] */ + + /* misc. variables */ + int previous_return_value; /* Return value of last command entered. */ + sign_array_type sign_array; /* for keeping track of unique "sign" variables */ + FILE *default_out; /* file pointer where all gfp output goes by default */ + FILE *gfp; /* global output file pointer, for dynamically redirecting Mathomatic output */ + char *gfp_filename; /* filename associated with gfp if redirection is happening */ + int gfp_append_flag; /* true if appending to gfp, false if overwriting */ + jmp_buf jmp_save; /* for setjmp(3) to longjmp(3) to when an error happens deep within this code */ + int eoption; /* -e option flag */ + int test_mode; /* test mode flag (-t) */ + int demo_mode; /* demo mode flag (-d), don't load rc file or pause commands when true */ + int quiet_mode; /* quiet mode (-q, don't display prompts) */ + int echo_input; /* if true, echo input */ + int readline_enabled; /* set to false (-r) to disable readline */ + int partial_flag; /* normally true for partial unfactoring, false for "unfactor fraction" */ + int symb_flag; /* true during "simplify symbolic", which is not 100% mathematically correct */ + int symblify; /* if true, set symb_flag when helpful during solving, etc. */ + int high_prec; /* flag to output constants in higher precision (used when saving equations) */ + int input_column; /* current column number on the screen at the beginning of a parse */ + int sign_cmp_flag; /* true when all "sign" variables are to compare equal */ + int approximate_roots; /* true if in calculate command (force approximation of roots like (2^.5)) */ + volatile int abort_flag; /* if true, abort current operation; set by control-C interrupt */ + int pull_number; /* equation space number to pull when using the library */ + int security_level; /* current enforced security level for session, -1 for m4 Mathomatic */ + int repeat_flag; /* true if the command is to repeat its function or simplification, set by repeat command */ + int show_usage; /* show command usage info if a command fails and this flag is true */ + int point_flag; /* point to location of parse error if true */ + + /* library variables go here */ + char *result_str; /* returned result text string when using as library */ + int result_en; /* equation number of the returned result, if stored in an equation space */ + const char *error_str; /* last error string */ + const char *warning_str; /* last warning string */ + + /* Screen character array, for buffering page-at-a-time 2D string output: */ + char *vscreen[TEXT_ROWS]; + int current_columns; + +/* Global variables for the optimize command. */ + int opt_en[N_EQUATIONS+1]; + int last_temp_var; +/* The following data is used to factor integers: */ + double nn, sqrt_value; + + /* from solve.c */ + int repeat_count; + int prev_n1, prev_n2; + int last_int_var; + + /* from help.c */ + int last_autocalc_en; + + /* from integrate.c */ + int constant_var_number; /* makes unique numbers for the constant of integration */ + + /* from list.c */ + int cur_line; /* current line */ + int cur_pos; /* current position in the current line on the screen */ + +} MathoMatic; + +//extern MathoMatic *mathomatic; + +#endif /*MATHO_EXTERNS_H*/ diff --git a/factor.c b/factor.c index 58c32a1..7cd5890 100644 --- a/factor.c +++ b/factor.c @@ -26,13 +26,13 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #define ALWAYS_FACTOR_POWER 1 -static int fplus_recurse(token_type *equation, int *np, int loc, int level, long v, double d, int whole_flag, int div_only); -static int fplus_sub(token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level, long v, double d, int whole_flag, int div_only); -static int big_fplus(token_type *equation, int level, int diff_sign, int sop1, int op1, int op2, int i1, int i2, int b1, int b2, int ai, int aj, int i, int j, int e1, int e2); -static int ftimes_recurse(token_type *equation, int *np, int loc, int level); -static int ftimes_sub(token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level); -static int fpower_recurse(token_type *equation, int *np, int loc, int level); -static int fpower_sub(token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level); +static int fplus_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, long v, double d, int whole_flag, int div_only); +static int fplus_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level, long v, double d, int whole_flag, int div_only); +static int big_fplus(MathoMatic* mathomatic, token_type *equation, int level, int diff_sign, int sop1, int op1, int op2, int i1, int i2, int b1, int b2, int ai, int aj, int i, int j, int e1, int e2); +static int ftimes_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level); +static int ftimes_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level); +static int fpower_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level); +static int fpower_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level); /* * Factor divides only: (a/c + b/c) -> ((a+b)/c). @@ -40,13 +40,9 @@ static int fpower_sub(token_type *equation, int *np, int loc, int i1, int n1, in * Return true if equation side was modified. */ int -factor_divide(equation, np, v, d) -token_type *equation; -int *np; -long v; -double d; +factor_divide(MathoMatic* mathomatic, token_type *equation, int *np, long v, double d) { - return fplus_recurse(equation, np, 0, 1, v, d, false, true); + return fplus_recurse(mathomatic, equation, np, 0, 1, v, d, false, true); } /* @@ -56,11 +52,9 @@ double d; * Return true if equation side was modified. */ int -subtract_itself(equation, np) -token_type *equation; -int *np; +subtract_itself(MathoMatic* mathomatic, token_type *equation, int *np) { - return fplus_recurse(equation, np, 0, 1, 0L, 0.0, true, false); + return fplus_recurse(mathomatic, equation, np, 0, 1, 0L, 0.0, true, false); } /* @@ -84,13 +78,13 @@ int *np; * Return true if equation side was modified. */ int -factor_plus(equation, np, v, d) -token_type *equation; /* pointer to beginning of equation side */ -int *np; /* pointer to length of equation side */ -long v; /* Mathomatic variable */ -double d; /* control exponent */ +factor_plus(MathoMatic* mathomatic, token_type *equation, int *np, long v, double d) +//token_type *equation; /* pointer to beginning of equation side */ +//int *np; /* pointer to length of equation side */ +//long v; /* Mathomatic variable */ +//double d; /* control exponent */ { - return fplus_recurse(equation, np, 0, 1, v, d, false, false); + return fplus_recurse(mathomatic, equation, np, 0, 1, v, d, false, false); } /* @@ -100,13 +94,9 @@ double d; /* control exponent */ * Return true if equation side was modified. */ static int -fplus_recurse(equation, np, loc, level, v, d, whole_flag, div_only) -token_type *equation; -int *np, loc, level; -long v; -double d; -int whole_flag; /* factor only whole expressions multiplied by a constant */ -int div_only; /* factor only divides */ +fplus_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, long v, double d, int whole_flag, int div_only) +//int whole_flag; /* factor only whole expressions multiplied by a constant */ +//int div_only; /* factor only divides */ { int modified = false; int i, j, k; @@ -137,7 +127,7 @@ int div_only; /* factor only divides */ break; } len2 = k - j; - if (fplus_sub(equation, np, loc, i, len1, j, len2, level + 1, v, d, whole_flag, div_only)) { + if (fplus_sub(mathomatic, equation, np, loc, i, len1, j, len2, level + 1, v, d, whole_flag, div_only)) { modified = true; goto f_again; } @@ -151,7 +141,7 @@ int div_only; /* factor only divides */ return true; for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= fplus_recurse(equation, np, i, level + 1, v, d, whole_flag, div_only); + modified |= fplus_recurse(mathomatic, equation, np, i, level + 1, v, d, whole_flag, div_only); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -168,16 +158,12 @@ int div_only; /* factor only divides */ * Return true if a transformation was made. */ static int -fplus_sub(equation, np, loc, i1, n1, i2, n2, level, v, d, whole_flag, div_only) -token_type *equation; /* the entire expression */ -int *np; /* pointer to length of the entire expression */ -int loc; /* index into the beginning of this additive sub-expression */ -int i1, n1, i2, n2; -int level; -long v; -double d; -int whole_flag; /* factor only whole expressions multiplied by a constant */ -int div_only; /* factor only divides */ +fplus_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level, long v, double d, int whole_flag, int div_only) +//token_type *equation; /* the entire expression */ +//int *np; /* pointer to length of the entire expression */ +//int loc; /* index into the beginning of this additive sub-expression */ +//int whole_flag; /* factor only whole expressions multiplied by a constant */ +//int div_only; /* factor only divides */ { int e1, e2; int op1, op2; @@ -315,7 +301,7 @@ int div_only; /* factor only divides */ save_k2 = equation[b2].token.constant; equation[b2].token.constant = 1.0; } - same_flag = se_compare(&equation[b1], i - b1, &equation[b2], j - b2, &diff_sign); + same_flag = se_compare(mathomatic, &equation[b1], i - b1, &equation[b2], j - b2, &diff_sign); if (flag1) { equation[i1].token.constant = save_k1; b1 += 2; @@ -329,131 +315,131 @@ int div_only; /* factor only divides */ power = 1.0; /* not doing Horner factoring */ horner_factor: if (sop1 == DIVIDE) { - scratch[0].level = level; - scratch[0].kind = CONSTANT; - scratch[0].token.constant = 1.0; - scratch[1].level = level; - scratch[1].kind = OPERATOR; - scratch[1].token.operatr = DIVIDE; + mathomatic->scratch[0].level = level; + mathomatic->scratch[0].kind = CONSTANT; + mathomatic->scratch[0].token.constant = 1.0; + mathomatic->scratch[1].level = level; + mathomatic->scratch[1].kind = OPERATOR; + mathomatic->scratch[1].token.operatr = DIVIDE; len = 2; } else { len = 0; } k = len; - blt(&scratch[len], &equation[b1], (ai - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (ai - b1) * sizeof(token_type)); len += ai - b1; if (power != 1.0) { for (; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = POWER; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = POWER; len++; - scratch[len].level = level + 1; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = power; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = power; len++; if (always_positive(power)) diff_sign = false; } else if (b1 == i1 && ai == e1) { for (; k < len; k++) - scratch[k].level++; + mathomatic->scratch[k].level++; } - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; k = len; - blt(&scratch[len], &equation[i1], (b1 - i1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i1], (b1 - i1) * sizeof(token_type)); len += b1 - i1; if (ai != i) { l = len; m = len + ai - b1; - blt(&scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); len += i - b1; if (b1 == i1 && i == e1) { for (; l < len; l++) - scratch[l].level++; + mathomatic->scratch[l].level++; } l = m; m++; for (; m < len; m++) - scratch[m].level++; - scratch[len].level = scratch[l].level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = MINUS; + mathomatic->scratch[m].level++; + mathomatic->scratch[len].level = mathomatic->scratch[l].level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = MINUS; len++; - scratch[len].level = scratch[l].level + 1; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = power; + mathomatic->scratch[len].level = mathomatic->scratch[l].level + 1; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = power; len++; - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; } - scratch[len].level = level; - scratch[len].kind = CONSTANT; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = CONSTANT; if (op1 == MINUS) { - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].token.constant = -1.0; } else { - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].token.constant = 1.0; } len++; - blt(&scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); len += e1 - i; for (; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level + 1; - scratch[len].kind = OPERATOR; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = OPERATOR; diff_sign ^= (op2 == MINUS); if (diff_sign) { - scratch[len].token.operatr = MINUS; + mathomatic->scratch[len].token.operatr = MINUS; } else { - scratch[len].token.operatr = PLUS; + mathomatic->scratch[len].token.operatr = PLUS; } len++; k = len; if (aj != j) { - if (len + n2 + 2 > n_tokens) { - error_huge(); + if (len + n2 + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } } else { - if (len + (b2 - i2) + (e2 - j) + 1 > n_tokens) { - error_huge(); + if (len + (b2 - i2) + (e2 - j) + 1 > mathomatic->n_tokens) { + error_huge(mathomatic); } } - blt(&scratch[len], &equation[i2], (b2 - i2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i2], (b2 - i2) * sizeof(token_type)); len += b2 - i2; if (aj != j) { m = len + aj - b2; - blt(&scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); len += j - b2; l = m; m++; for (; m < len; m++) - scratch[m].level++; - scratch[len].level = scratch[l].level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = MINUS; + mathomatic->scratch[m].level++; + mathomatic->scratch[len].level = mathomatic->scratch[l].level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = MINUS; len++; - scratch[len].level = scratch[l].level + 1; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = power; + mathomatic->scratch[len].level = mathomatic->scratch[l].level + 1; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = power; len++; } else { - scratch[len].level = level; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = 1.0; len++; } - blt(&scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); len += e2 - j; for (; k < len; k++) - scratch[k].level += 2; + mathomatic->scratch[k].level += 2; end_mess: - if (*np + len - n1 - (n2 + 1) > n_tokens) { - error_huge(); + if (*np + len - n1 - (n2 + 1) > mathomatic->n_tokens) { + error_huge(mathomatic); } if (op1 == MINUS) { equation[i1-1].token.operatr = PLUS; @@ -462,7 +448,7 @@ int div_only; /* factor only divides */ *np -= n2 + 1; blt(&equation[i1+len], &equation[e1], (*np - e1) * sizeof(token_type)); *np += len - n1; - blt(&equation[i1], scratch, len * sizeof(token_type)); + blt(&equation[i1], mathomatic->scratch, len * sizeof(token_type)); return true; } if (whole_flag) @@ -517,7 +503,7 @@ int div_only; /* factor only divides */ goto f_inner; if (d == 1.0 && (save_d1 < 0.0 || save_d2 < 0.0)) goto f_inner; - if (se_compare(&equation[b1], ai - b1, &equation[b2], aj - b2, &diff_sign)) { + if (se_compare(mathomatic, &equation[b1], ai - b1, &equation[b2], aj - b2, &diff_sign)) { if (save_d1 > 0.0 || save_d2 > 0.0) { if (save_d1 < 0.0) { power = save_d2; @@ -563,10 +549,10 @@ int div_only; /* factor only divides */ } } if (d1 <= d2) { - len = big_fplus(equation, level, diff_sign, sop1, + len = big_fplus(mathomatic, equation, level, diff_sign, sop1, op1, op2, i1, i2, b1, b2, ai, aj, i, j, e1, e2); } else { - len = big_fplus(equation, level, diff_sign, sop1, + len = big_fplus(mathomatic, equation, level, diff_sign, sop1, op2, op1, i2, i1, b2, b1, aj, ai, j, i, e2, e1); } goto end_mess; @@ -579,111 +565,101 @@ int div_only; /* factor only divides */ * with a common base and any exponent. */ static int -big_fplus(equation, level, diff_sign, sop1, op1, op2, i1, i2, b1, b2, ai, aj, i, j, e1, e2) -token_type *equation; -int level; -int diff_sign; -int sop1; -int op1, op2; -int i1, i2; -int b1, b2; -int ai, aj; -int i, j; -int e1, e2; +big_fplus(MathoMatic* mathomatic, token_type *equation, int level, int diff_sign, int sop1, int op1, int op2, int i1, int i2, int b1, int b2, int ai, int aj, int i, int j, int e1, int e2) { int k, l, m, n, o; int len; if (sop1 == DIVIDE) { - scratch[0].level = level; - scratch[0].kind = CONSTANT; - scratch[0].token.constant = 1.0; - scratch[1].level = level; - scratch[1].kind = OPERATOR; - scratch[1].token.operatr = DIVIDE; + mathomatic->scratch[0].level = level; + mathomatic->scratch[0].kind = CONSTANT; + mathomatic->scratch[0].token.constant = 1.0; + mathomatic->scratch[1].level = level; + mathomatic->scratch[1].kind = OPERATOR; + mathomatic->scratch[1].token.operatr = DIVIDE; len = 2; } else { len = 0; } k = len; o = len + ai - b1; - blt(&scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); len += i - b1; if (b1 == i1 && i == e1) { for (; k < len; k++) - scratch[k].level++; + mathomatic->scratch[k].level++; } - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; k = len; - blt(&scratch[len], &equation[i1], (b1 - i1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i1], (b1 - i1) * sizeof(token_type)); len += b1 - i1; - scratch[len].level = level; - scratch[len].kind = CONSTANT; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = CONSTANT; if (op1 == MINUS) { - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].token.constant = -1.0; } else { - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].token.constant = 1.0; } len++; - blt(&scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); len += e1 - i; for (; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = op2; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = op2; len++; k = len; - blt(&scratch[len], &equation[i2], (b2 - i2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i2], (b2 - i2) * sizeof(token_type)); len += b2 - i2; - if (len + (e2 - b2) + 2 * (i - ai) + 2 > n_tokens) { - error_huge(); + if (len + (e2 - b2) + 2 * (i - ai) + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } n = len; m = len + aj - b2; - blt(&scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); len += j - b2; l = m; m++; for (; m < len; m++) - scratch[m].level++; + mathomatic->scratch[m].level++; if (diff_sign && b2 == i2 && j == e2) { for (; n < len; n++) - scratch[n].level++; + mathomatic->scratch[n].level++; } - scratch[len].level = scratch[l].level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = MINUS; + mathomatic->scratch[len].level = mathomatic->scratch[l].level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = MINUS; len++; m = len; - blt(&scratch[len], &equation[ai+1], (i - (ai + 1)) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[ai+1], (i - (ai + 1)) * sizeof(token_type)); len += i - (ai + 1); - n = min_level(&equation[ai+1], i - (ai + 1)); - n = scratch[l].level + 2 - n; + n = min_level(mathomatic, &equation[ai+1], i - (ai + 1)); + n = mathomatic->scratch[l].level + 2 - n; for (; m < len; m++) - scratch[m].level += n; + mathomatic->scratch[m].level += n; if (diff_sign) { - scratch[len].level = level; - scratch[len].kind = OPERATOR; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; if (sop1 == DIVIDE) - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].token.operatr = TIMES; else - scratch[len].token.operatr = DIVIDE; + mathomatic->scratch[len].token.operatr = DIVIDE; len++; - scratch[len].level = level + 1; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = -1.0; len++; - blt(&scratch[len], &scratch[o], (i - ai) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &mathomatic->scratch[o], (i - ai) * sizeof(token_type)); len += i - ai; } - blt(&scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); len += e2 - j; for (; k < len; k++) - scratch[k].level += 2; + mathomatic->scratch[k].level += 2; return len; } @@ -693,17 +669,13 @@ int e1, e2; * Return true if equation side was modified. */ int -factor_times(equation, np) -token_type *equation; -int *np; +factor_times(MathoMatic* mathomatic, token_type *equation, int *np) { - return ftimes_recurse(equation, np, 0, 1); + return ftimes_recurse(mathomatic, equation, np, 0, 1); } static int -ftimes_recurse(equation, np, loc, level) -token_type *equation; -int *np, loc, level; +ftimes_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level) { int modified = false; int i, j, k; @@ -734,7 +706,7 @@ int *np, loc, level; break; } len2 = k - j; - if (ftimes_sub(equation, np, loc, i, len1, j, len2, level + 1)) { + if (ftimes_sub(mathomatic, equation, np, loc, i, len1, j, len2, level + 1)) { modified = true; goto f_again; } @@ -748,7 +720,7 @@ int *np, loc, level; return true; for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= ftimes_recurse(equation, np, i, level + 1); + modified |= ftimes_recurse(mathomatic, equation, np, i, level + 1); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -760,9 +732,7 @@ int *np, loc, level; } static int -ftimes_sub(equation, np, loc, i1, n1, i2, n2, level) -token_type *equation; -int *np, loc, i1, n1, i2, n2, level; +ftimes_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level) { int e1, e2; int op1, op2; @@ -789,7 +759,7 @@ int *np, loc, i1, n1, i2, n2, level; } #endif both_divide = (op1 == DIVIDE && op2 == DIVIDE); - if (se_compare(&equation[i1], n1, &equation[i2], n2, &diff_sign)) { + if (se_compare(mathomatic, &equation[i1], n1, &equation[i2], n2, &diff_sign)) { i = e1; j = e2; goto common_base; @@ -807,15 +777,15 @@ int *np, loc, i1, n1, i2, n2, level; if (i >= e1 && j >= e2) { return false; } - if (se_compare(&equation[i1], i - i1, &equation[i2], j - i2, &diff_sign)) { + if (se_compare(mathomatic, &equation[i1], i - i1, &equation[i2], j - i2, &diff_sign)) { goto common_base; } if (i < e1 && j < e2) { - if (se_compare(&equation[i1], n1, &equation[i2], j - i2, &diff_sign)) { + if (se_compare(mathomatic, &equation[i1], n1, &equation[i2], j - i2, &diff_sign)) { i = e1; goto common_base; } - if (se_compare(&equation[i1], i - i1, &equation[i2], n2, &diff_sign)) { + if (se_compare(mathomatic, &equation[i1], i - i1, &equation[i2], n2, &diff_sign)) { j = e2; goto common_base; } @@ -833,8 +803,8 @@ int *np, loc, i1, n1, i2, n2, level; if (j - i2 == 1 && equation[i2].kind == CONSTANT) return false; len2 = 2 + e2 - j; - if (*np + len2 + len > n_tokens) { - error_huge(); + if (*np + len2 + len > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[e2+len2], &equation[e2], (*np - e2) * sizeof(token_type)); *np += len2; @@ -846,8 +816,8 @@ int *np, loc, i1, n1, i2, n2, level; equation[e2+1].token.constant = -1.0; blt(&equation[e2+2], &equation[j], (e2 - j) * sizeof(token_type)); } - if (*np + len > n_tokens) { - error_huge(); + if (*np + len > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[e1+len], &equation[e1], (*np - e1) * sizeof(token_type)); *np += len; @@ -901,17 +871,13 @@ int *np, loc, i1, n1, i2, n2, level; * Return true if equation side was modified. */ int -factor_power(equation, np) -token_type *equation; -int *np; +factor_power(MathoMatic* mathomatic, token_type *equation, int *np) { - return fpower_recurse(equation, np, 0, 1); + return fpower_recurse(mathomatic, equation, np, 0, 1); } static int -fpower_recurse(equation, np, loc, level) -token_type *equation; -int *np, loc, level; +fpower_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level) { int modified = false; int i, j, k; @@ -942,7 +908,7 @@ int *np, loc, level; break; } len2 = k - j; - if (fpower_sub(equation, np, loc, i, len1, j, len2, level + 1)) { + if (fpower_sub(mathomatic, equation, np, loc, i, len1, j, len2, level + 1)) { modified = true; goto f_again; } @@ -955,7 +921,7 @@ int *np, loc, level; for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= fpower_recurse(equation, np, i, level + 1); + modified |= fpower_recurse(mathomatic, equation, np, i, level + 1); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -967,9 +933,7 @@ int *np, loc, level; } static int -fpower_sub(equation, np, loc, i1, n1, i2, n2, level) -token_type *equation; -int *np, loc, i1, n1, i2, n2, level; +fpower_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level) { int e1, e2; int op1, op2; @@ -1048,10 +1012,10 @@ int *np, loc, i1, n1, i2, n2, level; #endif start2 = j; #if 1 - if (se_compare(&equation[i+1], e1 - (i + 1), &one_token, 1, &diff_sign)) { + if (se_compare(mathomatic, &equation[i+1], e1 - (i + 1), &mathomatic->one_token, 1, &diff_sign)) { return false; } - if (se_compare(&equation[i+1], e1 - (i + 1), &equation[j+1], e2 - (j + 1), &diff_sign)) { + if (se_compare(mathomatic, &equation[i+1], e1 - (i + 1), &equation[j+1], e2 - (j + 1), &diff_sign)) { b1 = i + 1; b2 = j + 1; i = e1; @@ -1075,7 +1039,7 @@ int *np, loc, i1, n1, i2, n2, level; break; } } - if (se_compare(&equation[b1], i - b1, &one_token, 1, &diff_sign)) { + if (se_compare(mathomatic, &equation[b1], i - b1, &mathomatic->one_token, 1, &diff_sign)) { goto fp_outer; } j = start2; @@ -1097,66 +1061,66 @@ int *np, loc, i1, n1, i2, n2, level; } else if (equation[b2-1].token.operatr != pop1) { goto fp_inner; } - if (se_compare(&equation[b1], i - b1, &equation[b2], j - b2, &diff_sign)) { + if (se_compare(mathomatic, &equation[b1], i - b1, &equation[b2], j - b2, &diff_sign)) { common_exponent: if (op2 == DIVIDE) diff_sign = !diff_sign; all_divide = (op1 == DIVIDE && diff_sign); len = 0; - blt(&scratch[len], &equation[i1], (b1 - i1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i1], (b1 - i1) * sizeof(token_type)); len += b1 - i1; - scratch[len].level = level + 1; - scratch[len].kind = CONSTANT; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = CONSTANT; if (!all_divide && op1 == DIVIDE) { - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].token.constant = -1.0; } else { - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].token.constant = 1.0; } len++; - blt(&scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); len += e1 - i; for (k = 0; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; k = len; - blt(&scratch[len], &equation[i2], (b2 - i2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i2], (b2 - i2) * sizeof(token_type)); len += b2 - i2; - scratch[len].level = level + 1; - scratch[len].kind = CONSTANT; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = CONSTANT; if (!all_divide && diff_sign) { - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].token.constant = -1.0; } else { - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].token.constant = 1.0; } len++; - blt(&scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); len += e2 - j; for (; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = POWER; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = POWER; len++; if (pop1 == DIVIDE) { - scratch[len].level = level + 1; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = 1.0; len++; - scratch[len].level = level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = DIVIDE; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = DIVIDE; len++; } k = len; - blt(&scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); len += i - b1; for (; k < len; k++) - scratch[k].level++; - if (*np + len - n1 - (n2 + 1) > n_tokens) { - error_huge(); + mathomatic->scratch[k].level++; + if (*np + len - n1 - (n2 + 1) > mathomatic->n_tokens) { + error_huge(mathomatic); } if (!all_divide && op1 == DIVIDE) { equation[i1-1].token.operatr = TIMES; @@ -1165,7 +1129,7 @@ int *np, loc, i1, n1, i2, n2, level; *np -= n2 + 1; blt(&equation[i1+len], &equation[e1], (*np - e1) * sizeof(token_type)); *np += len - n1; - blt(&equation[i1], scratch, len * sizeof(token_type)); + blt(&equation[i1], mathomatic->scratch, len * sizeof(token_type)); return true; } goto fp_inner; diff --git a/factor_int.c b/factor_int.c index 48b772f..5b5f8e4 100644 --- a/factor_int.c +++ b/factor_int.c @@ -24,12 +24,11 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "includes.h" -static void try_factor(double arg); -static int fc_recurse(token_type *equation, int *np, int loc, int level, int level_code); +static void try_factor(MathoMatic* mathomatic, double arg); +static int fc_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int level_code); /* The following data is used to factor integers: */ -static double nn, sqrt_value; -static double skip_multiples[] = { /* Additive array that skips over multiples of 2, 3, 5, and 7. */ +static const double skip_multiples[] = { /* Additive array that skips over multiples of 2, 3, 5, and 7. */ 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, @@ -45,53 +44,52 @@ static double skip_multiples[] = { /* Additive array that skips over multiples o * Return true if successful. */ int -factor_one(value) -double value; +factor_one(MathoMatic* mathomatic, double value) { int i; double d; - uno = 0; - nn = value; - if (nn == 0.0 || !isfinite(nn)) { + mathomatic->uno = 0; + mathomatic->nn = value; + if (mathomatic->nn == 0.0 || !isfinite(mathomatic->nn)) { /* zero or not finite */ return false; } - if (fabs(nn) >= MAX_K_INTEGER) { + if (fabs(mathomatic->nn) >= MAX_K_INTEGER) { /* too large to factor */ return false; } - if (fmod(nn, 1.0) != 0.0) { + if (fmod(mathomatic->nn, 1.0) != 0.0) { /* not an integer */ return false; } - sqrt_value = 1.0 + sqrt(fabs(nn)); - try_factor(2.0); - try_factor(3.0); - try_factor(5.0); - try_factor(7.0); + mathomatic->sqrt_value = 1.0 + sqrt(fabs(mathomatic->nn)); + try_factor(mathomatic, 2.0); + try_factor(mathomatic, 3.0); + try_factor(mathomatic, 5.0); + try_factor(mathomatic, 7.0); d = 1.0; - while (d <= sqrt_value) { + while (d <= mathomatic->sqrt_value) { for (i = 0; i < ARR_CNT(skip_multiples); i++) { d += skip_multiples[i]; - try_factor(d); + try_factor(mathomatic, d); } } - if (nn != 1.0) { - if (nn < 0 && nn != -1.0) { - try_factor(fabs(nn)); + if (mathomatic->nn != 1.0) { + if (mathomatic->nn < 0 && mathomatic->nn != -1.0) { + try_factor(mathomatic, fabs(mathomatic->nn)); } - try_factor(nn); + try_factor(mathomatic, mathomatic->nn); } - if (uno == 0) { - try_factor(1.0); + if (mathomatic->uno == 0) { + try_factor(mathomatic, 1.0); } /* Do some floating point arithmetic self-checking. If the following fails, it is due to a floating point bug. */ - if (nn != 1.0) { - error_bug("Internal error factoring integers (final nn != 1.0)."); + if (mathomatic->nn != 1.0) { + error_bug(mathomatic, "Internal error factoring integers (final nn != 1.0)."); } - if (value != multiply_out_unique()) { - error_bug("Internal error factoring integers (result array value is incorrect)."); + if (value != multiply_out_unique(mathomatic)) { + error_bug(mathomatic, "Internal error factoring integers (result array value is incorrect)."); } return true; } @@ -101,31 +99,30 @@ double value; * If so, save it and remove it from "nn". */ static void -try_factor(arg) -double arg; +try_factor(MathoMatic* mathomatic, double arg) { #if DEBUG if (fmod(arg, 1.0) != 0.0) { - error_bug("Trying factor that is not an integer!"); + error_bug(mathomatic, "Trying factor that is not an integer!"); } #endif - while (fmod(nn, arg) == 0.0) { - if (uno > 0 && ucnt[uno-1] > 0 && unique[uno-1] == arg) { - ucnt[uno-1]++; + while (fmod(mathomatic->nn, arg) == 0.0) { + if (mathomatic->uno > 0 && mathomatic->ucnt[mathomatic->uno-1] > 0 && mathomatic->unique[mathomatic->uno-1] == arg) { + mathomatic->ucnt[mathomatic->uno-1]++; } else { - while (uno > 0 && ucnt[uno-1] <= 0) - uno--; - unique[uno] = arg; - ucnt[uno++] = 1; + while (mathomatic->uno > 0 && mathomatic->ucnt[mathomatic->uno-1] <= 0) + mathomatic->uno--; + mathomatic->unique[mathomatic->uno] = arg; + mathomatic->ucnt[mathomatic->uno++] = 1; } - nn /= arg; + mathomatic->nn /= arg; #if DEBUG - if (fmod(nn, 1.0) != 0.0) { - error_bug("nn turned non-integer in try_factor()."); + if (fmod(mathomatic->nn, 1.0) != 0.0) { + error_bug(mathomatic, "nn turned non-integer in try_factor()."); } #endif - sqrt_value = 1.0 + sqrt(fabs(nn)); - if (fabs(nn) <= 1.5 || fabs(arg) <= 1.5) + mathomatic->sqrt_value = 1.0 + sqrt(fabs(mathomatic->nn)); + if (fabs(mathomatic->nn) <= 1.5 || fabs(arg) <= 1.5) break; } } @@ -136,20 +133,20 @@ double arg; * Nothing is changed and the value is returned. */ double -multiply_out_unique(void) +multiply_out_unique(MathoMatic* mathomatic) { int i, j; double d; d = 1.0; - for (i = 0; i < uno; i++) { + for (i = 0; i < mathomatic->uno; i++) { #if DEBUG - if (ucnt[i] < 0) { - error_bug("Error in ucnt[] being negative."); + if (mathomatic->ucnt[i] < 0) { + error_bug(mathomatic, "Error in ucnt[] being negative."); } #endif - for (j = 0; j < ucnt[i]; j++) { - d *= unique[i]; + for (j = 0; j < mathomatic->ucnt[i]; j++) { + d *= mathomatic->unique[i]; } } return d; @@ -163,33 +160,33 @@ multiply_out_unique(void) * Return true if successful. */ int -display_unique(void) +display_unique(MathoMatic* mathomatic) { int i; double value; - if (uno <= 0) + if (mathomatic->uno <= 0) return false; - value = multiply_out_unique(); - fprintf(gfp, "%.0f = ", value); - for (i = 0; i < uno;) { - if (ucnt[i] > 0) { - fprintf(gfp, "%.0f", unique[i]); + value = multiply_out_unique(mathomatic); + fprintf(mathomatic->gfp, "%.0f = ", value); + for (i = 0; i < mathomatic->uno;) { + if (mathomatic->ucnt[i] > 0) { + fprintf(mathomatic->gfp, "%.0f", mathomatic->unique[i]); } else { i++; continue; } - if (ucnt[i] > 1) { - fprintf(gfp, "^%d", ucnt[i]); + if (mathomatic->ucnt[i] > 1) { + fprintf(mathomatic->gfp, "^%d", mathomatic->ucnt[i]); } do { i++; - } while (i < uno && ucnt[i] <= 0); - if (i < uno) { - fprintf(gfp, " * "); + } while (i < mathomatic->uno && mathomatic->ucnt[i] <= 0); + if (i < mathomatic->uno) { + fprintf(mathomatic->gfp, " * "); } } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); return true; } @@ -199,20 +196,20 @@ display_unique(void) * Return true if x is a prime number. */ int -is_prime(void) +is_prime(MathoMatic* mathomatic) { double value; - if (uno <= 0) { + if (mathomatic->uno <= 0) { #if DEBUG - error_bug("uno == 0 in is_prime()."); + error_bug(mathomatic, "uno == 0 in is_prime()."); #endif return false; } - value = multiply_out_unique(); + value = multiply_out_unique(mathomatic); if (value < 2.0) return false; - if (uno == 1 && ucnt[0] == 1) + if (mathomatic->uno == 1 && mathomatic->ucnt[0] == 1) return true; return false; } @@ -223,9 +220,7 @@ is_prime(void) * Return true if the equation side was modified. */ int -factor_int(equation, np) -token_type *equation; -int *np; +factor_int(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j; int xsize; @@ -233,24 +228,24 @@ int *np; int modified = false; for (i = 0; i < *np; i += 2) { - if (equation[i].kind == CONSTANT && factor_one(equation[i].token.constant) && uno > 0) { - if (uno == 1 && ucnt[0] <= 1) + if (equation[i].kind == CONSTANT && factor_one(mathomatic, equation[i].token.constant) && mathomatic->uno > 0) { + if (mathomatic->uno == 1 && mathomatic->ucnt[0] <= 1) continue; /* prime number */ level = equation[i].level; - if (uno > 1 && *np > 1) + if (mathomatic->uno > 1 && *np > 1) level++; xsize = -2; - for (j = 0; j < uno; j++) { - if (ucnt[j] > 1) + for (j = 0; j < mathomatic->uno; j++) { + if (mathomatic->ucnt[j] > 1) xsize += 4; else xsize += 2; } - if (*np + xsize > n_tokens) { - error_huge(); + if (*np + xsize > mathomatic->n_tokens) { + error_huge(mathomatic); } - for (j = 0; j < uno; j++) { - if (ucnt[j] > 1) + for (j = 0; j < mathomatic->uno; j++) { + if (mathomatic->ucnt[j] > 1) xsize = 4; else xsize = 2; @@ -269,8 +264,8 @@ int *np; } equation[i].kind = CONSTANT; equation[i].level = level; - equation[i].token.constant = unique[j]; - if (ucnt[j] > 1) { + equation[i].token.constant = mathomatic->unique[j]; + if (mathomatic->ucnt[j] > 1) { equation[i].level = level + 1; i++; equation[i].kind = OPERATOR; @@ -279,7 +274,7 @@ int *np; i++; equation[i].level = level + 1; equation[i].kind = CONSTANT; - equation[i].token.constant = ucnt[j]; + equation[i].token.constant = mathomatic->ucnt[j]; } } modified = true; @@ -294,16 +289,16 @@ int *np; * Return true if something was factored. */ int -factor_int_equation(n) -int n; /* equation space number */ +factor_int_equation(MathoMatic* mathomatic, int n) +//int n; /* equation space number */ { int rv = false; - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return rv; - if (factor_int(lhs[n], &n_lhs[n])) + if (factor_int(mathomatic, mathomatic->lhs[n], &mathomatic->n_lhs[n])) rv = true; - if (factor_int(rhs[n], &n_rhs[n])) + if (factor_int(mathomatic, mathomatic->rhs[n], &mathomatic->n_rhs[n])) rv = true; return rv; } @@ -312,15 +307,12 @@ int n; /* equation space number */ * List an equation side with optional integer factoring. */ int -list_factor(equation, np, factor_flag) -token_type *equation; -int *np; -int factor_flag; +list_factor(MathoMatic* mathomatic, token_type *equation, int *np, int factor_flag) { - if (factor_flag || factor_int_flag) { - factor_int(equation, np); + if (factor_flag || mathomatic->factor_int_flag) { + factor_int(mathomatic, equation, np); } - return list_proc(equation, *np, false); + return list_proc(mathomatic, equation, *np, false); } /* @@ -352,21 +344,18 @@ int factor_flag; * Return true if equation side was modified. */ int -factor_constants(equation, np, level_code) -token_type *equation; /* pointer to the beginning of equation side */ -int *np; /* pointer to length of equation side */ -int level_code; /* see above */ +factor_constants(MathoMatic* mathomatic, token_type *equation, int *np, int level_code) +//token_type *equation; /* pointer to the beginning of equation side */ +//int *np; /* pointer to length of equation side */ +//int level_code; /* see above */ { if (level_code == 3) return false; - return fc_recurse(equation, np, 0, 1, level_code); + return fc_recurse(mathomatic, equation, np, 0, 1, level_code); } static int -fc_recurse(equation, np, loc, level, level_code) -token_type *equation; -int *np, loc, level; -int level_code; +fc_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int level_code) { int i, j, k, eloc; int op; @@ -376,7 +365,7 @@ int level_code; for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= fc_recurse(equation, np, i, level + 1, level_code); + modified |= fc_recurse(mathomatic, equation, np, i, level + 1, level_code); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -387,7 +376,7 @@ int level_code; if (modified) return true; improve_readability = ((level_code & 3) > 1 || ((level_code & 3) && (level == 1))); - gcd_flag = ((improve_readability && factor_out_all_numeric_gcds) || (level_code & 4)); + gcd_flag = ((improve_readability && mathomatic->factor_out_all_numeric_gcds) || (level_code & 4)); for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level == level) { switch (equation[i].kind) { @@ -422,14 +411,14 @@ int level_code; if (minimum > d) minimum = d; if (gcd_flag && cogcd != 0.0) - cogcd = gcd_verified(d, cogcd); + cogcd = gcd_verified(mathomatic, d, cogcd); } } else { op = 0; for (j = i + 1; j < *np && equation[j].level > level; j += 2) { #if DEBUG if (equation[j].kind != OPERATOR) { - error_bug("Bug in factor_constants()."); + error_bug(mathomatic, "Bug in factor_constants()."); } #endif if (equation[j].level == level + 1) { @@ -455,7 +444,7 @@ int level_code; if (minimum > d) minimum = d; if (gcd_flag && cogcd != 0.0) - cogcd = gcd_verified(d, cogcd); + cogcd = gcd_verified(mathomatic, d, cogcd); } i = j; } @@ -473,7 +462,7 @@ int level_code; if (minimum > 1.0) minimum = 1.0; if (gcd_flag && cogcd != 0.0) - cogcd = gcd_verified(1.0, cogcd); + cogcd = gcd_verified(mathomatic, 1.0, cogcd); } i = j; continue; @@ -529,8 +518,8 @@ int level_code; minimum = -minimum; if (minimum == 1.0) return modified; - if (*np + ((op_count + 2) * 2) > n_tokens) { - error_huge(); + if (*np + ((op_count + 2) * 2) > mathomatic->n_tokens) { + error_huge(mathomatic); } for (i = loc; i < *np && equation[i].level >= level; i++) { if (equation[i].kind != OPERATOR) { diff --git a/gcd.c b/gcd.c index 1946b5d..078bf08 100644 --- a/gcd.c +++ b/gcd.c @@ -42,8 +42,7 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. * Returns 0 on failure, otherwise returns the positive GCD. */ double -gcd(d1, d2) -double d1, d2; +gcd(MathoMatic* mathomatic, double d1, double d2) { int count; double larger, divisor, remainder1, lower_limit; @@ -66,7 +65,7 @@ double d1, d2; larger = d2; divisor = d1; } - lower_limit = larger * epsilon; + lower_limit = larger * mathomatic->epsilon; if (divisor <= lower_limit || larger >= MAX_K_INTEGER) { return 0.0; /* out of range, result would be too inaccurate */ } @@ -92,18 +91,17 @@ double d1, d2; * Result is not necessarily integer unless both d1 and d2 are integer. */ double -gcd_verified(d1, d2) -double d1, d2; +gcd_verified(MathoMatic* mathomatic, double d1, double d2) { double divisor, d3, d4; - divisor = gcd(d1, d2); + divisor = gcd(mathomatic, d1, d2); if (divisor != 0.0) { d3 = d1 / divisor; d4 = d2 / divisor; if (fmod(d3, 1.0) != 0.0 || fmod(d4, 1.0) != 0.0) return 0.0; - if (gcd(d3, d4) != 1.0) + if (gcd(mathomatic, d3, d4) != 1.0) return 0.0; } return divisor; @@ -141,10 +139,10 @@ double d1; /* value to round */ * True return indicates d is rational and finite, otherwise d is probably irrational. */ int -f_to_fraction(d, numeratorp, denominatorp) -double d; /* floating point number to convert */ -double *numeratorp; /* returned numerator */ -double *denominatorp; /* returned denominator */ +f_to_fraction(MathoMatic* mathomatic, double d, double *numeratorp, double *denominatorp) +//double d; /* floating point number to convert */ +//double *numeratorp; /* returned numerator */ +//double *denominatorp; /* returned denominator */ { double divisor; double numerator, denominator; @@ -163,7 +161,7 @@ double *denominatorp; /* returned denominator */ /* more than 15 digits in number means we do nothing (for better accuracy) */ if (fabs(d) >= MAX_K_INTEGER) return false; - k3 = fabs(d) * small_epsilon; + k3 = fabs(d) * mathomatic->small_epsilon; if (k3 >= .5) return false; /* fixes "factor number 17!" to give error instead of wrong answer */ k4 = my_round(d); @@ -173,7 +171,7 @@ double *denominatorp; /* returned denominator */ return true; } /* try to convert non-integer floating point value in "d" to a fraction: */ - if ((divisor = gcd(1.0, d)) > epsilon) { + if ((divisor = gcd(mathomatic, 1.0, d)) > mathomatic->epsilon) { numerator = my_round(d / divisor); denominator = my_round(1.0 / divisor); /* don't allow more than 11 digits in the numerator or denominator: */ @@ -182,19 +180,19 @@ double *denominatorp; /* returned denominator */ if (denominator >= 1.0e12 || denominator < 2.0) return false; /* make sure the result is a fully reduced fraction: */ - divisor = gcd(numerator, denominator); + divisor = gcd(mathomatic, numerator, denominator); if (divisor > 1.0) { /* just in case result isn't already fully reduced */ numerator /= divisor; denominator /= divisor; } k3 = (numerator / denominator); - if (fabs(k3 - d) > (small_epsilon * fabs(k3))) { + if (fabs(k3 - d) > (mathomatic->small_epsilon * fabs(k3))) { return false; /* result is too inaccurate */ } if (fmod(numerator, 1.0) != 0.0 || fmod(denominator, 1.0) != 0.0) { /* Shouldn't happen if everything works. */ #if DEBUG - error_bug("Fraction should have been fully reduced by gcd(), but was not."); + error_bug(mathomatic, "Fraction should have been fully reduced by gcd(), but was not."); #endif return false; } @@ -213,16 +211,16 @@ double *denominatorp; /* returned denominator */ * Returns true if any fractions were created. */ int -make_fractions(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +make_fractions(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { - switch (fractions_display) { + switch (mathomatic->fractions_display) { case 2: - return make_mixed_fractions(equation, np); + return make_mixed_fractions(mathomatic, equation, np); break; default: - return make_simple_fractions(equation, np); + return make_simple_fractions(mathomatic, equation, np); break; } } @@ -236,9 +234,9 @@ int *np; /* pointer to length of equation side */ * Returns true if any fractions were created. */ int -make_simple_fractions(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +make_simple_fractions(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { int i, j, k; int level; @@ -250,14 +248,14 @@ int *np; /* pointer to length of equation side */ level = equation[i].level; if (i > 0 && equation[i-1].level == level && (equation[i-1].token.operatr == DIVIDE /* || equation[i-1].token.operatr == POWER */)) continue; - if (!f_to_fraction(equation[i].token.constant, &numerator, &denominator)) + if (!f_to_fraction(mathomatic, equation[i].token.constant, &numerator, &denominator)) continue; if (denominator == 1.0) { equation[i].token.constant = numerator; continue; } - if ((*np + 2) > n_tokens) { - error_huge(); + if ((*np + 2) > mathomatic->n_tokens) { + error_huge(mathomatic); } modified = true; inc_level = (*np > 1); @@ -324,9 +322,9 @@ int *np; /* pointer to length of equation side */ * Returns true if any fractions were created. */ int -make_mixed_fractions(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +make_mixed_fractions(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { int i, j, k; int level; @@ -338,7 +336,7 @@ int *np; /* pointer to length of equation side */ level = equation[i].level; if (i > 0 && equation[i-1].level == level && (equation[i-1].token.operatr == DIVIDE /* || equation[i-1].token.operatr == POWER */)) continue; - if (!f_to_fraction(equation[i].token.constant, &numerator, &denominator)) + if (!f_to_fraction(mathomatic, equation[i].token.constant, &numerator, &denominator)) continue; if (denominator == 1.0) { equation[i].token.constant = numerator; @@ -349,8 +347,8 @@ int *np; /* pointer to length of equation side */ remainder1 = modf(fabs(numerator) / denominator, "ient1); remainder1 = my_round(remainder1 * denominator); if (numerator < 0.0) { - if ((*np + 6) > n_tokens) { - error_huge(); + if ((*np + 6) > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[i+7], &equation[i+1], (*np - (i + 1)) * sizeof(token_type)); *np += 6; @@ -381,8 +379,8 @@ int *np; /* pointer to length of equation side */ equation[i].kind = CONSTANT; equation[i].token.constant = denominator; } else { - if ((*np + 4) > n_tokens) { - error_huge(); + if ((*np + 4) > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[i+5], &equation[i+1], (*np - (i + 1)) * sizeof(token_type)); *np += 4; @@ -406,8 +404,8 @@ int *np; /* pointer to length of equation side */ equation[i].token.constant = denominator; } } else { - if ((*np + 2) > n_tokens) { - error_huge(); + if ((*np + 2) > mathomatic->n_tokens) { + error_huge(mathomatic); } inc_level = (*np > 1); if ((i + 1) < *np && equation[i+1].level == level) { @@ -462,7 +460,7 @@ int *np; /* pointer to length of equation side */ } } if (modified) { - organize(equation, np); + organize(mathomatic, equation, np); } return modified; } diff --git a/globals.c b/globals.c index 2649170..e89eac4 100644 --- a/globals.c +++ b/globals.c @@ -28,147 +28,108 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "includes.h" -int n_tokens = DEFAULT_N_TOKENS; /* maximum size of expressions, must only be set during startup */ - -int n_equations, /* number of equation spaces allocated */ - cur_equation; /* current equation space number (origin 0) */ - -/* expression storage pointers and current length variables (they go together) */ -token_type *lhs[N_EQUATIONS], /* The Left Hand Sides of equation spaces */ - *rhs[N_EQUATIONS]; /* The Right Hand Sides of equation spaces */ - -int n_lhs[N_EQUATIONS], /* number of tokens in each lhs[], 0 means equation space is empty */ - n_rhs[N_EQUATIONS]; /* number of tokens in each rhs[], 0 means not an equation */ - -token_type *tlhs, /* LHS during solve and temporary storage for expressions, quotient for poly_div() and smart_div(). */ - *trhs, /* RHS during solve and temporary storage for expressions, remainder for poly_div() and smart_div(). */ - *tes, /* Temporary Equation Side, used in commands, simpa_repeat_side(), simple_frac_repeat_side(), etc. */ - *scratch; /* Very temporary storage for expressions, used only in low level routines for expression manipulation. */ - /* Do not run any functions on scratch[], except for blt() (which is memmove(3)). */ - -int n_tlhs, /* number of tokens in tlhs */ - n_trhs, /* number of tokens in trhs */ - n_tes; /* number of tokens in tes */ - -token_type zero_token, /* the universal constant 0.0 as an expression */ - one_token; /* the universal constant 1.0 as an expression */ - -/* Set options with their initial values. */ -int precision = 14; /* the display precision for doubles (number of digits) */ -int case_sensitive_flag = true; /* "set case_sensitive" flag */ -int factor_int_flag; /* factor integers when displaying expressions */ -#if LIBRARY && !ROBOT_COMMAND -int display2d = false; /* "set no display2d" to allow feeding the output to the input */ -#else -int display2d = true; /* "set display2d" flag for 2D display */ -#endif -int fractions_display = 1; /* "set fraction" mode */ -int preserve_surds = true; /* set option to preserve roots like (2^.5) */ -int rationalize_denominators = true; /* try to rationalize denominators if true */ -int modulus_mode = 2; /* true for mathematically correct modulus */ -volatile int screen_columns = STANDARD_SCREEN_COLUMNS; /* screen width of the terminal; 0 = infinite */ -volatile int screen_rows = STANDARD_SCREEN_ROWS; /* screen height of the terminal; 0 = infinite */ -int finance_option = -1; /* for displaying dollars and cents */ -int autosolve = true; /* Allows solving by typing the variable name at the main prompt */ -int autocalc = true; /* Allows automatically calculating a numerical expression */ -int autodelete = false; /* Automatically deletes the previous calculated numerical expression when a new one is entered */ -int autoselect = true; /* Allows selecting equation spaces by typing the number */ -#if LIBRARY -char special_variable_characters[256] = "\\[]"; /* allow backslash in variable names for Latex compatibility */ -#else -char special_variable_characters[256] = "'\\[]"; /* user defined characters for variable names, '\0' terminated */ -#endif -#if MINGW -char plot_prefix[256] = "set grid; set xlabel 'X'; set ylabel 'Y';"; /* prefix fed into gnuplot before the plot command */ -#else -char plot_prefix[256] = "set grid; set xlabel \"X\"; set ylabel \"Y\";"; /* prefix fed into gnuplot before the plot command */ -#endif -int factor_out_all_numeric_gcds = false; /* if true, factor out the GCD of rational coefficients */ -int right_associative_power; /* if true, evaluate power operators right to left */ -int power_starstar; /* if true, display power operator as "**", otherwise "^" */ -#if !SILENT -int debug_level; /* current debug level */ -#endif - -/* variables having to do with color output mode */ -#if LIBRARY || NO_COLOR -int color_flag = 0; /* library shouldn't default to color mode */ -#else -int color_flag = 1; /* "set color" flag; 0 for no color, 1 for color, 2 for alternative color output mode */ -#endif -#if BOLD_COLOR -int bold_colors = 1; /* "set bold color" flag for brighter colors */ -#else -int bold_colors = 0; /* bold_colors must be 0 or 1; 0 is dim */ -#endif -int text_color = -1; /* Current normal text color, -1 for no color */ -int cur_color = -1; /* memory of current color on the terminal */ -int html_flag; /* 1 for HTML mode on all standard output; 2 for HTML mode on all output, even redirected output */ - -/* double precision floating point epsilon constants for number comparisons for equivalency */ -double small_epsilon = 0.000000000000005; /* for ignoring small, floating point round-off errors */ -double epsilon = 0.00000000000005; /* for ignoring larger, accumulated round-off errors */ - -/* string variables */ -char *prog_name = "mathomatic"; /* name of this program */ -char *var_names[MAX_VAR_NAMES]; /* index for storage of variable name strings */ -char var_str[MAX_VAR_LEN+80]; /* temp storage for listing a variable name */ -char prompt_str[MAX_PROMPT_LEN]; /* temp storage for the prompt string */ -#if !SECURE -char rc_file[MAX_CMD_LEN]; /* pathname for the set options startup file */ -#endif - -#if CYGWIN || MINGW -char *dir_path; /* directory path to the executable */ -#endif -#if READLINE || EDITLINE -char *last_history_string; /* To prevent repeated, identical entries. Must not point to temporary string. */ -#endif -#if READLINE -char *history_filename; -char history_filename_storage[MAX_CMD_LEN]; -#endif - -/* The following are for integer factoring (filled by factor_one()): */ -double unique[64]; /* storage for the unique prime factors */ -int ucnt[64]; /* number of times the factor occurs */ -int uno; /* number of unique factors stored in unique[] */ - -/* misc. variables */ -int previous_return_value = 1; /* Return value of last command entered. */ -sign_array_type sign_array; /* for keeping track of unique "sign" variables */ -FILE *default_out; /* file pointer where all gfp output goes by default */ -FILE *gfp; /* global output file pointer, for dynamically redirecting Mathomatic output */ -char *gfp_filename; /* filename associated with gfp if redirection is happening */ -int gfp_append_flag; /* true if appending to gfp, false if overwriting */ -jmp_buf jmp_save; /* for setjmp(3) to longjmp(3) to when an error happens deep within this code */ -int eoption; /* -e option flag */ -int test_mode; /* test mode flag (-t) */ -int demo_mode; /* demo mode flag (-d), don't load rc file or pause commands when true */ -int quiet_mode; /* quiet mode (-q, don't display prompts) */ -int echo_input; /* if true, echo input */ -int readline_enabled = true; /* set to false (-r) to disable readline */ -int partial_flag; /* normally true for partial unfactoring, false for "unfactor fraction" */ -int symb_flag; /* true during "simplify symbolic", which is not 100% mathematically correct */ -int symblify = true; /* if true, set symb_flag when helpful during solving, etc. */ -int high_prec; /* flag to output constants in higher precision (used when saving equations) */ -int input_column; /* current column number on the screen at the beginning of a parse */ -int sign_cmp_flag; /* true when all "sign" variables are to compare equal */ -int domain_check; /* flag to track domain errors in the pow() function */ -int approximate_roots; /* true if in calculate command (force approximation of roots like (2^.5)) */ -volatile int abort_flag; /* if true, abort current operation; set by control-C interrupt */ -int pull_number; /* equation space number to pull when using the library */ -int security_level; /* current enforced security level for session, -1 for m4 Mathomatic */ -int repeat_flag; /* true if the command is to repeat its function or simplification, set by repeat command */ -int show_usage; /* show command usage info if a command fails and this flag is true */ -int point_flag; /* point to location of parse error if true */ - -/* library variables go here */ -char *result_str; /* returned result text string when using as library */ -int result_en = -1; /* equation number of the returned result, if stored in an equation space */ -const char *error_str; /* last error string */ -const char *warning_str; /* last warning string */ - -/* Screen character array, for buffering page-at-a-time 2D string output: */ -char *vscreen[TEXT_ROWS]; -int current_columns; +//MathoMatic *mathomatic; + +MathoMatic *newtMathoMatic(void) { + MathoMatic *mathomatic = malloc(sizeof(MathoMatic)); + if(!mathomatic) return NULL; + memset(mathomatic, 0, sizeof(MathoMatic)); + + mathomatic->n_tokens = DEFAULT_N_TOKENS; /* maximum size of expressions, must only be set during startup */ + /* Set options with their initial values. */ + mathomatic->precision = 14; /* the display precision for doubles (number of digits) */ + mathomatic->case_sensitive_flag = true; /* "set case_sensitive" flag */ + #if LIBRARY && !ROBOT_COMMAND + mathomatic->display2d = false; /* "set no display2d" to allow feeding the output to the input */ + #else + mathomatic->display2d = true; /* "set display2d" flag for 2D display */ + #endif + mathomatic->fractions_display = 1; /* "set fraction" mode */ + mathomatic->preserve_surds = true; /* set option to preserve roots like (2^.5) */ + mathomatic->rationalize_denominators = true; /* try to rationalize denominators if true */ + mathomatic->modulus_mode = 2; /* true for mathematically correct modulus */ + mathomatic->screen_columns = STANDARD_SCREEN_COLUMNS; /* screen width of the terminal; 0 = infinite */ + mathomatic->screen_rows = STANDARD_SCREEN_ROWS; /* screen height of the terminal; 0 = infinite */ + mathomatic->finance_option = -1; /* for displaying dollars and cents */ + mathomatic->autosolve = true; /* Allows solving by typing the variable name at the main prompt */ + mathomatic->autocalc = true; /* Allows automatically calculating a numerical expression */ + mathomatic->autodelete = false; /* Automatically deletes the previous calculated numerical expression when a new one is entered */ + mathomatic->autoselect = true; /* Allows selecting equation spaces by typing the number */ + #if LIBRARY + strcpy(mathomatic->special_variable_characters, "\\[]"); /* allow backslash in variable names for Latex compatibility */ + #else + strcpy(mathomatic->special_variable_characters, "'\\[]"); /* user defined characters for variable names, '\0' terminated */ + #endif + #if MINGW + strcpy(mathomatic->plot_prefix, "set grid; set xlabel 'X'; set ylabel 'Y';"); /* prefix fed into gnuplot before the plot command */ + #else + strcpy(mathomatic->plot_prefix, "set grid; set xlabel \"X\"; set ylabel \"Y\";"); /* prefix fed into gnuplot before the plot command */ + #endif + mathomatic->factor_out_all_numeric_gcds = false; /* if true, factor out the GCD of rational coefficients */ + + /* variables having to do with color output mode */ + #if LIBRARY || NO_COLOR + mathomatic->color_flag = 0; /* library shouldn't default to color mode */ + #else + mathomatic->color_flag = 1; /* "set color" flag; 0 for no color, 1 for color, 2 for alternative color output mode */ + #endif + #if BOLD_COLOR + mathomatic->bold_colors = 1; /* "set bold color" flag for brighter colors */ + #else + mathomatic->bold_colors = 0; /* bold_colors must be 0 or 1; 0 is dim */ + #endif + mathomatic->text_color = -1; /* Current normal text color, -1 for no color */ + mathomatic->cur_color = -1; /* memory of current color on the terminal */ + + /* double precision floating point epsilon constants for number comparisons for equivalency */ + mathomatic->small_epsilon = 0.000000000000005; /* for ignoring small, floating point round-off errors */ + mathomatic->epsilon = 0.00000000000005; /* for ignoring larger, accumulated round-off errors */ + + /* string variables */ + mathomatic->prog_name = "mathomatic"; /* name of this program */ + + /* misc. variables */ + mathomatic->previous_return_value = 1; /* Return value of last command entered. */ + mathomatic->readline_enabled = true; /* set to false (-r) to disable readline */ + mathomatic->symblify = true; /* if true, set symb_flag when helpful during solving, etc. */ + + /* library variables go here */ + mathomatic->result_en = -1; /* equation number of the returned result, if stored in an equation space */ + + mathomatic->last_autocalc_en = -1; + mathomatic->constant_var_number = 1; /* makes unique numbers for the constant of integration */ + + return mathomatic; +} + +void closetMathoMatic(MathoMatic *mathomatic) { + free(mathomatic); +} + +int matho_cur_equation(MathoMatic * mathomatic) { + return mathomatic->cur_equation; +} + +int matho_result_en(MathoMatic * mathomatic) { + return mathomatic->result_en; +} + +const char *matho_get_warning_str(MathoMatic * mathomatic) { + return mathomatic->warning_str; +} + +void matho_set_warning_str(MathoMatic * mathomatic, const char *ws) { + mathomatic->warning_str = ws; +} + +void matho_set_error_str(MathoMatic * mathomatic, const char *ws) { + mathomatic->error_str = ws; +} + +int matho_get_abort_flag(MathoMatic* mathomatic) { + return mathomatic->abort_flag; +} + +void matho_inc_abort_flag(MathoMatic* mathomatic) { + ++mathomatic->abort_flag; +} diff --git a/help.c b/help.c index c9511e2..21add31 100644 --- a/help.c +++ b/help.c @@ -46,7 +46,7 @@ typedef struct { /* * The Mathomatic command table follows. It should be in alphabetical order. */ -static com_type com_list[] = { +static const com_type com_list[] = { /* command name, alternate name, function, usage, information */ { "approximate", NULL, approximate_cmd, "[equation-number-ranges]", "Approximate all numerical values in equation spaces.", "\"repeat approximate\" approximates more, like calculate." }, #if !LIBRARY @@ -210,20 +210,18 @@ char *conversion_strings[] = { * Return true if successful. */ int -parse(n, cp) -int n; -char *cp; +parse(MathoMatic* mathomatic, int n, char *cp) { - if (parse_equation(n, cp)) { - if (n_lhs[n] == 0 && n_rhs[n] == 0) + if (parse_equation(mathomatic, n, cp)) { + if (mathomatic->n_lhs[n] == 0 && mathomatic->n_rhs[n] == 0) return true; - if (n_lhs[n] == 0) { + if (mathomatic->n_lhs[n] == 0) { /* RHS expression only, set equal to zero */ - n_lhs[n] = 1; - lhs[n][0] = zero_token; + mathomatic->n_lhs[n] = 1; + mathomatic->lhs[n][0] = mathomatic->zero_token; } - cur_equation = n; - return return_result(cur_equation); + mathomatic->cur_equation = n; + return return_result(mathomatic, mathomatic->cur_equation); } return false; } @@ -241,9 +239,7 @@ char *cp; * Return true if successful. */ int -process_parse(n, cp) -int n; -char *cp; +process_parse(MathoMatic* mathomatic, int n, char *cp) { int i; char *cp1, *ep; @@ -253,7 +249,7 @@ char *cp; #endif int rv; int op = 0; - static int last_autocalc_en = -1; + //static int last_autocalc_en = -1; long answer_v = 0; /* Mathomatic answer variable */ if (cp == NULL) @@ -291,178 +287,178 @@ char *cp; } } if (op) { - if (cur_equation == n || empty_equation_space(cur_equation)) { - error(_("No current equation to manipulate.")); + if (mathomatic->cur_equation == n || empty_equation_space(mathomatic, mathomatic->cur_equation)) { + error(mathomatic, _("No current equation to manipulate.")); return false; } - input_column += (cp1 + 1) - cp; - if (parse_equation(n, cp1 + 1) == NULL) { + mathomatic->input_column += (cp1 + 1) - cp; + if (parse_equation(mathomatic, n, cp1 + 1) == NULL) { return false; } - if (n_lhs[n] <= 0 || n_rhs[n] != 0) { - error(_("Syntax error.")); - n_lhs[n] = 0; - n_rhs[n] = 0; + if (mathomatic->n_lhs[n] <= 0 || mathomatic->n_rhs[n] != 0) { + error(mathomatic, _("Syntax error.")); + mathomatic->n_lhs[n] = 0; + mathomatic->n_rhs[n] = 0; return false; } - if (n_lhs[cur_equation] + 1 + n_lhs[n] > n_tokens - || n_rhs[cur_equation] + 1 + n_lhs[n] > n_tokens) { - n_lhs[n] = 0; - n_rhs[n] = 0; - error_huge(); + if (mathomatic->n_lhs[mathomatic->cur_equation] + 1 + mathomatic->n_lhs[n] > mathomatic->n_tokens + || mathomatic->n_rhs[mathomatic->cur_equation] + 1 + mathomatic->n_lhs[n] > mathomatic->n_tokens) { + mathomatic->n_lhs[n] = 0; + mathomatic->n_rhs[n] = 0; + error_huge(mathomatic); } - for (i = 0; i < n_lhs[cur_equation]; i++) { - lhs[cur_equation][i].level++; + for (i = 0; i < mathomatic->n_lhs[mathomatic->cur_equation]; i++) { + mathomatic->lhs[mathomatic->cur_equation][i].level++; } - lhs[cur_equation][i].kind = OPERATOR; - lhs[cur_equation][i].level = 1; - lhs[cur_equation][i].token.operatr = op; + mathomatic->lhs[mathomatic->cur_equation][i].kind = OPERATOR; + mathomatic->lhs[mathomatic->cur_equation][i].level = 1; + mathomatic->lhs[mathomatic->cur_equation][i].token.operatr = op; i++; - blt(&lhs[cur_equation][i], lhs[n], n_lhs[n] * sizeof(token_type)); - n_lhs[cur_equation] += 1 + n_lhs[n]; - for (; i < n_lhs[cur_equation]; i++) { - lhs[cur_equation][i].level++; + blt(&mathomatic->lhs[mathomatic->cur_equation][i], mathomatic->lhs[n], mathomatic->n_lhs[n] * sizeof(token_type)); + mathomatic->n_lhs[mathomatic->cur_equation] += 1 + mathomatic->n_lhs[n]; + for (; i < mathomatic->n_lhs[mathomatic->cur_equation]; i++) { + mathomatic->lhs[mathomatic->cur_equation][i].level++; } - if (n_rhs[cur_equation] > 0) { - for (i = 0; i < n_rhs[cur_equation]; i++) { - rhs[cur_equation][i].level++; + if (mathomatic->n_rhs[mathomatic->cur_equation] > 0) { + for (i = 0; i < mathomatic->n_rhs[mathomatic->cur_equation]; i++) { + mathomatic->rhs[mathomatic->cur_equation][i].level++; } - rhs[cur_equation][i].kind = OPERATOR; - rhs[cur_equation][i].level = 1; - rhs[cur_equation][i].token.operatr = op; + mathomatic->rhs[mathomatic->cur_equation][i].kind = OPERATOR; + mathomatic->rhs[mathomatic->cur_equation][i].level = 1; + mathomatic->rhs[mathomatic->cur_equation][i].token.operatr = op; i++; - blt(&rhs[cur_equation][i], lhs[n], n_lhs[n] * sizeof(token_type)); - n_rhs[cur_equation] += 1 + n_lhs[n]; - for (; i < n_rhs[cur_equation]; i++) { - rhs[cur_equation][i].level++; + blt(&mathomatic->rhs[mathomatic->cur_equation][i], mathomatic->lhs[n], mathomatic->n_lhs[n] * sizeof(token_type)); + mathomatic->n_rhs[mathomatic->cur_equation] += 1 + mathomatic->n_lhs[n]; + for (; i < mathomatic->n_rhs[mathomatic->cur_equation]; i++) { + mathomatic->rhs[mathomatic->cur_equation][i].level++; } } - n_lhs[n] = 0; - n_rhs[n] = 0; - simp_equation(cur_equation); - return return_result(cur_equation); + mathomatic->n_lhs[n] = 0; + mathomatic->n_rhs[n] = 0; + simp_equation(mathomatic, mathomatic->cur_equation); + return return_result(mathomatic, mathomatic->cur_equation); } } - if ((ep = parse_equation(n, cp))) { + if ((ep = parse_equation(mathomatic, n, cp))) { for (cp1 = cp; cp1 < ep; cp1++) { if (*cp1 == '=') { equals_flag = true; break; } } - if (n_lhs[n] == 0 && n_rhs[n] == 0) { - if (strcmp(cp, "=") == 0 && cur_equation != n && equation_space_is_equation(cur_equation)) { - debug_string(0, _("Swapping both sides of the current equation...")); - n = cur_equation; - i = n_lhs[n]; - blt(scratch, lhs[n], i * sizeof(token_type)); - n_lhs[n] = n_rhs[n]; - blt(lhs[n], rhs[n], n_rhs[n] * sizeof(token_type)); - n_rhs[n] = i; - blt(rhs[n], scratch, i * sizeof(token_type)); - return return_result(cur_equation); + if (mathomatic->n_lhs[n] == 0 && mathomatic->n_rhs[n] == 0) { + if (strcmp(cp, "=") == 0 && mathomatic->cur_equation != n && equation_space_is_equation(mathomatic, mathomatic->cur_equation)) { + debug_string(mathomatic, 0, _("Swapping both sides of the current equation...")); + n = mathomatic->cur_equation; + i = mathomatic->n_lhs[n]; + blt(mathomatic->scratch, mathomatic->lhs[n], i * sizeof(token_type)); + mathomatic->n_lhs[n] = mathomatic->n_rhs[n]; + blt(mathomatic->lhs[n], mathomatic->rhs[n], mathomatic->n_rhs[n] * sizeof(token_type)); + mathomatic->n_rhs[n] = i; + blt(mathomatic->rhs[n], mathomatic->scratch, i * sizeof(token_type)); + return return_result(mathomatic, mathomatic->cur_equation); } return true; } - if (n_lhs[n] == 0 || n_rhs[n] == 0) { - if (equals_flag && cur_equation != n && !empty_equation_space(cur_equation) && n_rhs[cur_equation] == 0) { - debug_string(0, _("Combining to make an equation out of the current non-equation.")); - if (n_lhs[n]) { + if (mathomatic->n_lhs[n] == 0 || mathomatic->n_rhs[n] == 0) { + if (equals_flag && mathomatic->cur_equation != n && !empty_equation_space(mathomatic, mathomatic->cur_equation) && mathomatic->n_rhs[mathomatic->cur_equation] == 0) { + debug_string(mathomatic, 0, _("Combining to make an equation out of the current non-equation.")); + if (mathomatic->n_lhs[n]) { /* copy the LHS to the RHS */ - blt(rhs[cur_equation], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_rhs[cur_equation] = n_lhs[cur_equation]; + blt(mathomatic->rhs[mathomatic->cur_equation], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_rhs[mathomatic->cur_equation] = mathomatic->n_lhs[mathomatic->cur_equation]; - blt(lhs[cur_equation], lhs[n], n_lhs[n] * sizeof(token_type)); - n_lhs[cur_equation] = n_lhs[n]; - } else if (n_rhs[n]) { - blt(rhs[cur_equation], rhs[n], n_rhs[n] * sizeof(token_type)); - n_rhs[cur_equation] = n_rhs[n]; + blt(mathomatic->lhs[mathomatic->cur_equation], mathomatic->lhs[n], mathomatic->n_lhs[n] * sizeof(token_type)); + mathomatic->n_lhs[mathomatic->cur_equation] = mathomatic->n_lhs[n]; + } else if (mathomatic->n_rhs[n]) { + blt(mathomatic->rhs[mathomatic->cur_equation], mathomatic->rhs[n], mathomatic->n_rhs[n] * sizeof(token_type)); + mathomatic->n_rhs[mathomatic->cur_equation] = mathomatic->n_rhs[n]; } - n_lhs[n] = 0; - n_rhs[n] = 0; - return return_result(cur_equation); + mathomatic->n_lhs[n] = 0; + mathomatic->n_rhs[n] = 0; + return return_result(mathomatic, mathomatic->cur_equation); } - if (autosolve || equals_flag) { - if ((n_lhs[n] == 1 && ((lhs[n][0].kind == CONSTANT && lhs[n][0].token.constant == 0.0) - || (lhs[n][0].kind == VARIABLE && ((lhs[n][0].token.variable & VAR_MASK) > SIGN || equals_flag)))) - || (n_rhs[n] == 1 && ((rhs[n][0].kind == CONSTANT && rhs[n][0].token.constant == 0.0) - || rhs[n][0].kind == VARIABLE))) { - rv = solve_espace(n, cur_equation); - n_lhs[n] = 0; - n_rhs[n] = 0; + if (mathomatic->autosolve || equals_flag) { + if ((mathomatic->n_lhs[n] == 1 && ((mathomatic->lhs[n][0].kind == CONSTANT && mathomatic->lhs[n][0].token.constant == 0.0) + || (mathomatic->lhs[n][0].kind == VARIABLE && ((mathomatic->lhs[n][0].token.variable & VAR_MASK) > SIGN || equals_flag)))) + || (mathomatic->n_rhs[n] == 1 && ((mathomatic->rhs[n][0].kind == CONSTANT && mathomatic->rhs[n][0].token.constant == 0.0) + || mathomatic->rhs[n][0].kind == VARIABLE))) { + rv = solve_espace(mathomatic, n, mathomatic->cur_equation); + mathomatic->n_lhs[n] = 0; + mathomatic->n_rhs[n] = 0; if (rv) { - return return_result(cur_equation); + return return_result(mathomatic, mathomatic->cur_equation); } else { return false; } } } - if (!equals_flag && autoselect && n_lhs[n] == 1 && lhs[n][0].kind == CONSTANT && fmod(lhs[n][0].token.constant, 1.0) == 0.0 - && lhs[n][0].token.constant > 0.0 && lhs[n][0].token.constant <= n_equations) { + if (!equals_flag && mathomatic->autoselect && mathomatic->n_lhs[n] == 1 && mathomatic->lhs[n][0].kind == CONSTANT && fmod(mathomatic->lhs[n][0].token.constant, 1.0) == 0.0 + && mathomatic->lhs[n][0].token.constant > 0.0 && mathomatic->lhs[n][0].token.constant <= mathomatic->n_equations) { /* easy selecting of equation spaces by just typing in the equation number */ - cur_equation = lhs[n][0].token.constant - 1; - n_lhs[n] = 0; - return_result(cur_equation); + mathomatic->cur_equation = mathomatic->lhs[n][0].token.constant - 1; + mathomatic->n_lhs[n] = 0; + return_result(mathomatic, mathomatic->cur_equation); return true; } - if (autocalc) { + if (mathomatic->autocalc) { /* the numerical input calculation */ - if (n_lhs[n]) { - if (!exp_is_numeric(lhs[n], n_lhs[n])) { + if (mathomatic->n_lhs[n]) { + if (!exp_is_numeric(mathomatic->lhs[n], mathomatic->n_lhs[n])) { goto set_equal_to_zero; /* not numerical (contains a variable) */ } /* copy the LHS to the RHS */ - blt(rhs[n], lhs[n], n_lhs[n] * sizeof(token_type)); - n_rhs[n] = n_lhs[n]; + blt(mathomatic->rhs[n], mathomatic->lhs[n], mathomatic->n_lhs[n] * sizeof(token_type)); + mathomatic->n_rhs[n] = mathomatic->n_lhs[n]; } - if (exp_is_numeric(rhs[n], n_rhs[n])) { + if (exp_is_numeric(mathomatic->rhs[n], mathomatic->n_rhs[n])) { /* make the expression an equation by making the LHS the "answer" variable */ - lhs[n][0].level = 1; - lhs[n][0].kind = VARIABLE; - parse_var(&answer_v, "answer"); /* convert to a Mathomatic variable */ - lhs[n][0].token.variable = answer_v; - n_lhs[n] = 1; + mathomatic->lhs[n][0].level = 1; + mathomatic->lhs[n][0].kind = VARIABLE; + parse_var(mathomatic, &answer_v, "answer"); /* convert to a Mathomatic variable */ + mathomatic->lhs[n][0].token.variable = answer_v; + mathomatic->n_lhs[n] = 1; /* make it the current equation and run the calculate command on it */ - cur_equation = n; + mathomatic->cur_equation = n; #if LIBRARY - previous_repeat_flag = repeat_flag; - repeat_flag = true; /* act like the calculate command does */ - rv = approximate_cmd(""); /* display an approximation even when using the Symbolic Math Library, unless autocalc is false */ - repeat_flag = previous_repeat_flag; + previous_repeat_flag = mathomatic->repeat_flag; + mathomatic->repeat_flag = true; /* act like the calculate command does */ + rv = approximate_cmd(mathomatic, ""); /* display an approximation even when using the Symbolic Math Library, unless autocalc is false */ + mathomatic->repeat_flag = previous_repeat_flag; #else - debug_string(0, _("Calculating...")); - rv = calculate_cmd(""); /* display the approximation */ + debug_string(mathomatic, 0, _("Calculating...")); + rv = calculate_cmd(mathomatic, ""); /* display the approximation */ #endif /* Keep the current input until next autocalc, then delete if "set autodelete". */ - i = last_autocalc_en; - if (autodelete && i >= 0 && i < n_equations) { - if (i != n && n_lhs[i] == 1 && lhs[i][0].kind == VARIABLE - && lhs[i][0].token.variable == answer_v) { + i = mathomatic->last_autocalc_en; + if (mathomatic->autodelete && i >= 0 && i < mathomatic->n_equations) { + if (i != n && mathomatic->n_lhs[i] == 1 && mathomatic->lhs[i][0].kind == VARIABLE + && mathomatic->lhs[i][0].token.variable == answer_v) { /* delete previous answer from memory */ - n_lhs[i] = 0; - n_rhs[i] = 0; + mathomatic->n_lhs[i] = 0; + mathomatic->n_rhs[i] = 0; } } - last_autocalc_en = n; + mathomatic->last_autocalc_en = n; return rv; } } set_equal_to_zero: if (equals_flag) { - debug_string(0, _("Setting new algebraic expression equal to zero.")); - if (n_rhs[n]) { + debug_string(mathomatic, 0, _("Setting new algebraic expression equal to zero.")); + if (mathomatic->n_rhs[n]) { /* RHS expression only with equals sign; set equal to zero */ - n_lhs[n] = 1; - lhs[n][0] = zero_token; - } else if (n_lhs[n]) { + mathomatic->n_lhs[n] = 1; + mathomatic->lhs[n][0] = mathomatic->zero_token; + } else if (mathomatic->n_lhs[n]) { /* LHS expression only with equals sign; set equal to zero */ - n_rhs[n] = 1; - rhs[n][0] = zero_token; + mathomatic->n_rhs[n] = 1; + mathomatic->rhs[n][0] = mathomatic->zero_token; } } } - cur_equation = n; - return return_result(cur_equation); + mathomatic->cur_equation = n; + return return_result(mathomatic, mathomatic->cur_equation); } return false; } @@ -474,19 +470,18 @@ char *cp; * Return true if line starts with a colon (:) or if successful. */ int -process(cp) -char *cp; +process(MathoMatic* mathomatic, char *cp) { if (cp && cp[0] == ':') { - input_column++; - previous_return_value = process_rv(cp + 1); + mathomatic->input_column++; + mathomatic->previous_return_value = process_rv(mathomatic, cp + 1); return true; } else { - previous_return_value = process_rv(cp); - if (!previous_return_value) { - debug_string(1, "Error return."); + mathomatic->previous_return_value = process_rv(mathomatic, cp); + if (!mathomatic->previous_return_value) { + debug_string(mathomatic, 1, "Error return."); } - return previous_return_value; + return mathomatic->previous_return_value; } } @@ -497,8 +492,7 @@ char *cp; * Return true if successful. */ int -process_rv(cp) -char *cp; +process_rv(MathoMatic* mathomatic, char *cp) { char *cp1 = NULL; char *cp_start; @@ -516,49 +510,49 @@ char *cp; #if DEBUG check_gvars(); #endif - init_gvars(); /* make sure we are in the default state */ - set_sign_array(); /* register all sign variables so that the next ones will be unique */ + init_gvars(mathomatic); /* make sure we are in the default state */ + set_sign_array(mathomatic); /* register all sign variables so that the next ones will be unique */ if (cp == NULL) { return false; } cp_start = cp; cp = skip_space(cp); /* handle search forward */ - if (*cp == '/' && isvarchar(cp[1])) { + if (*cp == '/' && isvarchar(mathomatic, cp[1])) { cp++; - debug_string(0, ("Searching forwards for variable.")); - if ((cp1 = parse_var(&v, cp)) == NULL) { + debug_string(mathomatic, 0, ("Searching forwards for variable.")); + if ((cp1 = parse_var(mathomatic, &v, cp)) == NULL) { return false; } - if (extra_characters(cp1)) { + if (extra_characters(mathomatic, cp1)) { return false; } - if (search_all_for_var(v, true)) { - return return_result(cur_equation); + if (search_all_for_var(mathomatic, v, true)) { + return return_result(mathomatic, mathomatic->cur_equation); } else { - error(_("Variable not found in any equation space.")); + error(mathomatic, _("Variable not found in any equation space.")); return false; } } /* handle the equation selector */ if (*cp == '#') { cp++; - if (isvarchar(*cp)) { - debug_string(0, ("Searching backwards for variable.")); - if ((cp1 = parse_var(&v, cp)) == NULL) { + if (isvarchar(mathomatic, *cp)) { + debug_string(mathomatic, 0, ("Searching backwards for variable.")); + if ((cp1 = parse_var(mathomatic, &v, cp)) == NULL) { return false; } - if (extra_characters(cp1)) { + if (extra_characters(mathomatic, cp1)) { return false; } - if (search_all_for_var(v, false)) { - return return_result(cur_equation); + if (search_all_for_var(mathomatic, v, false)) { + return return_result(mathomatic, mathomatic->cur_equation); } else { - error(_("Variable not found in any equation space.")); + error(mathomatic, _("Variable not found in any equation space.")); return false; } } - i = cur_equation; + i = mathomatic->cur_equation; cp1 = cp; switch (*cp) { case '+': @@ -575,8 +569,8 @@ char *cp; return true; /* treat as comment */ } if (*cp1 == '\0' || *cp1 == ':' || isspace(*cp1)) { - if (!alloc_to_espace(i)) { - put_up_arrow(cp - cp_start, _("Equation number out of range.")); + if (!alloc_to_espace(mathomatic, i)) { + put_up_arrow(mathomatic, cp - cp_start, _("Equation number out of range.")); return false; } cp = cp1; @@ -585,11 +579,11 @@ char *cp; } cp = skip_space(cp); if (*cp) { - input_column += (cp - cp_start); - return parse(i, cp); + mathomatic->input_column += (cp - cp_start); + return parse(mathomatic, i, cp); } - cur_equation = i; - return_result(cur_equation); + mathomatic->cur_equation = i; + return_result(mathomatic, mathomatic->cur_equation); return true; } else { cp--; @@ -598,13 +592,13 @@ char *cp; #if SHELL_OUT /* handle shell escape */ if (*cp == '!') { - if (security_level > 0) { - error(_("Shelling out disabled by security level.")); + if (mathomatic->security_level > 0) { + error(mathomatic, _("Shelling out disabled by security level.")); return false; } cp = skip_space(cp + 1); - if (*cp == '\0' && security_level < 0) { - error(_("Running an interactive shell is not possible with m4.")); + if (*cp == '\0' && mathomatic->security_level < 0) { + error(mathomatic, _("Running an interactive shell is not possible with m4.")); return false; } #if MINGW @@ -618,11 +612,11 @@ char *cp; #if 0 if (*cp1 == '/' && access(cp1, X_OK)) { perror(cp1); - error(_("Shell not found or not executable, check SHELL environment variable.")); + error(mathomatic, _("Shell not found or not executable, check SHELL environment variable.")); return false; } #endif - rv = shell_out(*cp ? cp : cp1); + rv = shell_out(mathomatic, *cp ? cp : cp1); return !rv; } #endif @@ -630,8 +624,8 @@ char *cp; /* a quick way to get help */ if (*cp == '?') { cp = skip_space(cp + 1); - input_column += (cp - cp_start); - return(help_cmd(cp)); + mathomatic->input_column += (cp - cp_start); + return(help_cmd(mathomatic, cp)); } #endif /* See if the string pointed to by cp is a command. */ @@ -654,69 +648,69 @@ char *cp; if (COMPARE_COMMAND_NAME(com_list[i].name) || (com_list[i].secondary_name && COMPARE_COMMAND_NAME(com_list[i].secondary_name))) { cp1 = skip_space(cp1); - input_column += (cp1 - cp_start); + mathomatic->input_column += (cp1 - cp_start); /* Copy the command-line to buf2 and use it, because the original string may be overwritten. */ if (my_strlcpy(buf2, cp1, sizeof(buf2)) >= sizeof(buf2)) { - error(_("Command-line too long.")); + error(mathomatic, _("Command-line too long.")); return false; } #if !SECURE fp = NULL; - if (security_level < 2) { + if (mathomatic->security_level < 2) { /* handle output redirection */ - gfp_append_flag = false; - gfp_filename = NULL; + mathomatic->gfp_append_flag = false; + mathomatic->gfp_filename = NULL; for (i1 = strlen(buf2) - 1; i1 >= 0; i1--) { if (buf2[i1] == '>') { - gfp_filename = skip_space(&buf2[i1+1]); + mathomatic->gfp_filename = skip_space(&buf2[i1+1]); if (i1 && buf2[i1-1] == '>') { i1--; - gfp_append_flag = true; + mathomatic->gfp_append_flag = true; } buf2[i1] = '\0'; break; } } - if (gfp_filename) { - if (gfp_append_flag) { - fp = fopen(gfp_filename, "a"); + if (mathomatic->gfp_filename) { + if (mathomatic->gfp_append_flag) { + fp = fopen(mathomatic->gfp_filename, "a"); } else { - fp = fopen(gfp_filename, "w"); + fp = fopen(mathomatic->gfp_filename, "w"); } if (fp == NULL) { - perror(gfp_filename); - error(_("Can't open redirected output file for writing.")); - gfp_filename = NULL; + perror(mathomatic->gfp_filename); + error(mathomatic, _("Can't open redirected output file for writing.")); + mathomatic->gfp_filename = NULL; return false; } - if (gfp != stdout && gfp != stderr && gfp != default_out) { - fclose(gfp); /* make sure previous redirection file is closed */ + if (mathomatic->gfp != stdout && mathomatic->gfp != stderr && mathomatic->gfp != mathomatic->default_out) { + fclose(mathomatic->gfp); /* make sure previous redirection file is closed */ } - gfp = fp; + mathomatic->gfp = fp; } } #endif remove_trailing_spaces(buf2); - pull_number = 1; - show_usage = true; - repeat_flag = our_repeat_flag; + mathomatic->pull_number = 1; + mathomatic->show_usage = true; + mathomatic->repeat_flag = our_repeat_flag; /* execute the command by calling the command function */ - rv = (*com_list[i].func)(buf2); - repeat_flag = false; + rv = (*com_list[i].func)(mathomatic, buf2); + mathomatic->repeat_flag = false; #if !SECURE - if (fp && gfp != default_out) { - if (gfp != stdout && gfp != stderr) - fclose(gfp); - gfp = default_out; + if (fp && mathomatic->gfp != mathomatic->default_out) { + if (mathomatic->gfp != stdout && mathomatic->gfp != stderr) + fclose(mathomatic->gfp); + mathomatic->gfp = mathomatic->default_out; } - gfp_filename = NULL; + mathomatic->gfp_filename = NULL; #endif #if !SILENT && !LIBRARY if (!rv) { - if (show_usage && debug_level >= 0) { + if (mathomatic->show_usage && mathomatic->debug_level >= 0) { printf("Command usage: %s %s\n", com_list[i].name, com_list[i].usage); #if DEBUG - } else if (!test_mode && !demo_mode) { + } else if (!mathomatic->test_mode && !mathomatic->demo_mode) { printf(_("Command returned with error.\n")); #endif } @@ -726,13 +720,13 @@ char *cp; } } if (our_repeat_flag) { - error(_("Follow \"repeat\" with a command to automatically repeat.")); + error(mathomatic, _("Follow \"repeat\" with a command to automatically repeat.")); return false; } /* cp is not a command, so parse the expression */ - i = next_espace(); - input_column += (cp - cp_start); - return process_parse(i, cp); + i = next_espace(mathomatic); + mathomatic->input_column += (cp - cp_start); + return process_parse(mathomatic, i, cp); } /* @@ -743,8 +737,8 @@ char *cp; * Return true if successful. */ int -display_process(cp) -char *cp; /* String to process; will be modified, so do not use constant strings. */ +display_process(MathoMatic* mathomatic, char *cp) +//char *cp; /* String to process; will be modified, so do not use constant strings. */ { int len; int nlt; /* true if cp is newline terminated */ @@ -752,21 +746,21 @@ char *cp; /* String to process; will be modified, so do not use constant strings if (cp == NULL) return false; #if !LIBRARY - error_str = NULL; - warning_str = NULL; + mathomatic->error_str = NULL; + mathomatic->warning_str = NULL; #endif len = strlen(cp); if (len > 0) len--; nlt = (cp[len] == '\n'); - input_column = 0; + mathomatic->input_column = 0; #if !SILENT || !LIBRARY - if (!quiet_mode) { - set_color(3); /* blue prompt */ - input_column = printf("%d%s", cur_equation + 1, html_flag ? HTML_PROMPT_STR : PROMPT_STR); - default_color(false); - if (html_flag) { - input_column -= (strlen(HTML_PROMPT_STR) - strlen(PROMPT_STR)); + if (!mathomatic->quiet_mode) { + set_color(mathomatic, 3); /* blue prompt */ + mathomatic->input_column = printf("%d%s", mathomatic->cur_equation + 1, mathomatic->html_flag ? HTML_PROMPT_STR : PROMPT_STR); + default_color(mathomatic, false); + if (mathomatic->html_flag) { + mathomatic->input_column -= (strlen(HTML_PROMPT_STR) - strlen(PROMPT_STR)); printf("%s", cp); /* make input bold */ } else { printf("%s", cp); @@ -775,22 +769,22 @@ char *cp; /* String to process; will be modified, so do not use constant strings printf("\n"); } #endif - if (gfp != stdout && gfp != stderr) { - if (html_flag == 2) { - set_color(3); - input_column = fprintf(gfp, "%d%s", cur_equation + 1, HTML_PROMPT_STR); - default_color(false); - input_column -= (strlen(HTML_PROMPT_STR) - strlen(PROMPT_STR)); - fprintf(gfp, "%s", cp); + if (mathomatic->gfp != stdout && mathomatic->gfp != stderr) { + if (mathomatic->html_flag == 2) { + set_color(mathomatic, 3); + mathomatic->input_column = fprintf(mathomatic->gfp, "%d%s", mathomatic->cur_equation + 1, HTML_PROMPT_STR); + default_color(mathomatic, false); + mathomatic->input_column -= (strlen(HTML_PROMPT_STR) - strlen(PROMPT_STR)); + fprintf(mathomatic->gfp, "%s", cp); } else { - input_column = fprintf(gfp, "%d%s", cur_equation + 1, PROMPT_STR); - fprintf(gfp, "%s", cp); + mathomatic->input_column = fprintf(mathomatic->gfp, "%d%s", mathomatic->cur_equation + 1, PROMPT_STR); + fprintf(mathomatic->gfp, "%s", cp); } if (!nlt) - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } - set_error_level(cp); - return process(cp); + set_error_level(mathomatic, cp); + return process(mathomatic, cp); } #if SHELL_OUT @@ -800,21 +794,21 @@ char *cp; /* String to process; will be modified, so do not use constant strings * Returns exit status of command (0 if no error). */ int -shell_out(cp) -char *cp; /* shell command string */ +shell_out(MathoMatic* mathomatic, char *cp) +//char *cp; /* shell command string */ { int rv; - if (security_level > 0) { - error(_("Shelling out disabled by security level.")); + if (mathomatic->security_level > 0) { + error(mathomatic, _("Shelling out disabled by security level.")); return -1; } #if !SILENT - if (debug_level > 0) { - fprintf(gfp, _("Running shell command-line: %s\n"), cp); + if (mathomatic->debug_level > 0) { + fprintf(mathomatic->gfp, _("Running shell command-line: %s\n"), cp); } #endif - reset_attr(); + reset_attr(mathomatic); errno = 0; rv = system(cp); @@ -823,9 +817,9 @@ char *cp; /* shell command string */ } printf("\n"); - default_color(false); + default_color(mathomatic, false); if (rv) { - show_usage = false; /* already shows enough */ + mathomatic->show_usage = false; /* already shows enough */ } return rv; } @@ -837,12 +831,12 @@ char *cp; /* shell command string */ * Return new position in string or NULL if error. */ char * -parse_var2(vp, cp) -long *vp; /* pointer to returned variable in Mathomatic internal format */ -char *cp; /* pointer to variable name string */ +parse_var2(MathoMatic* mathomatic, long *vp, char *cp) +//long *vp; /* pointer to returned variable in Mathomatic internal format */ +//char *cp; /* pointer to variable name string */ { cp = skip_comma_space(cp); - cp = parse_var(vp, cp); + cp = parse_var(mathomatic, vp, cp); if (cp == NULL) { return NULL; } @@ -857,18 +851,17 @@ char *cp; /* pointer to variable name string */ * Return number of lines displayed. */ int -display_usage(pstr, i) -char *pstr; /* prefix string */ -int i; +display_usage(MathoMatic* mathomatic, char *pstr, int i) +//char *pstr; /* prefix string */ { int len = 0; - len += fprintf(gfp, "%s", pstr); - set_color(0); - len += fprintf(gfp, "%s", com_list[i].name); - default_color(false); - len += fprintf(gfp, " %s\n", com_list[i].usage); - if (screen_columns && len > screen_columns) { + len += fprintf(mathomatic->gfp, "%s", pstr); + set_color(mathomatic, 0); + len += fprintf(mathomatic->gfp, "%s", com_list[i].name); + default_color(mathomatic, false); + len += fprintf(mathomatic->gfp, " %s\n", com_list[i].usage); + if (mathomatic->screen_columns && len > mathomatic->screen_columns) { return 2; } else { return 1; @@ -881,25 +874,25 @@ int i; * Return the number of lines output. */ int -display_command(i) -int i; /* command table index of command */ +display_command(MathoMatic* mathomatic, int i) +//int i; /* command table index of command */ { int rows = 2; - fprintf(gfp, "%s - %s\n", com_list[i].name, com_list[i].info); - rows += display_usage("Usage: ", i); + fprintf(mathomatic->gfp, "%s - %s\n", com_list[i].name, com_list[i].info); + rows += display_usage(mathomatic, "Usage: ", i); if (com_list[i].secondary_name) { - fprintf(gfp, "Alternate name for this command: %s\n", com_list[i].secondary_name); + fprintf(mathomatic->gfp, "Alternate name for this command: %s\n", com_list[i].secondary_name); rows++; } if (com_list[i].extra) { - fprintf(gfp, "%s\n", com_list[i].extra); + fprintf(mathomatic->gfp, "%s\n", com_list[i].extra); rows++; } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); #if DEBUG if (com_list[i].secondary_name && com_list[i].extra) { - error_bug("Alternate name and extra info fields both set for this command, only one or the other is currently allowed."); + error_bug(mathomatic, "Alternate name and extra info fields both set for this command, only one or the other is currently allowed."); } #endif return rows; @@ -911,21 +904,20 @@ int i; /* command table index of command */ * Return the number of lines output. */ int -display_repeat_command(void) +display_repeat_command(MathoMatic* mathomatic) { - EP("repeat - Automatically repeat the following command over and over."); - fprintf(gfp, "Usage: "); - set_color(0); - fprintf(gfp, "repeat"); - default_color(false); - fprintf(gfp, " command arguments\n"); - EP("Not all commands are repeatable.\n"); + EP(mathomatic, "repeat - Automatically repeat the following command over and over."); + fprintf(mathomatic->gfp, "Usage: "); + set_color(mathomatic, 0); + fprintf(mathomatic->gfp, "repeat"); + default_color(mathomatic, false); + fprintf(mathomatic->gfp, " command arguments\n"); + EP(mathomatic, "Not all commands are repeatable.\n"); return 3; } int -read_examples(cpp) -char **cpp; +read_examples(MathoMatic* mathomatic, char **cpp) { int i; char *cp; @@ -934,7 +926,7 @@ char **cpp; cp = strdup(cpp[i]); if (cp == NULL) return false; - if (!display_process(cp)) { + if (!display_process(mathomatic, cp)) { free(cp); return false; } @@ -947,71 +939,70 @@ char **cpp; * Display a row of dashes to underline a title. */ void -underline_title(count) -int count; /* length of title, including newline */ +underline_title(MathoMatic* mathomatic, int count) +//int count; /* length of title, including newline */ { #if !NOT80COLUMNS int i; for (i = 1; i < count; i++) { - fprintf(gfp, "-"); + fprintf(mathomatic->gfp, "-"); } #endif - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } /* * The help command. */ int -help_cmd(cp) -char *cp; +help_cmd(MathoMatic* mathomatic, char *cp) { int i, j; char *cp1; int flag, html_out; int row; - html_out = ((html_flag == 2) || (html_flag && gfp == stdout)); + html_out = ((mathomatic->html_flag == 2) || (mathomatic->html_flag && mathomatic->gfp == stdout)); if (*cp == '\0') { intro: /* default help text: */ - SP("Mathomatic is a Computer Algebra System (CAS) and calculator program."); + SP(mathomatic, "Mathomatic is a Computer Algebra System (CAS) and calculator program."); #if !LIBRARY - SP("Type \"help options\" for a list of shell command-line startup options."); + SP(mathomatic, "Type \"help options\" for a list of shell command-line startup options."); #endif - SP("For helpful interactive examples, \"help examples\". For news, \"help news\"."); - SP("Type \"help equations\" for help with entering expressions and equations."); - SP("Type \"help all\" for a summary of all commands or \"help usage\" just for syntax."); - SP("Other help topics: constants, color, license, bugs, geometry, or conversions."); - SP("\"help\" or \"?\" followed by a command name will give info on that command."); - fprintf(gfp, "These are the %d commands for this version of Mathomatic:\n", ARR_CNT(com_list)); - set_color(0); + SP(mathomatic, "For helpful interactive examples, \"help examples\". For news, \"help news\"."); + SP(mathomatic, "Type \"help equations\" for help with entering expressions and equations."); + SP(mathomatic, "Type \"help all\" for a summary of all commands or \"help usage\" just for syntax."); + SP(mathomatic, "Other help topics: constants, color, license, bugs, geometry, or conversions."); + SP(mathomatic, "\"help\" or \"?\" followed by a command name will give info on that command."); + fprintf(mathomatic->gfp, "These are the %d commands for this version of Mathomatic:\n", ARR_CNT(com_list)); + set_color(mathomatic, 0); for (i = 0; i < ARR_CNT(com_list); i++) { if ((i % 5) == 0) - fprintf(gfp, "\n"); - j = 15 - fprintf(gfp, "%s", com_list[i].name); + fprintf(mathomatic->gfp, "\n"); + j = 15 - fprintf(mathomatic->gfp, "%s", com_list[i].name); for (; j > 0; j--) - fprintf(gfp, " "); + fprintf(mathomatic->gfp, " "); } - default_color(false); + default_color(mathomatic, false); - SP("\n\nTo see what is allowed at the main prompt, type \"help main\"."); - EP("For more help, go to the official website: www.mathomatic.org"); + SP(mathomatic, "\n\nTo see what is allowed at the main prompt, type \"help main\"."); + EP(mathomatic, "For more help, go to the official website: www.mathomatic.org"); } else if (strcasecmp(cp, "table") == 0) { - fprintf(gfp, "Mathomatic version %s Quick Reference Card\n", VERSION); - fprintf(gfp, "Command\tUsage\tNotes\n"); + fprintf(mathomatic->gfp, "Mathomatic version %s Quick Reference Card\n", VERSION); + fprintf(mathomatic->gfp, "Command\tUsage\tNotes\n"); for (i = 0; i < ARR_CNT(com_list); i++) { - fprintf(gfp, "%s", com_list[i].name); - fprintf(gfp, "\t%s %s", com_list[i].name, com_list[i].usage); + fprintf(mathomatic->gfp, "%s", com_list[i].name); + fprintf(mathomatic->gfp, "\t%s %s", com_list[i].name, com_list[i].usage); if (com_list[i].secondary_name) { - fprintf(gfp, "\tAlternate name for this command: %s", com_list[i].secondary_name); + fprintf(mathomatic->gfp, "\tAlternate name for this command: %s", com_list[i].secondary_name); } else if (com_list[i].extra) { - fprintf(gfp, "\t%s", com_list[i].extra); + fprintf(mathomatic->gfp, "\t%s", com_list[i].extra); } else { - fprintf(gfp, "\t%s", com_list[i].info); + fprintf(mathomatic->gfp, "\t%s", com_list[i].info); } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } return true; } @@ -1022,24 +1013,24 @@ char *cp; cp1++; if (cp1 != cp) { #if NOT80COLUMNS - EP("**********"); + EP(mathomatic, "**********"); #else - EP("*******************************************************************************"); + EP(mathomatic, "*******************************************************************************"); #endif - if (gfp != stdout) { - EP(""); + if (mathomatic->gfp != stdout) { + EP(mathomatic, ""); } /* first, see if the argument matches any command names */ flag = false; for (i = 0; i < ARR_CNT(com_list); i++) { if (strncasecmp(cp, com_list[i].name, cp1 - cp) == 0 || (com_list[i].secondary_name && strncasecmp(cp, com_list[i].secondary_name, cp1 - cp) == 0)) { - display_command(i); + display_command(mathomatic, i); flag = true; } } if (strncasecmp(cp, "repeat", cp1 - cp) == 0) { - display_repeat_command(); + display_repeat_command(mathomatic); flag = true; } if (flag) { @@ -1047,108 +1038,108 @@ char *cp; goto next_argument; } if (strncasecmp(cp, "startup", cp1 - cp) == 0) { - underline_title(EP("Help startup:")); - display_startup_message(gfp); + underline_title(mathomatic, EP(mathomatic, "Help startup:")); + display_startup_message(mathomatic, mathomatic->gfp); goto next_space; } #if !LIBRARY if (strncasecmp(cp, "options", cp1 - cp) == 0) { - underline_title(EP("Help startup options:")); - EP("In the Mathomatic application, these options can be applied, upon invocation:\n"); - usage(gfp); + underline_title(mathomatic, EP(mathomatic, "Help startup options:")); + EP(mathomatic, "In the Mathomatic application, these options can be applied, upon invocation:\n"); + usage(mathomatic->gfp); goto next_space; } #endif if (strncasecmp(cp, "examples", cp1 - cp) == 0) { - return read_examples(example_strings); + return read_examples(mathomatic, example_strings); } if (strncasecmp(cp, "geometry", cp1 - cp) == 0) { - underline_title(EP("Help geometry:")); - underline_title(EP("Commonly used standard (Euclidean) geometric formulas")); - return read_examples(geometry_strings); + underline_title(mathomatic, EP(mathomatic, "Help geometry:")); + underline_title(mathomatic, EP(mathomatic, "Commonly used standard (Euclidean) geometric formulas")); + return read_examples(mathomatic, geometry_strings); } if (strncasecmp(cp, "conversions", cp1 - cp) == 0) { - underline_title(EP("Help conversions:")); - SP("Commonly used metric/English conversions."); - SP("Select the equation you want (for example, with \"1\" or \"/celsius\")"); - SP("and type the unit name you want, to solve for it (like \"celsius\")."); - EP("Then type \"repeat calculate\" for units conversion and trying different values."); - underline_title(EP("These values are correct for the US and UK.")); - return read_examples(conversion_strings); + underline_title(mathomatic, EP(mathomatic, "Help conversions:")); + SP(mathomatic, "Commonly used metric/English conversions."); + SP(mathomatic, "Select the equation you want (for example, with \"1\" or \"/celsius\")"); + SP(mathomatic, "and type the unit name you want, to solve for it (like \"celsius\")."); + EP(mathomatic, "Then type \"repeat calculate\" for units conversion and trying different values."); + underline_title(mathomatic, EP(mathomatic, "These values are correct for the US and UK.")); + return read_examples(mathomatic, conversion_strings); } if (strncasecmp(cp, "main", cp1 - cp) == 0 || strncasecmp(cp, "prompt", cp1 - cp) == 0) { - underline_title(EP("Help main or prompt:")); - EP("At the Mathomatic main prompt, you may enter:\n"); + underline_title(mathomatic, EP(mathomatic, "Help main or prompt:")); + EP(mathomatic, "At the Mathomatic main prompt, you may enter:\n"); - EP(" * a numerical expression, which is instantly evaluated and displayed with"); - EP(" the calculate command (autocalc) (see \"help constants\" and autodelete),"); - EP(" * an algebraic expression or equation, which is stored and made the current"); - EP(" equation (see \"help expressions\"),"); - EP(" * a variable to solve the current equation for (autosolve),"); - EP(" * an equation number to select as the current equation (autoselect),"); - EP(" * a slash (/) or pound sign (#) followed by a variable name to search all"); - EP(" equations spaces forward or backward for, respectively,"); - EP(" * a Mathomatic command (see \"help all\"),"); - EP(" * a question mark (?) for quick, short help (same as the help command),"); - EP(" * a semicolon (;) followed by a line comment (everything on a line after a"); - EP(" semicolon is ignored),"); + EP(mathomatic, " * a numerical expression, which is instantly evaluated and displayed with"); + EP(mathomatic, " the calculate command (autocalc) (see \"help constants\" and autodelete),"); + EP(mathomatic, " * an algebraic expression or equation, which is stored and made the current"); + EP(mathomatic, " equation (see \"help expressions\"),"); + EP(mathomatic, " * a variable to solve the current equation for (autosolve),"); + EP(mathomatic, " * an equation number to select as the current equation (autoselect),"); + EP(mathomatic, " * a slash (/) or pound sign (#) followed by a variable name to search all"); + EP(mathomatic, " equations spaces forward or backward for, respectively,"); + EP(mathomatic, " * a Mathomatic command (see \"help all\"),"); + EP(mathomatic, " * a question mark (?) for quick, short help (same as the help command),"); + EP(mathomatic, " * a semicolon (;) followed by a line comment (everything on a line after a"); + EP(mathomatic, " semicolon is ignored),"); #if SHELL_OUT - EP(" * or an exclamation point (!) followed by a shell or system command. \"!\" by"); - EP(" itself invokes the default shell. \"!\" is also the factorial operator.\n"); + EP(mathomatic, " * or an exclamation point (!) followed by a shell or system command. \"!\" by"); + EP(mathomatic, " itself invokes the default shell. \"!\" is also the factorial operator.\n"); #else - EP(" * shelling out (!) is disabled by security level or system type."); - EP(" The factorial operator \"!\" still works.\n"); + EP(mathomatic, " * shelling out (!) is disabled by security level or system type."); + EP(mathomatic, " The factorial operator \"!\" still works.\n"); #endif - SP("If a colon (:) starts the line, preceding any of the above input to the main"); - SP("prompt, it will always return with successful status, preventing any current"); - EP("read command operation from aborting due to an error return status."); + SP(mathomatic, "If a colon (:) starts the line, preceding any of the above input to the main"); + SP(mathomatic, "prompt, it will always return with successful status, preventing any current"); + EP(mathomatic, "read command operation from aborting due to an error return status."); goto next_space; } if (strncasecmp(cp, "copyrights", cp1 - cp) == 0 || strncasecmp(cp, "licenses", cp1 - cp) == 0 || strncasecmp(cp, "licences", cp1 - cp) == 0) { - underline_title(EP("Copyright and License for Mathomatic")); + underline_title(mathomatic, EP(mathomatic, "Copyright and License for Mathomatic")); - fprintf(gfp, "%s", license_string); + fprintf(mathomatic->gfp, "%s", license_string); goto next_space; } if (strncasecmp(cp, "bugs", cp1 - cp) == 0) { - underline_title(EP("Help bugs:")); - SP("Please report bugs on the Mathomatic project site on Launchpad.net:"); - EP("https://launchpad.net/mathomatic"); - EP("Launchpad features a complete bug management system."); + underline_title(mathomatic, EP(mathomatic, "Help bugs:")); + SP(mathomatic, "Please report bugs on the Mathomatic project site on Launchpad.net:"); + EP(mathomatic, "https://launchpad.net/mathomatic"); + EP(mathomatic, "Launchpad features a complete bug management system."); #if linux - SP("\nIn Debian, a convenient way to report bugs from the shell command-line"); - EP("is \"reportbug mathomatic\". In Ubuntu, use \"apport-bug mathomatic\"."); + SP(mathomatic, "\nIn Debian, a convenient way to report bugs from the shell command-line"); + EP(mathomatic, "is \"reportbug mathomatic\". In Ubuntu, use \"apport-bug mathomatic\"."); #endif - SP("\nPlease include the following information when reporting bugs,"); - EP("from the \"version status\" command:\n"); + SP(mathomatic, "\nPlease include the following information when reporting bugs,"); + EP(mathomatic, "from the \"version status\" command:\n"); - version_report(); + version_report(mathomatic); goto next_space; } #if SHELL_OUT if (strncasecmp(cp, "news", cp1 - cp) == 0) { - underline_title(EP("What's New!")); - shell_out("w3m http://mathomatic.org/NEWS"); + underline_title(mathomatic, EP(mathomatic, "What's New!")); + shell_out(mathomatic, "w3m http://mathomatic.org/NEWS"); goto next_space; } #endif if (strncasecmp(cp, "usage", cp1 - cp) == 0 || strncasecmp(cp, "syntax", cp1 - cp) == 0) { - underline_title(EP("Mathomatic Command Usage Syntax")); + underline_title(mathomatic, EP(mathomatic, "Mathomatic Command Usage Syntax")); for (i = 0, row = 3; i < ARR_CNT(com_list);) { - row += display_usage("", i); + row += display_usage(mathomatic, "", i); i++; if (i >= ARR_CNT(com_list)) break; - if (screen_rows && row >= (screen_rows - 3)) { + if (mathomatic->screen_rows && row >= (mathomatic->screen_rows - 3)) { row = 2; - if (gfp == stdout) { - if (!pause_cmd("")) + if (mathomatic->gfp == stdout) { + if (!pause_cmd(mathomatic, "")) return false; } } @@ -1156,75 +1147,75 @@ char *cp; goto next_space; } if (cp[0] == '!') { - SP("A command preceded by an exclamation point (such as \"!ls\") is taken to"); - SP("be a shell command and is passed unchanged to the shell (/bin/sh) when"); - SP("Mathomatic is not in secure mode. \"!\" by itself invokes the default shell,"); - EP("which is specified in the SHELL environment variable.\n"); + SP(mathomatic, "A command preceded by an exclamation point (such as \"!ls\") is taken to"); + SP(mathomatic, "be a shell command and is passed unchanged to the shell (/bin/sh) when"); + SP(mathomatic, "Mathomatic is not in secure mode. \"!\" by itself invokes the default shell,"); + EP(mathomatic, "which is specified in the SHELL environment variable.\n"); - EP("\"!\" is also the factorial operator."); + EP(mathomatic, "\"!\" is also the factorial operator."); goto next_space; } if (is_mathomatic_operator(cp[0]) || strncasecmp(cp, "operators", cp1 - cp) == 0 || strncasecmp(cp, "expressions", cp1 - cp) == 0 || strncasecmp(cp, "equations", cp1 - cp) == 0) { - underline_title(EP("Help equations:")); - SP("To enter an expression or equation, type or copy/paste it in at the prompt."); - EP("Operators have precedence decreasing as indicated:\n"); + underline_title(mathomatic, EP(mathomatic, "Help equations:")); + SP(mathomatic, "To enter an expression or equation, type or copy/paste it in at the prompt."); + EP(mathomatic, "Operators have precedence decreasing as indicated:\n"); - EP(" ! factorial (same as gamma(x+1) function; highest precedence)"); - EP(" ** or ^ power (exponentiation; high precedence)"); - EP(" * multiply / divide % modulus // integral divide"); - EP(" + add - subtract or negate"); - EP(" = equate (denotes equivalence; lowest precedence)\n"); + EP(mathomatic, " ! factorial (same as gamma(x+1) function; highest precedence)"); + EP(mathomatic, " ** or ^ power (exponentiation; high precedence)"); + EP(mathomatic, " * multiply / divide % modulus // integral divide"); + EP(mathomatic, " + add - subtract or negate"); + EP(mathomatic, " = equate (denotes equivalence; lowest precedence)\n"); - SP("Multiple operators of the same precedence level are grouped left to right."); - SP("Parentheses are used to override operator precedence and group things together."); - EP("Valid parentheses characters are () and {}. [] are reserved for arrays.\n"); + SP(mathomatic, "Multiple operators of the same precedence level are grouped left to right."); + SP(mathomatic, "Parentheses are used to override operator precedence and group things together."); + EP(mathomatic, "Valid parentheses characters are () and {}. [] are reserved for arrays.\n"); - SP("Variables consist of any combination of letters, digits, and underscores (_),"); - SP("and \"set special_variable_characters\". Variables never start with a digit."); - EP("Predefined variables follow (\"help constants\" shows predefined constants):\n"); + SP(mathomatic, "Variables consist of any combination of letters, digits, and underscores (_),"); + SP(mathomatic, "and \"set special_variable_characters\". Variables never start with a digit."); + EP(mathomatic, "Predefined variables follow (\"help constants\" shows predefined constants):\n"); if (html_out) { - EP(" sign, sign1, sign2, … - may only be ±1"); - EP(" integer, integer1, … - may be any integer value\n"); + EP(mathomatic, " sign, sign1, sign2, … - may only be ±1"); + EP(mathomatic, " integer, integer1, … - may be any integer value\n"); } else { - EP(" sign, sign1, sign2, ... - may only be +1 or -1"); - EP(" integer, integer1, ... - may be any integer value\n"); + EP(mathomatic, " sign, sign1, sign2, ... - may only be +1 or -1"); + EP(mathomatic, " integer, integer1, ... - may be any integer value\n"); } - EP("Absolute value notation \"|x|\" and dual polarity \"+/-x\" are understood."); + EP(mathomatic, "Absolute value notation \"|x|\" and dual polarity \"+/-x\" are understood."); goto next_space; } if (isdigit(cp[0]) || cp[0] == '.' || strncasecmp(cp, "constants", cp1 - cp) == 0 || strncasecmp(cp, "decimal", cp1 - cp) == 0 || strncasecmp(cp, "floats", cp1 - cp) == 0 || strncasecmp(cp, "doubles", cp1 - cp) == 0 || strncasecmp(cp, "hexadecimal", cp1 - cp) == 0) { - underline_title(EP("Help constants:")); - SP("Constants are displayed as decimal, double precision floating point values,"); - SP("rounded to 14 decimal digits. They are displayed in standard or scientific"); - SP("notation, whichever is shortest. They can be entered in standard, scientific,"); - SP("or hexadecimal notation. Any constant can be entered in hexadecimal (base 16)"); - SP("by starting it with \"0x\". Excepting named constants, constants always start"); - EP("with a decimal digit (0..9), a period, or a dash (-).\n"); + underline_title(mathomatic, EP(mathomatic, "Help constants:")); + SP(mathomatic, "Constants are displayed as decimal, double precision floating point values,"); + SP(mathomatic, "rounded to 14 decimal digits. They are displayed in standard or scientific"); + SP(mathomatic, "notation, whichever is shortest. They can be entered in standard, scientific,"); + SP(mathomatic, "or hexadecimal notation. Any constant can be entered in hexadecimal (base 16)"); + SP(mathomatic, "by starting it with \"0x\". Excepting named constants, constants always start"); + EP(mathomatic, "with a decimal digit (0..9), a period, or a dash (-).\n"); - EP("Named constants follow:\n"); + EP(mathomatic, "Named constants follow:\n"); if (html_out) { - EP(" e, ê, or e# - the universal constant e (2.718281828…)"); - EP(" pi or pi# - the universal constant pi (3.1415926…)"); - EP(" i, î, or i# - the imaginary unit (√(-1))"); + EP(mathomatic, " e, ê, or e# - the universal constant e (2.718281828…)"); + EP(mathomatic, " pi or pi# - the universal constant pi (3.1415926…)"); + EP(mathomatic, " i, î, or i# - the imaginary unit (√(-1))"); } else { - EP(" e or e# - the universal constant e (2.718281828...)"); - EP(" pi or pi# - the universal constant pi (3.1415926...)"); - EP(" i or i# - the imaginary unit (square root of -1)"); + EP(mathomatic, " e or e# - the universal constant e (2.718281828...)"); + EP(mathomatic, " pi or pi# - the universal constant pi (3.1415926...)"); + EP(mathomatic, " i or i# - the imaginary unit (square root of -1)"); } - EP("The above constants may also be used anywhere variables are required."); - EP(" inf - floating point infinity constant"); - EP(" NaN - invalid floating point result\n"); + EP(mathomatic, "The above constants may also be used anywhere variables are required."); + EP(mathomatic, " inf - floating point infinity constant"); + EP(mathomatic, " NaN - invalid floating point result\n"); - EP("Double precision floating point limits:"); - fprintf(gfp, "The largest valid constant is +/-%.7g (slightly less than 2^1024).\n", DBL_MAX); - fprintf(gfp, "The smallest valid constant is +/-%.7g or 0.\n", DBL_MIN); + EP(mathomatic, "Double precision floating point limits:"); + fprintf(mathomatic->gfp, "The largest valid constant is +/-%.7g (slightly less than 2^1024).\n", DBL_MAX); + fprintf(mathomatic->gfp, "The smallest valid constant is +/-%.7g or 0.\n", DBL_MIN); goto next_space; } if (strncasecmp(cp, "introduction", cp1 - cp) == 0) { @@ -1232,80 +1223,80 @@ char *cp; goto intro; } if (strncasecmp(cp, "colors", cp1 - cp) == 0 || strncasecmp(cp, "colours", cp1 - cp) == 0) { - underline_title(EP("Help colors:")); - if (color_flag) { - if (color_flag == 2) { - fprintf(gfp, "Alternative "); + underline_title(mathomatic, EP(mathomatic, "Help colors:")); + if (mathomatic->color_flag) { + if (mathomatic->color_flag == 2) { + fprintf(mathomatic->gfp, "Alternative "); } - fprintf(gfp, "Color mode is currently on, bold mode is currently %s.\n", bold_colors ? "on" : "off"); - if (html_flag) { - EP("HTML mode is currently on, so color mode is HTML."); + fprintf(mathomatic->gfp, "Color mode is currently on, bold mode is currently %s.\n", mathomatic->bold_colors ? "on" : "off"); + if (mathomatic->html_flag) { + EP(mathomatic, "HTML mode is currently on, so color mode is HTML."); } else { #if WIN32_CONSOLE_COLORS - if (color_flag == 2) { - EP("Using ANSI color mode."); + if (mathomatic->color_flag == 2) { + EP(mathomatic, "Using ANSI color mode."); } else { - EP("Using WIN32 CONSOLE color mode."); + EP(mathomatic, "Using WIN32 CONSOLE color mode."); } #else - EP("Using ANSI color mode."); + EP(mathomatic, "Using ANSI color mode."); #endif } - if (display_all_colors()) { - fprintf(gfp, " are the available colors.\n"); + if (display_all_colors(mathomatic)) { + fprintf(mathomatic->gfp, " are the available colors.\n"); } else { - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } } else { - EP("Color mode is currently turned off."); + EP(mathomatic, "Color mode is currently turned off."); } #if !LIBRARY - SP("\nIn the Mathomatic application,"); - EP("color mode is toggled by the -c option on the shell command-line, like this:\n"); + SP(mathomatic, "\nIn the Mathomatic application,"); + EP(mathomatic, "color mode is toggled by the -c option on the shell command-line, like this:\n"); - EP(" $ mathomatic -c\n"); + EP(mathomatic, " $ mathomatic -c\n"); - SP("Color modes like ANSI color mode output ANSI terminal escape sequences"); - SP("to make each level of parentheses a different color, improving readability."); - SP("If ANSI color mode is on, an ANSI compatible terminal emulator is required."); - SP("If the colors are hard to see, use the -b option instead, which will always"); - EP("turn on bold color mode, increasing the color brightness.\n"); + SP(mathomatic, "Color modes like ANSI color mode output ANSI terminal escape sequences"); + SP(mathomatic, "to make each level of parentheses a different color, improving readability."); + SP(mathomatic, "If ANSI color mode is on, an ANSI compatible terminal emulator is required."); + SP(mathomatic, "If the colors are hard to see, use the -b option instead, which will always"); + EP(mathomatic, "turn on bold color mode, increasing the color brightness.\n"); - EP("These and other startup command-line options are listed with \"help options\"."); + EP(mathomatic, "These and other startup command-line options are listed with \"help options\"."); - SP("\nThe Mathomatic set commands \"set color\" and \"set bold color\" also"); - SP("turn on color and bold color mode for the current session. \"set no bold\""); - SP("restores dim colors and \"set no color\" always turns color mode off."); - EP("When Mathomatic exits, these settings are lost, unless \"set save\" was entered."); + SP(mathomatic, "\nThe Mathomatic set commands \"set color\" and \"set bold color\" also"); + SP(mathomatic, "turn on color and bold color mode for the current session. \"set no bold\""); + SP(mathomatic, "restores dim colors and \"set no color\" always turns color mode off."); + EP(mathomatic, "When Mathomatic exits, these settings are lost, unless \"set save\" was entered."); #endif goto next_space; } if (is_all(cp)) { - underline_title(fprintf(gfp, "Mathomatic Version %s Command Summary\n", VERSION)); + underline_title(mathomatic, fprintf(mathomatic->gfp, "Mathomatic Version %s Command Summary\n", VERSION)); for (i = 0, row = 3; i < ARR_CNT(com_list);) { - row += display_command(i); + row += display_command(mathomatic, i); i++; if (i >= ARR_CNT(com_list)) break; - if (screen_rows && row >= (screen_rows - 5)) { + if (mathomatic->screen_rows && row >= (mathomatic->screen_rows - 5)) { row = 1; - if (gfp == stdout) { - if (!pause_cmd("")) + if (mathomatic->gfp == stdout) { + if (!pause_cmd(mathomatic, "")) return false; } } } - fprintf(gfp, "End of command list. Total of %d different commands.\n", ARR_CNT(com_list)); + fprintf(mathomatic->gfp, "End of command list. Total of %d different commands.\n", ARR_CNT(com_list)); goto next_space; } - error(_("Unrecognized help topic or command.")); + error(mathomatic, _("Unrecognized help topic or command.")); return false; } return true; next_space: - if (gfp != stdout) { - EP(""); + if (mathomatic->gfp != stdout) { + EP(mathomatic, ""); } cp = skip_comma_space(cp1); goto next_argument; diff --git a/includes.h b/includes.h index 2e5667a..02164b8 100644 --- a/includes.h +++ b/includes.h @@ -113,7 +113,7 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "standard.h" /* a standard include file for any math program written in C */ #include "am.h" /* the main include file for Mathomatic, contains tunable parameters */ #include "complex.h" /* floating point complex number arithmetic function prototypes */ +#include "externs.h" /* global variable extern definitions */ #include "proto.h" /* global function prototypes, made with cproto utility */ #include "altproto.h" /* backup global function prototypes, in case of no proto.h */ -#include "externs.h" /* global variable extern definitions */ #include "blt.h" /* blt() function definition */ diff --git a/integrate.c b/integrate.c index 07bb246..936a7a7 100644 --- a/integrate.c +++ b/integrate.c @@ -24,21 +24,21 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "includes.h" -static int integrate_sub(token_type *equation, int *np, int loc, int eloc, long v); -static int laplace_sub(token_type *equation, int *np, int loc, int eloc, long v); -static int inv_laplace_sub(token_type *equation, int *np, int loc, int eloc, long v); +static int integrate_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v); +static int laplace_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v); +static int inv_laplace_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v); -static int constant_var_number = 1; /* makes unique numbers for the constant of integration */ +//static int constant_var_number = 1; /* makes unique numbers for the constant of integration */ /* * Make variable "v" always raised to a power, * unless it is on the right side of a power operator. */ void -make_powers(equation, np, v) -token_type *equation; /* pointer to beginning of equation side */ -int *np; /* pointer to length of equation side */ -long v; /* Mathomatic variable */ +make_powers(MathoMatic* mathomatic, token_type *equation, int *np, long v) +//token_type *equation; /* pointer to beginning of equation side */ +//int *np; /* pointer to length of equation side */ +//long v; /* Mathomatic variable */ { int i; int level; @@ -52,8 +52,8 @@ long v; /* Mathomatic variable */ } if (equation[i].kind == VARIABLE && equation[i].token.variable == v) { if ((i + 1) >= *np || equation[i+1].token.operatr != POWER) { - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } level++; equation[i].level = level; @@ -81,22 +81,22 @@ long v; /* Mathomatic variable */ * Return true if successful. */ int -int_dispatch(equation, np, v, func) -token_type *equation; /* pointer to beginning of equation side to integrate */ -int *np; /* pointer to length of equation side */ -long v; /* integration variable */ -int (*func)(token_type *equation, int *np, int loc, int eloc, long v); /* integration function to call for each term */ +int_dispatch(MathoMatic* mathomatic, token_type *equation, int *np, long v, int (*func)(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v)) +//token_type *equation; /* pointer to beginning of equation side to integrate */ +//int *np; /* pointer to length of equation side */ +//long v; /* integration variable */ +//int (*func)(token_type *equation, int *np, int loc, int eloc, long v); /* integration function to call for each term */ { int i, j; - make_powers(equation, np, v); + make_powers(mathomatic, equation, np, v); for (j = 0, i = 1;; i += 2) { if (i >= *np) { - return((*func)(equation, np, j, i, v)); + return((*func)(mathomatic, equation, np, j, i, v)); } if (equation[i].level == 1 && (equation[i].token.operatr == PLUS || equation[i].token.operatr == MINUS)) { - if (!(*func)(equation, np, j, i, v)) { + if (!(*func)(mathomatic, equation, np, j, i, v)) { return false; } for (i = j + 1;; i += 2) { @@ -119,12 +119,12 @@ int (*func)(token_type *equation, int *np, int loc, int eloc, long v); /* integ * Return true if successful. */ static int -integrate_sub(equation, np, loc, eloc, v) -token_type *equation; /* pointer to beginning of equation side */ -int *np; /* pointer to length of equation side */ -int loc; /* beginning location of term */ -int eloc; /* end location of term */ -long v; /* variable of integration */ +integrate_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v) +//token_type *equation; /* pointer to beginning of equation side */ +//int *np; /* pointer to length of equation side */ +//int loc; /* beginning location of term */ +//int eloc; /* end location of term */ +//long v; /* variable of integration */ { int i, j, k; int len; @@ -132,7 +132,7 @@ long v; /* variable of integration */ int count; int div_flag; - level = min_level(&equation[loc], eloc - loc); + level = min_level(mathomatic, &equation[loc], eloc - loc); /* determine if the term is a polynomial term in "v" */ for (i = loc, count = 0; i < eloc; i += 2) { if (equation[i].kind == VARIABLE && equation[i].token.variable == v) { @@ -183,8 +183,8 @@ long v; /* variable of integration */ && equation[i].kind == CONSTANT && equation[i].token.constant == 1.0) return false; - if (*np + 2 > n_tokens) - error_huge(); + if (*np + 2 > mathomatic->n_tokens) + error_huge(mathomatic); for (j = i; j < eloc && equation[j].level >= level; j++) equation[j].level++; equation[i-3].token.operatr = TIMES; @@ -201,8 +201,8 @@ long v; /* variable of integration */ for (j = i; j < eloc && equation[j].level >= level; j++) equation[j].level++; len = j - i; - if (*np + len + 5 > n_tokens) - error_huge(); + if (*np + len + 5 > mathomatic->n_tokens) + error_huge(mathomatic); blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type)); *np += 2; eloc += 2; @@ -224,8 +224,8 @@ long v; /* variable of integration */ return true; } } - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[eloc+2], &equation[eloc], (*np - eloc) * sizeof(token_type)); *np += 2; @@ -243,8 +243,7 @@ long v; /* variable of integration */ * The integrate command. */ int -integrate_cmd(cp) -char *cp; +integrate_cmd(MathoMatic* mathomatic, char *cp) { int i, j; int len; @@ -257,13 +256,13 @@ char *cp; long l1; cp_start = cp; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - n_tlhs = 0; - n_trhs = 0; - solved = solved_equation(cur_equation); - i = next_espace(); + mathomatic->n_tlhs = 0; + mathomatic->n_trhs = 0; + solved = solved_equation(mathomatic, mathomatic->cur_equation); + i = next_espace(mathomatic); for (;; cp = skip_param(cp)) { if (strcmp_tospace(cp, "definite") == 0) { definite_flag = true; @@ -276,27 +275,27 @@ char *cp; break; } if (constant_flag && definite_flag) { - error(_("Conflicting options given.")); + error(mathomatic, _("Conflicting options given.")); return false; } - if (n_rhs[cur_equation]) { + if (mathomatic->n_rhs[mathomatic->cur_equation]) { if (!solved) { - warning(_("Not a solved equation.")); + warning(mathomatic, _("Not a solved equation.")); } - debug_string(0, _("Only the RHS will be transformed.")); - source = rhs[cur_equation]; - nps = &n_rhs[cur_equation]; - dest = rhs[i]; - np = &n_rhs[i]; + debug_string(mathomatic, 0, _("Only the RHS will be transformed.")); + source = mathomatic->rhs[mathomatic->cur_equation]; + nps = &mathomatic->n_rhs[mathomatic->cur_equation]; + dest = mathomatic->rhs[i]; + np = &mathomatic->n_rhs[i]; } else { - source = lhs[cur_equation]; - nps = &n_lhs[cur_equation]; - dest = lhs[i]; - np = &n_lhs[i]; + source = mathomatic->lhs[mathomatic->cur_equation]; + nps = &mathomatic->n_lhs[mathomatic->cur_equation]; + dest = mathomatic->lhs[i]; + np = &mathomatic->n_lhs[i]; } if (*cp) { - if (isvarchar(*cp)) { - cp = parse_var2(&v, cp); + if (isvarchar(mathomatic, *cp)) { + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } @@ -305,60 +304,60 @@ char *cp; integrate_order = strtod(cp, &cp); } if (!isfinite(integrate_order) || integrate_order <= 0 || fmod(integrate_order, 1.0) != 0.0) { - error(_("The order must be a positive integer.")); + error(mathomatic, _("The order must be a positive integer.")); return false; } } if (*cp) { cp = skip_comma_space(cp); - input_column += (cp - cp_start); - cp = parse_expr(tlhs, &n_tlhs, cp, false); - if (cp == NULL || n_tlhs <= 0) { + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, cp, false); + if (cp == NULL || mathomatic->n_tlhs <= 0) { return false; } } if (*cp) { cp_start = cp; cp = skip_comma_space(cp); - input_column += (cp - cp_start); - cp = parse_expr(trhs, &n_trhs, cp, false); - if (cp == NULL || extra_characters(cp) || n_trhs <= 0) { + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, cp, false); + if (cp == NULL || extra_characters(mathomatic, cp) || mathomatic->n_trhs <= 0) { return false; } } - show_usage = false; + mathomatic->show_usage = false; if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } #if !SILENT - list_var(v, 0); - if (n_rhs[cur_equation]) { - fprintf(gfp, _("Integrating the RHS with respect to %s"), var_str); + list_var(mathomatic, v, 0); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + fprintf(mathomatic->gfp, _("Integrating the RHS with respect to %s"), mathomatic->var_str); } else { - fprintf(gfp, _("Integrating with respect to %s"), var_str); + fprintf(mathomatic->gfp, _("Integrating with respect to %s"), mathomatic->var_str); } if (integrate_order != 1.0) { - fprintf(gfp, _(" %.*g times"), precision, integrate_order); + fprintf(mathomatic->gfp, _(" %.*g times"), mathomatic->precision, integrate_order); } - fprintf(gfp, _(" and simplifying...\n")); + fprintf(mathomatic->gfp, _(" and simplifying...\n")); #endif - partial_flag = false; - uf_simp(source, nps); - partial_flag = true; - factorv(source, nps, v); + mathomatic->partial_flag = false; + uf_simp(mathomatic, source, nps); + mathomatic->partial_flag = true; + factorv(mathomatic, source, nps, v); blt(dest, source, *nps * sizeof(token_type)); n1 = *nps; for (l1 = 0; l1 < integrate_order; l1++) { - if (!int_dispatch(dest, &n1, v, integrate_sub)) { - error(_("Integration failed, not a polynomial.")); + if (!int_dispatch(mathomatic, dest, &n1, v, integrate_sub)) { + error(mathomatic, _("Integration failed, not a polynomial.")); return false; } if (constant_flag) { - if (n1 + 2 > n_tokens) { - error_huge(); + if (n1 + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } for (j = 0; j < n1; j++) { dest[j].level++; @@ -369,66 +368,66 @@ char *cp; n1++; dest[n1].kind = VARIABLE; dest[n1].level = 1; - snprintf(var_name_buf, sizeof(var_name_buf), "C_%d", constant_var_number); - if (parse_var(&dest[n1].token.variable, var_name_buf) == NULL) { + snprintf(var_name_buf, sizeof(var_name_buf), "C_%d", mathomatic->constant_var_number); + if (parse_var(mathomatic, &dest[n1].token.variable, var_name_buf) == NULL) { return false; } n1++; - constant_var_number++; - if (constant_var_number < 0) { - constant_var_number = 1; + mathomatic->constant_var_number++; + if (mathomatic->constant_var_number < 0) { + mathomatic->constant_var_number = 1; } } - simp_loop(dest, &n1); + simp_loop(mathomatic, dest, &n1); } if (definite_flag) { - if (n_tlhs == 0) { - my_strlcpy(prompt_str, _("Enter lower bound: "), sizeof(prompt_str)); - if (!get_expr(tlhs, &n_tlhs)) { + if (mathomatic->n_tlhs == 0) { + my_strlcpy(mathomatic->prompt_str, _("Enter lower bound: "), sizeof(mathomatic->prompt_str)); + if (!get_expr(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) { return false; } } - if (n_trhs == 0) { - my_strlcpy(prompt_str, _("Enter upper bound: "), sizeof(prompt_str)); - if (!get_expr(trhs, &n_trhs)) { + if (mathomatic->n_trhs == 0) { + my_strlcpy(mathomatic->prompt_str, _("Enter upper bound: "), sizeof(mathomatic->prompt_str)); + if (!get_expr(mathomatic, mathomatic->trhs, &mathomatic->n_trhs)) { return false; } } - blt(scratch, dest, n1 * sizeof(token_type)); + blt(mathomatic->scratch, dest, n1 * sizeof(token_type)); n2 = n1; - subst_var_with_exp(scratch, &n2, tlhs, n_tlhs, v); - subst_var_with_exp(dest, &n1, trhs, n_trhs, v); - if (n1 + 1 + n2 > n_tokens) { - error_huge(); + subst_var_with_exp(mathomatic, mathomatic->scratch, &n2, mathomatic->tlhs, mathomatic->n_tlhs, v); + subst_var_with_exp(mathomatic, dest, &n1, mathomatic->trhs, mathomatic->n_trhs, v); + if (n1 + 1 + n2 > mathomatic->n_tokens) { + error_huge(mathomatic); } for (j = 0; j < n1; j++) { dest[j].level++; } for (j = 0; j < n2; j++) { - scratch[j].level++; + mathomatic->scratch[j].level++; } dest[n1].kind = OPERATOR; dest[n1].level = 1; dest[n1].token.operatr = MINUS; n1++; - blt(&dest[n1], scratch, n2 * sizeof(token_type)); + blt(&dest[n1], mathomatic->scratch, n2 * sizeof(token_type)); n1 += n2; } - simpa_side(dest, &n1, false, false); + simpa_side(mathomatic, dest, &n1, false, false); *np = n1; - if (n_rhs[cur_equation]) { - blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_lhs[i] = n_lhs[cur_equation]; - if (solved && isvarchar('\'')) { - len = list_var(lhs[i][0].token.variable, 0); - for (l1 = 0; l1 < integrate_order && len > 0 && var_str[len-1] == '\''; l1++) { - var_str[--len] = '\0'; + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + blt(mathomatic->lhs[i], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_lhs[i] = mathomatic->n_lhs[mathomatic->cur_equation]; + if (solved && isvarchar(mathomatic, '\'')) { + len = list_var(mathomatic, mathomatic->lhs[i][0].token.variable, 0); + for (l1 = 0; l1 < integrate_order && len > 0 && mathomatic->var_str[len-1] == '\''; l1++) { + mathomatic->var_str[--len] = '\0'; } - parse_var(&lhs[i][0].token.variable, var_str); + parse_var(mathomatic, &mathomatic->lhs[i][0].token.variable, mathomatic->var_str); } } - cur_equation = i; - return return_result(cur_equation); + mathomatic->cur_equation = i; + return return_result(mathomatic, mathomatic->cur_equation); } /* @@ -437,17 +436,13 @@ char *cp; * Return true if successful. */ static int -laplace_sub(equation, np, loc, eloc, v) -token_type *equation; -int *np; -int loc, eloc; -long v; +laplace_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v) { int i, j, k; int len; int level, mlevel; - mlevel = min_level(&equation[loc], eloc - loc) + 1; + mlevel = min_level(mathomatic, &equation[loc], eloc - loc) + 1; for (j = loc; j < eloc; j++) equation[j].level += 2; for (i = loc; i < eloc; i += 2) { @@ -460,8 +455,8 @@ long v; for (j = i; j < eloc && equation[j].level >= level; j++) equation[j].level++; len = j - i; - if (*np + len + 7 > n_tokens) - error_huge(); + if (*np + len + 7 > mathomatic->n_tokens) + error_huge(mathomatic); blt(&equation[j+4], &equation[j], (*np - j) * sizeof(token_type)); *np += 4; eloc += 4; @@ -502,8 +497,8 @@ long v; return true; } } - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[eloc+2], &equation[eloc], (*np - eloc) * sizeof(token_type)); *np += 2; @@ -523,17 +518,13 @@ long v; * Return true if successful. */ static int -inv_laplace_sub(equation, np, loc, eloc, v) -token_type *equation; -int *np; -int loc, eloc; -long v; +inv_laplace_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v) { int i, j, k; int len; int level, mlevel; - mlevel = min_level(&equation[loc], eloc - loc) + 1; + mlevel = min_level(mathomatic, &equation[loc], eloc - loc) + 1; for (j = loc; j < eloc; j++) equation[j].level += 2; for (i = loc; i < eloc; i += 2) { @@ -548,8 +539,8 @@ long v; for (j = i; j < eloc && equation[j].level >= level; j++) equation[j].level++; len = j - i; - if (*np + len + 7 > n_tokens) - error_huge(); + if (*np + len + 7 > mathomatic->n_tokens) + error_huge(mathomatic); equation[i-3].token.operatr = TIMES; blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type)); *np += 2; @@ -589,8 +580,7 @@ long v; * The laplace command. */ int -laplace_cmd(cp) -char *cp; +laplace_cmd(MathoMatic* mathomatic, char *cp) { int i; long v = 0; @@ -598,84 +588,83 @@ char *cp; token_type *source, *dest; int n1, *nps, *np; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - solved = solved_equation(cur_equation); - i = next_espace(); - if (n_rhs[cur_equation]) { + solved = solved_equation(mathomatic, mathomatic->cur_equation); + i = next_espace(mathomatic); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { if (!solved) { - warning(_("Not a solved equation.")); + warning(mathomatic, _("Not a solved equation.")); } #if !SILENT - fprintf(gfp, _("Only the RHS will be transformed.\n")); + fprintf(mathomatic->gfp, _("Only the RHS will be transformed.\n")); #endif - source = rhs[cur_equation]; - nps = &n_rhs[cur_equation]; - dest = rhs[i]; - np = &n_rhs[i]; + source = mathomatic->rhs[mathomatic->cur_equation]; + nps = &mathomatic->n_rhs[mathomatic->cur_equation]; + dest = mathomatic->rhs[i]; + np = &mathomatic->n_rhs[i]; } else { - source = lhs[cur_equation]; - nps = &n_lhs[cur_equation]; - dest = lhs[i]; - np = &n_lhs[i]; + source = mathomatic->lhs[mathomatic->cur_equation]; + nps = &mathomatic->n_lhs[mathomatic->cur_equation]; + dest = mathomatic->lhs[i]; + np = &mathomatic->n_lhs[i]; } inverse_flag = (strcmp_tospace(cp, "inverse") == 0); if (inverse_flag) { cp = skip_param(cp); } if (*cp) { - cp = parse_var2(&v, cp); + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } - if (extra_characters(cp)) { + if (extra_characters(mathomatic, cp)) { return false; } } - show_usage = false; + mathomatic->show_usage = false; if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } - partial_flag = false; - uf_simp(source, nps); - partial_flag = true; - factorv(source, nps, v); + mathomatic->partial_flag = false; + uf_simp(mathomatic, source, nps); + mathomatic->partial_flag = true; + factorv(mathomatic, source, nps, v); blt(dest, source, *nps * sizeof(token_type)); n1 = *nps; if (inverse_flag) { - if (!poly_in_v(dest, n1, v, true) || !int_dispatch(dest, &n1, v, inv_laplace_sub)) { - error(_("Inverse Laplace transformation failed.")); + if (!poly_in_v(mathomatic, dest, n1, v, true) || !int_dispatch(mathomatic, dest, &n1, v, inv_laplace_sub)) { + error(mathomatic, _("Inverse Laplace transformation failed.")); return false; } } else { - if (!poly_in_v(dest, n1, v, false) || !int_dispatch(dest, &n1, v, laplace_sub)) { - error(_("Laplace transformation failed, not a polynomial.")); + if (!poly_in_v(mathomatic, dest, n1, v, false) || !int_dispatch(mathomatic, dest, &n1, v, laplace_sub)) { + error(mathomatic, _("Laplace transformation failed, not a polynomial.")); return false; } } #if 1 - simp_loop(dest, &n1); + simp_loop(mathomatic, dest, &n1); #else - simpa_side(dest, &n1, false, false); + simpa_side(mathomatic, dest, &n1, false, false); #endif - if (n_rhs[cur_equation]) { - blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_lhs[i] = n_lhs[cur_equation]; + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + blt(mathomatic->lhs[i], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_lhs[i] = mathomatic->n_lhs[mathomatic->cur_equation]; } *np = n1; - cur_equation = i; - return return_result(cur_equation); + mathomatic->cur_equation = i; + return return_result(mathomatic, mathomatic->cur_equation); } /* * Numerical integrate command. */ int -nintegrate_cmd(cp) -char *cp; +nintegrate_cmd(MathoMatic* mathomatic, char *cp) { long v = 0; /* Mathomatic variable */ int i, j, k, i1, i2; @@ -689,33 +678,33 @@ char *cp; char *cp_start; cp_start = cp; - if (current_not_defined()) { + if (current_not_defined(mathomatic)) { return false; } - n_tlhs = 0; - n_trhs = 0; - solved = solved_equation(cur_equation); - i = next_espace(); - if (n_rhs[cur_equation]) { + mathomatic->n_tlhs = 0; + mathomatic->n_trhs = 0; + solved = solved_equation(mathomatic, mathomatic->cur_equation); + i = next_espace(mathomatic); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { if (!solved) { - warning(_("Not a solved equation.")); + warning(mathomatic, _("Not a solved equation.")); } - source = rhs[cur_equation]; - nps = &n_rhs[cur_equation]; - dest = rhs[i]; - np = &n_rhs[i]; + source = mathomatic->rhs[mathomatic->cur_equation]; + nps = &mathomatic->n_rhs[mathomatic->cur_equation]; + dest = mathomatic->rhs[i]; + np = &mathomatic->n_rhs[i]; } else { - source = lhs[cur_equation]; - nps = &n_lhs[cur_equation]; - dest = lhs[i]; - np = &n_lhs[i]; + source = mathomatic->lhs[mathomatic->cur_equation]; + nps = &mathomatic->n_lhs[mathomatic->cur_equation]; + dest = mathomatic->lhs[i]; + np = &mathomatic->n_lhs[i]; } trap_flag = (strncasecmp(cp, "trap", 4) == 0); if (trap_flag) { cp = skip_param(cp); } if (*cp) { - cp = parse_var2(&v, cp); + cp = parse_var2(mathomatic, &v, cp); if (cp == NULL) { return false; } @@ -723,38 +712,38 @@ char *cp; iterations = decstrtol(cp, &cp); } if (iterations <= 0 || (iterations % 2) != 0) { - error(_("Number of partitions must be a positive, even integer.")); + error(mathomatic, _("Number of partitions must be a positive, even integer.")); return false; } } if (*cp) { - input_column += (cp - cp_start); - cp = parse_expr(tlhs, &n_tlhs, cp, false); - if (cp == NULL || n_tlhs <= 0) { + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, cp, false); + if (cp == NULL || mathomatic->n_tlhs <= 0) { return false; } } if (*cp) { cp_start = cp; cp = skip_comma_space(cp); - input_column += (cp - cp_start); - cp = parse_expr(trhs, &n_trhs, cp, false); - if (cp == NULL || extra_characters(cp) || n_trhs <= 0) { + mathomatic->input_column += (cp - cp_start); + cp = parse_expr(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, cp, false); + if (cp == NULL || extra_characters(mathomatic, cp) || mathomatic->n_trhs <= 0) { return false; } } - show_usage = false; + mathomatic->show_usage = false; if (v == 0) { - if (!prompt_var(&v)) { + if (!prompt_var(mathomatic, &v)) { return false; } } #if !SILENT - list_var(v, 0); - if (n_rhs[cur_equation]) { - fprintf(gfp, _("Numerically integrating the RHS with respect to %s...\n"), var_str); + list_var(mathomatic, v, 0); + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + fprintf(mathomatic->gfp, _("Numerically integrating the RHS with respect to %s...\n"), mathomatic->var_str); } else { - fprintf(gfp, _("Numerically integrating with respect to %s...\n"), var_str); + fprintf(mathomatic->gfp, _("Numerically integrating with respect to %s...\n"), mathomatic->var_str); } #endif singularity = false; @@ -770,72 +759,72 @@ char *cp; } } if (singularity) { - warning(_("Singularity detected, result of numerical integration might be wrong.")); + warning(mathomatic, _("Singularity detected, result of numerical integration might be wrong.")); } - if (n_tlhs == 0) { - my_strlcpy(prompt_str, _("Enter lower bound: "), sizeof(prompt_str)); - if (!get_expr(tlhs, &n_tlhs)) { + if (mathomatic->n_tlhs == 0) { + my_strlcpy(mathomatic->prompt_str, _("Enter lower bound: "), sizeof(mathomatic->prompt_str)); + if (!get_expr(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) { return false; } } - subst_constants(tlhs, &n_tlhs); - simp_loop(tlhs, &n_tlhs); - if (exp_contains_infinity(tlhs, n_tlhs)) { - error(_("Not computable because: Lower bound contains infinity or NaN.")); + subst_constants(mathomatic->tlhs, &mathomatic->n_tlhs); + simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + if (exp_contains_infinity(mathomatic->tlhs, mathomatic->n_tlhs)) { + error(mathomatic, _("Not computable because: Lower bound contains infinity or NaN.")); return false; } - if (n_trhs == 0) { - my_strlcpy(prompt_str, _("Enter upper bound: "), sizeof(prompt_str)); - if (!get_expr(trhs, &n_trhs)) { + if (mathomatic->n_trhs == 0) { + my_strlcpy(mathomatic->prompt_str, _("Enter upper bound: "), sizeof(mathomatic->prompt_str)); + if (!get_expr(mathomatic, mathomatic->trhs, &mathomatic->n_trhs)) { return false; } } - subst_constants(trhs, &n_trhs); - simp_loop(trhs, &n_trhs); - if (exp_contains_infinity(trhs, n_trhs)) { - error(_("Not computable because: Upper bound contains infinity or NaN.")); + subst_constants(mathomatic->trhs, &mathomatic->n_trhs); + simp_loop(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + if (exp_contains_infinity(mathomatic->trhs, mathomatic->n_trhs)) { + error(mathomatic, _("Not computable because: Upper bound contains infinity or NaN.")); return false; } - if ((n_tlhs + n_trhs + 3) > n_tokens) { - error_huge(); + if ((mathomatic->n_tlhs + mathomatic->n_trhs + 3) > mathomatic->n_tokens) { + error_huge(mathomatic); } #if !SILENT - fprintf(gfp, _("Approximating the definite integral\n")); + fprintf(mathomatic->gfp, _("Approximating the definite integral\n")); if (trap_flag) { - fprintf(gfp, _("using the trapezoid method (%d partitions)...\n"), iterations); + fprintf(mathomatic->gfp, _("using the trapezoid method (%d partitions)...\n"), iterations); } else { - fprintf(gfp, _("using Simpson's rule (%d partitions)...\n"), iterations); + fprintf(mathomatic->gfp, _("using Simpson's rule (%d partitions)...\n"), iterations); } #endif subst_constants(source, nps); - simp_loop(source, nps); - for (j = 0; j < n_trhs; j++) { - trhs[j].level += 2; - } - trhs[n_trhs].level = 2; - trhs[n_trhs].kind = OPERATOR; - trhs[n_trhs].token.operatr = MINUS; - n_trhs++; - j = n_trhs; - blt(&trhs[n_trhs], tlhs, n_tlhs * sizeof(token_type)); - n_trhs += n_tlhs; - for (; j < n_trhs; j++) { - trhs[j].level += 2; - } - trhs[n_trhs].level = 1; - trhs[n_trhs].kind = OPERATOR; - trhs[n_trhs].token.operatr = DIVIDE; - n_trhs++; - trhs[n_trhs].level = 1; - trhs[n_trhs].kind = CONSTANT; - trhs[n_trhs].token.constant = iterations; - n_trhs++; - simp_loop(trhs, &n_trhs); - dest[0] = zero_token; + simp_loop(mathomatic, source, nps); + for (j = 0; j < mathomatic->n_trhs; j++) { + mathomatic->trhs[j].level += 2; + } + mathomatic->trhs[mathomatic->n_trhs].level = 2; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = MINUS; + mathomatic->n_trhs++; + j = mathomatic->n_trhs; + blt(&mathomatic->trhs[mathomatic->n_trhs], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_trhs += mathomatic->n_tlhs; + for (; j < mathomatic->n_trhs; j++) { + mathomatic->trhs[j].level += 2; + } + mathomatic->trhs[mathomatic->n_trhs].level = 1; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = DIVIDE; + mathomatic->n_trhs++; + mathomatic->trhs[mathomatic->n_trhs].level = 1; + mathomatic->trhs[mathomatic->n_trhs].kind = CONSTANT; + mathomatic->trhs[mathomatic->n_trhs].token.constant = iterations; + mathomatic->n_trhs++; + simp_loop(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + dest[0] = mathomatic->zero_token; n1 = 1; for (j = 0; j <= iterations; j++) { - if ((n1 + 1 + *nps) > n_tokens) - error_huge(); + if ((n1 + 1 + *nps) > mathomatic->n_tokens) + error_huge(mathomatic); for (k = 0; k < n1; k++) { dest[k].level++; } @@ -853,14 +842,14 @@ char *cp; for (k = i1; k < n1; k += 2) { if (dest[k].kind == VARIABLE && dest[k].token.variable == v) { level = dest[k].level; - i2 = n_tlhs + 2 + n_trhs; - if ((n1 + i2) > n_tokens) - error_huge(); + i2 = mathomatic->n_tlhs + 2 + mathomatic->n_trhs; + if ((n1 + i2) > mathomatic->n_tokens) + error_huge(mathomatic); blt(&dest[k+1+i2], &dest[k+1], (n1 - (k + 1)) * sizeof(token_type)); n1 += i2; i2 = k; - blt(&dest[k], tlhs, n_tlhs * sizeof(token_type)); - k += n_tlhs; + blt(&dest[k], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + k += mathomatic->n_tlhs; level++; for (; i2 < k; i2++) { dest[i2].level += level; @@ -880,8 +869,8 @@ char *cp; ep->token.operatr = TIMES; k += 3; i2 = k; - blt(&dest[k], trhs, n_trhs * sizeof(token_type)); - k += n_trhs; + blt(&dest[k], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + k += mathomatic->n_trhs; for (; i2 < k; i2++) { dest[i2].level += level; } @@ -889,8 +878,8 @@ char *cp; } } if (j > 0 && j < iterations) { - if ((n1 + 2) > n_tokens) - error_huge(); + if ((n1 + 2) > mathomatic->n_tokens) + error_huge(mathomatic); ep = &dest[n1]; ep->level = 2; ep->kind = OPERATOR; @@ -911,16 +900,16 @@ char *cp; } /* simplify and approximate the partial result quickly: */ - approximate_roots = true; - elim_loop(dest, &n1); - ufactor(dest, &n1); - simp_divide(dest, &n1); - factor_imaginary(dest, &n1); - approximate_roots = false; - side_debug(1, dest, n1); + mathomatic->approximate_roots = true; + elim_loop(mathomatic, dest, &n1); + ufactor(mathomatic, dest, &n1); + simp_divide(mathomatic, dest, &n1); + factor_imaginary(mathomatic, dest, &n1); + mathomatic->approximate_roots = false; + side_debug(mathomatic, 1, dest, n1); if (exp_contains_infinity(dest, n1)) { - error(_("Integration failed because result contains infinity or NaN (a singularity).")); + error(mathomatic, _("Integration failed because result contains infinity or NaN (a singularity).")); return false; } /* detect an ever growing result: */ @@ -934,14 +923,14 @@ char *cp; break; default: if ((n1 / 8) >= first_size) { - error(_("Result growing, integration failed.")); + error(mathomatic, _("Result growing, integration failed.")); return false; } break; } } - if ((n1 + 3 + n_trhs) > n_tokens) - error_huge(); + if ((n1 + 3 + mathomatic->n_trhs) > mathomatic->n_tokens) + error_huge(mathomatic); for (k = 0; k < n1; k++) dest[k].level++; ep = &dest[n1]; @@ -962,34 +951,34 @@ char *cp; ep->token.operatr = TIMES; n1 += 3; k = n1; - blt(&dest[k], trhs, n_trhs * sizeof(token_type)); - n1 += n_trhs; + blt(&dest[k], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + n1 += mathomatic->n_trhs; for (; k < n1; k++) dest[k].level++; /* simplify and approximate the result even more: */ - approximate_roots = true; + mathomatic->approximate_roots = true; do { - elim_loop(dest, &n1); - ufactor(dest, &n1); - simp_divide(dest, &n1); - } while (factor_imaginary(dest, &n1)); - approximate_roots = false; + elim_loop(mathomatic, dest, &n1); + ufactor(mathomatic, dest, &n1); + simp_divide(mathomatic, dest, &n1); + } while (factor_imaginary(mathomatic, dest, &n1)); + mathomatic->approximate_roots = false; #if !SILENT - fprintf(gfp, _("Numerical integration successful:\n")); + fprintf(mathomatic->gfp, _("Numerical integration successful:\n")); #endif *np = n1; - if (n_rhs[cur_equation]) { - blt(lhs[i], lhs[cur_equation], n_lhs[cur_equation] * sizeof(token_type)); - n_lhs[i] = n_lhs[cur_equation]; - if (solved && isvarchar('\'')) { - len = list_var(lhs[i][0].token.variable, 0); - if (len > 0 && var_str[len-1] == '\'') { - var_str[--len] = '\0'; + if (mathomatic->n_rhs[mathomatic->cur_equation]) { + blt(mathomatic->lhs[i], mathomatic->lhs[mathomatic->cur_equation], mathomatic->n_lhs[mathomatic->cur_equation] * sizeof(token_type)); + mathomatic->n_lhs[i] = mathomatic->n_lhs[mathomatic->cur_equation]; + if (solved && isvarchar(mathomatic, '\'')) { + len = list_var(mathomatic, mathomatic->lhs[i][0].token.variable, 0); + if (len > 0 && mathomatic->var_str[len-1] == '\'') { + mathomatic->var_str[--len] = '\0'; } - parse_var(&lhs[i][0].token.variable, var_str); + parse_var(mathomatic, &mathomatic->lhs[i][0].token.variable, mathomatic->var_str); } } - return return_result(i); + return return_result(mathomatic, i); } diff --git a/lib/example.c b/lib/example.c index a78cf2f..5b9f28c 100644 --- a/lib/example.c +++ b/lib/example.c @@ -10,23 +10,26 @@ int main() { + MathoMatic *mathomatic; + mathomatic = newtMathoMatic(); + #if WANT_LEAKS /* Causes memory leaks, wrong code to use, but will work in a pinch. */ char *output; - matho_init(); - matho_parse("x^2=4", NULL); - matho_process("solve x", &output); + matho_init(mathomatic); + matho_parse(mathomatic, "x^2=4", NULL); + matho_process(mathomatic, "solve x", &output); printf("%s\n", output); #else /* right code to use */ char *output; int rv; - if (!matho_init()) { + if (!matho_init(mathomatic)) { printf("Not enough memory.\n"); exit(1); } - matho_parse((char *) "x^2=4", NULL); - rv = matho_process((char *) "solve x", &output); + matho_parse(mathomatic, (char *) "x^2=4", NULL); + rv = matho_process(mathomatic, (char *) "solve x", &output); if (output) { printf("%s\n", output); if (rv) { @@ -37,5 +40,6 @@ main() } #endif + closetMathoMatic(mathomatic); exit(0); } diff --git a/lib/lib.c b/lib/lib.c index 68c5345..4f552c2 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -25,12 +25,12 @@ * and Mathomatic cannot be used. */ int -matho_init(void) +matho_init(MathoMatic* mathomatic) { - init_gvars(); - default_out = stdout; /* if default_out is a file that is not stdout, output is logged to that file */ - gfp = default_out; - if (!init_mem()) { + init_gvars(mathomatic); + mathomatic->default_out = stdout; /* if default_out is a file that is not stdout, output is logged to that file */ + mathomatic->gfp = mathomatic->default_out; + if (!init_mem(mathomatic)) { return false; } signal(SIGFPE, fphandler); /* handle floating point exceptions, currently ignored */ @@ -47,9 +47,9 @@ matho_init(void) * to initialize the Mathomatic symbolic math engine. */ void -matho_clear(void) +matho_clear(MathoMatic* mathomatic) { - clear_all(); + clear_all(mathomatic); } /** 3 @@ -85,57 +85,57 @@ matho_clear(void) * this function with "outputp" set to NULL. */ int -matho_process(char *input, char **outputp) +matho_process(MathoMatic* mathomatic, char *input, char **outputp) { int i; int rv; if (outputp) *outputp = NULL; - result_str = NULL; - result_en = -1; - error_str = NULL; - warning_str = NULL; + mathomatic->result_str = NULL; + mathomatic->result_en = -1; + mathomatic->error_str = NULL; + mathomatic->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 = setjmp(mathomatic->jmp_save)) != 0) { + clean_up(mathomatic); /* Mathomatic processing was interrupted, so do a clean up. */ if (i == 14) { - error(_("Expression too large.")); + error(mathomatic, _("Expression too large.")); } if (outputp) { - if (error_str) { - *outputp = (char *) error_str; + if (mathomatic->error_str) { + *outputp = (char *) mathomatic->error_str; } else { *outputp = _("Processing was interrupted."); } } - free_result_str(); + free_result_str(mathomatic); free(input); - previous_return_value = 0; + mathomatic->previous_return_value = 0; return false; } - set_error_level(input); - rv = process(input); + set_error_level(mathomatic, input); + rv = process(mathomatic, input); if (rv) { if (outputp) { - *outputp = result_str; + *outputp = mathomatic->result_str; } else { - if (result_str) { - free(result_str); - result_str = NULL; + if (mathomatic->result_str) { + free(mathomatic->result_str); + mathomatic->result_str = NULL; } } } else { if (outputp) { - if (error_str) { - *outputp = (char *) error_str; + if (mathomatic->error_str) { + *outputp = (char *) mathomatic->error_str; } else { *outputp = _("Unknown error."); } } - free_result_str(); + free_result_str(mathomatic); } free(input); return rv; @@ -167,61 +167,61 @@ matho_process(char *input, char **outputp) * Returns true (non-zero) if successful. */ int -matho_parse(char *input, char **outputp) +matho_parse(MathoMatic* mathomatic, char *input, char **outputp) { int i; int rv; if (outputp) *outputp = NULL; - result_str = NULL; - result_en = -1; - error_str = NULL; - warning_str = NULL; + mathomatic->result_str = NULL; + mathomatic->result_en = -1; + mathomatic->error_str = NULL; + mathomatic->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 = setjmp(mathomatic->jmp_save)) != 0) { + clean_up(mathomatic); /* Mathomatic processing was interrupted, so do a clean up. */ if (i == 14) { - error(_("Expression too large.")); + error(mathomatic, _("Expression too large.")); } if (outputp) { - if (error_str) { - *outputp = (char *) error_str; + if (mathomatic->error_str) { + *outputp = (char *) mathomatic->error_str; } else { *outputp = _("Processing was interrupted."); } } - free_result_str(); + free_result_str(mathomatic); free(input); return false; } - set_error_level(input); - i = next_espace(); + set_error_level(mathomatic, input); + i = next_espace(mathomatic); #if 1 /* Leave this as 1 if you want to be able to enter single variable or constant expressions with no solving or selecting. */ - rv = parse(i, input); /* All set auto options ignored. */ + rv = parse(mathomatic, i, input); /* All set auto options ignored. */ #else - rv = process_parse(i, input); /* All set auto options respected. */ + rv = process_parse(mathomatic, i, input); /* All set auto options respected. */ #endif if (rv) { if (outputp) { - *outputp = result_str; + *outputp = mathomatic->result_str; } else { - if (result_str) { - free(result_str); - result_str = NULL; + if (mathomatic->result_str) { + free(mathomatic->result_str); + mathomatic->result_str = NULL; } } } else { if (outputp) { - if (error_str) { - *outputp = (char *) error_str; + if (mathomatic->error_str) { + *outputp = (char *) mathomatic->error_str; } else { *outputp = _("Unknown error."); } } - free_result_str(); + free_result_str(mathomatic); } free(input); return rv; diff --git a/lib/mathomatic.h b/lib/mathomatic.h index ce0989f..320a642 100644 --- a/lib/mathomatic.h +++ b/lib/mathomatic.h @@ -1,25 +1,34 @@ /* * Include file for user programs using the Mathomatic symbolic math library API. */ +#ifndef MATHO_EXTERNS_H +typedef struct MathoMatic MathoMatic; +#endif -extern int matho_init(void); /* one-time Mathomatic initialization */ -extern int matho_process(char *input, char **outputp); /* Mathomatic command or expression input */ -extern int matho_parse(char *input, char **outputp); /* Mathomatic expression or equation input */ -extern void matho_clear(void); /* Restart Mathomatic quickly and cleanly, replaces clear_all(). */ +extern MathoMatic *newtMathoMatic(void); +extern void closetMathoMatic(MathoMatic *mathomatic); +extern int matho_init(MathoMatic* mathomatic); /* one-time Mathomatic initialization */ +extern int matho_process(MathoMatic* mathomatic, char *input, char **outputp); /* Mathomatic command or expression input */ +extern int matho_parse(MathoMatic* mathomatic, char *input, char **outputp); /* Mathomatic expression or equation input */ +extern void matho_clear(MathoMatic* mathomatic); /* Restart Mathomatic quickly and cleanly, replaces clear_all(). */ extern void free_mem(void); /* Free all allocated memory before quitting Mathomatic, if operating system doesn't when done. */ /* Mathomatic becomes unusable after free_mem(), until matho_init() is called again. */ /* Only Symbian OS is known to need a call to free_mem() before quitting. */ -extern int load_rc(int return_true_if_no_file, FILE *ofp); /* Load Mathomatic startup set options from ~/.mathomaticrc, should allow "set save" to work. */ +extern int load_rc(MathoMatic* mathomatic, int return_true_if_no_file, FILE *ofp); /* Load Mathomatic startup set options from ~/.mathomaticrc, should allow "set save" to work. */ -extern int cur_equation; /* current equation space number (origin 0) */ +extern int matho_cur_equation(MathoMatic * mathomatic); /* current equation space number (origin 0) */ -extern int result_en; /* Equation number of the API's returned result, */ +extern int matho_result_en(MathoMatic * mathomatic); /* Equation number of the API's returned result, */ /* if the result is also stored in an equation space, */ /* otherwise -1 for no equation number associated with result. */ /* Set by the last call to matho_parse() or matho_process(). */ /* Useful if you want to know where the result string is from, */ /* to act on it with further commands. */ -extern const char *warning_str; /* optional warning message generated by the last command */ +extern const char *matho_get_warning_str(MathoMatic * mathomatic); /* optional warning message generated by the last command */ +extern void matho_set_warning_str(MathoMatic * mathomatic, const char *ws); +extern void matho_set_error_str(MathoMatic * mathomatic, const char *ws); +extern int matho_get_abort_flag(MathoMatic* mathomatic); +extern void matho_inc_abort_flag(MathoMatic* mathomatic); diff --git a/lib/testmain.c b/lib/testmain.c index 9ba83bb..6f737ac 100644 --- a/lib/testmain.c +++ b/lib/testmain.c @@ -17,15 +17,17 @@ main(int argc, char **argv) int rv; /* return value */ char buf[10000]; /* input buffer */ char *version; /* version number of the library */ + MathoMatic *mathomatic; + mathomatic = newtMathoMatic(); printf("Mathomatic library test/example program.\n"); /* Initialize all global variables and arrays so that Mathomatic will work properly. */ - if (!matho_init()) { /* call this library function exactly once in your program */ + if (!matho_init(mathomatic)) { /* call this library function exactly once in your program */ fprintf(stderr, "Not enough memory.\n"); exit(1); } /* Mathomatic is ready for use. */ - if (matho_process((char *) "version", &version)) { + if (matho_process(mathomatic, (char *) "version", &version)) { printf("Mathomatic library version %s\n", version); } else { fprintf(stderr, "Error getting Symbolic Math Library version number.\n"); @@ -39,20 +41,20 @@ main(int argc, char **argv) /* This is a standard input/output loop for testing. */ printf("Press the EOF character (Control-D) to exit.\n"); for (;;) { - printf("%d-> ", cur_equation + 1); + printf("%d-> ", matho_cur_equation(mathomatic) + 1); fflush(stdout); if ((cp = fgets(buf, sizeof(buf), stdin)) == NULL) break; /* Run the Mathomatic symbolic math engine. */ - rv = matho_process(cp, &ocp); - if (warning_str) { + rv = matho_process(mathomatic, cp, &ocp); + if (matho_get_warning_str(mathomatic)) { /* Optionally display any warnings (not required, but helpful). */ - printf("Warning: %s\n", warning_str); + printf("Warning: %s\n", matho_get_warning_str(mathomatic)); } if (ocp) { - if (rv && result_en >= 0) { + if (rv && matho_result_en(mathomatic) >= 0) { /* Display the result equation number. */ - printf("%d: ", result_en + 1); + printf("%d: ", matho_result_en(mathomatic) + 1); } /* Display the result. */ printf("Library result string:\n%s\n", ocp); @@ -68,5 +70,6 @@ main(int argc, char **argv) free_mem(); /* reclaim all memory to check for memory leaks with something like valgrind(1) */ #endif printf("\n"); + closetMathoMatic(mathomatic); exit(0); } diff --git a/list.c b/list.c index 785be3e..409d749 100644 --- a/list.c +++ b/list.c @@ -37,7 +37,7 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #define FOREGROUND_WHITE (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE) /* MS-Windows color array for coloring mathematical expressions, warnings, and errors. */ -static short windows_carray[] = { +static const short windows_carray[] = { FOREGROUND_GREEN, FOREGROUND_YELLOW, /* warning text color */ FOREGROUND_RED, /* error text color */ @@ -51,7 +51,7 @@ extern HANDLE hOut; /* ANSI terminal color code array for 8 color ANSI; we don't use black or white */ /* because the background may be the same color, so there are only 6 colors here. */ -static int carray[] = { +static const int carray[] = { 32, /* must be green (default color) */ 33, /* must be yellow (for warnings) */ 31, /* must be red (for errors) */ @@ -63,13 +63,13 @@ static int carray[] = { #define EQUATE_STRING " = " /* string displayed between the LHS and RHS of equations */ #define MODULUS_STRING " % " /* string displayed for the modulus operator */ -static int flist_sub(token_type *p1, int n, int out_flag, char *string, int sbuffer_size, int pos, int *highp, int *lowp); -static int flist_recurse(token_type *p1, int n, int out_flag, char *string, int sbuffer_size, int line, int pos, int cur_level, int *highp, int *lowp); +static int flist_sub(MathoMatic* mathomatic, token_type *p1, int n, int out_flag, char *string, int sbuffer_size, int pos, int *highp, int *lowp); +static int flist_recurse(MathoMatic* mathomatic, token_type *p1, int n, int out_flag, char *string, int sbuffer_size, int line, int pos, int cur_level, int *highp, int *lowp); /* Bright HTML color array. */ /* Used when HTML output and "set color" and "set bold" options are enabled. */ /* Good looking with a dark background. */ -static char *bright_html_carray[] = { +static const char *bright_html_carray[] = { "#00FF00", /* must be bright green (default color) */ "#FFFF00", /* must be bright yellow (for warnings) */ "#FF0000", /* must be bright red (for errors) */ @@ -82,7 +82,7 @@ static char *bright_html_carray[] = { /* Dim HTML color array for color HTML output. */ /* Used for HTML output with "set color" and "set no bold" options. */ /* Good looking with a white background. */ -static char *html_carray[] = { +static const char *html_carray[] = { "green", "olive", "red", @@ -98,24 +98,24 @@ static char *html_carray[] = { * Subsequent output will have no color until the next call to set_color(). */ void -reset_attr(void) +reset_attr(MathoMatic* mathomatic) { FILE *fp; - if (html_flag == 2) { - fp = gfp; + if (mathomatic->html_flag == 2) { + fp = mathomatic->gfp; } else { fp = stdout; } #if !LIBRARY fflush(NULL); /* flush all output */ #endif - if (color_flag && cur_color >= 0) { - if (html_flag) { + if (mathomatic->color_flag && mathomatic->cur_color >= 0) { + if (mathomatic->html_flag) { fprintf(fp, ""); } else { #if WIN32_CONSOLE_COLORS - if (color_flag == 2) { + if (mathomatic->color_flag == 2) { fprintf(fp, "\033[0m"); } else { SetConsoleTextAttribute(hOut, FOREGROUND_WHITE); @@ -126,7 +126,7 @@ reset_attr(void) } fflush(fp); } - cur_color = -1; + mathomatic->cur_color = -1; } /* @@ -138,41 +138,40 @@ reset_attr(void) * Return actual color number displayed or -1 if no color. */ int -set_color(color) -int color; +set_color(MathoMatic* mathomatic, int color) { int rv = -1; - if (html_flag != 2 && gfp != stdout) { + if (mathomatic->html_flag != 2 && mathomatic->gfp != stdout) { return rv; } - if (color_flag) { - if (cur_color == color) /* color already set */ + if (mathomatic->color_flag) { + if (mathomatic->cur_color == color) /* color already set */ return rv; - if (html_flag) { - if (cur_color >= 0) { - fprintf(gfp, ""); + if (mathomatic->html_flag) { + if (mathomatic->cur_color >= 0) { + fprintf(mathomatic->gfp, ""); } - if (bold_colors) { - fprintf(gfp, "", bright_html_carray[rv = (color % ARR_CNT(bright_html_carray))]); + if (mathomatic->bold_colors) { + fprintf(mathomatic->gfp, "", bright_html_carray[rv = (color % ARR_CNT(bright_html_carray))]); } else { - fprintf(gfp, "", html_carray[rv = (color % ARR_CNT(html_carray))]); + fprintf(mathomatic->gfp, "", html_carray[rv = (color % ARR_CNT(html_carray))]); } } else { #if WIN32_CONSOLE_COLORS - if (color_flag == 2) { - fprintf(gfp, "\033[%d;%dm", bold_colors, carray[rv = (color % ARR_CNT(carray))]); + if (mathomatic->color_flag == 2) { + fprintf(mathomatic->gfp, "\033[%d;%dm", mathomatic->bold_colors, carray[rv = (color % ARR_CNT(carray))]); } else { short attr = windows_carray[rv = (color % ARR_CNT(windows_carray))]; - if (bold_colors) + if (mathomatic->bold_colors) attr |= FOREGROUND_INTENSITY; SetConsoleTextAttribute(hOut, attr); } #else - fprintf(gfp, "\033[%d;%dm", bold_colors, carray[rv = (color % ARR_CNT(carray))]); + fprintf(mathomatic->gfp, "\033[%d;%dm", mathomatic->bold_colors, carray[rv = (color % ARR_CNT(carray))]); #endif } - cur_color = color; + mathomatic->cur_color = color; } return rv; } @@ -181,32 +180,32 @@ int color; * Set normal text color for subsequent output. */ void -default_color(set_no_color_flag) -int set_no_color_flag; /* If true, set no color even if text_color is set. Normally this would be false. */ +default_color(MathoMatic* mathomatic, int set_no_color_flag) +//int set_no_color_flag; /* If true, set no color even if text_color is set. Normally this would be false. */ { - if (html_flag != 2 && gfp != stdout) { + if (mathomatic->html_flag != 2 && mathomatic->gfp != stdout) { return; } - if (color_flag && cur_color >= 0) { - if (html_flag) { - fprintf(gfp, ""); + if (mathomatic->color_flag && mathomatic->cur_color >= 0) { + if (mathomatic->html_flag) { + fprintf(mathomatic->gfp, ""); } else { #if WIN32_CONSOLE_COLORS - if (color_flag == 2) { - fprintf(gfp, "\033[0m"); + if (mathomatic->color_flag == 2) { + fprintf(mathomatic->gfp, "\033[0m"); } else { SetConsoleTextAttribute(hOut, FOREGROUND_WHITE); } #else - fprintf(gfp, "\033[0m"); + fprintf(mathomatic->gfp, "\033[0m"); #endif } } - cur_color = -1; - if (text_color >= 0 && !set_no_color_flag) { - set_color(text_color); + mathomatic->cur_color = -1; + if (mathomatic->text_color >= 0 && !set_no_color_flag) { + set_color(mathomatic, mathomatic->text_color); } - fflush(gfp); + fflush(mathomatic->gfp); } /* @@ -215,22 +214,22 @@ int set_no_color_flag; /* If true, set no color even if text_color is set. Norm * Return true if successful. */ int -display_all_colors(void) +display_all_colors(MathoMatic* mathomatic) { int i, j; i = 0; - default_color(true); - if (set_color(i) < 0) { - default_color(false); + default_color(mathomatic, true); + if (set_color(mathomatic, i) < 0) { + default_color(mathomatic, false); return false; } do { printf("#"); i++; - j = set_color(i); + j = set_color(mathomatic, i); } while (j > 0); - default_color(false); + default_color(mathomatic, false); return(j >= 0); } @@ -262,30 +261,30 @@ char *buf; * Return length (number of screen columns) of output line. */ int -list1_sub(n, export_flag) -int n; /* equation space number */ -int export_flag; /* non-zero for exportable format (readable by other math programs) */ +list1_sub(MathoMatic* mathomatic, int n, int export_flag) +//int n; /* equation space number */ +//int export_flag; /* non-zero for exportable format (readable by other math programs) */ /* 1 for Maxima, 2 for other, 3 for gnuplot, 4 for hexadecimal */ { int len = 0; - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return 0; - if ((export_flag == 0 || export_flag == 4) && !high_prec) { - len += fprintf(gfp, "#%d: ", n + 1); + if ((export_flag == 0 || export_flag == 4) && !mathomatic->high_prec) { + len += fprintf(mathomatic->gfp, "#%d: ", n + 1); } - len += list_proc(lhs[n], n_lhs[n], export_flag); - if (n_rhs[n]) { - len += fprintf(gfp, EQUATE_STRING); - len += list_proc(rhs[n], n_rhs[n], export_flag); + len += list_proc(mathomatic, mathomatic->lhs[n], mathomatic->n_lhs[n], export_flag); + if (mathomatic->n_rhs[n]) { + len += fprintf(mathomatic->gfp, EQUATE_STRING); + len += list_proc(mathomatic, mathomatic->rhs[n], mathomatic->n_rhs[n], export_flag); } if (export_flag == 1) { - len += fprintf(gfp, ";"); + len += fprintf(mathomatic->gfp, ";"); } #if CYGWIN - fprintf(gfp, "\r\n"); /* might be redirecting to a Microsoft text file */ + fprintf(mathomatic->gfp, "\r\n"); /* might be redirecting to a Microsoft text file */ #else - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); #endif return len; } @@ -297,43 +296,38 @@ int export_flag; /* non-zero for exportable format (readable by other math progr * or zero on failure. */ int -list_sub(n) -int n; /* equation space number */ +list_sub(MathoMatic* mathomatic, int n) +//int n; /* equation space number */ { - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return 0; - make_fractions_and_group(n); - if (factor_int_flag) { - factor_int_equation(n); + make_fractions_and_group(mathomatic, n); + if (mathomatic->factor_int_flag) { + factor_int_equation(mathomatic, n); } - if (display2d) { + if (mathomatic->display2d) { /* display in fraction format */ - return flist_equation(n); + return flist_equation(mathomatic, n); } else { /* display in single-line format */ - return list1_sub(n, false); + return list1_sub(mathomatic, n, false); } } #if !SILENT void -list_debug(level, p1, n1, p2, n2) -int level; -token_type *p1; -int n1; -token_type *p2; -int n2; +list_debug(MathoMatic* mathomatic, int level, token_type *p1, int n1, token_type *p2, int n2) { - if (debug_level >= level) { + if (mathomatic->debug_level >= level) { if (level >= -2) { - fprintf(gfp, _("level %d: "), level); + fprintf(mathomatic->gfp, _("level %d: "), level); } - list_proc(p1, n1, false); + list_proc(mathomatic, p1, n1, false); if (p2 && n2 > 0) { - fprintf(gfp, EQUATE_STRING); - list_proc(p2, n2, false); + fprintf(mathomatic->gfp, EQUATE_STRING); + list_proc(mathomatic, p2, n2, false); } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } } #endif @@ -345,15 +339,15 @@ int n2; * Does not return the actual variable name, use list_var() for that. */ char * -var_name(v) -long v; /* Mathomatic variable */ +var_name(MathoMatic* mathomatic, long v) +//long v; /* Mathomatic variable */ { char *cp = NULL; long l; l = (labs(v) & VAR_MASK) - VAR_OFFSET; if (l >= 0 && l < MAX_VAR_NAMES) { - cp = var_names[l]; + cp = mathomatic->var_names[l]; } return cp; } @@ -371,18 +365,18 @@ long v; /* Mathomatic variable */ * -5 for mathomatic-only variable format. */ int -list_var(v, lang_code) -long v; /* variable to convert */ -int lang_code; /* language code */ +list_var(MathoMatic* mathomatic, long v, int lang_code) +//long v; /* variable to convert */ +//int lang_code; /* language code */ { int j; int from_memory = false; char *cp = NULL; - var_str[0] = '\0'; + mathomatic->var_str[0] = '\0'; switch (labs(v) & VAR_MASK) { case V_NULL: - return(strlen(var_str)); + return(strlen(mathomatic->var_str)); case SIGN: cp = "sign"; break; @@ -461,19 +455,19 @@ int lang_code; /* language code */ cp = "all"; break; default: - cp = var_name(v); + cp = var_name(mathomatic, v); from_memory = true; break; } if (cp) { j = (labs(v) >> VAR_SHIFT) & SUBSCRIPT_MASK; if (j) { /* for "sign" variables */ - snprintf(var_str, sizeof(var_str), "%s%d", cp, j - 1); + snprintf(mathomatic->var_str, sizeof(mathomatic->var_str), "%s%d", cp, j - 1); } else { - my_strlcpy(var_str, cp, sizeof(var_str)); + my_strlcpy(mathomatic->var_str, cp, sizeof(mathomatic->var_str)); } } else { - my_strlcpy(var_str, "bad_variable", sizeof(var_str)); + my_strlcpy(mathomatic->var_str, "bad_variable", sizeof(mathomatic->var_str)); } /* Make valid C type variable if exporting or generating code: */ if (from_memory) { @@ -483,15 +477,15 @@ int lang_code; /* language code */ case -5: break; default: - for (j = 0; var_str[j] && var_str[j] != '('; j++) { - if (strchr("_[]", var_str[j]) == NULL && !isalnum(var_str[j])) { - var_str[j] = '_'; + for (j = 0; mathomatic->var_str[j] && mathomatic->var_str[j] != '('; j++) { + if (strchr("_[]", mathomatic->var_str[j]) == NULL && !isalnum(mathomatic->var_str[j])) { + mathomatic->var_str[j] = '_'; } } break; } } - return(strlen(var_str)); + return(strlen(mathomatic->var_str)); } /* @@ -501,13 +495,13 @@ int lang_code; /* language code */ * Return number of characters output (excluding escape sequences). */ int -list_proc(p1, n, export_flag) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ -int export_flag; /* flag for exportable format (usually false) */ +list_proc(MathoMatic* mathomatic, token_type *p1, int n, int export_flag) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ +//int export_flag; /* flag for exportable format (usually false) */ /* 1 for Maxima, 2 for other, 3 for gnuplot, 4 for hexadecimal */ { - return list_string_sub(p1, n, true, NULL, export_flag); + return list_string_sub(mathomatic, p1, n, true, NULL, export_flag); } /* @@ -517,30 +511,30 @@ int export_flag; /* flag for exportable format (usually false) */ * Returns text string, or NULL if error. */ char * -list_equation(n, export_flag) -int n; /* equation space number */ -int export_flag; /* flag for exportable format (usually false) */ +list_equation(MathoMatic* mathomatic, int n, int export_flag) +//int n; /* equation space number */ +//int export_flag; /* flag for exportable format (usually false) */ { int len; char *cp; - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return NULL; - len = list_string(lhs[n], n_lhs[n], NULL, export_flag); - if (n_rhs[n]) { + len = list_string(mathomatic, mathomatic->lhs[n], mathomatic->n_lhs[n], NULL, export_flag); + if (mathomatic->n_rhs[n]) { len += strlen(EQUATE_STRING); - len += list_string(rhs[n], n_rhs[n], NULL, export_flag); + len += list_string(mathomatic, mathomatic->rhs[n], mathomatic->n_rhs[n], NULL, export_flag); } len += 2; /* for possible semicolon and terminating null character */ cp = (char *) malloc(len); if (cp == NULL) { - error(_("Out of memory (can't malloc(3)).")); + error(mathomatic, _("Out of memory (can't malloc(3)).")); return NULL; } - list_string(lhs[n], n_lhs[n], cp, export_flag); - if (n_rhs[n]) { + list_string(mathomatic, mathomatic->lhs[n], mathomatic->n_lhs[n], cp, export_flag); + if (mathomatic->n_rhs[n]) { strcat(cp, EQUATE_STRING); - list_string(rhs[n], n_rhs[n], &cp[strlen(cp)], export_flag); + list_string(mathomatic, mathomatic->rhs[n], mathomatic->n_rhs[n], &cp[strlen(cp)], export_flag); } if (export_flag == 1) { strcat(cp, ";"); @@ -555,10 +549,9 @@ int export_flag; /* flag for exportable format (usually false) */ * Return string, or NULL if error. */ char * -list_expression(p1, n, export_flag) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ -int export_flag; +list_expression(MathoMatic* mathomatic, token_type *p1, int n, int export_flag) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ { int len; char *cp; @@ -566,14 +559,14 @@ int export_flag; if (n <= 0) { return NULL; } - len = list_string(p1, n, NULL, export_flag); + len = list_string(mathomatic, p1, n, NULL, export_flag); len++; /* for terminating null character */ cp = (char *) malloc(len); if (cp == NULL) { - error(_("Out of memory (can't malloc(3)).")); + error(mathomatic, _("Out of memory (can't malloc(3)).")); return NULL; } - list_string(p1, n, cp, export_flag); + list_string(mathomatic, p1, n, cp, export_flag); return cp; } @@ -586,25 +579,25 @@ int export_flag; * Return length (number of characters). */ int -list_string(p1, n, string, export_flag) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ -char *string; /* buffer to save output to or NULL pointer */ -int export_flag; +list_string(MathoMatic* mathomatic, token_type *p1, int n, char *string, int export_flag) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ +//char *string; /* buffer to save output to or NULL pointer */ +//int export_flag; { - return list_string_sub(p1, n, false, string, export_flag); + return list_string_sub(mathomatic, p1, n, false, string, export_flag); } -#define APPEND(str) { if (string) { strcpy(&string[len], str); } if (outflag) { fprintf(gfp, "%s", str); } len += strlen(str); } -#define APPEND2(str) { if (string) { if ((sbuffer_size - current_len) > 0) my_strlcpy(&string[current_len], str, sbuffer_size - current_len); } else { fprintf(gfp, "%s", str); } current_len += strlen(str); } +#define APPEND(str) { if (string) { strcpy(&string[len], str); } if (outflag) { fprintf(mathomatic->gfp, "%s", str); } len += strlen(str); } +#define APPEND2(str) { if (string) { if ((sbuffer_size - current_len) > 0) my_strlcpy(&string[current_len], str, sbuffer_size - current_len); } else { fprintf(mathomatic->gfp, "%s", str); } current_len += strlen(str); } int -list_string_sub(p1, n, outflag, string, export_flag) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ -int outflag; /* if true, output to gfp */ -char *string; /* buffer to save output to or NULL pointer */ -int export_flag; /* flag for exportable format (usually false) */ +list_string_sub(MathoMatic* mathomatic, token_type *p1, int n, int outflag, char *string, int export_flag) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ +//int outflag; /* if true, output to gfp */ +//char *string; /* buffer to save output to or NULL pointer */ +//int export_flag; /* flag for exportable format (usually false) */ /* 1 for Maxima, 2 for other, 3 for gnuplot, 4 for hexadecimal */ { int i, j, k, i1; @@ -618,17 +611,17 @@ int export_flag; /* flag for exportable format (usually false) */ cflag = (outflag && (export_flag == 0 || export_flag == 4)); if (cflag) - set_color(0); + set_color(mathomatic, 0); if (string) string[0] = '\0'; - if (high_prec) + if (mathomatic->high_prec) export_precision = 20; else export_precision = DBL_DIG; - cur_level = min1 = min_level(p1, n); + cur_level = min1 = min_level(mathomatic, p1, n); for (i = 0; i < n; i++) { power_flag = false; - if (export_flag == 0 && !high_prec) { + if (export_flag == 0 && !mathomatic->high_prec) { for (j = i - 1; j <= (i + 1); j++) { if ((j - 1) >= 0 && (j + 1) < n && p1[j].kind == OPERATOR && (p1[j].token.operatr == POWER || p1[j].token.operatr == FACTORIAL) @@ -651,11 +644,11 @@ int export_flag; /* flag for exportable format (usually false) */ cur_level--; APPEND(")"); if (cflag) - set_color(cur_level-min1); + set_color(mathomatic, cur_level-min1); } else { cur_level++; if (cflag) - set_color(cur_level-min1); + set_color(mathomatic, cur_level-min1); APPEND("("); } } @@ -669,20 +662,20 @@ int export_flag; /* flag for exportable format (usually false) */ } else if (export_flag == 3) { snprintf(buf, sizeof(buf), "%#.*g", DBL_DIG, p1[i].token.constant); trim_zeros(buf); - } else if (export_flag || high_prec) { + } else if (export_flag || mathomatic->high_prec) { snprintf(buf, sizeof(buf), "%.*g", export_precision, p1[i].token.constant); - } else if (finance_option >= 0) { + } else if (mathomatic->finance_option >= 0) { #if THOUSANDS_SEPARATOR /* Fails miserably in MinGW and possibly others, displaying nothing but the format string. */ - snprintf(buf, sizeof(buf), "%'.*f", finance_option, p1[i].token.constant); + snprintf(buf, sizeof(buf), "%'.*f", mathomatic->finance_option, p1[i].token.constant); #else - snprintf(buf, sizeof(buf), "%.*f", finance_option, p1[i].token.constant); + snprintf(buf, sizeof(buf), "%.*f", mathomatic->finance_option, p1[i].token.constant); #endif } else { if (p1[i].token.constant < 0.0 && (i + 1) < n && p1[i+1].level == p1[i].level && (p1[i+1].token.operatr >= POWER)) { - snprintf(buf, sizeof(buf), "(%.*g)", precision, p1[i].token.constant); + snprintf(buf, sizeof(buf), "(%.*g)", mathomatic->precision, p1[i].token.constant); } else { - snprintf(buf, sizeof(buf), "%.*g", precision, p1[i].token.constant); + snprintf(buf, sizeof(buf), "%.*g", mathomatic->precision, p1[i].token.constant); } APPEND(buf); break; @@ -695,8 +688,8 @@ int export_flag; /* flag for exportable format (usually false) */ } break; case VARIABLE: - list_var(p1[i].token.variable, 0 - export_flag); - APPEND(var_str); + list_var(mathomatic, p1[i].token.variable, 0 - export_flag); + APPEND(mathomatic->var_str); break; case OPERATOR: cp = _("(unknown operator)"); @@ -720,7 +713,7 @@ int export_flag; /* flag for exportable format (usually false) */ cp = MODULUS_STRING; break; case POWER: - if (power_starstar || export_flag == 3) { + if (mathomatic->power_starstar || export_flag == 3) { cp = "**"; } else { cp = "^"; @@ -739,10 +732,10 @@ int export_flag; /* flag for exportable format (usually false) */ APPEND(")"); j--; if (cflag) - set_color(j); + set_color(mathomatic, j); } if (cflag) - default_color(false); + default_color(mathomatic, false); return len; } @@ -787,29 +780,28 @@ int n; /* length of expression */ * Return length of output (number of characters). */ int -list_code_equation(en, language, int_flag) -int en; /* equation space number */ -enum language_list language; -int int_flag; /* integer arithmetic flag */ +list_code_equation(MathoMatic* mathomatic, int en, enum language_list language, int int_flag) +//int en; /* equation space number */ +//int int_flag; /* integer arithmetic flag */ { int len = 0; - if (empty_equation_space(en)) + if (empty_equation_space(mathomatic, en)) return 0; - len += list_code(lhs[en], &n_lhs[en], true, NULL, language, int_flag); - if (n_rhs[en]) { - len += fprintf(gfp, EQUATE_STRING); - len += list_code(rhs[en], &n_rhs[en], true, NULL, language, int_flag); + len += list_code(mathomatic, mathomatic->lhs[en], &mathomatic->n_lhs[en], true, NULL, language, int_flag); + if (mathomatic->n_rhs[en]) { + len += fprintf(mathomatic->gfp, EQUATE_STRING); + len += list_code(mathomatic, mathomatic->rhs[en], &mathomatic->n_rhs[en], true, NULL, language, int_flag); } switch (language) { case C: case JAVA: - len += fprintf(gfp, ";"); + len += fprintf(mathomatic->gfp, ";"); break; default: break; } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); return len; } @@ -820,31 +812,30 @@ int int_flag; /* integer arithmetic flag */ * Return string, or NULL if error. */ char * -string_code_equation(en, language, int_flag) -int en; /* equation space number */ -enum language_list language; -int int_flag; /* integer arithmetic flag */ +string_code_equation(MathoMatic* mathomatic, int en, enum language_list language, int int_flag) +//int en; /* equation space number */ +//int int_flag; /* integer arithmetic flag */ { int len; char *cp; - if (empty_equation_space(en)) + if (empty_equation_space(mathomatic, en)) return NULL; - len = list_code(lhs[en], &n_lhs[en], false, NULL, language, int_flag); - if (n_rhs[en]) { + len = list_code(mathomatic, mathomatic->lhs[en], &mathomatic->n_lhs[en], false, NULL, language, int_flag); + if (mathomatic->n_rhs[en]) { len += strlen(EQUATE_STRING); - len += list_code(rhs[en], &n_rhs[en], false, NULL, language, int_flag); + len += list_code(mathomatic, mathomatic->rhs[en], &mathomatic->n_rhs[en], false, NULL, language, int_flag); } len += 2; /* for possible semicolon and terminating null character */ cp = (char *) malloc(len); if (cp == NULL) { - error(_("Out of memory (can't malloc(3)).")); + error(mathomatic, _("Out of memory (can't malloc(3)).")); return NULL; } - list_code(lhs[en], &n_lhs[en], false, cp, language, int_flag); - if (n_rhs[en]) { + list_code(mathomatic, mathomatic->lhs[en], &mathomatic->n_lhs[en], false, cp, language, int_flag); + if (mathomatic->n_rhs[en]) { strcat(cp, EQUATE_STRING); - list_code(rhs[en], &n_rhs[en], false, &cp[strlen(cp)], language, int_flag); + list_code(mathomatic, mathomatic->rhs[en], &mathomatic->n_rhs[en], false, &cp[strlen(cp)], language, int_flag); } switch (language) { case C: @@ -864,13 +855,13 @@ int int_flag; /* integer arithmetic flag */ * Return length of output (number of characters). */ int -list_code(equation, np, outflag, string, language, int_flag) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ -int outflag; /* if true, output to gfp */ -char *string; /* buffer to save output to or NULL pointer */ -enum language_list language; /* see enumeration language_list in am.h */ -int int_flag; /* integer arithmetic flag, should work with any language */ +list_code(MathoMatic* mathomatic, token_type *equation, int *np, int outflag, char *string, enum language_list language, int int_flag) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ +//int outflag; /* if true, output to gfp */ +//char *string; /* buffer to save output to or NULL pointer */ +//enum language_list language; /* see enumeration language_list in am.h */ +//int int_flag; /* integer arithmetic flag, should work with any language */ { int i, j, k, i1, i2; int min1; @@ -881,7 +872,7 @@ int int_flag; /* integer arithmetic flag, should work with any language */ if (string) string[0] = '\0'; - min1 = min_level(equation, *np); + min1 = min_level(mathomatic, equation, *np); if (*np > 1) min1--; cur_level = min1; @@ -952,8 +943,8 @@ int int_flag; /* integer arithmetic flag, should work with any language */ if (int_flag && (language == C || language == JAVA) && equation[i].token.variable == IMAGINARY) { APPEND("1i"); } else { - list_var(equation[i].token.variable, language); - APPEND(var_str); + list_var(mathomatic, equation[i].token.variable, language); + APPEND(mathomatic->var_str); } break; case OPERATOR: @@ -1002,8 +993,8 @@ int int_flag; /* integer arithmetic flag, should work with any language */ } /* global variables for the flist functions below */ -static int cur_line; /* current line */ -static int cur_pos; /* current position in the current line on the screen */ +//static int cur_line; /* current line */ +//static int cur_pos; /* current position in the current line on the screen */ /* * Return a multi-line C string containing the specified equation space in 2D multi-line fraction format. @@ -1021,8 +1012,8 @@ static int cur_pos; /* current position in the current line on the screen */ * current_columns is set in malloc_vscreen(). */ char * -flist_equation_string(n) -int n; /* equation space number */ +flist_equation_string(MathoMatic* mathomatic, int n) +//int n; /* equation space number */ { int i; int len, cur_len, buf_len; @@ -1032,19 +1023,19 @@ int n; /* equation space number */ int screen_line; char *cp; - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return NULL; - if (!malloc_vscreen()) + if (!malloc_vscreen(mathomatic)) return NULL; for (i = 0; i < TEXT_ROWS; i++) { - vscreen[i][0] = '\0'; + mathomatic->vscreen[i][0] = '\0'; } - cur_line = 0; - cur_pos = 0; - len = flist_sub(lhs[n], n_lhs[n], false, NULL, current_columns, 0, &max_line, &min_line); - if (n_rhs[n]) { + mathomatic->cur_line = 0; + mathomatic->cur_pos = 0; + len = flist_sub(mathomatic, mathomatic->lhs[n], mathomatic->n_lhs[n], false, NULL, mathomatic->current_columns, 0, &max_line, &min_line); + if (mathomatic->n_rhs[n]) { len += strlen(EQUATE_STRING); - len += flist_sub(rhs[n], n_rhs[n], false, NULL, current_columns, 0, &high, &low); + len += flist_sub(mathomatic, mathomatic->rhs[n], mathomatic->n_rhs[n], false, NULL, mathomatic->current_columns, 0, &high, &low); if (high > max_line) max_line = high; if (low < min_line) @@ -1052,34 +1043,34 @@ int n; /* equation space number */ } if ((max_line - min_line) >= TEXT_ROWS) return NULL; - for (cur_line = max_line, screen_line = 0; cur_line >= min_line; cur_line--, screen_line++) { - pos = cur_pos = 0; - pos += flist_sub(lhs[n], n_lhs[n], true, vscreen[screen_line], current_columns, pos, &high, &low); - if (n_rhs[n]) { - if (cur_line == 0) { - cur_pos += strlen(EQUATE_STRING); - cur_len = strlen(vscreen[screen_line]); - if ((current_columns - cur_len) > 0) - my_strlcpy(&vscreen[screen_line][cur_len], EQUATE_STRING, current_columns - cur_len); + for (mathomatic->cur_line = max_line, screen_line = 0; mathomatic->cur_line >= min_line; mathomatic->cur_line--, screen_line++) { + pos = mathomatic->cur_pos = 0; + pos += flist_sub(mathomatic, mathomatic->lhs[n], mathomatic->n_lhs[n], true, mathomatic->vscreen[screen_line], mathomatic->current_columns, pos, &high, &low); + if (mathomatic->n_rhs[n]) { + if (mathomatic->cur_line == 0) { + mathomatic->cur_pos += strlen(EQUATE_STRING); + cur_len = strlen(mathomatic->vscreen[screen_line]); + if ((mathomatic->current_columns - cur_len) > 0) + my_strlcpy(&mathomatic->vscreen[screen_line][cur_len], EQUATE_STRING, mathomatic->current_columns - cur_len); } pos += strlen(EQUATE_STRING); - pos += flist_sub(rhs[n], n_rhs[n], true, vscreen[screen_line], current_columns, pos, &high, &low); + pos += flist_sub(mathomatic, mathomatic->rhs[n], mathomatic->n_rhs[n], true, mathomatic->vscreen[screen_line], mathomatic->current_columns, pos, &high, &low); } } if (screen_line <= 0) return NULL; for (i = 0, buf_len = 1; i < screen_line; i++) { - buf_len += strlen(vscreen[i]); + buf_len += strlen(mathomatic->vscreen[i]); buf_len++; /* For newlines */ } cp = (char *) malloc(buf_len); if (cp == NULL) { - error(_("Out of memory (can't malloc(3)).")); + error(mathomatic, _("Out of memory (can't malloc(3)).")); return NULL; } cp[0] = '\0'; for (i = 0; i < screen_line; i++) { - strcat(cp, vscreen[i]); + strcat(cp, mathomatic->vscreen[i]); strcat(cp, "\n"); } return(cp); @@ -1096,8 +1087,8 @@ int n; /* equation space number */ * or zero on failure. */ int -flist_equation(n) -int n; /* equation space number */ +flist_equation(MathoMatic* mathomatic, int n) +//int n; /* equation space number */ { int sind; char buf[50]; @@ -1108,26 +1099,26 @@ int n; /* equation space number */ int max2_line = 0, min2_line = 0; int use_screen_columns; /* use infinite width if false */ - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return 0; #if 1 /* always respect "set columns" */ use_screen_columns = true; #else - use_screen_columns = (gfp == stdout); + use_screen_columns = (mathomatic->gfp == stdout); #endif len = snprintf(buf, sizeof(buf), "#%d: ", n + 1); - cur_line = 0; - cur_pos = 0; - sind = n_rhs[n]; - len += flist_sub(lhs[n], n_lhs[n], false, NULL, screen_columns, 0, &max_line, &min_line); - if (n_rhs[n]) { + mathomatic->cur_line = 0; + mathomatic->cur_pos = 0; + sind = mathomatic->n_rhs[n]; + len += flist_sub(mathomatic, mathomatic->lhs[n], mathomatic->n_lhs[n], false, NULL, mathomatic->screen_columns, 0, &max_line, &min_line); + if (mathomatic->n_rhs[n]) { len += strlen(EQUATE_STRING); make_smaller: - len2 = flist_sub(rhs[n], sind, false, NULL, screen_columns, 0, &high, &low); - if (screen_columns && use_screen_columns && (len + len2) >= screen_columns && sind > 0) { + len2 = flist_sub(mathomatic, mathomatic->rhs[n], sind, false, NULL, mathomatic->screen_columns, 0, &high, &low); + if (mathomatic->screen_columns && use_screen_columns && (len + len2) >= mathomatic->screen_columns && sind > 0) { for (sind--; sind > 0; sind--) { - if (rhs[n][sind].level == 1 && rhs[n][sind].kind == OPERATOR) { - switch (rhs[n][sind].token.operatr) { + if (mathomatic->rhs[n][sind].level == 1 && mathomatic->rhs[n][sind].kind == OPERATOR) { + switch (mathomatic->rhs[n][sind].token.operatr) { case PLUS: case MINUS: case MODULUS: @@ -1141,49 +1132,49 @@ int n; /* equation space number */ max_line = high; if (low < min_line) min_line = low; - len3 = flist_sub(&rhs[n][sind], n_rhs[n] - sind, false, NULL, screen_columns, 0, &max2_line, &min2_line); + len3 = flist_sub(mathomatic, &mathomatic->rhs[n][sind], mathomatic->n_rhs[n] - sind, false, NULL, mathomatic->screen_columns, 0, &max2_line, &min2_line); } else { len2 = 0; len3 = 0; } width = max(len + len2, len3); - if (screen_columns && use_screen_columns && width >= screen_columns) { + if (mathomatic->screen_columns && use_screen_columns && width >= mathomatic->screen_columns) { /* output too wide to fit screen, output in single-line format */ - width = list1_sub(n, false); + width = list1_sub(mathomatic, n, false); #if CYGWIN - fprintf(gfp, "\r\n"); /* Be consistent with list1_sub() output. */ + fprintf(mathomatic->gfp, "\r\n"); /* Be consistent with list1_sub() output. */ #else - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); #endif return width; } - fprintf(gfp, "\n"); - for (cur_line = max_line; cur_line >= min_line; cur_line--) { - pos = cur_pos = 0; - if (cur_line == 0) { - cur_pos += fprintf(gfp, "%s", buf); + fprintf(mathomatic->gfp, "\n"); + for (mathomatic->cur_line = max_line; mathomatic->cur_line >= min_line; mathomatic->cur_line--) { + pos = mathomatic->cur_pos = 0; + if (mathomatic->cur_line == 0) { + mathomatic->cur_pos += fprintf(mathomatic->gfp, "%s", buf); } pos += strlen(buf); - pos += flist_sub(lhs[n], n_lhs[n], true, NULL, screen_columns, pos, &high, &low); - if (n_rhs[n]) { - if (cur_line == 0) { - cur_pos += fprintf(gfp, "%s", EQUATE_STRING); + pos += flist_sub(mathomatic, mathomatic->lhs[n], mathomatic->n_lhs[n], true, NULL, mathomatic->screen_columns, pos, &high, &low); + if (mathomatic->n_rhs[n]) { + if (mathomatic->cur_line == 0) { + mathomatic->cur_pos += fprintf(mathomatic->gfp, "%s", EQUATE_STRING); } pos += strlen(EQUATE_STRING); - pos += flist_sub(rhs[n], sind, true, NULL, screen_columns, pos, &high, &low); + pos += flist_sub(mathomatic, mathomatic->rhs[n], sind, true, NULL, mathomatic->screen_columns, pos, &high, &low); } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); } - if (sind < n_rhs[n]) { + if (sind < mathomatic->n_rhs[n]) { /* output second half of split equation that was too wide to display on the screen without splitting */ - fprintf(gfp, "\n"); - for (cur_line = max2_line; cur_line >= min2_line; cur_line--) { - cur_pos = 0; - flist_sub(&rhs[n][sind], n_rhs[n] - sind, true, NULL, screen_columns, 0, &high, &low); - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); + for (mathomatic->cur_line = max2_line; mathomatic->cur_line >= min2_line; mathomatic->cur_line--) { + mathomatic->cur_pos = 0; + flist_sub(mathomatic, &mathomatic->rhs[n][sind], mathomatic->n_rhs[n] - sind, true, NULL, mathomatic->screen_columns, 0, &high, &low); + fprintf(mathomatic->gfp, "\n"); } } - fprintf(gfp, "\n"); + fprintf(mathomatic->gfp, "\n"); return width; } @@ -1199,35 +1190,27 @@ int n; /* equation space number */ * Return the width of the expression (that is, the required number of screen columns). */ static int -flist_sub(p1, n, out_flag, string, sbuffer_size, pos, highp, lowp) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ -int out_flag; /* if true, output to gfp or string */ -char *string; /* if not NULL, put output to here instead of gfp */ -int sbuffer_size; /* string buffer size */ -int pos; -int *highp, *lowp; +flist_sub(MathoMatic* mathomatic, token_type *p1, int n, int out_flag, char *string, int sbuffer_size, int pos, int *highp, int *lowp) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ +//int out_flag; /* if true, output to gfp or string */ +//char *string; /* if not NULL, put output to here instead of gfp */ +//int sbuffer_size; /* string buffer size */ { int rv; - rv = flist_recurse(p1, n, out_flag, string, sbuffer_size, 0, pos, 1, highp, lowp); + rv = flist_recurse(mathomatic, p1, n, out_flag, string, sbuffer_size, 0, pos, 1, highp, lowp); if (out_flag && (string == NULL)) { - default_color(false); + default_color(mathomatic, false); } return rv; } static int -flist_recurse(p1, n, out_flag, string, sbuffer_size, line, pos, cur_level, highp, lowp) -token_type *p1; -int n; -int out_flag; /* if true, output to gfp or string */ -char *string; /* if not NULL, put output to here instead of gfp */ -int sbuffer_size; /* string buffer size */ -int line; -int pos; -int cur_level; -int *highp, *lowp; +flist_recurse(MathoMatic* mathomatic, token_type *p1, int n, int out_flag, char *string, int sbuffer_size, int line, int pos, int cur_level, int *highp, int *lowp) +//int out_flag; /* if true, output to gfp or string */ +//char *string; /* if not NULL, put output to here instead of gfp */ +//int sbuffer_size; /* string buffer size */ { int i, j, k, i1; int l1, l2; @@ -1252,11 +1235,11 @@ int *highp, *lowp; if (n <= 0) { return 0; } - oflag = (out_flag && line == cur_line); + oflag = (out_flag && line == mathomatic->cur_line); cflag = (oflag && string == NULL); - html_out = ((html_flag == 2) || (html_flag && gfp == stdout)); + html_out = ((mathomatic->html_flag == 2) || (mathomatic->html_flag && mathomatic->gfp == stdout)); if (oflag) { - for (; cur_pos < pos; cur_pos++) { + for (; mathomatic->cur_pos < pos; mathomatic->cur_pos++) { APPEND2(" "); } } @@ -1291,7 +1274,7 @@ int *highp, *lowp; if (i == stop_at) { #if DEBUG if (div_loc < 0) { - error_bug("Bug in flist_recurse()."); + error_bug(mathomatic, "Bug in flist_recurse()."); } #endif j = cur_level - p1[div_loc].level; @@ -1316,7 +1299,7 @@ int *highp, *lowp; } if (k < 1) { if (cflag) - set_color(cur_level-1); + set_color(mathomatic, cur_level-1); } for (i1 = 1; i1 <= k; i1++) { if (j > 0) { @@ -1325,27 +1308,27 @@ int *highp, *lowp; if (oflag) { APPEND2(")"); if (cflag) - set_color(cur_level-1); + set_color(mathomatic, cur_level-1); } } else { cur_level++; len++; if (oflag) { if (cflag) - set_color(cur_level-1); + set_color(mathomatic, cur_level-1); APPEND2("("); } } } if (i == stop_at) { level = p1[div_loc].level; - len1 = flist_recurse(&p1[stop_at], div_loc - stop_at, false, string, sbuffer_size, line + 1, pos + len, level, &high, &low); + len1 = flist_recurse(mathomatic, &p1[stop_at], div_loc - stop_at, false, string, sbuffer_size, line + 1, pos + len, level, &high, &low); l1 = (2 * (line + 1)) - low; for (j = div_loc + 2; j < n; j += 2) { if (p1[j].level <= level) break; } - len2 = flist_recurse(&p1[div_loc+1], j - (div_loc + 1), false, string, sbuffer_size, line - 1, pos + len, level, &high, &low); + len2 = flist_recurse(mathomatic, &p1[div_loc+1], j - (div_loc + 1), false, string, sbuffer_size, line - 1, pos + len, level, &high, &low); l2 = (2 * (line - 1)) - high; ii = j; len_div = max(len1, len2); @@ -1353,7 +1336,7 @@ int *highp, *lowp; if (len1 < len_div) { j = (len_div - len1) / 2; } - flist_recurse(&p1[stop_at], div_loc - stop_at, out_flag, string, sbuffer_size, l1, pos + len + j, level, &high, &low); + flist_recurse(mathomatic, &p1[stop_at], div_loc - stop_at, out_flag, string, sbuffer_size, l1, pos + len + j, level, &high, &low); if (high > *highp) *highp = high; if (low < *lowp) @@ -1361,7 +1344,7 @@ int *highp, *lowp; if (oflag) { /* display fraction bar */ if (cflag) - set_color(level-1); + set_color(mathomatic, level-1); for (j = 0; j < len_div; j++) { if (html_out) { APPEND2("–"); @@ -1370,13 +1353,13 @@ int *highp, *lowp; } } if (cflag) - set_color(cur_level-1); + set_color(mathomatic, cur_level-1); } j = 0; if (len2 < len_div) { j = (len_div - len2) / 2; } - flist_recurse(&p1[div_loc+1], ii - (div_loc + 1), out_flag, string, sbuffer_size, l2, pos + len + j, level, &high, &low); + flist_recurse(mathomatic, &p1[div_loc+1], ii - (div_loc + 1), out_flag, string, sbuffer_size, l2, pos + len + j, level, &high, &low); if (high > *highp) *highp = high; if (low < *lowp) @@ -1401,26 +1384,26 @@ int *highp, *lowp; && (i + 1) < n && p1[i].level == p1[i+1].level && p1[i+1].token.operatr == TIMES) { i++; len += snprintf(buf, sizeof(buf), "-"); - } else if (finance_option >= 0) { + } else if (mathomatic->finance_option >= 0) { if (p1[i].token.constant < 0.0) { #if THOUSANDS_SEPARATOR - len += snprintf(buf, sizeof(buf), "(%'.*f)", finance_option, p1[i].token.constant); + len += snprintf(buf, sizeof(buf), "(%'.*f)", mathomatic->finance_option, p1[i].token.constant); #else - len += snprintf(buf, sizeof(buf), "(%.*f)", finance_option, p1[i].token.constant); + len += snprintf(buf, sizeof(buf), "(%.*f)", mathomatic->finance_option, p1[i].token.constant); #endif } else { #if THOUSANDS_SEPARATOR - len += snprintf(buf, sizeof(buf), "%'.*f", finance_option, p1[i].token.constant); + len += snprintf(buf, sizeof(buf), "%'.*f", mathomatic->finance_option, p1[i].token.constant); #else - len += snprintf(buf, sizeof(buf), "%.*f", finance_option, p1[i].token.constant); + len += snprintf(buf, sizeof(buf), "%.*f", mathomatic->finance_option, p1[i].token.constant); #endif } } else { if (p1[i].token.constant < 0.0 && (i + 1) < n && p1[i+1].level == p1[i].level && (p1[i+1].token.operatr >= POWER)) { - len += snprintf(buf, sizeof(buf), "(%.*g)", precision, p1[i].token.constant); + len += snprintf(buf, sizeof(buf), "(%.*g)", mathomatic->precision, p1[i].token.constant); } else { - len += snprintf(buf, sizeof(buf), "%.*g", precision, p1[i].token.constant); + len += snprintf(buf, sizeof(buf), "%.*g", mathomatic->precision, p1[i].token.constant); } } if (oflag) @@ -1440,9 +1423,9 @@ int *highp, *lowp; if (oflag) APPEND2("î"); } else { - len += list_var(p1[i].token.variable, 0); + len += list_var(mathomatic, p1[i].token.variable, 0); if (oflag) - APPEND2(var_str); + APPEND2(mathomatic->var_str); } break; case OPERATOR: @@ -1485,13 +1468,13 @@ int *highp, *lowp; if (html_out && p1[i+1].level == p1[i].level && p1[i+1].kind == CONSTANT) { - len += (snprintf(buf, sizeof(buf), "%.*g", precision, p1[i+1].token.constant) - 11); + len += (snprintf(buf, sizeof(buf), "%.*g", mathomatic->precision, p1[i+1].token.constant) - 11); cp = buf; i++; break; } #endif - if (power_starstar) { + if (mathomatic->power_starstar) { cp = "**"; len += 2; } else { @@ -1521,10 +1504,10 @@ int *highp, *lowp; if (oflag) { APPEND2(")"); if (j > 0 && cflag) - set_color(cur_level-1); + set_color(mathomatic, cur_level-1); } } if (oflag) - cur_pos += len; + mathomatic->cur_pos += len; return len; } diff --git a/main.c b/main.c index 8d2fe5e..8b09a25 100644 --- a/main.c +++ b/main.c @@ -70,6 +70,8 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #if !LIBRARY /* This comments out this whole file if compiling as the symbolic math library. */ #include "includes.h" +#include "lib/mathomatic.h" + #if !NO_GETOPT_H #include #endif @@ -81,15 +83,16 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. HANDLE hOut; #endif +MathoMatic *mathomatic; + /* * Display invocation usage info. */ void -usage(fp) -FILE *fp; +usage(FILE *fp) { fprintf(fp, _("Mathomatic computer algebra system, version %s\n"), VERSION); - fprintf(fp, _("Usage: %s [ options ] [ input_files or input ]\n\n"), prog_name); + fprintf(fp, _("Usage: %s [ options ] [ input_files or input ]\n\n"), mathomatic->prog_name); fprintf(fp, _("Options:\n")); fprintf(fp, _(" -a Enable alternative color mode.\n")); fprintf(fp, _(" -b Enable bold color mode.\n")); @@ -134,45 +137,46 @@ char **argv; #if I18N /* Initialize internationalization so that messages are in the right language. */ setlocale(LC_ALL, ""); - bindtextdomain(prog_name, LOCALEDIR); - textdomain(prog_name); + bindtextdomain(mathomatic->prog_name, LOCALEDIR); + textdomain(mathomatic->prog_name); #endif #if CYGWIN || MINGW dir_path = strdup(dirname_win(argv[0])); /* set dir_path to this executable's directory */ #endif + mathomatic = newtMathoMatic(); /* initialize the global variables */ - init_gvars(); - default_out = stdout; /* set default_out to any file you want to redirect output to */ - gfp = default_out; - get_screen_size(); + init_gvars(mathomatic); + mathomatic->default_out = stdout; /* set default_out to any file you want to redirect output to */ + mathomatic->gfp = mathomatic->default_out; + get_screen_size(mathomatic); /* process command line options */ while ((i = getopt(argc, argv, "s:abqrtdchuvwxm:e")) >= 0) { switch (i) { case 's': if (optarg) { - security_level = strtod(optarg, &cp); + mathomatic->security_level = strtod(optarg, &cp); #if SECURE - if (security_level != 4) { - fprintf(stderr, _("%s: Already compiled for maximum security (level 4), therefore setting security level ignored.\n"), prog_name); + if (mathomatic->security_level != 4) { + fprintf(stderr, _("%s: Already compiled for maximum security (level 4), therefore setting security level ignored.\n"), mathomatic->prog_name); } #endif } if (optarg == NULL || cp == NULL || (cp == optarg && *cp != ':') || (*cp != '\0' && *cp != ':')) { - fprintf(stderr, _("%s: Error in setting security level.\n"), prog_name); + fprintf(stderr, _("%s: Error in setting security level.\n"), mathomatic->prog_name); exit(2); } if (*cp == ':') { time_out_seconds = strtol(cp + 1, &cp, 10); if (!(*cp == '\0' && time_out_seconds > 0)) { - fprintf(stderr, _("%s: Error in setting time out seconds.\n"), prog_name); + fprintf(stderr, _("%s: Error in setting time out seconds.\n"), mathomatic->prog_name); exit(2); } } #if !SECURE if (time_out_seconds > 0) { - printf(_("Security level is %d, time out seconds is %d.\n"), security_level, time_out_seconds); + printf(_("Security level is %d, time out seconds is %d.\n"), mathomatic->security_level, time_out_seconds); } #endif break; @@ -189,34 +193,34 @@ char **argv; coption++; break; case 'x': - html_flag = 1; + mathomatic->html_flag = 1; wide_flag = true; break; case 'm': if (optarg) new_size = strtod(optarg, &cp) * DEFAULT_N_TOKENS; if (optarg == NULL || cp == NULL || *cp || new_size <= 0 || new_size >= (INT_MAX / sizeof(token_type))) { - fprintf(stderr, _("%s: Invalid memory size multiplier specified.\n"), prog_name); + fprintf(stderr, _("%s: Invalid memory size multiplier specified.\n"), mathomatic->prog_name); exit(2); } - n_tokens = (int) new_size; + mathomatic->n_tokens = (int) new_size; break; case 'q': - quiet_mode = true; + mathomatic->quiet_mode = true; break; case 'r': - readline_enabled = false; + mathomatic->readline_enabled = false; break; case 't': - readline_enabled = false; + mathomatic->readline_enabled = false; wide_flag = true; - test_mode = true; + mathomatic->test_mode = true; break; case 'd': - demo_mode = true; + mathomatic->demo_mode = true; break; case 'u': - echo_input = true; + mathomatic->echo_input = true; setbuf(stdout, NULL); /* make output unbuffered */ setbuf(stderr, NULL); break; @@ -228,30 +232,30 @@ char **argv; printf(_("Mathomatic version %s\n"), VERSION); exit(0); case 'e': - eoption = true; - autoselect = false; + mathomatic->eoption = true; + mathomatic->autoselect = false; break; default: usage(stdout); exit(2); } } - if (n_tokens < 100 || n_tokens >= (INT_MAX / sizeof(token_type))) { - fprintf(stderr, _("%s: Standard expression array size %d out of range!\n"), prog_name, n_tokens); + if (mathomatic->n_tokens < 100 || mathomatic->n_tokens >= (INT_MAX / sizeof(token_type))) { + fprintf(stderr, _("%s: Standard expression array size %d out of range!\n"), mathomatic->prog_name, mathomatic->n_tokens); } - if (!init_mem()) { - fprintf(stderr, _("%s: Not enough memory.\n"), prog_name); + if (!init_mem(mathomatic)) { + fprintf(stderr, _("%s: Not enough memory.\n"), mathomatic->prog_name); exit(2); } #if READLINE - if (readline_enabled) { /* readline_enabled flag must not change after this */ + if (mathomatic->readline_enabled) { /* readline_enabled flag must not change after this */ if ((cp = getenv("HOME"))) { #if MINGW - snprintf(history_filename_storage, sizeof(history_filename_storage), "%s/matho_history", cp); + snprintf(mathomatic->history_filename_storage, sizeof(mathomatic->history_filename_storage), "%s/matho_history", cp); #else - snprintf(history_filename_storage, sizeof(history_filename_storage), "%s/.matho_history", cp); + snprintf(mathomatic->history_filename_storage, sizeof(mathomatic->history_filename_storage), "%s/.matho_history", cp); #endif - history_filename = history_filename_storage; + mathomatic->history_filename = mathomatic->history_filename_storage; } using_history(); /* initialize readline history */ rl_initialize(); /* initialize readline */ @@ -259,58 +263,58 @@ char **argv; rl_inhibit_completion = true; /* turn off readline file name completion */ #if 0 /* not 100% tested and this might confuse the user with the -c toggle */ #if !WIN32_CONSOLE_COLORS - if (!html_flag) { /* If doing ANSI color: */ - color_flag = (tigetnum("colors") >= 8); /* autoset color output mode. Requires ncurses. */ + if (!mathomatic->html_flag) { /* If doing ANSI color: */ + mathomatic->color_flag = (tigetnum("colors") >= 8); /* autoset color output mode. Requires ncurses. */ } #endif #endif #if !SECURE - if (security_level <= 3) { - read_history(history_filename); /* restore readline history of previous session */ + if (mathomatic->security_level <= 3) { + read_history(mathomatic->history_filename); /* restore readline history of previous session */ } #endif } #endif - if (html_flag) { + if (mathomatic->html_flag) { printf("
\n");
 	}
-	if (!test_mode && !quiet_mode && !eoption) {
-		display_startup_message(stdout);
+	if (!mathomatic->test_mode && !mathomatic->quiet_mode && !mathomatic->eoption) {
+		display_startup_message(mathomatic, stdout);
 	}
 	fflush(stdout);
 #if	!SECURE
 	/* read the user options initialization file */
-	if (security_level <= 3 && !test_mode && !demo_mode && !load_rc(true, NULL)) {
-		fprintf(stderr, _("%s: Error loading startup set options from \"%s\".\n"), prog_name, rc_file);
+	if (mathomatic->security_level <= 3 && !mathomatic->test_mode && !mathomatic->demo_mode && !load_rc(mathomatic, true, NULL)) {
+		fprintf(stderr, _("%s: Error loading startup set options from \"%s\".\n"), mathomatic->prog_name, mathomatic->rc_file);
 		fprintf(stderr, _("Use the \"set no save\" command to startup with the program defaults every time.\n\n"));
 	}
 #endif
 	if (wide_flag) {
-		screen_columns = 0;
-		screen_rows = 0;
+		mathomatic->screen_columns = 0;
+		mathomatic->screen_rows = 0;
 	}
 	if (coption & 1) {
-		color_flag = !color_flag;
+		mathomatic->color_flag = !mathomatic->color_flag;
 	}
 	if (boption) {
-		color_flag = 1;
-		bold_colors = 1;
+		mathomatic->color_flag = 1;
+		mathomatic->bold_colors = 1;
 	}
-	if (color_flag && aoption) {
-		color_flag = 2;
+	if (mathomatic->color_flag && aoption) {
+		mathomatic->color_flag = 2;
 	}
-	if (test_mode) {
-		color_flag = 0;
-	} else if (!quiet_mode && !eoption) {
-		if (color_flag) {
+	if (mathomatic->test_mode) {
+		mathomatic->color_flag = 0;
+	} else if (!mathomatic->quiet_mode && !mathomatic->eoption) {
+		if (mathomatic->color_flag) {
 #if	WIN32_CONSOLE_COLORS
-			if (color_flag == 2) {
-				printf(_("%s%s color mode enabled"), html_flag ? "HTML" : "ANSI", bold_colors ? " bold" : "");
+			if (mathomatic->color_flag == 2) {
+				printf(_("%s%s color mode enabled"), mathomatic->html_flag ? "HTML" : "ANSI", mathomatic->bold_colors ? " bold" : "");
 			} else {
-				printf(_("%s%s color mode enabled"), html_flag ? "HTML" : "WIN32 CONSOLE", bold_colors ? " bold" : "");
+				printf(_("%s%s color mode enabled"), mathomatic->html_flag ? "HTML" : "WIN32 CONSOLE", mathomatic->bold_colors ? " bold" : "");
 			}
 #else
-			printf(_("%s%s color mode enabled"), html_flag ? "HTML" : "ANSI", bold_colors ? " bold" : "");
+			printf(_("%s%s color mode enabled"), mathomatic->html_flag ? "HTML" : "ANSI", mathomatic->bold_colors ? " bold" : "");
 #endif
 			printf(_("; manage by typing \"help color\".\n"));
 		} else {
@@ -318,18 +322,18 @@ char	**argv;
 		}
 	}
 	fflush(stdout);
-	if ((i = setjmp(jmp_save)) != 0) {
+	if ((i = setjmp(mathomatic->jmp_save)) != 0) {
 		/* for error handling */
-		clean_up();
+		clean_up(mathomatic);
 		switch (i) {
 		case 14:
-			error(_("Expression too large."));
+			error(mathomatic, _("Expression too large."));
 		default:
 			printf(_("Operation aborted.\n"));
 			break;
 		}
-		previous_return_value = 0;
-		if (eoption)
+		mathomatic->previous_return_value = 0;
+		if (mathomatic->eoption)
 			exit_value = 1;
 	} else {
 		if ((rv = set_signals(time_out_seconds))) {
@@ -339,38 +343,38 @@ char	**argv;
 #endif
 			exit_value = 2;
 		}
-		if (!f_to_fraction(0.5, &numerator, &denominator)
+		if (!f_to_fraction(mathomatic, 0.5, &numerator, &denominator)
 		    || numerator != 1.0 || denominator != 2.0
-		    || !f_to_fraction(1.0/3.0, &numerator, &denominator)
+		    || !f_to_fraction(mathomatic, 1.0/3.0, &numerator, &denominator)
 		    || numerator != 1.0 || denominator != 3.0) {
-			fprintf(stderr, _("%s: Cannot convert any floating point values to fractions!\n"), prog_name);
+			fprintf(stderr, _("%s: Cannot convert any floating point values to fractions!\n"), mathomatic->prog_name);
 			fprintf(stderr, _("Roots will not work properly.\n"));
 			exit_value = 2;
 		}
-		if (max_memory_usage() <= 0) {
-			fprintf(stderr, _("%s: Calculated maximum memory usage overflows a long integer!\n"), prog_name);
+		if (max_memory_usage(mathomatic) <= 0) {
+			fprintf(stderr, _("%s: Calculated maximum memory usage overflows a long integer!\n"), mathomatic->prog_name);
 			exit_value = 2;
 		}
-		if (eoption) {
+		if (mathomatic->eoption) {
 			/* process expressions and commands from the command line */
 			for (i = optind; i < argc && argv[i]; i++) {
-				if (!display_process(argv[i])) {
+				if (!display_process(mathomatic, argv[i])) {
 					exit_value = 1;
 				}
 			}
 		} else {
 #if	SECURE
-			if (!quiet_mode && !test_mode)
+			if (!mathomatic->quiet_mode && !mathomatic->test_mode)
 				printf(_("Anything done here is temporary.\n"));
 			if (optind < argc) {
-				warning(_("File arguments ignored in high security mode."));
+				warning(mathomatic, _("File arguments ignored in high security mode."));
 			}
 #else
-			if (!quiet_mode && !test_mode) {
+			if (!mathomatic->quiet_mode && !mathomatic->test_mode) {
 				if (optind < argc) {
 					printf(_("Reading in file%s specified on the command line...\n"), (optind == (argc - 1)) ? "" : "s");
 				} else {
-					if (security_level >= 2) {
+					if (mathomatic->security_level >= 2) {
 						printf(_("Anything done here is temporary.\n"));
 					} else {
 						printf(_("Anything done here is temporary, unless it is saved or redirected.\n"));
@@ -381,7 +385,7 @@ char	**argv;
 			for (i = optind; i < argc && argv[i]; i++) {
 				if (strcmp(argv[i], "-") == 0) {
 					main_io_loop();
-				} else if (!read_file(argv[i])) {
+				} else if (!read_file(mathomatic, argv[i])) {
 					fflush(NULL);	/* flush all output */
 					fprintf(stderr, _("Read of file \"%s\" failed.\n"), argv[i]);
 					exit_program(1);
@@ -390,7 +394,7 @@ char	**argv;
 #endif
 		}
 	}
-	if (!eoption)
+	if (!mathomatic->eoption)
 		main_io_loop();		/* main input/output loop */
 	exit_program(exit_value);	/* exit Mathomatic, doesn't return */
 	return(exit_value);		/* so the compiler doesn't complain */
@@ -405,13 +409,13 @@ main_io_loop(void)
 	char	*cp = NULL;
 
 	for (;;) {
-		error_str = NULL;
-		warning_str = NULL;
-		default_color(false);
-		snprintf(prompt_str, sizeof(prompt_str), "%d%s", cur_equation + 1, html_flag ? HTML_PROMPT_STR : PROMPT_STR);
-		if ((cp = get_string((char *) tlhs, n_tokens * sizeof(token_type))) == NULL)
+		matho_set_error_str(mathomatic, NULL);
+		matho_set_warning_str(mathomatic, NULL);
+		default_color(mathomatic, false);
+		snprintf(mathomatic->prompt_str, sizeof(mathomatic->prompt_str), "%d%s", mathomatic->cur_equation + 1, mathomatic->html_flag ? HTML_PROMPT_STR : PROMPT_STR);
+		if ((cp = get_string(mathomatic, (char *) mathomatic->tlhs, mathomatic->n_tokens * sizeof(token_type))) == NULL)
 			break;
-		process(cp);
+		process(mathomatic, cp);
 	}
 }
 
@@ -466,7 +470,7 @@ fphandler(sig)
 int	sig;
 {
 #if	DEBUG
-	warning("Floating point exception.");
+	warning(mathomatic, "Floating point exception.");
 #endif
 }
 
@@ -479,8 +483,8 @@ void
 inthandler(sig)
 int	sig;
 {
-	abort_flag++;
-	switch (abort_flag) {
+	matho_inc_abort_flag(mathomatic);
+	switch (matho_get_abort_flag(mathomatic)) {
 	case 0:
 	case 1:
 		/* wait for graceful abort */
@@ -505,7 +509,7 @@ alarmhandler(sig)
 int	sig;
 {
 	printf(_("\nTimeout, quitting...\n"));
-	exit_program(1);
+	exit_program(mathomatic, 1);
 }
 #endif
 
@@ -513,8 +517,7 @@ int	sig;
  * Signal handler for proper exiting to the operating system.
  */
 void
-exithandler(sig)
-int	sig;
+exithandler(int sig)
 {
 	exit_program(1);
 }
@@ -524,11 +527,10 @@ int	sig;
  * Window resize signal handler.
  */
 void
-resizehandler(sig)
-int	sig;
+resizehandler(int sig)
 {
-	if (screen_columns)
-		get_screen_size();
+	if (mathomatic->screen_columns)
+		get_screen_size(mathomatic);
 }
 #endif
 
@@ -536,19 +538,19 @@ int	sig;
  * Properly exit this program and return to the operating system.
  */
 void
-exit_program(exit_value)
-int	exit_value;	/* zero if OK, non-zero indicates error return */
+exit_program(int exit_value)
+//int	exit_value;	/* zero if OK, non-zero indicates error return */
 {
-	reset_attr();
-	if (html_flag) {
+	reset_attr(mathomatic);
+	if (mathomatic->html_flag) {
 		printf("
\n"); } #if READLINE && !SECURE - if (readline_enabled && security_level <= 3) { - write_history(history_filename); /* save readline history */ + if (mathomatic->readline_enabled && mathomatic->security_level <= 3) { + write_history(mathomatic->history_filename); /* save readline history */ } #endif - if (exit_value == 0 && !quiet_mode && !eoption && !html_flag) { + if (exit_value == 0 && !mathomatic->quiet_mode && !mathomatic->eoption && !mathomatic->html_flag) { printf(_("ByeBye!! from Mathomatic.\n")); } #if VALGRIND @@ -556,6 +558,7 @@ int exit_value; /* zero if OK, non-zero indicates error return */ printf("If you are not using valgrind, please compile without -DVALGRIND.\n"); free_mem(); /* Free all known memory buffers to check for memory leaks with something like valgrind(1). */ #endif + closetMathoMatic(mathomatic); exit(exit_value); } #endif diff --git a/parse.c b/parse.c index aa9b98c..398f589 100644 --- a/parse.c +++ b/parse.c @@ -45,35 +45,34 @@ char *cp; * followed by the error message, which must be a constant string. */ void -put_up_arrow(cnt, cp) -int cnt; /* position of error, relative to "input_column" */ -char *cp; /* error message (constant ASCII string) */ +put_up_arrow(MathoMatic* mathomatic, int cnt, char *cp) +//int cnt; /* position of error, relative to "input_column" */ +//char *cp; /* error message (constant ASCII string) */ { #if !SILENT && !LIBRARY int i; - cnt += input_column; - if (!quiet_mode && point_flag && (screen_columns == 0 || cnt < screen_columns)) { + cnt += mathomatic->input_column; + if (!mathomatic->quiet_mode && mathomatic->point_flag && (mathomatic->screen_columns == 0 || cnt < mathomatic->screen_columns)) { for (i = 0; i < cnt; i++) { printf(" "); } printf("^ "); } #endif - error(cp); + error(mathomatic, cp); } /* * Return true if character is a valid starting variable character. */ int -isvarchar(ch) -int ch; +isvarchar(MathoMatic* mathomatic, int ch) { if (isdigit(ch)) { /* variable names can never start with a digit */ return false; } - return(ch == '_' || (ch && strchr(special_variable_characters, ch)) || isalpha(ch)); + return(ch == '_' || (ch && strchr(mathomatic->special_variable_characters, ch)) || isalpha(ch)); } /* @@ -130,7 +129,7 @@ int i; /* location of operator to parenthesize in expression */ #if DEBUG if (i >= (n - 1) || (n & 1) != 1 || (i & 1) != 1 || p1[i].kind != OPERATOR) { - error_bug("Internal error in arguments to binary_parenthesize()."); + error_bug(mathomatic, "Internal error in arguments to binary_parenthesize()."); } #endif skip_negate = (p1[i].token.operatr != NEGATE); @@ -186,9 +185,9 @@ int *np; * organize() should be called after this to remove unneeded parentheses. */ void -give_priority(equation, np) -token_type *equation; /* pointer to expression */ -int *np; /* pointer to expression length */ +give_priority(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to expression */ +//int *np; /* pointer to expression length */ { int i; @@ -199,7 +198,7 @@ int *np; /* pointer to expression length */ } } - if (right_associative_power) { + if (mathomatic->right_associative_power) { for (i = *np - 2; i >= 1; i -= 2) { /* count down (for right to left evaluation) */ if (equation[i].token.operatr == POWER) { binary_parenthesize(equation, *np, i); @@ -236,11 +235,11 @@ int *np; /* pointer to expression length */ * Returns the new string position, or NULL if error. */ char * -parse_section(equation, np, cp, allow_space) -token_type *equation; /* where the parsed expression is stored (equation side) */ -int *np; /* pointer to the returned parsed expression length */ -char *cp; /* string to parse */ -int allow_space; /* if false, any space characters terminate parsing */ +parse_section(MathoMatic* mathomatic, token_type *equation, int *np, char *cp, int allow_space) +//token_type *equation; /* where the parsed expression is stored (equation side) */ +//int *np; /* pointer to the returned parsed expression length */ +//char *cp; /* string to parse */ +//int allow_space; /* if false, any space characters terminate parsing */ { int i; int n = 0, old_n; /* position in equation[] */ @@ -255,8 +254,8 @@ int allow_space; /* if false, any space characters terminate parsing */ return(NULL); cp_start = cp; for (;; cp++) { - if (n > (n_tokens - 10)) { - error_huge(); + if (n > (mathomatic->n_tokens - 10)) { + error_huge(mathomatic); } switch (*cp) { case '(': @@ -279,7 +278,7 @@ int allow_space; /* if false, any space characters terminate parsing */ case '}': cur_level--; if (cur_level <= 0 || (abs_count > 0 && cur_level < abs_array[abs_count-1])) { - put_up_arrow(cp - cp_start, _("Unmatched parenthesis: too many )")); + put_up_arrow(mathomatic, cp - cp_start, _("Unmatched parenthesis: too many )")); return(NULL); } if (!operand) { @@ -301,7 +300,7 @@ int allow_space; /* if false, any space characters terminate parsing */ continue; case '\033': if (cp[1] == '[' || cp[1] == 'O') { - error(_("Cursor or function key string encountered, unable to interpret.")); + error(mathomatic, _("Cursor or function key string encountered, unable to interpret.")); return(NULL); } continue; @@ -311,7 +310,7 @@ int allow_space; /* if false, any space characters terminate parsing */ case '|': if (operand) { if (abs_count >= ARR_CNT(abs_array)) { - error(_("Too many nested absolute values.")); + error(mathomatic, _("Too many nested absolute values.")); return(NULL); } cur_level += 3; @@ -347,7 +346,7 @@ int allow_space; /* if false, any space characters terminate parsing */ goto syntax_error; } if (cp[1] == '!' && cp[2] != '!') { - warning(_("Multifactorial not implemented, using x!! = (x!)!")); + warning(mathomatic, _("Multifactorial not implemented, using x!! = (x!)!")); } equation[n].level = cur_level; equation[n].kind = OPERATOR; @@ -425,7 +424,7 @@ int allow_space; /* if false, any space characters terminate parsing */ if (strncmp(cp, "+/-", 3) == 0) { equation[n].level = cur_level; equation[n].kind = VARIABLE; - next_sign(&equation[n].token.variable); + next_sign(mathomatic, &equation[n].token.variable); n++; equation[n].level = cur_level; equation[n].kind = OPERATOR; @@ -475,7 +474,7 @@ int allow_space; /* if false, any space characters terminate parsing */ goto syntax_error; } if (errno) { - put_up_arrow(cp1 - cp_start, _("Constant out of range.")); + put_up_arrow(mathomatic, cp1 - cp_start, _("Constant out of range.")); return(NULL); } equation[n].kind = CONSTANT; @@ -494,42 +493,42 @@ int allow_space; /* if false, any space characters terminate parsing */ case '+': case '-': i = strtol(cp, &cp1, 10); - i = cur_equation + i; + i = mathomatic->cur_equation + i; break; default: i = strtol(cp, &cp1, 10) - 1; break; } if (cp1 == NULL || cp == cp1) { - put_up_arrow(cp - cp_start, _("Error parsing equation space number after #.")); + put_up_arrow(mathomatic, cp - cp_start, _("Error parsing equation space number after #.")); return NULL; } - if (empty_equation_space(i)) { - put_up_arrow(cp - cp_start, _("No expression available in # specified equation space.")); + if (empty_equation_space(mathomatic, i)) { + put_up_arrow(mathomatic, cp - cp_start, _("No expression available in # specified equation space.")); return NULL; } cp = cp1 - 1; old_n = n; - if (n_rhs[i]) { - n += n_rhs[i]; - if (n > n_tokens) { - error_huge(); + if (mathomatic->n_rhs[i]) { + n += mathomatic->n_rhs[i]; + if (n > mathomatic->n_tokens) { + error_huge(mathomatic); } - blt(&equation[old_n], rhs[i], n_rhs[i] * sizeof(token_type)); + blt(&equation[old_n], mathomatic->rhs[i], mathomatic->n_rhs[i] * sizeof(token_type)); } else { - n += n_lhs[i]; - if (n > n_tokens) { - error_huge(); + n += mathomatic->n_lhs[i]; + if (n > mathomatic->n_tokens) { + error_huge(mathomatic); } - blt(&equation[old_n], lhs[i], n_lhs[i] * sizeof(token_type)); + blt(&equation[old_n], mathomatic->lhs[i], mathomatic->n_lhs[i] * sizeof(token_type)); } for (; old_n < n; old_n++) { equation[old_n].level += cur_level; } break; default: - if (!isvarchar(*cp)) { - put_up_arrow(cp - cp_start, _("Unrecognized character.")); + if (!isvarchar(mathomatic, *cp)) { + put_up_arrow(mathomatic, cp - cp_start, _("Unrecognized character.")); return(NULL); } if (!operand) { @@ -541,18 +540,18 @@ int allow_space; /* if false, any space characters terminate parsing */ } cp1 = cp; if (strncasecmp(cp, "inf", strlen("inf")) == 0 - && !isvarchar(cp[strlen("inf")])) { + && !isvarchar(mathomatic, cp[strlen("inf")])) { equation[n].kind = CONSTANT; equation[n].token.constant = INFINITY; /* the infinity constant */ cp += strlen("inf"); } else if (strncasecmp(cp, INFINITY_NAME, strlen(INFINITY_NAME)) == 0 - && !isvarchar(cp[strlen(INFINITY_NAME)])) { + && !isvarchar(mathomatic, cp[strlen(INFINITY_NAME)])) { equation[n].kind = CONSTANT; equation[n].token.constant = INFINITY; /* the infinity constant */ cp += strlen(INFINITY_NAME); } else { equation[n].kind = VARIABLE; - cp = parse_var(&equation[n].token.variable, cp); + cp = parse_var(mathomatic, &equation[n].token.variable, cp); if (cp == NULL) { return(NULL); } @@ -560,9 +559,9 @@ int allow_space; /* if false, any space characters terminate parsing */ if (*cp == '(') { /* Named functions currently not implemented, except when using m4. */ #if LIBRARY - put_up_arrow(cp1 - cp_start, _("Unknown function.")); + put_up_arrow(mathomatic, cp1 - cp_start, _("Unknown function.")); #else - put_up_arrow(cp1 - cp_start, _("Unknown function; try using rmath, which allows basic functions.")); + put_up_arrow(mathomatic, cp1 - cp_start, _("Unknown function; try using rmath, which allows basic functions.")); #endif return(NULL); } @@ -577,21 +576,21 @@ int allow_space; /* if false, any space characters terminate parsing */ goto syntax_error; } if (cur_level != 1) { - put_up_arrow(cp - cp_start, _("Unmatched parenthesis: missing )")); + put_up_arrow(mathomatic, cp - cp_start, _("Unmatched parenthesis: missing )")); return(NULL); } while (*cp == '=') cp++; *np = n; if (n) { - give_priority(equation, np); - organize(equation, np); + give_priority(mathomatic, equation, np); + organize(mathomatic, equation, np); } - input_column += (cp - cp_start); + mathomatic->input_column += (cp - cp_start); return cp; syntax_error: - put_up_arrow(cp - cp_start, _("Syntax error.")); + put_up_arrow(mathomatic, cp - cp_start, _("Syntax error.")); return(NULL); } @@ -604,18 +603,18 @@ int allow_space; /* if false, any space characters terminate parsing */ * Currently, there can be no more to parse in the string when this returns. */ char * -parse_equation(n, cp) -int n; /* equation space number */ -char *cp; /* pointer to the beginning of the equation character string */ +parse_equation(MathoMatic* mathomatic, int n, char *cp) +//int n; /* equation space number */ +//char *cp; /* pointer to the beginning of the equation character string */ { - if ((cp = parse_expr(lhs[n], &n_lhs[n], cp, true)) != NULL) { - if ((cp = parse_expr(rhs[n], &n_rhs[n], cp, true)) != NULL) { - if (!extra_characters(cp)) + if ((cp = parse_expr(mathomatic, mathomatic->lhs[n], &mathomatic->n_lhs[n], cp, true)) != NULL) { + if ((cp = parse_expr(mathomatic, mathomatic->rhs[n], &mathomatic->n_rhs[n], cp, true)) != NULL) { + if (!extra_characters(mathomatic, cp)) return cp; } } - n_lhs[n] = 0; - n_rhs[n] = 0; + mathomatic->n_lhs[n] = 0; + mathomatic->n_rhs[n] = 0; return NULL; } @@ -626,18 +625,18 @@ char *cp; /* pointer to the beginning of the equation character string */ * Returns the new string position, or NULL if error. */ char * -parse_expr(equation, np, cp, allow_space) -token_type *equation; /* where the parsed expression is stored (equation side) */ -int *np; /* pointer to the returned parsed expression length */ -char *cp; /* string to parse */ -int allow_space; /* if true, allow and ignore space characters; if false, space means terminate parsing */ +parse_expr(MathoMatic* mathomatic, token_type *equation, int *np, char *cp, int allow_space) +//token_type *equation; /* where the parsed expression is stored (equation side) */ +//int *np; /* pointer to the returned parsed expression length */ +//char *cp; /* string to parse */ +//int allow_space; /* if true, allow and ignore space characters; if false, space means terminate parsing */ { if (cp == NULL) return NULL; - if (!case_sensitive_flag) { + if (!mathomatic->case_sensitive_flag) { str_tolower(cp); } - cp = parse_section(equation, np, cp, allow_space); + cp = parse_section(mathomatic, equation, np, cp, allow_space); return cp; } @@ -651,9 +650,7 @@ int allow_space; /* if true, allow and ignore space characters; if false, space * Display error message and return NULL on failure. */ char * -parse_var(vp, cp) -long *vp; -char *cp; +parse_var(MathoMatic* mathomatic, long *vp, char *cp) { int i, j; long vtmp; @@ -663,17 +660,17 @@ char *cp; int level; /* parentheses level */ int (*strcmpfunc)(); - if (case_sensitive_flag) { + if (mathomatic->case_sensitive_flag) { strcmpfunc = strcmp; } else { strcmpfunc = strcasecmp; } - if (!isvarchar(*cp) || paren_increment(*cp) < 0) { - error(_("Invalid variable.")); + if (!isvarchar(mathomatic, *cp) || paren_increment(*cp) < 0) { + error(mathomatic, _("Invalid variable.")); return(NULL); /* variable name must start with a valid variable character */ } for (level = 0, cp1 = cp, i = 0; *cp1;) { - if (level <= 0 && !isvarchar(*cp1)) { + if (level <= 0 && !isvarchar(mathomatic, *cp1)) { break; } j = paren_increment(*cp1); @@ -681,7 +678,7 @@ char *cp; if (level < 0) break; if (i >= MAX_VAR_LEN) { - error(_("Variable name too long.")); + error(mathomatic, _("Variable name too long.")); return(NULL); } buf[i++] = *cp1++; @@ -690,15 +687,15 @@ char *cp; } buf[i] = '\0'; if (level > 0) { - error(_("Unmatched parenthesis: missing )")); + error(mathomatic, _("Unmatched parenthesis: missing )")); return(NULL); } if (strcasecmp(buf, NAN_NAME) == 0) { - warning(_("Attempt to enter NaN (Not a Number); Converted to variable.")); + warning(mathomatic, _("Attempt to enter NaN (Not a Number); Converted to variable.")); } if (strcasecmp(buf, "inf") == 0 || strcasecmp(buf, INFINITY_NAME) == 0) { - error(_("Infinity cannot be used as a variable.")); + error(mathomatic, _("Infinity cannot be used as a variable.")); return(NULL); } else if ((*strcmpfunc)(buf, "sign") == 0) { vtmp = SIGN; @@ -716,7 +713,7 @@ char *cp; return(cp + 3); } for (level = 0, cp1 = cp, i = 0; *cp1;) { - if (level <= 0 && !isvarchar(*cp1) && !isdigit(*cp1)) { + if (level <= 0 && !isvarchar(mathomatic, *cp1) && !isdigit(*cp1)) { break; } j = paren_increment(*cp1); @@ -724,7 +721,7 @@ char *cp; if (level < 0) break; if (i >= MAX_VAR_LEN) { - error(_("Variable name too long.")); + error(mathomatic, _("Variable name too long.")); return(NULL); } buf[i++] = *cp1++; @@ -732,12 +729,12 @@ char *cp; break; } if (i <= 0) { - error(_("Empty variable name parsed!")); + error(mathomatic, _("Empty variable name parsed!")); return(NULL); } buf[i] = '\0'; if (level > 0) { - error(_("Unmatched parenthesis: missing )")); + error(mathomatic, _("Unmatched parenthesis: missing )")); return(NULL); } if ((*strcmpfunc)(buf, "i") == 0) { @@ -753,33 +750,33 @@ char *cp; return(cp1); } if (is_all(buf)) { - error(_("\"all\" is a reserved word and may not be used as a variable name.")); + error(mathomatic, _("\"all\" is a reserved word and may not be used as a variable name.")); return(NULL); } vtmp = 0; - for (i = 0; var_names[i]; i++) { - if ((*strcmpfunc)(buf, var_names[i]) == 0) { + for (i = 0; mathomatic->var_names[i]; i++) { + if ((*strcmpfunc)(buf, mathomatic->var_names[i]) == 0) { vtmp = i + VAR_OFFSET; break; } } if (vtmp == 0) { if (i >= (MAX_VAR_NAMES - 1)) { - error(_("Maximum number of variable names reached.")); + error(mathomatic, _("Maximum number of variable names reached.")); #if !SILENT printf(_("Please restart or use \"clear all\".\n")); #endif return(NULL); } len = strlen(buf) + 1; - var_names[i] = (char *) malloc(len); - if (var_names[i] == NULL) { - error(_("Out of memory (can't malloc(3) variable name).")); + mathomatic->var_names[i] = (char *) malloc(len); + if (mathomatic->var_names[i] == NULL) { + error(mathomatic, _("Out of memory (can't malloc(3) variable name).")); return(NULL); } - blt(var_names[i], buf, len); + blt(mathomatic->var_names[i], buf, len); vtmp = i + VAR_OFFSET; - var_names[i+1] = NULL; + mathomatic->var_names[i+1] = NULL; } *vp = vtmp; return cp1; @@ -788,15 +785,15 @@ char *cp; if (isdigit(*cp1)) { j = strtol(cp1, &cp1, 10); if (j < 0 || j > MAX_SUBSCRIPT) { - error(_("Maximum subscript exceeded in special variable name.")); + error(mathomatic, _("Maximum subscript exceeded in special variable name.")); return(NULL); } if (vtmp == SIGN) { - sign_array[j+1] = true; + mathomatic->sign_array[j+1] = true; } vtmp += ((long) (j + 1)) << VAR_SHIFT; } else if (vtmp == SIGN) { - sign_array[0] = true; + mathomatic->sign_array[0] = true; } *vp = vtmp; return cp1; @@ -806,8 +803,7 @@ char *cp; * Remove trailing spaces from a string. */ void -remove_trailing_spaces(cp) -char *cp; +remove_trailing_spaces(char *cp) { int i; @@ -824,20 +820,20 @@ char *cp; * Truncate string to the actual content. */ void -set_error_level(cp) -char *cp; /* input string */ +set_error_level(MathoMatic* mathomatic, char *cp) +//char *cp; /* input string */ { char *cp1; int len; - point_flag = true; + mathomatic->point_flag = true; /* handle comments, line breaks, and the DOS EOF character (control-Z) by truncating the string where found */ cp1 = cp; while ((cp1 = strpbrk(cp1, ";\n\r\032"))) { if (cp1 > cp && *(cp1 - 1) == '\\') { if (*cp1 == ';') { /* skip backslash escaped semicolon */ - point_flag = false; + mathomatic->point_flag = false; len = strlen(cp1); blt(cp1 - 1, cp1, len + 1); continue; @@ -852,7 +848,7 @@ char *cp; /* input string */ /* set point_flag to false if non-printable characters encountered */ for (cp1 = cp; *cp1; cp1++) { if (!isprint(*cp1)) { - point_flag = false; + mathomatic->point_flag = false; } } } diff --git a/poly.c b/poly.c index aaf0996..3f8600f 100644 --- a/poly.c +++ b/poly.c @@ -41,7 +41,7 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "includes.h" -#define REMAINDER_IS_ZERO() (n_trhs == 1 && trhs[0].kind == CONSTANT && trhs[0].token.constant == 0.0) +#define REMAINDER_IS_ZERO() (mathomatic->n_trhs == 1 && mathomatic->trhs[0].kind == CONSTANT && mathomatic->trhs[0].token.constant == 0.0) /* * The following static expression storage areas are of non-standard size @@ -58,14 +58,14 @@ int n_quotient; /* length of expression in quotient[] */ token_type gcd_divisor[DIVISOR_SIZE]; /* static expression storage area for polynomial GCD routine */ int len_d; /* length of expression in gcd_divisor[] */ -static int pf_recurse(token_type *equation, int *np, int loc, int level, int do_repeat); -static int pf_sub(token_type *equation, int *np, int loc, int len, int level, int do_repeat); -static int save_factors(token_type *equation, int *np, int loc1, int len, int level); -static int do_gcd(long *vp); -static int mod_recurse(token_type *equation, int *np, int loc, int level); -static int polydiv_recurse(token_type *equation, int *np, int loc, int level); -static int pdiv_recurse(token_type *equation, int *np, int loc, int level, int code); -static int poly_div_sub(token_type *d1, int len1, token_type *d2, int len2, long *vp); +static int pf_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int do_repeat); +static int pf_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int len, int level, int do_repeat); +static int save_factors(MathoMatic* mathomatic, token_type *equation, int *np, int loc1, int len, int level); +static int do_gcd(MathoMatic* mathomatic, long *vp); +static int mod_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level); +static int polydiv_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level); +static int pdiv_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int code); +static int poly_div_sub(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int len2, long *vp); static int find_highest_count(token_type *p1, int n1, token_type *p2, int n2, long *vp1); /* @@ -92,17 +92,17 @@ sort_type *p1, *p2; * as long as it doesn't contain the variable v. */ int -poly_in_v_sub(p1, n, v, allow_divides) -token_type *p1; /* expression pointer */ -int n; /* expression length */ -long v; /* Mathomatic variable */ -int allow_divides; /* if true, allow division by variable */ +poly_in_v_sub(MathoMatic* mathomatic, token_type *p1, int n, long v, int allow_divides) +//token_type *p1; /* expression pointer */ +//int n; /* expression length */ +//long v; /* Mathomatic variable */ +//int allow_divides; /* if true, allow division by variable */ { int i, k; int level, vlevel; int count; - level = min_level(p1, n); + level = min_level(mathomatic, p1, n); for (i = 0, count = 0; i < n; i += 2) { if (p1[i].kind == VARIABLE && p1[i].token.variable == v) { count++; @@ -147,18 +147,18 @@ int allow_divides; /* if true, allow division by variable */ * The passed expression should be fully unfactored, for a proper determination. */ int -poly_in_v(p1, n, v, allow_divides) -token_type *p1; /* expression pointer */ -int n; /* expression length */ -long v; /* Mathomatic variable */ -int allow_divides; /* allow variable to be right of a divide (negative exponents) as a polynomial term */ +poly_in_v(MathoMatic* mathomatic, token_type *p1, int n, long v, int allow_divides) +//token_type *p1; /* expression pointer */ +//int n; /* expression length */ +//long v; /* Mathomatic variable */ +//int allow_divides; /* allow variable to be right of a divide (negative exponents) as a polynomial term */ { int i, j; for (i = 1, j = 0;; i += 2) { if (i >= n || (p1[i].level == 1 && (p1[i].token.operatr == PLUS || p1[i].token.operatr == MINUS))) { - if (!poly_in_v_sub(&p1[j], i - j, v, allow_divides)) { + if (!poly_in_v_sub(mathomatic, &p1[j], i - j, v, allow_divides)) { return false; } j = i + 1; @@ -182,19 +182,16 @@ int allow_divides; /* allow variable to be right of a divide (negative exponent * Return true if equation side was modified (factored). */ int -poly_factor(equation, np, do_repeat) -token_type *equation; /* pointer to the beginning of equation side */ -int *np; /* pointer to length of equation side */ -int do_repeat; /* factor repeated factors flag */ +poly_factor(MathoMatic* mathomatic, token_type *equation, int *np, int do_repeat) +//token_type *equation; /* pointer to the beginning of equation side */ +//int *np; /* pointer to length of equation side */ +//int do_repeat; /* factor repeated factors flag */ { - return pf_recurse(equation, np, 0, 1, do_repeat); + return pf_recurse(mathomatic, equation, np, 0, 1, do_repeat); } static int -pf_recurse(equation, np, loc, level, do_repeat) -token_type *equation; -int *np, loc, level; -int do_repeat; +pf_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int do_repeat) { int modified = false; int i; @@ -212,11 +209,11 @@ int do_repeat; } if (level_count && count > 1) { /* so we don't factor expressions with only one additive operator */ /* try to factor the sub-expression */ - modified = pf_sub(equation, np, loc, i - loc, level, do_repeat); + modified = pf_sub(mathomatic, equation, np, loc, i - loc, level, do_repeat); } for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= pf_recurse(equation, np, i, level + 1, do_repeat); + modified |= pf_recurse(mathomatic, equation, np, i, level + 1, do_repeat); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -235,13 +232,13 @@ int do_repeat; * Return true if equation side was modified (factored). */ static int -pf_sub(equation, np, loc, len, level, do_repeat) -token_type *equation; /* equation side holding the possible polynomial to factor */ -int *np, /* pointer to length of equation side */ - loc, /* index of start of polynomial in equation side */ - len; /* length of polynomial */ -int level; /* level of additive operators in polynomial */ -int do_repeat; /* factor repeated factors flag */ +pf_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int len, int level, int do_repeat) +//token_type *equation; /* equation side holding the possible polynomial to factor */ +//int *np, /* pointer to length of equation side */ +// loc, /* index of start of polynomial in equation side */ +// len; /* length of polynomial */ +//int level; /* level of additive operators in polynomial */ +//int do_repeat; /* factor repeated factors flag */ { token_type *p1; int modified = false, symbolic_modified = false; @@ -258,30 +255,30 @@ int do_repeat; /* factor repeated factors flag */ double d; int old_partial; - debug_string(3, "Entering pf_sub()."); - old_partial = partial_flag; + debug_string(mathomatic, 3, "Entering pf_sub()."); + old_partial = mathomatic->partial_flag; loc2 = loc1 = loc; find_greatest_power(&equation[loc1], len, &v, &d, &j, &k, &div_flag); if (v == 0) return false; - blt(save_save, jmp_save, sizeof(jmp_save)); - if ((i = setjmp(jmp_save)) != 0) { /* trap errors */ - partial_flag = old_partial; - blt(jmp_save, save_save, sizeof(jmp_save)); + blt(save_save, mathomatic->jmp_save, sizeof(mathomatic->jmp_save)); + if ((i = setjmp(mathomatic->jmp_save)) != 0) { /* trap errors */ + mathomatic->partial_flag = old_partial; + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); if (i == 13) { /* critical error code */ - longjmp(jmp_save, i); + longjmp(mathomatic->jmp_save, i); } return(modified || symbolic_modified); } /* First factor polynomials with repeated factors */ /* using poly_gcd(polynomial, v * differentiate(polynomial, v)) to discover the factors: */ for (count = 1; do_repeat; count++) { - blt(trhs, &equation[loc1], len * sizeof(token_type)); - n_trhs = len; - partial_flag = false; - uf_simp(trhs, &n_trhs); - partial_flag = old_partial; - if (level1_plus_count(trhs, n_trhs) < 2) { + blt(mathomatic->trhs, &equation[loc1], len * sizeof(token_type)); + mathomatic->n_trhs = len; + mathomatic->partial_flag = false; + uf_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + mathomatic->partial_flag = old_partial; + if (level1_plus_count(mathomatic, mathomatic->trhs, mathomatic->n_trhs) < 2) { /* must be at least 2 level 1 additive operators to be factorable */ goto skip_factor; } @@ -290,12 +287,12 @@ int do_repeat; /* factor repeated factors flag */ for (vc = 0; vc < ARR_CNT(va);) { cnt = 0; v1 = -1; - for (i = 0; i < n_trhs; i += 2) { - if (trhs[i].kind == VARIABLE && trhs[i].token.variable > last_v) { - if (v1 == -1 || trhs[i].token.variable < v1) { - v1 = trhs[i].token.variable; + for (i = 0; i < mathomatic->n_trhs; i += 2) { + if (mathomatic->trhs[i].kind == VARIABLE && mathomatic->trhs[i].token.variable > last_v) { + if (v1 == -1 || mathomatic->trhs[i].token.variable < v1) { + v1 = mathomatic->trhs[i].token.variable; cnt = 1; - } else if (trhs[i].token.variable == v1) { + } else if (mathomatic->trhs[i].token.variable == v1) { cnt++; } } @@ -307,12 +304,12 @@ int do_repeat; /* factor repeated factors flag */ va[vc].count = cnt; vc++; } - side_debug(3, &equation[loc1], len); - side_debug(3, trhs, n_trhs); + side_debug(mathomatic, 3, &equation[loc1], len); + side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); /* Find a valid polynomial base variable "v": */ cnt = -1; if (v) { - if (vc > 1 && !poly_in_v(trhs, n_trhs, v, true)) { + if (vc > 1 && !poly_in_v(mathomatic, mathomatic->trhs, mathomatic->n_trhs, v, true)) { v = 0; } } @@ -321,7 +318,7 @@ int do_repeat; /* factor repeated factors flag */ continue; } if (v == 0) { - if (poly_in_v(trhs, n_trhs, va[i].v, true)) { + if (poly_in_v(mathomatic, mathomatic->trhs, mathomatic->n_trhs, va[i].v, true)) { v = va[i].v; } } @@ -341,9 +338,9 @@ int do_repeat; /* factor repeated factors flag */ continue; } v = va[i].v; - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; - if (differentiate(tlhs, &n_tlhs, v)) { + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; + if (differentiate(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, v)) { break; } v = 0; @@ -353,48 +350,48 @@ int do_repeat; /* factor repeated factors flag */ } #endif } else { - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; - if (!differentiate(tlhs, &n_tlhs, v)) { + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; + if (!differentiate(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, v)) { break; } } #if !SILENT - if (debug_level >= 3) { - list_var(v, 0); - fprintf(gfp, _("Differentiation successful using variable %s.\n"), var_str); + if (mathomatic->debug_level >= 3) { + list_var(mathomatic, v, 0); + fprintf(mathomatic->gfp, _("Differentiation successful using variable %s.\n"), mathomatic->var_str); } #endif - simp_loop(tlhs, &n_tlhs); - if ((n_tlhs + 2) > min(DIVISOR_SIZE, n_tokens)) + simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + if ((mathomatic->n_tlhs + 2) > min(DIVISOR_SIZE, mathomatic->n_tokens)) break; - for (i = 0; i < n_tlhs; i++) - tlhs[i].level++; - tlhs[n_tlhs].kind = OPERATOR; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].token.operatr = TIMES; - n_tlhs++; - tlhs[n_tlhs].kind = VARIABLE; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].token.variable = v; - n_tlhs++; - uf_simp(tlhs, &n_tlhs); - if (poly_gcd(&equation[loc1], len, tlhs, n_tlhs, v) <= 0) + for (i = 0; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; + mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = TIMES; + mathomatic->n_tlhs++; + mathomatic->tlhs[mathomatic->n_tlhs].kind = VARIABLE; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].token.variable = v; + mathomatic->n_tlhs++; + uf_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + if (poly_gcd(mathomatic, &equation[loc1], len, mathomatic->tlhs, mathomatic->n_tlhs, v) <= 0) break; - if (level1_plus_count(tlhs, n_tlhs) == 0) + if (level1_plus_count(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs) == 0) break; - if (!save_factors(equation, np, loc1, len, level)) + if (!save_factors(mathomatic, equation, np, loc1, len, level)) break; - loc1 += n_tlhs + 1; - len = n_trhs; + loc1 += mathomatic->n_tlhs + 1; + len = mathomatic->n_trhs; switch (count) { case 1: - debug_string(1, "Polynomial with repeated factor factored."); - len_first = n_tlhs; + debug_string(mathomatic, 1, "Polynomial with repeated factor factored."); + len_first = mathomatic->n_tlhs; loc2 = loc1; break; case 2: - len2 = n_tlhs; + len2 = mathomatic->n_tlhs; break; } modified = true; @@ -404,10 +401,10 @@ int do_repeat; /* factor repeated factors flag */ last_v = 0; next_v: p1 = &equation[loc1]; - blt(trhs, p1, len * sizeof(token_type)); - n_trhs = len; - uf_simp_no_repeat(trhs, &n_trhs); - if (level1_plus_count(trhs, n_trhs) < 2) { + blt(mathomatic->trhs, p1, len * sizeof(token_type)); + mathomatic->n_trhs = len; + uf_simp_no_repeat(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + if (level1_plus_count(mathomatic, mathomatic->trhs, mathomatic->n_trhs) < 2) { /* must be at least 2 level 1 additive operators to be factorable */ goto skip_factor; } @@ -425,49 +422,49 @@ int do_repeat; /* factor repeated factors flag */ } last_v = v; /* make sure there is more than one "v" raised to the highest power: */ - if (find_greatest_power(trhs, n_trhs, &v, &d, &j, &k, &div_flag) <= 1) { + if (find_greatest_power(mathomatic->trhs, mathomatic->n_trhs, &v, &d, &j, &k, &div_flag) <= 1) { continue; } - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; /* do the grouping: */ - while (factor_plus(tlhs, &n_tlhs, v, 0.0)) { - simp_loop(tlhs, &n_tlhs); + while (factor_plus(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, v, 0.0)) { + simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); } /* extract the highest power group: */ - if (find_greatest_power(tlhs, n_tlhs, &v, &d, &j, &k, &div_flag) != 1) { + if (find_greatest_power(mathomatic->tlhs, mathomatic->n_tlhs, &v, &d, &j, &k, &div_flag) != 1) { continue; } if (j) { - blt(tlhs, &tlhs[j], k * sizeof(token_type)); + blt(mathomatic->tlhs, &mathomatic->tlhs[j], k * sizeof(token_type)); } - n_tlhs = k; + mathomatic->n_tlhs = k; #if !SILENT - if (debug_level >= 3) { - fprintf(gfp, _("Trying factor: ")); - list_proc(tlhs, n_tlhs, false); - fprintf(gfp, "\n"); + if (mathomatic->debug_level >= 3) { + fprintf(mathomatic->gfp, _("Trying factor: ")); + list_proc(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs, false); + fprintf(mathomatic->gfp, "\n"); } #endif - if (poly_gcd(&equation[loc1], len, tlhs, n_tlhs, 0L) <= 0) + if (poly_gcd(mathomatic, &equation[loc1], len, mathomatic->tlhs, mathomatic->n_tlhs, 0L) <= 0) goto next_v; - if (level1_plus_count(tlhs, n_tlhs) == 0) + if (level1_plus_count(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs) == 0) goto next_v; if (!symbolic_modified) { - debug_string(1, "Symbolic polynomial factored."); + debug_string(mathomatic, 1, "Symbolic polynomial factored."); } else { - debug_string(1, "Found another symbolic factor."); + debug_string(mathomatic, 1, "Found another symbolic factor."); } - if (!save_factors(equation, np, loc1, len, level)) + if (!save_factors(mathomatic, equation, np, loc1, len, level)) break; - len = n_tlhs; + len = mathomatic->n_tlhs; symbolic_modified = true; last_v = 0; goto next_v; } } skip_factor: - blt(jmp_save, save_save, sizeof(jmp_save)); + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); if (modified) { /* Repeated factor was factored out. */ /* See if we can factor out more of the repeated factor. */ @@ -478,18 +475,18 @@ int do_repeat; /* factor repeated factors flag */ loct = loc; lent = len_first; } - if (poly_gcd(&equation[loc1], len, &equation[loct], lent, v) > 0) { - if (save_factors(equation, np, loc1, len, level)) { - loc1 += n_tlhs + 1; - len = n_trhs; + if (poly_gcd(mathomatic, &equation[loc1], len, &equation[loct], lent, v) > 0) { + if (save_factors(mathomatic, equation, np, loc1, len, level)) { + loc1 += mathomatic->n_tlhs + 1; + len = mathomatic->n_trhs; } } if (len2) { loc1 = loc2; len = len2; } - if (poly_gcd(&equation[loc], len_first, &equation[loc1], len, 0L) > 0) { - save_factors(equation, np, loc, len_first, level); + if (poly_gcd(mathomatic, &equation[loc], len_first, &equation[loc1], len, 0L) > 0) { + save_factors(mathomatic, equation, np, loc, len_first, level); } } if (modified || symbolic_modified) { @@ -497,42 +494,40 @@ int do_repeat; /* factor repeated factors flag */ ; #if DEBUG if ((i & 1) != 1) { - error_bug("Error in result of pf_sub()."); + error_bug(mathomatic, "Error in result of pf_sub()."); } #endif - debug_string(1, "Resulting factors of pf_sub():"); - side_debug(1, &equation[loc], i - loc); + debug_string(mathomatic, 1, "Resulting factors of pf_sub():"); + side_debug(mathomatic, 1, &equation[loc], i - loc); } return(modified || symbolic_modified); } static int -save_factors(equation, np, loc1, len, level) -token_type *equation; -int *np, loc1, len, level; +save_factors(MathoMatic* mathomatic, token_type *equation, int *np, int loc1, int len, int level) { int i, j; - i = n_tlhs + 1 + n_trhs; + i = mathomatic->n_tlhs + 1 + mathomatic->n_trhs; if (i > (len * 3)) goto rejected; - if ((*np + (i - len)) > n_tokens) + if ((*np + (i - len)) > mathomatic->n_tokens) goto rejected; blt(&equation[loc1+i], &equation[loc1+len], (*np - (loc1 + len)) * sizeof(token_type)); *np += i - len; - blt(&equation[loc1], tlhs, n_tlhs * sizeof(token_type)); - i = loc1 + n_tlhs; + blt(&equation[loc1], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + i = loc1 + mathomatic->n_tlhs; equation[i].level = 0; equation[i].kind = OPERATOR; equation[i].token.operatr = TIMES; i++; - blt(&equation[i], trhs, n_trhs * sizeof(token_type)); - i += n_trhs; + blt(&equation[i], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + i += mathomatic->n_trhs; for (j = loc1; j < i; j++) equation[j].level += level; return true; rejected: - debug_string(1, "Polynomial factor rejected because too large."); + debug_string(mathomatic, 1, "Polynomial factor rejected because too large."); return false; } @@ -544,37 +539,37 @@ int *np, loc1, len, level; * If this returns false, nothing is removed. */ int -remove_factors(void) +remove_factors(MathoMatic* mathomatic) { int i, j, k; int plus_flag = false, divide_flag = false; int op; - debug_string(3, "Entering remove_factors() with: "); - side_debug(3, tlhs, n_tlhs); + debug_string(mathomatic, 3, "Entering remove_factors() with: "); + side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); do { - simp_ssub(tlhs, &n_tlhs, 0L, 1.0, false, true, 4); - } while (uf_power(tlhs, &n_tlhs)); + simp_ssub(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, 0L, 1.0, false, true, 4); + } while (uf_power(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)); for (i = 1, j = 0, k = 0;; i += 2) { - if (i >= n_tlhs) { + if (i >= mathomatic->n_tlhs) { if (plus_flag && !divide_flag) { if (k > 0) j--; - blt(&scratch[k], &tlhs[j], (i - j) * sizeof(token_type)); + blt(&mathomatic->scratch[k], &mathomatic->tlhs[j], (i - j) * sizeof(token_type)); k += i - j; } if (k <= 0) { - debug_string(3, "Leaving remove_factors() with false return and no change."); + debug_string(mathomatic, 3, "Leaving remove_factors() with false return and no change."); return false; } - blt(tlhs, scratch, k * sizeof(token_type)); - n_tlhs = k; - debug_string(3, "Leaving remove_factors() with success and: "); - side_debug(3, tlhs, n_tlhs); + blt(mathomatic->tlhs, mathomatic->scratch, k * sizeof(token_type)); + mathomatic->n_tlhs = k; + debug_string(mathomatic, 3, "Leaving remove_factors() with success and: "); + side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); return true; } - op = tlhs[i].token.operatr; - switch (tlhs[i].level) { + op = mathomatic->tlhs[i].token.operatr; + switch (mathomatic->tlhs[i].level) { case 1: switch (op) { case PLUS: @@ -585,13 +580,13 @@ remove_factors(void) case DIVIDE: break; default: - debug_string(3, "Leaving remove_factors() with false return and no change."); + debug_string(mathomatic, 3, "Leaving remove_factors() with false return and no change."); return false; } if (plus_flag && !divide_flag) { if (k > 0) j--; - blt(&scratch[k], &tlhs[j], (i - j) * sizeof(token_type)); + blt(&mathomatic->scratch[k], &mathomatic->tlhs[j], (i - j) * sizeof(token_type)); k += i - j; } plus_flag = false; @@ -619,31 +614,31 @@ remove_factors(void) * If a negative number, switching operands won't work either. */ static int -do_gcd(vp) -long *vp; /* polynomial base variable pointer */ +do_gcd(MathoMatic* mathomatic, long *vp) +//long *vp; /* polynomial base variable pointer */ { int i; int count; for (count = 1; count < 50; count++) { - switch (poly_div(trhs, n_trhs, gcd_divisor, len_d, vp)) { + switch (poly_div(mathomatic, mathomatic->trhs, mathomatic->n_trhs, gcd_divisor, len_d, vp)) { case 0: /* divide failed */ return(1 - count); case 2: /* Total success! Remainder is zero. */ - debug_string(2, "Found raw polynomial GCD:"); - side_debug(2, gcd_divisor, len_d); + debug_string(mathomatic, 2, "Found raw polynomial GCD:"); + side_debug(mathomatic, 2, gcd_divisor, len_d); return count; } /* Do the Euclidean shuffle: swap trhs[] (remainder) and gcd_divisor[] */ - if (len_d > n_tokens || n_trhs > DIVISOR_SIZE) + if (len_d > mathomatic->n_tokens || mathomatic->n_trhs > DIVISOR_SIZE) return 0; - blt(scratch, trhs, n_trhs * sizeof(token_type)); - blt(trhs, gcd_divisor, len_d * sizeof(token_type)); - blt(gcd_divisor, scratch, n_trhs * sizeof(token_type)); - i = n_trhs; - n_trhs = len_d; + blt(mathomatic->scratch, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); + blt(gcd_divisor, mathomatic->scratch, mathomatic->n_trhs * sizeof(token_type)); + i = mathomatic->n_trhs; + mathomatic->n_trhs = len_d; len_d = i; } return 0; @@ -660,60 +655,60 @@ long *vp; /* polynomial base variable pointer */ * The results are unfactored and simplified. */ int -poly_gcd(larger, llen, smaller, slen, v) -token_type *larger; /* larger polynomial */ -int llen; /* larger polynomial length */ -token_type *smaller; /* smaller polynomial */ -int slen; /* smaller polynomial length */ -long v; /* polynomial base variable */ +poly_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *smaller, int slen, long v) +//token_type *larger; /* larger polynomial */ +//int llen; /* larger polynomial length */ +//token_type *smaller; /* smaller polynomial */ +//int slen; /* smaller polynomial length */ +//long v; /* polynomial base variable */ { int count; - debug_string(3, "Entering poly_gcd():"); - side_debug(3, larger, llen); - side_debug(3, smaller, slen); - if (llen > n_tokens || slen > min(ARR_CNT(gcd_divisor), n_tokens)) + debug_string(mathomatic, 3, "Entering poly_gcd():"); + side_debug(mathomatic, 3, larger, llen); + side_debug(mathomatic, 3, smaller, slen); + if (llen > mathomatic->n_tokens || slen > min(ARR_CNT(gcd_divisor), mathomatic->n_tokens)) return 0; - if (trhs != larger) { - blt(trhs, larger, llen * sizeof(token_type)); + if (mathomatic->trhs != larger) { + blt(mathomatic->trhs, larger, llen * sizeof(token_type)); } - n_trhs = llen; - if (tlhs != smaller) { - blt(tlhs, smaller, slen * sizeof(token_type)); + mathomatic->n_trhs = llen; + if (mathomatic->tlhs != smaller) { + blt(mathomatic->tlhs, smaller, slen * sizeof(token_type)); } - n_tlhs = slen; - if (!remove_factors()) + mathomatic->n_tlhs = slen; + if (!remove_factors(mathomatic)) return 0; - if (n_tlhs > ARR_CNT(gcd_divisor)) + if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) return 0; - blt(gcd_divisor, tlhs, n_tlhs * sizeof(token_type)); - len_d = n_tlhs; - count = do_gcd(&v); + blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + len_d = mathomatic->n_tlhs; + count = do_gcd(mathomatic, &v); if (count <= 0) return 0; if (count > 1) { - if (len_d > n_tokens) + if (len_d > mathomatic->n_tokens) return 0; - blt(tlhs, gcd_divisor, len_d * sizeof(token_type)); - n_tlhs = len_d; - if (!remove_factors()) + blt(mathomatic->tlhs, gcd_divisor, len_d * sizeof(token_type)); + mathomatic->n_tlhs = len_d; + if (!remove_factors(mathomatic)) return 0; - if (n_tlhs > ARR_CNT(gcd_divisor)) + if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) return 0; - blt(gcd_divisor, tlhs, n_tlhs * sizeof(token_type)); - len_d = n_tlhs; - if (poly_div(larger, llen, gcd_divisor, len_d, &v) != 2) { - debug_string(1, "Polynomial GCD found, but larger divide failed in poly_gcd()."); + blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + len_d = mathomatic->n_tlhs; + if (poly_div(mathomatic, larger, llen, gcd_divisor, len_d, &v) != 2) { + debug_string(mathomatic, 1, "Polynomial GCD found, but larger divide failed in poly_gcd()."); return 0; } } - if (len_d > n_tokens) + if (len_d > mathomatic->n_tokens) return 0; - blt(trhs, gcd_divisor, len_d * sizeof(token_type)); - n_trhs = len_d; - uf_simp(tlhs, &n_tlhs); - uf_simp(trhs, &n_trhs); - debug_string(3, "poly_gcd() successful."); + blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); + mathomatic->n_trhs = len_d; + uf_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + uf_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + debug_string(mathomatic, 3, "poly_gcd() successful."); return(count); } @@ -726,13 +721,13 @@ long v; /* polynomial base variable */ * Return smaller/GCD in trhs[]. */ int -poly2_gcd(larger, llen, smaller, slen, v, require_additive) -token_type *larger; /* larger polynomial */ -int llen; /* larger polynomial length */ -token_type *smaller; /* smaller polynomial */ -int slen; /* smaller polynomial length */ -long v; /* polynomial base variable */ -int require_additive; /* require the GCD to contain addition or subtraction */ +poly2_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *smaller, int slen, long v, int require_additive) +//token_type *larger; /* larger polynomial */ +//int llen; /* larger polynomial length */ +//token_type *smaller; /* smaller polynomial */ +//int slen; /* smaller polynomial length */ +//long v; /* polynomial base variable */ +//int require_additive; /* require the GCD to contain addition or subtraction */ { int i; int count; @@ -760,65 +755,65 @@ int require_additive; /* require the GCD to contain addition or subtraction */ if (count == 0 /* || count > 200 */) return 0; } - debug_string(3, "Entering poly2_gcd():"); - side_debug(3, larger, llen); - side_debug(3, smaller, slen); - if (llen > n_tokens || slen > min(ARR_CNT(gcd_divisor), n_tokens)) + debug_string(mathomatic, 3, "Entering poly2_gcd():"); + side_debug(mathomatic, 3, larger, llen); + side_debug(mathomatic, 3, smaller, slen); + if (llen > mathomatic->n_tokens || slen > min(ARR_CNT(gcd_divisor), mathomatic->n_tokens)) return 0; - blt(trhs, larger, llen * sizeof(token_type)); - n_trhs = llen; - blt(tlhs, smaller, slen * sizeof(token_type)); - n_tlhs = slen; + blt(mathomatic->trhs, larger, llen * sizeof(token_type)); + mathomatic->n_trhs = llen; + blt(mathomatic->tlhs, smaller, slen * sizeof(token_type)); + mathomatic->n_tlhs = slen; #if 0 if (require_additive) { /* Require a level 1 additive operator in the divisor. */ - blt(save_save, jmp_save, sizeof(jmp_save)); - if ((i = setjmp(jmp_save)) != 0) { /* trap errors */ - blt(jmp_save, save_save, sizeof(jmp_save)); + blt(save_save, mathomatic->jmp_save, sizeof(mathomatic->jmp_save)); + if ((i = setjmp(mathomatic->jmp_save)) != 0) { /* trap errors */ + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); if (i == 13) { /* critical error code */ - longjmp(jmp_save, i); + longjmp(mathomatic->jmp_save, i); } return 0; } - uf_simp(tlhs, &n_tlhs); - blt(jmp_save, save_save, sizeof(jmp_save)); - if (level1_plus_count(tlhs, n_tlhs) == 0) + uf_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); + if (level1_plus_count(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs) == 0) return 0; } #endif - if (n_tlhs > ARR_CNT(gcd_divisor)) + if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) return 0; - blt(gcd_divisor, tlhs, n_tlhs * sizeof(token_type)); - len_d = n_tlhs; - count = do_gcd(&v); + blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + len_d = mathomatic->n_tlhs; + count = do_gcd(mathomatic, &v); if (count <= 0) return count; if (count > 1) { - if (require_additive && level1_plus_count(gcd_divisor, len_d) == 0) + if (require_additive && level1_plus_count(mathomatic, gcd_divisor, len_d) == 0) return 0; - if (poly_div(smaller, slen, gcd_divisor, len_d, &v) != 2) { - debug_string(1, "Polynomial GCD found, but smaller divide failed in poly2_gcd()."); + if (poly_div(mathomatic, smaller, slen, gcd_divisor, len_d, &v) != 2) { + debug_string(mathomatic, 1, "Polynomial GCD found, but smaller divide failed in poly2_gcd()."); return 0; } - blt(trhs, gcd_divisor, len_d * sizeof(token_type)); - n_trhs = len_d; - if (n_tlhs > ARR_CNT(gcd_divisor)) + blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); + mathomatic->n_trhs = len_d; + if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) return 0; - blt(gcd_divisor, tlhs, n_tlhs * sizeof(token_type)); - len_d = n_tlhs; - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; - if (poly_div(larger, llen, tlhs, n_tlhs, &v) != 2) { - debug_string(1, "Polynomial GCD found, but larger divide failed in poly2_gcd()."); + blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + len_d = mathomatic->n_tlhs; + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; + if (poly_div(mathomatic, larger, llen, mathomatic->tlhs, mathomatic->n_tlhs, &v) != 2) { + debug_string(mathomatic, 1, "Polynomial GCD found, but larger divide failed in poly2_gcd()."); return 0; } - blt(trhs, gcd_divisor, len_d * sizeof(token_type)); - n_trhs = len_d; + blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); + mathomatic->n_trhs = len_d; } else { - n_trhs = 1; - trhs[0] = one_token; + mathomatic->n_trhs = 1; + mathomatic->trhs[0] = mathomatic->one_token; } - debug_string(3, "poly2_gcd() successful."); + debug_string(mathomatic, 3, "poly2_gcd() successful."); return count; } @@ -829,19 +824,18 @@ int require_additive; /* require the GCD to contain addition or subtraction */ * Integer variable names start with "integer". */ int -is_integer_var(v) -long v; +is_integer_var(MathoMatic* mathomatic, long v) { char *cp; int (*strncmpfunc)(); - if (case_sensitive_flag) { + if (mathomatic->case_sensitive_flag) { strncmpfunc = strncmp; } else { strncmpfunc = strncasecmp; } - cp = var_name(v); + cp = var_name(mathomatic, v); if (cp && strncmpfunc(cp, V_INTEGER_PREFIX, strlen(V_INTEGER_PREFIX)) == 0) return true; else @@ -857,16 +851,16 @@ long v; * Should first be unfactored with uf_pplus() for a proper determination. */ int -is_integer_expr(p1, n) -token_type *p1; /* expression pointer */ -int n; /* length of expression */ +is_integer_expr(MathoMatic* mathomatic, token_type *p1, int n) +//token_type *p1; /* expression pointer */ +//int n; /* length of expression */ { int i; long v; #if DEBUG if (p1 == NULL || n < 1) { - error_bug("(p1 == NULL || n < 1) in is_integer_expr()."); + error_bug(mathomatic, "(p1 == NULL || n < 1) in is_integer_expr()."); } #endif for (i = 0; i < n; i++) { @@ -881,7 +875,7 @@ int n; /* length of expression */ break; case VARIABLE: v = labs(p1[i].token.variable); - if (!is_integer_var(v) && (v & VAR_MASK) != SIGN) + if (!is_integer_var(mathomatic, v) && (v & VAR_MASK) != SIGN) return false; break; } @@ -897,17 +891,15 @@ int n; /* length of expression */ * Return true if equation side was modified. */ int -mod_simp(equation, np) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of the equation side */ +mod_simp(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of the equation side */ { - return mod_recurse(equation, np, 0, 1); + return mod_recurse(mathomatic, equation, np, 0, 1); } static int -mod_recurse(equation, np, loc, level) -token_type *equation; -int *np, loc, level; +mod_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level) { int modified = false; int i, j, k; @@ -918,7 +910,7 @@ int *np, loc, level; for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= mod_recurse(equation, np, i, level + 1); + modified |= mod_recurse(mathomatic, equation, np, i, level + 1); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -958,14 +950,14 @@ int *np, loc, level; case MODULUS: /* simplify (x%n)%n to x%n */ len3 = k - (i1 + 1); - if (se_compare(&equation[i+1], len1, &equation[i1+1], len3, &diff_sign)) { + if (se_compare(mathomatic, &equation[i+1], len1, &equation[i1+1], len3, &diff_sign)) { blt(&equation[i1], &equation[k], (*np - k) * sizeof(token_type)); *np -= len3 + 1; return true; } break; case TIMES: - if (!is_integer_expr(&equation[j], len2)) + if (!is_integer_expr(mathomatic, &equation[j], len2)) break; /* simplify (i%n*j)%n to (i*j)%n if j is integer */ for (i2 = i1 = j + 1;; i1 += 2) { @@ -974,7 +966,7 @@ int *np, loc, level; if (equation[i2].level == (level + 2) && equation[i2].token.operatr == MODULUS) { len3 = i1 - (i2 + 1); - if (se_compare(&equation[i+1], len1, &equation[i2+1], len3, &diff_sign)) { + if (se_compare(mathomatic, &equation[i+1], len1, &equation[i2+1], len3, &diff_sign)) { blt(&equation[i2], &equation[i1], (*np - i1) * sizeof(token_type)); *np -= len3 + 1; return true; @@ -997,7 +989,7 @@ int *np, loc, level; switch (equation[i2].token.operatr) { case MODULUS: len3 = i1 - (i2 + 1); - if (se_compare(&equation[i+1], len1, &equation[i2+1], len3, &diff_sign)) { + if (se_compare(mathomatic, &equation[i+1], len1, &equation[i2+1], len3, &diff_sign)) { blt(&equation[i2], &equation[i1], (*np - i1) * sizeof(token_type)); *np -= len3 + 1; return true; @@ -1005,7 +997,7 @@ int *np, loc, level; break; case TIMES: i2 = i1 - 2; - if (!is_integer_expr(&equation[i3+1], i1 - (i3 + 1))) { + if (!is_integer_expr(mathomatic, &equation[i3+1], i1 - (i3 + 1))) { break; } for (i4 = i3 + 2; i4 < i1; i4 += 2) { @@ -1014,7 +1006,7 @@ int *np, loc, level; for (i5 = i4 + 2; i5 < i1 && equation[i5].level > (level + 3); i5 += 2) ; len3 = i5 - (i4 + 1); - if (se_compare(&equation[i+1], len1, &equation[i4+1], len3, &diff_sign)) { + if (se_compare(mathomatic, &equation[i+1], len1, &equation[i4+1], len3, &diff_sign)) { blt(&equation[i4], &equation[i5], (*np - i5) * sizeof(token_type)); *np -= len3 + 1; return true; @@ -1036,19 +1028,19 @@ int *np, loc, level; /* Remove integer*n multiples in x for x%n by doing */ /* polynomial division x/n and replacing with remainder%n. */ /* Globals tlhs[] and trhs[] are wiped out by the polynomial division here. */ - if (poly_div(&equation[j], len2, &equation[i+1], len1, NULL)) { - uf_pplus(tlhs, &n_tlhs); /* so integer%(integer^integer) isn't simplified to 0 */ - if (is_integer_expr(tlhs, n_tlhs)) { - if (n_trhs < len2 || REMAINDER_IS_ZERO()) { /* if it will make it smaller */ - if ((*np + (n_trhs - len2)) > n_tokens) - error_huge(); - for (k = 0; k < n_trhs; k++) - trhs[k].level += level; - blt(&equation[j+n_trhs], &equation[j+len2], (*np - (j + len2)) * sizeof(token_type)); - *np += n_trhs - len2; - blt(&equation[j], trhs, n_trhs * sizeof(token_type)); - debug_string(2, "Polynomial division successful in modulus simplification. The result is:"); - side_debug(2, equation, *np); + if (poly_div(mathomatic, &equation[j], len2, &equation[i+1], len1, NULL)) { + uf_pplus(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); /* so integer%(integer^integer) isn't simplified to 0 */ + if (is_integer_expr(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs)) { + if (mathomatic->n_trhs < len2 || REMAINDER_IS_ZERO()) { /* if it will make it smaller */ + if ((*np + (mathomatic->n_trhs - len2)) > mathomatic->n_tokens) + error_huge(mathomatic); + for (k = 0; k < mathomatic->n_trhs; k++) + mathomatic->trhs[k].level += level; + blt(&equation[j+mathomatic->n_trhs], &equation[j+len2], (*np - (j + len2)) * sizeof(token_type)); + *np += mathomatic->n_trhs - len2; + blt(&equation[j], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + debug_string(mathomatic, 2, "Polynomial division successful in modulus simplification. The result is:"); + side_debug(mathomatic, 2, equation, *np); return true; } } @@ -1069,17 +1061,13 @@ int *np, loc, level; * and denominator by the GCD. */ int -poly_gcd_simp(equation, np) -token_type *equation; -int *np; +poly_gcd_simp(MathoMatic* mathomatic, token_type *equation, int *np) { - return polydiv_recurse(equation, np, 0, 1); + return polydiv_recurse(mathomatic, equation, np, 0, 1); } static int -polydiv_recurse(equation, np, loc, level) -token_type *equation; -int *np, loc, level; +polydiv_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level) { int modified = false; int i, j, k; @@ -1089,7 +1077,7 @@ int *np, loc, level; for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= polydiv_recurse(equation, np, i, level + 1); + modified |= polydiv_recurse(mathomatic, equation, np, i, level + 1); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -1101,7 +1089,7 @@ int *np, loc, level; for (i = loc + 1; i < *np && equation[i].level >= level; i += 2) { #if DEBUG if (equation[i].kind != OPERATOR) - error_bug("Bug in poly_gcd_simp()."); + error_bug(mathomatic, "Bug in poly_gcd_simp()."); #endif if (equation[i].level == level && equation[i].token.operatr == DIVIDE) { for (k = i + 2;; k += 2) { @@ -1122,7 +1110,7 @@ int *np, loc, level; case TIMES: break; default: - error_bug("Expression is corrupt in poly_gcd_simp()."); + error_bug(mathomatic, "Expression is corrupt in poly_gcd_simp()."); } last_op2 = DIVIDE; for (k = j + 1;; k += 2) { @@ -1130,28 +1118,28 @@ int *np, loc, level; break; } len2 = k - j; - if ((rv = poly2_gcd(&equation[i+1], len1, &equation[j], len2, 0L, true)) > 0) { + if ((rv = poly2_gcd(mathomatic, &equation[i+1], len1, &equation[j], len2, 0L, true)) > 0) { store_code: - for (k = 0; k < n_tlhs; k++) - tlhs[k].level += level; - for (k = 0; k < n_trhs; k++) - trhs[k].level += level; - if (((*np + (n_trhs - len2)) > n_tokens) - || ((*np + (n_trhs - len2) + (n_tlhs - len1)) > n_tokens)) - error_huge(); - blt(&equation[j+n_trhs], &equation[j+len2], (*np - (j + len2)) * sizeof(token_type)); - *np += n_trhs - len2; + for (k = 0; k < mathomatic->n_tlhs; k++) + mathomatic->tlhs[k].level += level; + for (k = 0; k < mathomatic->n_trhs; k++) + mathomatic->trhs[k].level += level; + if (((*np + (mathomatic->n_trhs - len2)) > mathomatic->n_tokens) + || ((*np + (mathomatic->n_trhs - len2) + (mathomatic->n_tlhs - len1)) > mathomatic->n_tokens)) + error_huge(mathomatic); + blt(&equation[j+mathomatic->n_trhs], &equation[j+len2], (*np - (j + len2)) * sizeof(token_type)); + *np += mathomatic->n_trhs - len2; if (i > j) - i += n_trhs - len2; - blt(&equation[j], trhs, n_trhs * sizeof(token_type)); - blt(&equation[i+n_tlhs+1], &equation[i+1+len1], (*np - (i + 1 + len1)) * sizeof(token_type)); - *np += n_tlhs - len1; - blt(&equation[i+1], tlhs, n_tlhs * sizeof(token_type)); - debug_string(1, _("Division simplified with polynomial GCD.")); + i += mathomatic->n_trhs - len2; + blt(&equation[j], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + blt(&equation[i+mathomatic->n_tlhs+1], &equation[i+1+len1], (*np - (i + 1 + len1)) * sizeof(token_type)); + *np += mathomatic->n_tlhs - len1; + blt(&equation[i+1], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + debug_string(mathomatic, 1, _("Division simplified with polynomial GCD.")); modified = true; goto start; } - if (rv == 0 && poly2_gcd(&equation[j], len2, &equation[i+1], len1, 0L, true) > 0) { + if (rv == 0 && poly2_gcd(mathomatic, &equation[j], len2, &equation[i+1], len1, 0L, true) > 0) { k = j - 1; j = i + 1; i = k; @@ -1179,28 +1167,24 @@ int *np, loc, level; * Return true if expression was simplified. */ int -div_remainder(equation, np, poly_flag, quick_flag) -token_type *equation; -int *np; -int poly_flag; /* if true, try polynomial division first, then smart division */ -int quick_flag; /* if true, keep algebraic fractions simpler */ +div_remainder(MathoMatic* mathomatic, token_type *equation, int *np, int poly_flag, int quick_flag) +//int poly_flag; /* if true, try polynomial division first, then smart division */ +//int quick_flag; /* if true, keep algebraic fractions simpler */ { int rv = false; - debug_string(3, "Entering div_remainder()."); + debug_string(mathomatic, 3, "Entering div_remainder()."); if (quick_flag) - group_proc(equation, np); - rv = pdiv_recurse(equation, np, 0, 1, poly_flag); + group_proc(mathomatic, equation, np); + rv = pdiv_recurse(mathomatic, equation, np, 0, 1, poly_flag); if (quick_flag) - organize(equation, np); - debug_string(3, "Leaving div_remainder()."); + organize(mathomatic, equation, np); + debug_string(mathomatic, 3, "Leaving div_remainder()."); return rv; } static int -pdiv_recurse(equation, np, loc, level, code) -token_type *equation; -int *np, loc, level, code; +pdiv_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int code) { int modified = false; int i, j, k; @@ -1264,51 +1248,51 @@ int *np, loc, level, code; len1 = real_len1; } if (flag || power_flag) { - rv = poly_div(&equation[j], len2, &equation[i+1], len1, NULL); + rv = poly_div(mathomatic, &equation[j], len2, &equation[i+1], len1, NULL); } else { - rv = smart_div(&equation[j], len2, &equation[i+1], len1); + rv = smart_div(mathomatic, &equation[j], len2, &equation[i+1], len1); } zero_remainder = (rv > 0 && REMAINDER_IS_ZERO()); if (power_flag && !zero_remainder) { rv = 0; } if (rv > 0) { /* if successful and the result is smaller than the original: */ - if ((n_tlhs + 2 + n_trhs + len1) > n_tokens) - error_huge(); - for (k = 0; k < n_tlhs; k++) - tlhs[k].level++; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].kind = OPERATOR; - tlhs[n_tlhs].token.operatr = PLUS; - n_tlhs++; - for (k = 0; k < n_trhs; k++) - trhs[k].level += 2; - blt(&tlhs[n_tlhs], trhs, n_trhs * sizeof(token_type)); - n_tlhs += n_trhs; - tlhs[n_tlhs].level = 2; - tlhs[n_tlhs].kind = OPERATOR; - tlhs[n_tlhs].token.operatr = DIVIDE; - n_tlhs++; - k = n_tlhs; - blt(&tlhs[n_tlhs], &equation[i+1], len1 * sizeof(token_type)); - n_tlhs += len1; - for (; k < n_tlhs; k++) - tlhs[k].level += 2; - side_debug(3, &equation[j], len2); - side_debug(3, &equation[i+1], len1); - simpb_side(tlhs, &n_tlhs, false, true, 3); /* parameters should match what's used in simpa_side() */ - side_debug(3, tlhs, n_tlhs); + if ((mathomatic->n_tlhs + 2 + mathomatic->n_trhs + len1) > mathomatic->n_tokens) + error_huge(mathomatic); + for (k = 0; k < mathomatic->n_tlhs; k++) + mathomatic->tlhs[k].level++; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; + mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = PLUS; + mathomatic->n_tlhs++; + for (k = 0; k < mathomatic->n_trhs; k++) + mathomatic->trhs[k].level += 2; + blt(&mathomatic->tlhs[mathomatic->n_tlhs], mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs += mathomatic->n_trhs; + mathomatic->tlhs[mathomatic->n_tlhs].level = 2; + mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; + mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; + mathomatic->n_tlhs++; + k = mathomatic->n_tlhs; + blt(&mathomatic->tlhs[mathomatic->n_tlhs], &equation[i+1], len1 * sizeof(token_type)); + mathomatic->n_tlhs += len1; + for (; k < mathomatic->n_tlhs; k++) + mathomatic->tlhs[k].level += 2; + side_debug(mathomatic, 3, &equation[j], len2); + side_debug(mathomatic, 3, &equation[i+1], len1); + simpb_side(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, false, true, 3); /* parameters should match what's used in simpa_side() */ + side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); if (power_flag) { - k = (var_count(tlhs, n_tlhs) <= var_count(&equation[j], len2)); + k = (var_count(mathomatic->tlhs, mathomatic->n_tlhs) <= var_count(&equation[j], len2)); } else { - k = ((var_count(tlhs, n_tlhs) + (n_tlhs >= len1 + 1 + len2)) <= (var_count(&equation[j], len2) + var_count(&equation[i+1], len1))); + k = ((var_count(mathomatic->tlhs, mathomatic->n_tlhs) + (mathomatic->n_tlhs >= len1 + 1 + len2)) <= (var_count(&equation[j], len2) + var_count(&equation[i+1], len1))); } if (k) { - for (k = 0; k < n_tlhs; k++) - tlhs[k].level += level; + for (k = 0; k < mathomatic->n_tlhs; k++) + mathomatic->tlhs[k].level += level; if (power_flag) { - if ((*np - len2 + n_tlhs + 2) > n_tokens) - error_huge(); + if ((*np - len2 + mathomatic->n_tlhs + 2) > mathomatic->n_tokens) + error_huge(mathomatic); for (k = i + 2 + len1; k <= i + real_len1; k++) { equation[k].level++; } @@ -1325,23 +1309,23 @@ int *np, loc, level, code; j += 2; } } else { - if ((*np - (len1 + 1 + len2) + n_tlhs) > n_tokens) - error_huge(); + if ((*np - (len1 + 1 + len2) + mathomatic->n_tlhs) > mathomatic->n_tokens) + error_huge(mathomatic); blt(&equation[i], &equation[i+1+len1], (*np - (i + 1 + len1)) * sizeof(token_type)); *np -= len1 + 1; if (i < j) { j -= len1 + 1; } } - blt(&equation[j+n_tlhs], &equation[j+len2], (*np - (j + len2)) * sizeof(token_type)); - *np -= len2 - n_tlhs; - blt(&equation[j], tlhs, n_tlhs * sizeof(token_type)); + blt(&equation[j+mathomatic->n_tlhs], &equation[j+len2], (*np - (j + len2)) * sizeof(token_type)); + *np -= len2 - mathomatic->n_tlhs; + blt(&equation[j], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); if (flag || power_flag) { - debug_string(1, _("Polynomial division successful.")); + debug_string(mathomatic, 1, _("Polynomial division successful.")); } else { - debug_string(1, _("Smart division successful.")); + debug_string(mathomatic, 1, _("Smart division successful.")); } - side_debug(3, equation, *np); + side_debug(mathomatic, 3, equation, *np); return true; } } @@ -1357,7 +1341,7 @@ int *np, loc, level, code; } for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= pdiv_recurse(equation, np, i, level + 1, code); + modified |= pdiv_recurse(mathomatic, equation, np, i, level + 1, code); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -1381,32 +1365,32 @@ int *np, loc, level, code; * If *vp is 0, automatically select the best polynomial base variable and return it in *vp. */ int -poly_div(d1, len1, d2, len2, vp) -token_type *d1; /* pointer to dividend */ -int len1; /* length of dividend */ -token_type *d2; /* pointer to divisor */ -int len2; /* length of divisor */ -long *vp; /* pointer to polynomial base variable */ +poly_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int len2, long *vp) +//token_type *d1; /* pointer to dividend */ +//int len1; /* length of dividend */ +//token_type *d2; /* pointer to divisor */ +//int len2; /* length of divisor */ +//long *vp; /* pointer to polynomial base variable */ { int i; int rv; int old_partial; jmp_buf save_save; - old_partial = partial_flag; - partial_flag = false; /* We want full unfactoring during polynomial division. */ - blt(save_save, jmp_save, sizeof(jmp_save)); - if ((i = setjmp(jmp_save)) != 0) { /* Trap errors so we almost always return normally. */ - blt(jmp_save, save_save, sizeof(jmp_save)); - partial_flag = old_partial; + old_partial = mathomatic->partial_flag; + mathomatic->partial_flag = false; /* We want full unfactoring during polynomial division. */ + blt(save_save, mathomatic->jmp_save, sizeof(mathomatic->jmp_save)); + if ((i = setjmp(mathomatic->jmp_save)) != 0) { /* Trap errors so we almost always return normally. */ + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); + mathomatic->partial_flag = old_partial; if (i == 13) { /* critical error code */ - longjmp(jmp_save, i); + longjmp(mathomatic->jmp_save, i); } return false; } - rv = poly_div_sub(d1, len1, d2, len2, vp); - blt(jmp_save, save_save, sizeof(jmp_save)); - partial_flag = old_partial; + rv = poly_div_sub(mathomatic, d1, len1, d2, len2, vp); + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); + mathomatic->partial_flag = old_partial; return rv; } @@ -1417,12 +1401,7 @@ long *vp; /* pointer to polynomial base variable */ * generalized, polynomial long division algorithm. */ static int -poly_div_sub(d1, len1, d2, len2, vp) -token_type *d1; -int len1; -token_type *d2; -int len2; -long *vp; +poly_div_sub(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int len2, long *vp) { int i; int t1, len_t1; @@ -1437,42 +1416,42 @@ long *vp; if (vp == NULL) vp = &tmp_v; - if (len1 > n_tokens || len2 > n_tokens) + if (len1 > mathomatic->n_tokens || len2 > mathomatic->n_tokens) return false; /* Copy the source polynomials to where we want them (tlhs and trhs). */ - if (trhs != d1) { - blt(trhs, d1, len1 * sizeof(token_type)); + if (mathomatic->trhs != d1) { + blt(mathomatic->trhs, d1, len1 * sizeof(token_type)); } - n_trhs = len1; - if (tlhs != d2) { - blt(tlhs, d2, len2 * sizeof(token_type)); + mathomatic->n_trhs = len1; + if (mathomatic->tlhs != d2) { + blt(mathomatic->tlhs, d2, len2 * sizeof(token_type)); } - n_tlhs = len2; + mathomatic->n_tlhs = len2; /* Do the basic unfactoring and simplification of the dividend and divisor. */ - uf_simp(trhs, &n_trhs); - uf_simp(tlhs, &n_tlhs); + uf_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + uf_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); if (*vp == 0) { /* Select the best polynomial base variable. */ - if (!find_highest_count(trhs, n_trhs, tlhs, n_tlhs, vp)) + if (!find_highest_count(mathomatic->trhs, mathomatic->n_trhs, mathomatic->tlhs, mathomatic->n_tlhs, vp)) return false; } #if !SILENT /* Display debugging info. */ - if (debug_level >= 3) { - list_var(*vp, 0); - fprintf(gfp, _("poly_div() starts using base variable %s:\n"), var_str); - side_debug(3, trhs, n_trhs); - side_debug(3, tlhs, n_tlhs); + if (mathomatic->debug_level >= 3) { + list_var(mathomatic, *vp, 0); + fprintf(mathomatic->gfp, _("poly_div() starts using base variable %s:\n"), mathomatic->var_str); + side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); + side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); } #endif /* Determine divide_flag and if the polynomials can be divided. */ divide_flag = 2; - last_count = find_greatest_power(trhs, n_trhs, vp, &last_power, &t1, &len_t1, ÷_flag); - divisor_count = find_greatest_power(tlhs, n_tlhs, vp, &divisor_power, &t2, &len_t2, ÷_flag); + last_count = find_greatest_power(mathomatic->trhs, mathomatic->n_trhs, vp, &last_power, &t1, &len_t1, ÷_flag); + divisor_count = find_greatest_power(mathomatic->tlhs, mathomatic->n_tlhs, vp, &divisor_power, &t2, &len_t2, ÷_flag); if (divisor_power <= 0 || last_power < divisor_power) { divide_flag = !divide_flag; - last_count = find_greatest_power(trhs, n_trhs, vp, &last_power, &t1, &len_t1, ÷_flag); - divisor_count = find_greatest_power(tlhs, n_tlhs, vp, &divisor_power, &t2, &len_t2, ÷_flag); + last_count = find_greatest_power(mathomatic->trhs, mathomatic->n_trhs, vp, &last_power, &t1, &len_t1, ÷_flag); + divisor_count = find_greatest_power(mathomatic->tlhs, mathomatic->n_tlhs, vp, &divisor_power, &t2, &len_t2, ÷_flag); if (divisor_power <= 0 || last_power < divisor_power) { return false; } @@ -1482,16 +1461,16 @@ long *vp; /* Initialize the quotient. */ n_quotient = 1; - quotient[0] = zero_token; + quotient[0] = mathomatic->zero_token; /* Store the divisor. */ - if (n_tlhs > ARR_CNT(divisor)) + if (mathomatic->n_tlhs > ARR_CNT(divisor)) return false; - blt(divisor, tlhs, n_tlhs * sizeof(token_type)); - n_divisor = n_tlhs; - sum_size = n_trhs + n_quotient; + blt(divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + n_divisor = mathomatic->n_tlhs; + sum_size = mathomatic->n_trhs + n_quotient; /* Loop until polynomial division is finished. */ for (;;) { - if (t1 > 0 && trhs[t1-1].token.operatr == MINUS) + if (t1 > 0 && mathomatic->trhs[t1-1].token.operatr == MINUS) sign = MINUS; else sign = PLUS; @@ -1501,83 +1480,83 @@ long *vp; else sign = MINUS; } - if ((len_t1 + len_t2 + 1) > n_tokens) + if ((len_t1 + len_t2 + 1) > mathomatic->n_tokens) return false; - blt(tlhs, &trhs[t1], len_t1 * sizeof(token_type)); - n_tlhs = len_t1; - for (i = 0; i < n_tlhs; i++) - tlhs[i].level++; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].kind = OPERATOR; - tlhs[n_tlhs].token.operatr = DIVIDE; - n_tlhs++; - blt(&tlhs[n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); - i = n_tlhs; - n_tlhs += len_t2; - for (; i < n_tlhs; i++) - tlhs[i].level++; - if (!simp_loop(tlhs, &n_tlhs)) + blt(mathomatic->tlhs, &mathomatic->trhs[t1], len_t1 * sizeof(token_type)); + mathomatic->n_tlhs = len_t1; + for (i = 0; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; + mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; + mathomatic->n_tlhs++; + blt(&mathomatic->tlhs[mathomatic->n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); + i = mathomatic->n_tlhs; + mathomatic->n_tlhs += len_t2; + for (; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; + if (!simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) return false; - if ((n_quotient + 1 + n_tlhs) > min(ARR_CNT(quotient), n_tokens)) + if ((n_quotient + 1 + mathomatic->n_tlhs) > min(ARR_CNT(quotient), mathomatic->n_tokens)) return false; - for (i = 0; i < n_tlhs; i++) - tlhs[i].level++; + for (i = 0; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; quotient[n_quotient].level = 1; quotient[n_quotient].kind = OPERATOR; quotient[n_quotient].token.operatr = sign; n_quotient++; - blt("ient[n_quotient], tlhs, n_tlhs * sizeof(token_type)); - n_quotient += n_tlhs; - if ((n_trhs + n_tlhs + n_divisor + 2) > n_tokens) + blt("ient[n_quotient], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + n_quotient += mathomatic->n_tlhs; + if ((mathomatic->n_trhs + mathomatic->n_tlhs + n_divisor + 2) > mathomatic->n_tokens) return false; - blt(&trhs[t1+1], &trhs[t1+len_t1], (n_trhs - (t1 + len_t1)) * sizeof(token_type)); - n_trhs -= len_t1 - 1; - trhs[t1] = zero_token; - for (i = 0; i < n_trhs; i++) - trhs[i].level++; - trhs[n_trhs].level = 1; - trhs[n_trhs].kind = OPERATOR; + blt(&mathomatic->trhs[t1+1], &mathomatic->trhs[t1+len_t1], (mathomatic->n_trhs - (t1 + len_t1)) * sizeof(token_type)); + mathomatic->n_trhs -= len_t1 - 1; + mathomatic->trhs[t1] = mathomatic->zero_token; + for (i = 0; i < mathomatic->n_trhs; i++) + mathomatic->trhs[i].level++; + mathomatic->trhs[mathomatic->n_trhs].level = 1; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; if (sign == PLUS) - trhs[n_trhs].token.operatr = MINUS; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = MINUS; else - trhs[n_trhs].token.operatr = PLUS; - n_trhs++; - blt(&trhs[n_trhs], tlhs, n_tlhs * sizeof(token_type)); - i = n_trhs; - n_trhs += n_tlhs; - for (; i < n_trhs; i++) - trhs[i].level++; - trhs[n_trhs].level = 2; - trhs[n_trhs].kind = OPERATOR; - trhs[n_trhs].token.operatr = TIMES; - n_trhs++; - i = n_trhs; - blt(&trhs[n_trhs], divisor, t2 * sizeof(token_type)); - n_trhs += t2; - trhs[n_trhs] = zero_token; - n_trhs++; - blt(&trhs[n_trhs], &divisor[t2+len_t2], (n_divisor - (t2 + len_t2)) * sizeof(token_type)); - n_trhs += (n_divisor - (t2 + len_t2)); - for (; i < n_trhs; i++) - trhs[i].level += 2; - side_debug(3, trhs, n_trhs); - uf_repeat(trhs, &n_trhs); - uf_tsimp(trhs, &n_trhs); - side_debug(4, trhs, n_trhs); - count = find_greatest_power(trhs, n_trhs, vp, &d, &t1, &len_t1, ÷_flag); + mathomatic->trhs[mathomatic->n_trhs].token.operatr = PLUS; + mathomatic->n_trhs++; + blt(&mathomatic->trhs[mathomatic->n_trhs], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + i = mathomatic->n_trhs; + mathomatic->n_trhs += mathomatic->n_tlhs; + for (; i < mathomatic->n_trhs; i++) + mathomatic->trhs[i].level++; + mathomatic->trhs[mathomatic->n_trhs].level = 2; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = TIMES; + mathomatic->n_trhs++; + i = mathomatic->n_trhs; + blt(&mathomatic->trhs[mathomatic->n_trhs], divisor, t2 * sizeof(token_type)); + mathomatic->n_trhs += t2; + mathomatic->trhs[mathomatic->n_trhs] = mathomatic->zero_token; + mathomatic->n_trhs++; + blt(&mathomatic->trhs[mathomatic->n_trhs], &divisor[t2+len_t2], (n_divisor - (t2 + len_t2)) * sizeof(token_type)); + mathomatic->n_trhs += (n_divisor - (t2 + len_t2)); + for (; i < mathomatic->n_trhs; i++) + mathomatic->trhs[i].level += 2; + side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); + uf_repeat(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + uf_tsimp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + side_debug(mathomatic, 4, mathomatic->trhs, mathomatic->n_trhs); + count = find_greatest_power(mathomatic->trhs, mathomatic->n_trhs, vp, &d, &t1, &len_t1, ÷_flag); if (d < divisor_power) { /* Success! Polynomial division ends here. */ - debug_string(3, "Successful polynomial division!"); - blt(tlhs, quotient, n_quotient * sizeof(token_type)); - n_tlhs = n_quotient; - debug_string(3, "Quotient:"); - side_debug(3, tlhs, n_tlhs); - debug_string(3, "Remainder:"); - side_debug(3, trhs, n_trhs); + debug_string(mathomatic, 3, "Successful polynomial division!"); + blt(mathomatic->tlhs, quotient, n_quotient * sizeof(token_type)); + mathomatic->n_tlhs = n_quotient; + debug_string(mathomatic, 3, "Quotient:"); + side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); + debug_string(mathomatic, 3, "Remainder:"); + side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); if (REMAINDER_IS_ZERO()) return 2; - if ((n_trhs + n_quotient) >= (sum_size /* - (sum_size / 10) */)) { - if ((n_trhs + 1) > sum_size && n_trhs > n_divisor) + if ((mathomatic->n_trhs + n_quotient) >= (sum_size /* - (sum_size / 10) */)) { + if ((mathomatic->n_trhs + 1) > sum_size && mathomatic->n_trhs > n_divisor) return -2; else return -1; @@ -1615,11 +1594,11 @@ long *vp; * Quotient is returned in tlhs[] and remainder in trhs[]. */ int -smart_div(d1, len1, d2, len2) -token_type *d1; /* pointer to dividend */ -int len1; /* length of dividend */ -token_type *d2; /* pointer to divisor */ -int len2; /* length of divisor */ +smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int len2) +//token_type *d1; /* pointer to dividend */ +//int len1; /* length of dividend */ +//token_type *d2; /* pointer to divisor */ +//int len2; /* length of divisor */ { int i, j, k; int t1, len_t1; @@ -1637,52 +1616,52 @@ int len2; /* length of divisor */ int dcount = 0; /* divisor term count */ int flag; - blt(trhs, d1, len1 * sizeof(token_type)); - n_trhs = len1; - blt(tlhs, d2, len2 * sizeof(token_type)); - n_tlhs = len2; + blt(mathomatic->trhs, d1, len1 * sizeof(token_type)); + mathomatic->n_trhs = len1; + blt(mathomatic->tlhs, d2, len2 * sizeof(token_type)); + mathomatic->n_tlhs = len2; /* Do the basic unfactoring and simplification of the dividend and divisor. */ - uf_simp_no_repeat(trhs, &n_trhs); - uf_simp_no_repeat(tlhs, &n_tlhs); + uf_simp_no_repeat(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + uf_simp_no_repeat(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); /* Display debugging info. */ - debug_string(3, "smart_div() starts:"); - side_debug(3, trhs, n_trhs); - side_debug(3, tlhs, n_tlhs); + debug_string(mathomatic, 3, "smart_div() starts:"); + side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); + side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); /* Find which divisor term to use. */ for (i = 0, j = 0, k = 0, flag = false;; i++) { - if (i >= n_tlhs || (tlhs[i].kind == OPERATOR && tlhs[i].level == 1 - && (tlhs[i].token.operatr == PLUS || tlhs[i].token.operatr == MINUS))) { + if (i >= mathomatic->n_tlhs || (mathomatic->tlhs[i].kind == OPERATOR && mathomatic->tlhs[i].level == 1 + && (mathomatic->tlhs[i].token.operatr == PLUS || mathomatic->tlhs[i].token.operatr == MINUS))) { dcount++; if (flag) { - if (len_t2 == 0 || var_count(&tlhs[j], i - j) < k) { + if (len_t2 == 0 || var_count(&mathomatic->tlhs[j], i - j) < k) { len_t2 = i - j; t2 = j; - k = var_count(&tlhs[t2], len_t2); + k = var_count(&mathomatic->tlhs[t2], len_t2); } } flag = false; j = i + 1; - } else if (tlhs[i].kind == VARIABLE && tlhs[i].token.variable != IMAGINARY) { + } else if (mathomatic->tlhs[i].kind == VARIABLE && mathomatic->tlhs[i].token.variable != IMAGINARY) { flag = true; } - if (i >= n_tlhs) + if (i >= mathomatic->n_tlhs) break; } if (len_t2 <= 0) return false; /* Initialize the quotient. */ n_quotient = 1; - quotient[0] = zero_token; - if (n_tlhs > ARR_CNT(divisor)) + quotient[0] = mathomatic->zero_token; + if (mathomatic->n_tlhs > ARR_CNT(divisor)) return false; - blt(divisor, tlhs, n_tlhs * sizeof(token_type)); - n_divisor = n_tlhs; + blt(divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + n_divisor = mathomatic->n_tlhs; try_one: - trhs_size = n_trhs; + trhs_size = mathomatic->n_trhs; for (skip_count = 0, count = 0;;) { - sum_size = n_trhs + n_quotient; + sum_size = mathomatic->n_trhs + n_quotient; for (term_count = 1, q_size = 0;; term_count++) { - if (!get_term(trhs, n_trhs, term_count, &t1, &len_t1)) + if (!get_term(mathomatic->trhs, mathomatic->n_trhs, term_count, &t1, &len_t1)) break; flag = false; for (i = 0; i < skip_count; i++) { @@ -1693,25 +1672,25 @@ int len2; /* length of divisor */ } if (flag) continue; - if ((len_t1 + len_t2 + 1) > n_tokens) + if ((len_t1 + len_t2 + 1) > mathomatic->n_tokens) return false; - blt(tlhs, &trhs[t1], len_t1 * sizeof(token_type)); - n_tlhs = len_t1; - for (i = 0; i < n_tlhs; i++) - tlhs[i].level++; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].kind = OPERATOR; - tlhs[n_tlhs].token.operatr = DIVIDE; - n_tlhs++; - blt(&tlhs[n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); - i = n_tlhs; - n_tlhs += len_t2; - for (; i < n_tlhs; i++) - tlhs[i].level++; - if (!simp_loop(tlhs, &n_tlhs)) + blt(mathomatic->tlhs, &mathomatic->trhs[t1], len_t1 * sizeof(token_type)); + mathomatic->n_tlhs = len_t1; + for (i = 0; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; + mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; + mathomatic->n_tlhs++; + blt(&mathomatic->tlhs[mathomatic->n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); + i = mathomatic->n_tlhs; + mathomatic->n_tlhs += len_t2; + for (; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; + if (!simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) continue; - if (basic_size(tlhs, n_tlhs) <= basic_size(&trhs[t1], len_t1)) { - q_size = n_tlhs; + if (basic_size(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs) <= basic_size(mathomatic, &mathomatic->trhs[t1], len_t1)) { + q_size = mathomatic->n_tlhs; term_pos = t1; term_size = len_t1; break; @@ -1729,20 +1708,20 @@ int len2; /* length of divisor */ } end_div: if (dcount > 1) { - if (n_quotient + n_trhs >= trhs_size + 1) { + if (n_quotient + mathomatic->n_trhs >= trhs_size + 1) { return false; } } end_div2: - blt(tlhs, quotient, n_quotient * sizeof(token_type)); - n_tlhs = n_quotient; - side_debug(3, tlhs, n_tlhs); - side_debug(3, trhs, n_trhs); + blt(mathomatic->tlhs, quotient, n_quotient * sizeof(token_type)); + mathomatic->n_tlhs = n_quotient; + side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); + side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); return true; /* Success! */ } t1 = term_pos; len_t1 = term_size; - if (t1 > 0 && trhs[t1-1].token.operatr == MINUS) + if (t1 > 0 && mathomatic->trhs[t1-1].token.operatr == MINUS) sign = MINUS; else sign = PLUS; @@ -1752,96 +1731,96 @@ int len2; /* length of divisor */ else sign = MINUS; } - if ((len_t1 + len_t2 + 1) > n_tokens) + if ((len_t1 + len_t2 + 1) > mathomatic->n_tokens) return false; - blt(tlhs, &trhs[t1], len_t1 * sizeof(token_type)); - n_tlhs = len_t1; - for (i = 0; i < n_tlhs; i++) - tlhs[i].level++; - tlhs[n_tlhs].level = 1; - tlhs[n_tlhs].kind = OPERATOR; - tlhs[n_tlhs].token.operatr = DIVIDE; - n_tlhs++; - blt(&tlhs[n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); - i = n_tlhs; - n_tlhs += len_t2; - for (; i < n_tlhs; i++) - tlhs[i].level++; - simp_loop(tlhs, &n_tlhs); - if ((n_quotient + 1 + n_tlhs) > min(ARR_CNT(quotient), n_tokens)) + blt(mathomatic->tlhs, &mathomatic->trhs[t1], len_t1 * sizeof(token_type)); + mathomatic->n_tlhs = len_t1; + for (i = 0; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; + mathomatic->tlhs[mathomatic->n_tlhs].level = 1; + mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; + mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; + mathomatic->n_tlhs++; + blt(&mathomatic->tlhs[mathomatic->n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); + i = mathomatic->n_tlhs; + mathomatic->n_tlhs += len_t2; + for (; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; + simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + if ((n_quotient + 1 + mathomatic->n_tlhs) > min(ARR_CNT(quotient), mathomatic->n_tokens)) return false; - for (i = 0; i < n_tlhs; i++) - tlhs[i].level++; + for (i = 0; i < mathomatic->n_tlhs; i++) + mathomatic->tlhs[i].level++; old_n_quotient = n_quotient; quotient[n_quotient].level = 1; quotient[n_quotient].kind = OPERATOR; quotient[n_quotient].token.operatr = sign; n_quotient++; qp = "ient[n_quotient]; - q_size = n_tlhs; - blt("ient[n_quotient], tlhs, n_tlhs * sizeof(token_type)); - n_quotient += n_tlhs; - if ((n_trhs + q_size + n_divisor + 2) > n_tokens) + q_size = mathomatic->n_tlhs; + blt("ient[n_quotient], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + n_quotient += mathomatic->n_tlhs; + if ((mathomatic->n_trhs + q_size + n_divisor + 2) > mathomatic->n_tokens) return false; - blt(tlhs, trhs, n_trhs * sizeof(token_type)); - n_tlhs = n_trhs; - blt(&trhs[t1+1], &trhs[t1+len_t1], (n_trhs - (t1 + len_t1)) * sizeof(token_type)); - n_trhs -= len_t1 - 1; - trhs[t1] = zero_token; - for (i = 0; i < n_trhs; i++) - trhs[i].level++; - trhs[n_trhs].level = 1; - trhs[n_trhs].kind = OPERATOR; + blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_trhs; + blt(&mathomatic->trhs[t1+1], &mathomatic->trhs[t1+len_t1], (mathomatic->n_trhs - (t1 + len_t1)) * sizeof(token_type)); + mathomatic->n_trhs -= len_t1 - 1; + mathomatic->trhs[t1] = mathomatic->zero_token; + for (i = 0; i < mathomatic->n_trhs; i++) + mathomatic->trhs[i].level++; + mathomatic->trhs[mathomatic->n_trhs].level = 1; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; if (sign == PLUS) - trhs[n_trhs].token.operatr = MINUS; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = MINUS; else - trhs[n_trhs].token.operatr = PLUS; - n_trhs++; - blt(&trhs[n_trhs], qp, q_size * sizeof(token_type)); - i = n_trhs; - n_trhs += q_size; - for (; i < n_trhs; i++) - trhs[i].level++; - trhs[n_trhs].level = 2; - trhs[n_trhs].kind = OPERATOR; - trhs[n_trhs].token.operatr = TIMES; - n_trhs++; - i = n_trhs; - blt(&trhs[n_trhs], divisor, t2 * sizeof(token_type)); - n_trhs += t2; - trhs[n_trhs] = zero_token; - n_trhs++; - blt(&trhs[n_trhs], &divisor[t2+len_t2], (n_divisor - (t2 + len_t2)) * sizeof(token_type)); - n_trhs += (n_divisor - (t2 + len_t2)); - for (; i < n_trhs; i++) - trhs[i].level += 2; - side_debug(3, trhs, n_trhs); - uf_tsimp(trhs, &n_trhs); - side_debug(4, trhs, n_trhs); + mathomatic->trhs[mathomatic->n_trhs].token.operatr = PLUS; + mathomatic->n_trhs++; + blt(&mathomatic->trhs[mathomatic->n_trhs], qp, q_size * sizeof(token_type)); + i = mathomatic->n_trhs; + mathomatic->n_trhs += q_size; + for (; i < mathomatic->n_trhs; i++) + mathomatic->trhs[i].level++; + mathomatic->trhs[mathomatic->n_trhs].level = 2; + mathomatic->trhs[mathomatic->n_trhs].kind = OPERATOR; + mathomatic->trhs[mathomatic->n_trhs].token.operatr = TIMES; + mathomatic->n_trhs++; + i = mathomatic->n_trhs; + blt(&mathomatic->trhs[mathomatic->n_trhs], divisor, t2 * sizeof(token_type)); + mathomatic->n_trhs += t2; + mathomatic->trhs[mathomatic->n_trhs] = mathomatic->zero_token; + mathomatic->n_trhs++; + blt(&mathomatic->trhs[mathomatic->n_trhs], &divisor[t2+len_t2], (n_divisor - (t2 + len_t2)) * sizeof(token_type)); + mathomatic->n_trhs += (n_divisor - (t2 + len_t2)); + for (; i < mathomatic->n_trhs; i++) + mathomatic->trhs[i].level += 2; + side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); + uf_tsimp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + side_debug(mathomatic, 4, mathomatic->trhs, mathomatic->n_trhs); if (REMAINDER_IS_ZERO()) goto end_div2; if (dcount > 1) { - if ((n_trhs + n_quotient) >= sum_size) { + if ((mathomatic->n_trhs + n_quotient) >= sum_size) { if (skip_count >= ARR_CNT(skip_terms)) { if (count == 0) { return false; } else { n_quotient = old_n_quotient; - blt(trhs, tlhs, n_tlhs * sizeof(token_type)); - n_trhs = n_tlhs; + blt(mathomatic->trhs, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_trhs = mathomatic->n_tlhs; goto end_div; } } skip_terms[skip_count] = term_pos; skip_count++; n_quotient = old_n_quotient; - blt(trhs, tlhs, n_tlhs * sizeof(token_type)); - n_trhs = n_tlhs; - debug_string(3, "Skipping last operation."); + blt(mathomatic->trhs, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_trhs = mathomatic->n_tlhs; + debug_string(mathomatic, 3, "Skipping last operation."); continue; } } - if (n_trhs == 1 && trhs[0].kind == CONSTANT) + if (mathomatic->n_trhs == 1 && mathomatic->trhs[0].kind == CONSTANT) goto end_div; skip_count = 0; count++; @@ -1853,9 +1832,7 @@ int len2; /* length of divisor */ * minus any constant multiplier. */ int -basic_size(p1, len) -token_type *p1; -int len; +basic_size(MathoMatic* mathomatic, token_type *p1, int len) { int i, j; int level; @@ -1863,7 +1840,7 @@ int len; int constant_flag = true; rv = len; - level = min_level(p1, len); + level = min_level(mathomatic, p1, len); for (i = 0, j = -1; i < len; i++) { if (p1[i].kind == OPERATOR) { if (p1[i].level == level diff --git a/proto.h b/proto.h index a00987c..df9c0d0 100644 --- a/proto.h +++ b/proto.h @@ -3,47 +3,47 @@ /* This file is required to compile Mathomatic quietly with the -Wall compiler option. */ /* am.c */ -void display_startup_message(FILE *fp); -void error(const char *str); -void reset_error(void); -void warning(const char *str); -void error_huge(void); -void error_bug(const char *str); -void check_err(void); -int get_screen_size(void); -int malloc_vscreen(void); -int init_mem(void); +void display_startup_message(MathoMatic* mathomatic, FILE *fp); +void error(MathoMatic* mathomatic, const char *str); +void reset_error(MathoMatic* mathomatic); +void warning(MathoMatic* mathomatic, const char *str); +void error_huge(MathoMatic* mathomatic); +void error_bug(MathoMatic* mathomatic, const char *str); +void check_err(MathoMatic* mathomatic); +int get_screen_size(MathoMatic* mathomatic); +int malloc_vscreen(MathoMatic* mathomatic); +int init_mem(MathoMatic* mathomatic); int check_gvars(void); -void init_gvars(void); -void clean_up(void); -void set_sign_array(void); -int next_sign(long *vp); -void clear_all(void); -int alloc_espace(int i); -int alloc_to_espace(int en); -int alloc_next_espace(void); -int next_espace(void); -void copy_espace(int src, int dest); -int solved_equation(int i); +void init_gvars(MathoMatic* mathomatic); +void clean_up(MathoMatic* mathomatic); +void set_sign_array(MathoMatic* mathomatic); +int next_sign(MathoMatic* mathomatic, long *vp); +void clear_all(MathoMatic* mathomatic); +int alloc_espace(MathoMatic* mathomatic, int i); +int alloc_to_espace(MathoMatic* mathomatic, int en); +int alloc_next_espace(MathoMatic* mathomatic); +int next_espace(MathoMatic* mathomatic); +void copy_espace(MathoMatic* mathomatic, int src, int dest); +int solved_equation(MathoMatic* mathomatic, int i); int found_var(token_type *p1, int n, long v); -int var_in_equation(int i, long v); -int search_all_for_var(long v, int forward_direction); -void rename_var_in_es(int en, long from_v, long to_v); -int subst_var_with_exp(token_type *equation, int *np, token_type *expression, int len, long v); -int min_level(token_type *expression, int n); -int get_default_en(char *cp); -int get_expr(token_type *equation, int *np); -int prompt_var(long *vp); -int not_defined(int i); -int current_not_defined(void); -char *get_string(char *string, int n); -int get_yes_no(void); -int return_result(int en); -void free_result_str(void); +int var_in_equation(MathoMatic* mathomatic, int i, long v); +int search_all_for_var(MathoMatic* mathomatic, long v, int forward_direction); +void rename_var_in_es(MathoMatic* mathomatic, int en, long from_v, long to_v); +int subst_var_with_exp(MathoMatic* mathomatic, token_type *equation, int *np, token_type *expression, int len, long v); +int min_level(MathoMatic* mathomatic, token_type *expression, int n); +int get_default_en(MathoMatic* mathomatic, char *cp); +int get_expr(MathoMatic* mathomatic, token_type *equation, int *np); +int prompt_var(MathoMatic* mathomatic, long *vp); +int not_defined(MathoMatic* mathomatic, int i); +int current_not_defined(MathoMatic* mathomatic); +char *get_string(MathoMatic* mathomatic, char *string, int n); +int get_yes_no(MathoMatic* mathomatic); +int return_result(MathoMatic* mathomatic, int en); +void free_result_str(MathoMatic* mathomatic); int is_all(char *cp); -int get_range(char **cpp, int *ip, int *jp); -int extra_characters(char *cp); -int get_range_eol(char **cpp, int *ip, int *jp); +int get_range(MathoMatic* mathomatic, char **cpp, int *ip, int *jp); +int extra_characters(MathoMatic* mathomatic, char *cp); +int get_range_eol(MathoMatic* mathomatic, char **cpp, int *ip, int *jp); char *skip_space(char *cp); char *skip_comma_space(char *cp); long decstrtol(char *cp, char **cpp); @@ -51,71 +51,71 @@ int isdelimiter(int ch); char *skip_param(char *cp); int strcmp_tospace(char *cp1, char *cp2); int level_plus_count(token_type *p1, int n1, int level); -int level1_plus_count(token_type *p1, int n1); +int level1_plus_count(MathoMatic* mathomatic, token_type *p1, int n1); int var_count(token_type *p1, int n1); int no_vars(token_type *source, int n, long *vp); int exp_contains_infinity(token_type *p1, int n1); int exp_contains_nan(token_type *p1, int n1); int exp_is_numeric(token_type *p1, int n1); int exp_is_absolute(token_type *p1, int n1); -int check_divide_by_zero(double denominator); -int load_rc(int return_true_if_no_file, FILE *ofp); +int check_divide_by_zero(MathoMatic* mathomatic, double denominator); +int load_rc(MathoMatic* mathomatic, int return_true_if_no_file, FILE *ofp); /* cmds.c */ -int plot_cmd(char *cp); -int version_cmd(char *cp); -long max_memory_usage(void); +int plot_cmd(MathoMatic* mathomatic, char *cp); +int version_cmd(MathoMatic* mathomatic, char *cp); +long max_memory_usage(MathoMatic* mathomatic); int show_status(FILE *ofp); -int version_report(void); -int solve_cmd(char *cp); -int sum_cmd(char *cp); -int product_cmd(char *cp); -int for_cmd(char *cp); -int optimize_cmd(char *cp); -int output_current_directory(FILE *ofp); +int version_report(MathoMatic* mathomatic); +int solve_cmd(MathoMatic* mathomatic, char *cp); +int sum_cmd(MathoMatic* mathomatic, char *cp); +int product_cmd(MathoMatic* mathomatic, char *cp); +int for_cmd(MathoMatic* mathomatic, char *cp); +int optimize_cmd(MathoMatic* mathomatic, char *cp); +int output_current_directory(MathoMatic* mathomatic, FILE *ofp); int fprintf_escaped(FILE *ofp, char *cp); -void output_options(FILE *ofp, int all_set_options); +void output_options(MathoMatic* mathomatic, FILE *ofp, int all_set_options); int skip_no(char **cpp); -int save_set_options(char *cp); -int set_options(char *cp, int loading_startup_file); -int set_cmd(char *cp); -int echo_cmd(char *cp); -int pause_cmd(char *cp); -int copy_cmd(char *cp); -int real_cmd(char *cp); -int imaginary_cmd(char *cp); -int tally_cmd(char *cp); -int calculate_cmd(char *cp); -int clear_cmd(char *cp); -int compare_es(int i, int j); -int compare_cmd(char *cp); -int display_fraction(double value); -int divide_cmd(char *cp); -int eliminate_cmd(char *cp); -int display_cmd(char *cp); -int list_cmd(char *cp); -int code_cmd(char *cp); -int variables_cmd(char *cp); -int approximate_cmd(char *cp); -int replace_cmd(char *cp); -int simplify_cmd(char *cp); -int factor_cmd(char *cp); -int display_term_count(int en); -int unfactor_cmd(char *cp); -int div_loc_find(token_type *expression, int n); -int fraction_cmd(char *cp); -int quit_cmd(char *cp); -int read_cmd(char *cp); -int read_file(char *cp); -int read_sub(FILE *fp, char *filename); -int edit_cmd(char *cp); -int save_cmd(char *cp); +int save_set_options(MathoMatic* mathomatic, char *cp); +int set_options(MathoMatic* mathomatic, char *cp, int loading_startup_file); +int set_cmd(MathoMatic* mathomatic, char *cp); +int echo_cmd(MathoMatic* mathomatic, char *cp); +int pause_cmd(MathoMatic* mathomatic, char *cp); +int copy_cmd(MathoMatic* mathomatic, char *cp); +int real_cmd(MathoMatic* mathomatic, char *cp); +int imaginary_cmd(MathoMatic* mathomatic, char *cp); +int tally_cmd(MathoMatic* mathomatic, char *cp); +int calculate_cmd(MathoMatic* mathomatic, char *cp); +int clear_cmd(MathoMatic* mathomatic, char *cp); +int compare_es(MathoMatic* mathomatic, int i, int j); +int compare_cmd(MathoMatic* mathomatic, char *cp); +int display_fraction(MathoMatic* mathomatic, double value); +int divide_cmd(MathoMatic* mathomatic, char *cp); +int eliminate_cmd(MathoMatic* mathomatic, char *cp); +int display_cmd(MathoMatic* mathomatic, char *cp); +int list_cmd(MathoMatic* mathomatic, char *cp); +int code_cmd(MathoMatic* mathomatic, char *cp); +int variables_cmd(MathoMatic* mathomatic, char *cp); +int approximate_cmd(MathoMatic* mathomatic, char *cp); +int replace_cmd(MathoMatic* mathomatic, char *cp); +int simplify_cmd(MathoMatic* mathomatic, char *cp); +int factor_cmd(MathoMatic* mathomatic, char *cp); +int display_term_count(MathoMatic* mathomatic, int en); +int unfactor_cmd(MathoMatic* mathomatic, char *cp); +int div_loc_find(MathoMatic* mathomatic, token_type *expression, int n); +int fraction_cmd(MathoMatic* mathomatic, char *cp); +int quit_cmd(MathoMatic* mathomatic, char *cp); +int read_cmd(MathoMatic* mathomatic, char *cp); +int read_file(MathoMatic* mathomatic, char *cp); +int read_sub(MathoMatic* mathomatic, FILE *fp, char *filename); +int edit_cmd(MathoMatic* mathomatic, char *cp); +int save_cmd(MathoMatic* mathomatic, char *cp); /* complex.c */ void rect_to_polar(double x, double y, double *radiusp, double *thetap); -int roots_cmd(char *cp); -int complex_root_simp(token_type *equation, int *np); -int approximate_complex_roots(token_type *equation, int *np); -int get_constant(token_type *p1, int n, double *dp); -int parse_complex(token_type *p1, int n, complexs *cp); +int roots_cmd(MathoMatic * mathomatic, char *cp); +int complex_root_simp(MathoMatic* mathomatic, token_type *equation, int *np); +int approximate_complex_roots(MathoMatic* mathomatic, token_type *equation, int *np); +int get_constant(MathoMatic* mathomatic, token_type *p1, int n, double *dp); +int parse_complex(MathoMatic* mathomatic, token_type *p1, int n, complexs *cp); /* complex_lib.c */ int complex_fixup(complexs *ap); complexs complex_add(complexs a, complexs b); @@ -126,76 +126,76 @@ complexs complex_log(complexs a); complexs complex_exp(complexs a); complexs complex_pow(complexs a, complexs b); /* diff.c */ -int differentiate(token_type *equation, int *np, long v); -int derivative_cmd(char *cp); -int extrema_cmd(char *cp); -int taylor_cmd(char *cp); -int limit_cmd(char *cp); +int differentiate(MathoMatic* mathomatic, token_type *equation, int *np, long v); +int derivative_cmd(MathoMatic* mathomatic, char *cp); +int extrema_cmd(MathoMatic* mathomatic, char *cp); +int taylor_cmd(MathoMatic* mathomatic, char *cp); +int limit_cmd(MathoMatic* mathomatic, char *cp); /* factor.c */ -int factor_divide(token_type *equation, int *np, long v, double d); -int subtract_itself(token_type *equation, int *np); -int factor_plus(token_type *equation, int *np, long v, double d); -int factor_times(token_type *equation, int *np); -int factor_power(token_type *equation, int *np); +int factor_divide(MathoMatic* mathomatic, token_type *equation, int *np, long v, double d); +int subtract_itself(MathoMatic* mathomatic, token_type *equation, int *np); +int factor_plus(MathoMatic* mathomatic, token_type *equation, int *np, long v, double d); +int factor_times(MathoMatic* mathomatic, token_type *equation, int *np); +int factor_power(MathoMatic* mathomatic, token_type *equation, int *np); /* factor_int.c */ -int factor_one(double value); -double multiply_out_unique(void); -int display_unique(void); -int is_prime(void); -int factor_int(token_type *equation, int *np); -int factor_int_equation(int n); -int list_factor(token_type *equation, int *np, int factor_flag); -int factor_constants(token_type *equation, int *np, int level_code); +int factor_one(MathoMatic* mathomatic, double value); +double multiply_out_unique(MathoMatic* mathomatic); +int display_unique(MathoMatic* mathomatic); +int is_prime(MathoMatic* mathomatic); +int factor_int(MathoMatic* mathomatic, token_type *equation, int *np); +int factor_int_equation(MathoMatic* mathomatic, int n); +int list_factor(MathoMatic* mathomatic, token_type *equation, int *np, int factor_flag); +int factor_constants(MathoMatic* mathomatic, token_type *equation, int *np, int level_code); /* gcd.c */ -double gcd(double d1, double d2); -double gcd_verified(double d1, double d2); +double gcd(MathoMatic* mathomatic, double d1, double d2); +double gcd_verified(MathoMatic* mathomatic, double d1, double d2); double my_round(double d1); -int f_to_fraction(double d, double *numeratorp, double *denominatorp); -int make_fractions(token_type *equation, int *np); -int make_simple_fractions(token_type *equation, int *np); -int make_mixed_fractions(token_type *equation, int *np); +int f_to_fraction(MathoMatic* mathomatic, double d, double *numeratorp, double *denominatorp); +int make_fractions(MathoMatic* mathomatic, token_type *equation, int *np); +int make_simple_fractions(MathoMatic* mathomatic, token_type *equation, int *np); +int make_mixed_fractions(MathoMatic* mathomatic, token_type *equation, int *np); /* globals.c */ /* help.c */ -int parse(int n, char *cp); -int process_parse(int n, char *cp); -int process(char *cp); -int process_rv(char *cp); -int display_process(char *cp); -int shell_out(char *cp); -char *parse_var2(long *vp, char *cp); -int display_usage(char *pstr, int i); -int display_command(int i); -int display_repeat_command(void); -int read_examples(char **cpp); -void underline_title(int count); -int help_cmd(char *cp); +int parse(MathoMatic* mathomatic, int n, char *cp); +int process_parse(MathoMatic* mathomatic, int n, char *cp); +int process(MathoMatic* mathomatic, char *cp); +int process_rv(MathoMatic* mathomatic, char *cp); +int display_process(MathoMatic* mathomatic, char *cp); +int shell_out(MathoMatic* mathomatic, char *cp); +char *parse_var2(MathoMatic* mathomatic, long *vp, char *cp); +int display_usage(MathoMatic* mathomatic, char *pstr, int i); +int display_command(MathoMatic* mathomatic, int i); +int display_repeat_command(MathoMatic* mathomatic); +int read_examples(MathoMatic* mathomatic, char **cpp); +void underline_title(MathoMatic* mathomatic, int count); +int help_cmd(MathoMatic* mathomatic, char *cp); /* integrate.c */ -void make_powers(token_type *equation, int *np, long v); -int int_dispatch(token_type *equation, int *np, long v, int (*func)(token_type *equation, int *np, int loc, int eloc, long v)); -int integrate_cmd(char *cp); -int laplace_cmd(char *cp); -int nintegrate_cmd(char *cp); +void make_powers(MathoMatic* mathomatic, token_type *equation, int *np, long v); +int int_dispatch(MathoMatic* mathomatic, token_type *equation, int *np, long v, int (*func)(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int eloc, long v)); +int integrate_cmd(MathoMatic* mathomatic, char *cp); +int laplace_cmd(MathoMatic* mathomatic, char *cp); +int nintegrate_cmd(MathoMatic* mathomatic, char *cp); /* list.c */ -void reset_attr(void); -int set_color(int color); -void default_color(int set_no_color_flag); -int display_all_colors(void); -int list1_sub(int n, int export_flag); -int list_sub(int n); -void list_debug(int level, token_type *p1, int n1, token_type *p2, int n2); -char *var_name(long v); -int list_var(long v, int lang_code); -int list_proc(token_type *p1, int n, int export_flag); -char *list_equation(int n, int export_flag); -char *list_expression(token_type *p1, int n, int export_flag); -int list_string(token_type *p1, int n, char *string, int export_flag); -int list_string_sub(token_type *p1, int n, int outflag, char *string, int export_flag); +void reset_attr(MathoMatic* mathomatic); +int set_color(MathoMatic* mathomatic, int color); +void default_color(MathoMatic* mathomatic, int set_no_color_flag); +int display_all_colors(MathoMatic* mathomatic); +int list1_sub(MathoMatic* mathomatic, int n, int export_flag); +int list_sub(MathoMatic* mathomatic, int n); +void list_debug(MathoMatic* mathomatic, int level, token_type *p1, int n1, token_type *p2, int n2); +char *var_name(MathoMatic* mathomatic, long v); +int list_var(MathoMatic* mathomatic, long v, int lang_code); +int list_proc(MathoMatic* mathomatic, token_type *p1, int n, int export_flag); +char *list_equation(MathoMatic* mathomatic, int n, int export_flag); +char *list_expression(MathoMatic* mathomatic, token_type *p1, int n, int export_flag); +int list_string(MathoMatic* mathomatic, token_type *p1, int n, char *string, int export_flag); +int list_string_sub(MathoMatic* mathomatic, token_type *p1, int n, int outflag, char *string, int export_flag); int int_expr(token_type *p1, int n); -int list_code_equation(int en, enum language_list language, int int_flag); -char *string_code_equation(int en, enum language_list language, int int_flag); -int list_code(token_type *equation, int *np, int outflag, char *string, enum language_list language, int int_flag); -char *flist_equation_string(int n); -int flist_equation(int n); +int list_code_equation(MathoMatic* mathomatic, int en, enum language_list language, int int_flag); +char *string_code_equation(MathoMatic* mathomatic, int en, enum language_list language, int int_flag); +int list_code(MathoMatic* mathomatic, token_type *equation, int *np, int outflag, char *string, enum language_list language, int int_flag); +char *flist_equation_string(MathoMatic* mathomatic, int n); +int flist_equation(MathoMatic* mathomatic, int n); /* main.c */ void usage(FILE *fp); int main(int argc, char **argv); @@ -208,97 +208,97 @@ void resizehandler(int sig); void exit_program(int exit_value); /* parse.c */ void str_tolower(char *cp); -void put_up_arrow(int cnt, char *cp); -int isvarchar(int ch); +void put_up_arrow(MathoMatic* mathomatic, int cnt, char *cp); +int isvarchar(MathoMatic* mathomatic, int ch); int paren_increment(int ch); int is_mathomatic_operator(int ch); void binary_parenthesize(token_type *p1, int n, int i); void handle_negate(token_type *equation, int *np); -void give_priority(token_type *equation, int *np); -char *parse_section(token_type *equation, int *np, char *cp, int allow_space); -char *parse_equation(int n, char *cp); -char *parse_expr(token_type *equation, int *np, char *cp, int allow_space); -char *parse_var(long *vp, char *cp); +void give_priority(MathoMatic* mathomatic, token_type *equation, int *np); +char *parse_section(MathoMatic* mathomatic, token_type *equation, int *np, char *cp, int allow_space); +char *parse_equation(MathoMatic* mathomatic, int n, char *cp); +char *parse_expr(MathoMatic* mathomatic, token_type *equation, int *np, char *cp, int allow_space); +char *parse_var(MathoMatic* mathomatic, long *vp, char *cp); void remove_trailing_spaces(char *cp); -void set_error_level(char *cp); +void set_error_level(MathoMatic* mathomatic, char *cp); int var_is_const(long v, double *dp); int subst_constants(token_type *equation, int *np); int my_strlcpy(char *dest, char *src, int n); /* poly.c */ -int poly_in_v_sub(token_type *p1, int n, long v, int allow_divides); -int poly_in_v(token_type *p1, int n, long v, int allow_divides); -int poly_factor(token_type *equation, int *np, int do_repeat); -int remove_factors(void); -int poly_gcd(token_type *larger, int llen, token_type *smaller, int slen, long v); -int poly2_gcd(token_type *larger, int llen, token_type *smaller, int slen, long v, int require_additive); -int is_integer_var(long v); -int is_integer_expr(token_type *p1, int n); -int mod_simp(token_type *equation, int *np); -int poly_gcd_simp(token_type *equation, int *np); -int div_remainder(token_type *equation, int *np, int poly_flag, int quick_flag); -int poly_div(token_type *d1, int len1, token_type *d2, int len2, long *vp); -int smart_div(token_type *d1, int len1, token_type *d2, int len2); -int basic_size(token_type *p1, int len); +int poly_in_v_sub(MathoMatic* mathomatic, token_type *p1, int n, long v, int allow_divides); +int poly_in_v(MathoMatic* mathomatic, token_type *p1, int n, long v, int allow_divides); +int poly_factor(MathoMatic* mathomatic, token_type *equation, int *np, int do_repeat); +int remove_factors(MathoMatic* mathomatic); +int poly_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *smaller, int slen, long v); +int poly2_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *smaller, int slen, long v, int require_additive); +int is_integer_var(MathoMatic* mathomatic, long v); +int is_integer_expr(MathoMatic* mathomatic, token_type *p1, int n); +int mod_simp(MathoMatic* mathomatic, token_type *equation, int *np); +int poly_gcd_simp(MathoMatic* mathomatic, token_type *equation, int *np); +int div_remainder(MathoMatic* mathomatic, token_type *equation, int *np, int poly_flag, int quick_flag); +int poly_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int len2, long *vp); +int smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int len2); +int basic_size(MathoMatic* mathomatic, token_type *p1, int len); int get_term(token_type *p1, int n1, int count, int *tp1, int *lentp1); void term_value(double *dp, token_type *p1, int n1, int loc); int find_greatest_power(token_type *p1, int n1, long *vp1, double *pp1, int *tp1, int *lentp1, int *dcodep); /* simplify.c */ -void organize(token_type *equation, int *np); -void elim_loop(token_type *equation, int *np); -void simp_ssub(token_type *equation, int *np, long v, double d, int power_flag, int times_flag, int fc_level); -void simp_equation(int n); -void mid_simp_side(token_type *equation, int *np); -void mid_simp_equation(int n); -void simps_side(token_type *equation, int *np, int zsolve); -void simpv_side(token_type *equation, int *np, long v); -void simpv_equation(int n, long v); -int factor_imaginary(token_type *equation, int *np); -void factorv(token_type *equation, int *np, long v); -void calc_simp(token_type *equation, int *np); -void approximate(token_type *equation, int *np); -int simp_i(token_type *equation, int *np); -void simp_divide(token_type *equation, int *np); -void simp2_divide(token_type *equation, int *np, long v, int fc_level); -void simpb_side(token_type *equation, int *np, int uf_power_flag, int power_flag, int fc_level); -void simple_frac_side(token_type *equation, int *np); -void simpa_side(token_type *equation, int *np, int quick_flag, int frac_flag); -void simpa_repeat_side(token_type *equation, int *np, int quick_flag, int frac_flag); -void simpa_repeat(int n, int quick_flag, int frac_flag); -void simple_frac_repeat_side(token_type *equation, int *np); -int simp_loop(token_type *equation, int *np); -int simp_pp(token_type *equation, int *np); -int integer_root_simp(token_type *equation, int *np); -int simp_constant_power(token_type *equation, int *np); -int simp2_power(token_type *equation, int *np); +void organize(MathoMatic* mathomatic, token_type *equation, int *np); +void elim_loop(MathoMatic* mathomatic, token_type *equation, int *np); +void simp_ssub(MathoMatic* mathomatic, token_type *equation, int *np, long v, double d, int power_flag, int times_flag, int fc_level); +void simp_equation(MathoMatic* mathomatic, int n); +void mid_simp_side(MathoMatic* mathomatic, token_type *equation, int *np); +void mid_simp_equation(MathoMatic* mathomatic, int n); +void simps_side(MathoMatic* mathomatic, token_type *equation, int *np, int zsolve); +void simpv_side(MathoMatic* mathomatic, token_type *equation, int *np, long v); +void simpv_equation(MathoMatic* mathomatic, int n, long v); +int factor_imaginary(MathoMatic* mathomatic, token_type *equation, int *np); +void factorv(MathoMatic* mathomatic, token_type *equation, int *np, long v); +void calc_simp(MathoMatic* mathomatic, token_type *equation, int *np); +void approximate(MathoMatic* mathomatic, token_type *equation, int *np); +int simp_i(MathoMatic* mathomatic, token_type *equation, int *np); +void simp_divide(MathoMatic* mathomatic, token_type *equation, int *np); +void simp2_divide(MathoMatic* mathomatic, token_type *equation, int *np, long v, int fc_level); +void simpb_side(MathoMatic* mathomatic, token_type *equation, int *np, int uf_power_flag, int power_flag, int fc_level); +void simple_frac_side(MathoMatic* mathomatic, token_type *equation, int *np); +void simpa_side(MathoMatic* mathomatic, token_type *equation, int *np, int quick_flag, int frac_flag); +void simpa_repeat_side(MathoMatic* mathomatic, token_type *equation, int *np, int quick_flag, int frac_flag); +void simpa_repeat(MathoMatic* mathomatic, int n, int quick_flag, int frac_flag); +void simple_frac_repeat_side(MathoMatic* mathomatic, token_type *equation, int *np); +int simp_loop(MathoMatic* mathomatic, token_type *equation, int *np); +int simp_pp(MathoMatic* mathomatic, token_type *equation, int *np); +int integer_root_simp(MathoMatic* mathomatic, token_type *equation, int *np); +int simp_constant_power(MathoMatic* mathomatic, token_type *equation, int *np); +int simp2_power(MathoMatic* mathomatic, token_type *equation, int *np); double fixed_fmod(double k1, double k2); -int combine_constants(token_type *equation, int *np, int iflag); -int calc(int *op1p, double *k1p, int op2, double k2); -int elim_k(token_type *equation, int *np); -int se_compare(token_type *p1, int n1, token_type *p2, int n2, int *diff_signp); -int elim_sign(token_type *equation, int *np); -int div_imaginary(token_type *equation, int *np); -int reorder(token_type *equation, int *np); -int rationalize(token_type *equation, int *np); +int combine_constants(MathoMatic* mathomatic, token_type *equation, int *np, int iflag); +int calc(MathoMatic* mathomatic, int *op1p, double *k1p, int op2, double k2); +int elim_k(MathoMatic* mathomatic, token_type *equation, int *np); +int se_compare(MathoMatic* mathomatic, token_type *p1, int n1, token_type *p2, int n2, int *diff_signp); +int elim_sign(MathoMatic* mathomatic, token_type *equation, int *np); +int div_imaginary(MathoMatic* mathomatic, token_type *equation, int *np); +int reorder(MathoMatic* mathomatic, token_type *equation, int *np); +int rationalize(MathoMatic* mathomatic, token_type *equation, int *np); /* solve.c */ -int solve_espace(int want, int have); -int solve_sub(token_type *wantp, int wantn, token_type *leftp, int *leftnp, token_type *rightp, int *rightnp); +int solve_espace(MathoMatic* mathomatic, int want, int have); +int solve_sub(MathoMatic* mathomatic, token_type *wantp, int wantn, token_type *leftp, int *leftnp, token_type *rightp, int *rightnp); /* super.c */ -void group_proc(token_type *equation, int *np); -int fractions_and_group(token_type *equation, int *np); -int make_fractions_and_group(int n); -int super_factor(token_type *equation, int *np, int start_flag); +void group_proc(MathoMatic* mathomatic, token_type *equation, int *np); +int fractions_and_group(MathoMatic* mathomatic, token_type *equation, int *np); +int make_fractions_and_group(MathoMatic* mathomatic, int n); +int super_factor(MathoMatic* mathomatic, token_type *equation, int *np, int start_flag); /* unfactor.c */ -int uf_tsimp(token_type *equation, int *np); -int uf_power(token_type *equation, int *np); -int uf_pplus(token_type *equation, int *np); -void uf_allpower(token_type *equation, int *np); -void uf_repeat(token_type *equation, int *np); -void uf_repeat_always(token_type *equation, int *np); -void uf_simp(token_type *equation, int *np); -void uf_simp_no_repeat(token_type *equation, int *np); -int ufactor(token_type *equation, int *np); -int uf_times(token_type *equation, int *np); -int sub_ufactor(token_type *equation, int *np, int ii); -int unsimp_power(token_type *equation, int *np); -void uf_neg_help(token_type *equation, int *np); -int patch_root_div(token_type *equation, int *np); +int uf_tsimp(MathoMatic* mathomatic, token_type *equation, int *np); +int uf_power(MathoMatic* mathomatic, token_type *equation, int *np); +int uf_pplus(MathoMatic* mathomatic, token_type *equation, int *np); +void uf_allpower(MathoMatic* mathomatic, token_type *equation, int *np); +void uf_repeat(MathoMatic* mathomatic, token_type *equation, int *np); +void uf_repeat_always(MathoMatic* mathomatic, token_type *equation, int *np); +void uf_simp(MathoMatic* mathomatic, token_type *equation, int *np); +void uf_simp_no_repeat(MathoMatic* mathomatic, token_type *equation, int *np); +int ufactor(MathoMatic* mathomatic, token_type *equation, int *np); +int uf_times(MathoMatic* mathomatic, token_type *equation, int *np); +int sub_ufactor(MathoMatic* mathomatic, token_type *equation, int *np, int ii); +int unsimp_power(MathoMatic* mathomatic, token_type *equation, int *np); +void uf_neg_help(token_type *equation, int *np, MathoMatic* mathomatic); +int patch_root_div(MathoMatic* mathomatic, token_type *equation, int *np); diff --git a/simplify.c b/simplify.c index b8d1be3..ffb2a50 100644 --- a/simplify.c +++ b/simplify.c @@ -33,10 +33,10 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. */ #define MAX_COMPARE_TERMS (DEFAULT_N_TOKENS / 6) -static int org_recurse(token_type *equation, int *np, int loc, int level, int *elocp); -static int const_recurse(token_type *equation, int *np, int loc, int level, int iflag); -static int compare_recurse(token_type *p1, int n1, int l1, token_type *p2, int n2, int l2, int *diff_signp); -static int order_recurse(token_type *equation, int *np, int loc, int level); +static int org_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int *elocp); +static int const_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int iflag); +static int compare_recurse(MathoMatic* mathomatic, token_type *p1, int n1, int l1, token_type *p2, int n2, int l2, int *diff_signp); +static int order_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level); /* * Fix up levels of parentheses in an equation side. @@ -45,29 +45,27 @@ static int order_recurse(token_type *equation, int *np, int loc, int level); * This is the inner-most loop in Mathomatic, make it fast. */ void -organize(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +organize(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { #if DEBUG if (equation == NULL || np == NULL) { - error_bug("NULL pointer passed to organize()."); + error_bug(mathomatic, "NULL pointer passed to organize()."); } #endif if (*np <= 0 || (*np & 1) == 0) { printf("Bad expression size = %d.\n", *np); - error_bug("Internal error: organize() called with bad expression size."); + error_bug(mathomatic, "Internal error: organize() called with bad expression size."); } - if (*np > n_tokens) { - error_bug("Internal error: expression array overflow detected in organize()."); + if (*np > mathomatic->n_tokens) { + error_bug(mathomatic, "Internal error: expression array overflow detected in organize()."); } - org_recurse(equation, np, 0, 1, NULL); + org_recurse(mathomatic, equation, np, 0, 1, NULL); } static inline void -org_up_level(bp, ep, level, invert) -token_type *bp, *ep; -int level, invert; +org_up_level(token_type *bp, token_type *ep, int level, int invert) { if (invert) { for (; bp <= ep; bp++) { @@ -101,10 +99,9 @@ int level, invert; * moving up levels to "level" of parentheses. */ static int -org_recurse(equation, np, loc, level, elocp) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ -int loc, level, *elocp; +org_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int *elocp) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { token_type *p1, *bp, *ep; int op, sub_op; @@ -145,7 +142,7 @@ int loc, level, *elocp; } for (i = loc; i <= eloc; i += 2) { if (equation[i].level > level) { - sub_op = org_recurse(equation, np, i, level + 1, &sub_eloc); + sub_op = org_recurse(mathomatic, equation, np, i, level + 1, &sub_eloc); switch (sub_op) { case PLUS: case MINUS: @@ -173,55 +170,55 @@ int loc, level, *elocp; * Just does constant simplification. */ void -elim_loop(equation, np) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of equation side */ +elim_loop(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of equation side */ { - if (abort_flag) { + if (mathomatic->abort_flag) { /* Control-C pressed, gracefully return to main prompt and leave unsimplified */ - abort_flag = false; + mathomatic->abort_flag = false; #if DEBUG && !SILENT char *cp, buf[100]; - my_strlcpy(prompt_str, _("Enter debug level, or an empty line to abort the current operation: "), sizeof(prompt_str)); - if ((cp = get_string(buf, sizeof(buf))) == NULL || *cp == '\0') { - longjmp(jmp_save, 13); + my_strlcpy(mathomatic->prompt_str, _("Enter debug level, or an empty line to abort the current operation: "), sizeof(mathomatic->prompt_str)); + if ((cp = get_string(mathomatic, buf, sizeof(buf))) == NULL || *cp == '\0') { + longjmp(mathomatic->jmp_save, 13); } else { - debug_level = decstrtol(cp, NULL); - printf(_("Debug level set to %d.\n"), debug_level); + mathomatic->debug_level = decstrtol(cp, NULL); + printf(_("Debug level set to %d.\n"), mathomatic->debug_level); } #else - longjmp(jmp_save, 13); + longjmp(mathomatic->jmp_save, 13); #endif } - side_debug(6, equation, *np); + side_debug(mathomatic, 6, equation, *np); do { do { do { - organize(equation, np); - } while (combine_constants(equation, np, true)); - } while (elim_k(equation, np)); - } while (simp_pp(equation, np)); - if (reorder(equation, np)) { + organize(mathomatic, equation, np); + } while (combine_constants(mathomatic, equation, np, true)); + } while (elim_k(mathomatic, equation, np)); + } while (simp_pp(mathomatic, equation, np)); + if (reorder(mathomatic, equation, np)) { do { - organize(equation, np); - } while (elim_k(equation, np)); + organize(mathomatic, equation, np); + } while (elim_k(mathomatic, equation, np)); } - side_debug(5, equation, *np); + side_debug(mathomatic, 5, equation, *np); } /* * Configurable high level simplify routine. */ void -simp_ssub(equation, np, v, d, power_flag, times_flag, fc_level) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of equation side */ -long v; /* variable to factor, 0L or MATCH_ANY to factor all variables */ -double d; /* factor expressions raised to the power of this if v */ -int power_flag; /* factor_power() flag */ -int times_flag; /* factor_times() flag */ -int fc_level; /* factor constants code, passed to factor_constants() */ +simp_ssub(MathoMatic* mathomatic, token_type *equation, int *np, long v, double d, int power_flag, int times_flag, int fc_level) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of equation side */ +//long v; /* variable to factor, 0L or MATCH_ANY to factor all variables */ +//double d; /* factor expressions raised to the power of this if v */ +//int power_flag; /* factor_power() flag */ +//int times_flag; /* factor_times() flag */ +//int fc_level; /* factor constants code, passed to factor_constants() */ { do { do { @@ -231,15 +228,15 @@ int fc_level; /* factor constants code, passed to factor_constants() */ do { do { do { - elim_loop(equation, np); - } while (simp2_power(equation, np)); - } while (times_flag && factor_times(equation, np)); - } while (elim_sign(equation, np)); - } while (subtract_itself(equation, np)); - } while (factor_constants(equation, np, fc_level)); - } while (factor_divide(equation, np, v, d)); - } while (factor_plus(equation, np, v, d)); - } while (power_flag && factor_power(equation, np)); + elim_loop(mathomatic, equation, np); + } while (simp2_power(mathomatic, equation, np)); + } while (times_flag && factor_times(mathomatic, equation, np)); + } while (elim_sign(mathomatic, equation, np)); + } while (subtract_itself(mathomatic, equation, np)); + } while (factor_constants(mathomatic, equation, np, fc_level)); + } while (factor_divide(mathomatic, equation, np, v, d)); + } while (factor_plus(mathomatic, equation, np, v, d)); + } while (power_flag && factor_power(mathomatic, equation, np)); } /* @@ -247,14 +244,14 @@ int fc_level; /* factor constants code, passed to factor_constants() */ * No factoring is done. */ void -simp_equation(n) -int n; /* equation space number to simplify */ +simp_equation(MathoMatic* mathomatic, int n) +//int n; /* equation space number to simplify */ { - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return; - simp_loop(lhs[n], &n_lhs[n]); - if (n_rhs[n] > 0) { - simp_loop(rhs[n], &n_rhs[n]); + simp_loop(mathomatic, mathomatic->lhs[n], &mathomatic->n_lhs[n]); + if (mathomatic->n_rhs[n] > 0) { + simp_loop(mathomatic, mathomatic->rhs[n], &mathomatic->n_rhs[n]); } } @@ -263,11 +260,11 @@ int n; /* equation space number to simplify */ * Trivial factoring is done. */ void -mid_simp_side(equation, np) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of equation side */ +mid_simp_side(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of equation side */ { - simp_ssub(equation, np, 0L, 1.0, true, true, 6); + simp_ssub(mathomatic, equation, np, 0L, 1.0, true, true, 6); } /* @@ -275,14 +272,14 @@ int *np; /* pointer to length of equation side */ * Trivial factoring is done. */ void -mid_simp_equation(n) -int n; /* equation space number to simplify */ +mid_simp_equation(MathoMatic* mathomatic, int n) +//int n; /* equation space number to simplify */ { - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return; - mid_simp_side(lhs[n], &n_lhs[n]); - if (n_rhs[n] > 0) { - mid_simp_side(rhs[n], &n_rhs[n]); + mid_simp_side(mathomatic, mathomatic->lhs[n], &mathomatic->n_lhs[n]); + if (mathomatic->n_rhs[n] > 0) { + mid_simp_side(mathomatic, mathomatic->rhs[n], &mathomatic->n_rhs[n]); } } @@ -290,28 +287,28 @@ int n; /* equation space number to simplify */ * This function is the mid-range simplifier used by the solver. */ void -simps_side(equation, np, zsolve) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of equation side */ -int zsolve; /* true for solving for zero */ +simps_side(MathoMatic* mathomatic, token_type *equation, int *np, int zsolve) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of equation side */ +//int zsolve; /* true for solving for zero */ { - elim_loop(equation, np); - simp_constant_power(equation, np); + elim_loop(mathomatic, equation, np); + simp_constant_power(mathomatic, equation, np); do { - simp_ssub(equation, np, 0L, 0.0, !zsolve, true, 6); - } while (super_factor(equation, np, 0)); + simp_ssub(mathomatic, equation, np, 0L, 0.0, !zsolve, true, 6); + } while (super_factor(mathomatic, equation, np, 0)); } /* * This function is used by the factor command. */ void -simpv_side(equation, np, v) -token_type *equation; /* pointer to the beginning of equation side to factor */ -int *np; /* pointer to length of equation side */ -long v; /* variable to factor, 0 for all variables */ +simpv_side(MathoMatic* mathomatic, token_type *equation, int *np, long v) +//token_type *equation; /* pointer to the beginning of equation side to factor */ +//int *np; /* pointer to length of equation side */ +//long v; /* variable to factor, 0 for all variables */ { - simp_ssub(equation, np, v, 0.0, v == 0, true, 6); + simp_ssub(mathomatic, equation, np, v, 0.0, v == 0, true, 6); } /* @@ -319,15 +316,15 @@ long v; /* variable to factor, 0 for all variables */ * Trivial factoring is done. */ void -simpv_equation(n, v) -int n; /* equation space number to simplify */ -long v; /* Mathomatic variable to factor or 0 */ +simpv_equation(MathoMatic* mathomatic, int n, long v) +//int n; /* equation space number to simplify */ +//long v; /* Mathomatic variable to factor or 0 */ { - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return; - simpv_side(lhs[n], &n_lhs[n], v); - if (n_rhs[n] > 0) { - simpv_side(rhs[n], &n_rhs[n], v); + simpv_side(mathomatic, mathomatic->lhs[n], &mathomatic->n_lhs[n], v); + if (mathomatic->n_rhs[n] > 0) { + simpv_side(mathomatic, mathomatic->rhs[n], &mathomatic->n_rhs[n], v); } } @@ -338,14 +335,14 @@ long v; /* Mathomatic variable to factor or 0 */ * Return true if anything was approximated. */ int -factor_imaginary(equation, np) -token_type *equation; /* pointer to the beginning of equation side */ -int *np; /* pointer to equation side length */ +factor_imaginary(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to the beginning of equation side */ +//int *np; /* pointer to equation side length */ { int rv; - rv = approximate_complex_roots(equation, np); - factorv(equation, np, IMAGINARY); + rv = approximate_complex_roots(mathomatic, equation, np); + factorv(mathomatic, equation, np, IMAGINARY); return rv; } @@ -357,16 +354,16 @@ int *np; /* pointer to equation side length */ * not in the divisor. */ void -factorv(equation, np, v) -token_type *equation; /* pointer to the beginning of equation side to factor */ -int *np; /* pointer to equation side length */ -long v; /* Mathomatic variable to factor */ +factorv(MathoMatic* mathomatic, token_type *equation, int *np, long v) +//token_type *equation; /* pointer to the beginning of equation side to factor */ +//int *np; /* pointer to equation side length */ +//long v; /* Mathomatic variable to factor */ { do { do { - simp_loop(equation, np); - } while (factor_plus(equation, np, v, 0.0)); - } while (v == IMAGINARY && div_imaginary(equation, np)); + simp_loop(mathomatic, equation, np); + } while (factor_plus(mathomatic, equation, np, v, 0.0)); + } while (v == IMAGINARY && div_imaginary(mathomatic, equation, np)); } /* @@ -374,41 +371,37 @@ long v; /* Mathomatic variable to factor */ * Includes complex number simplification. */ void -calc_simp(equation, np) -token_type *equation; -int *np; +calc_simp(MathoMatic* mathomatic, token_type *equation, int *np) { - approximate_roots = true; + mathomatic->approximate_roots = true; subst_constants(equation, np); - mid_simp_side(equation, np); - factor_imaginary(equation, np); - ufactor(equation, np); - factor_imaginary(equation, np); - uf_simp(equation, np); - factor_imaginary(equation, np); - mid_simp_side(equation, np); - make_simple_fractions(equation, np); - uf_tsimp(equation, np); - approximate_roots = false; + mid_simp_side(mathomatic, equation, np); + factor_imaginary(mathomatic, equation, np); + ufactor(mathomatic, equation, np); + factor_imaginary(mathomatic, equation, np); + uf_simp(mathomatic, equation, np); + factor_imaginary(mathomatic, equation, np); + mid_simp_side(mathomatic, equation, np); + make_simple_fractions(mathomatic, equation, np); + uf_tsimp(mathomatic, equation, np); + mathomatic->approximate_roots = false; } /* * Approximate an equation side for the approximate command. */ void -approximate(equation, np) -token_type *equation; -int *np; +approximate(MathoMatic* mathomatic, token_type *equation, int *np) { - if (repeat_flag) { + if (mathomatic->repeat_flag) { /* do more */ - calc_simp(equation, np); + calc_simp(mathomatic, equation, np); } else { subst_constants(equation, np); - approximate_roots = true; - simp_loop(equation, np); - factor_imaginary(equation, np); - approximate_roots = false; + mathomatic->approximate_roots = true; + simp_loop(mathomatic, equation, np); + factor_imaginary(mathomatic, equation, np); + mathomatic->approximate_roots = false; } } @@ -419,21 +412,19 @@ int *np; * Return true if any imaginary units where substituted. */ int -simp_i(equation, np) -token_type *equation; -int *np; +simp_i(MathoMatic* mathomatic, token_type *equation, int *np) { int i; int level; int rv = false; - simp_loop(equation, np); + simp_loop(mathomatic, equation, np); for (i = 0; i < *np; i++) { switch (equation[i].kind) { case VARIABLE: if (equation[i].token.variable == IMAGINARY) { - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } level = equation[i].level + 1; blt(&equation[i+2], &equation[i], (*np - i) * sizeof(token_type)); @@ -472,14 +463,14 @@ int *np; do { do { do { - organize(equation, np); - } while (combine_constants(equation, np, false)); - } while (elim_k(equation, np)); - } while (simp_pp(equation, np)); + organize(mathomatic, equation, np); + } while (combine_constants(mathomatic, equation, np, false)); + } while (elim_k(mathomatic, equation, np)); + } while (simp_pp(mathomatic, equation, np)); /* The following factor_power() messes up absolute values and complex numbers sometimes: */ - } while (factor_power(equation, np)); - } while (factor_times(equation, np)); - simp_loop(equation, np); + } while (factor_power(mathomatic, equation, np)); + } while (factor_times(mathomatic, equation, np)); + simp_loop(mathomatic, equation, np); return rv; } @@ -487,15 +478,13 @@ int *np; * Combine all like denominators. */ void -simp_divide(equation, np) -token_type *equation; -int *np; +simp_divide(MathoMatic* mathomatic, token_type *equation, int *np) { do { do { - simp_loop(equation, np); - } while (factor_constants(equation, np, 1)); - } while (factor_divide(equation, np, 0L, 0.0)); + simp_loop(mathomatic, equation, np); + } while (factor_constants(mathomatic, equation, np, 1)); + } while (factor_divide(mathomatic, equation, np, 0L, 0.0)); } /* @@ -505,23 +494,19 @@ int *np; * For beauty simplifier simpb_side() below. */ void -simp2_divide(equation, np, v, fc_level) -token_type *equation; -int *np; -long v; -int fc_level; +simp2_divide(MathoMatic* mathomatic, token_type *equation, int *np, long v, int fc_level) { do { do { do { do { do { - elim_loop(equation, np); - } while (simp2_power(equation, np)); - } while (elim_sign(equation, np)); - } while (subtract_itself(equation, np)); - } while (factor_constants(equation, np, fc_level)); - } while (factor_divide(equation, np, v, 0.0)); + elim_loop(mathomatic, equation, np); + } while (simp2_power(mathomatic, equation, np)); + } while (elim_sign(mathomatic, equation, np)); + } while (subtract_itself(mathomatic, equation, np)); + } while (factor_constants(mathomatic, equation, np, fc_level)); + } while (factor_divide(mathomatic, equation, np, v, 0.0)); } /* @@ -555,21 +540,21 @@ sort_type *p1, *p2; * Factors variables in order: "sign" variables first, then by frequency. */ void -simpb_side(equation, np, uf_power_flag, power_flag, fc_level) -token_type *equation; /* pointer to the beginning of equation side */ -int *np; /* pointer to length of equation side */ -int uf_power_flag; /* uf_allpower() flag */ -int power_flag; /* factor_power() flag */ -int fc_level; /* factor constants code, passed to factor_constants() */ +simpb_side(MathoMatic* mathomatic, token_type *equation, int *np, int uf_power_flag, int power_flag, int fc_level) +//token_type *equation; /* pointer to the beginning of equation side */ +//int *np; /* pointer to length of equation side */ +//int uf_power_flag; /* uf_allpower() flag */ +//int power_flag; /* factor_power() flag */ +//int fc_level; /* factor constants code, passed to factor_constants() */ { int i; int vc, cnt; /* counts */ long v1, last_v; /* Mathomatic variables */ sort_type va[MAX_VARS]; /* array of all real variables found in equation side */ - elim_loop(equation, np); + elim_loop(mathomatic, equation, np); if (uf_power_flag) { - uf_allpower(equation, np); + uf_allpower(mathomatic, equation, np); } last_v = 0; for (vc = 0; vc < ARR_CNT(va);) { @@ -598,35 +583,35 @@ int fc_level; /* factor constants code, passed to factor_constants() */ /* sort variable array va[] */ qsort((char *) va, vc, sizeof(*va), simpb_vcmp); /* factor division by most frequently occurring variables first */ - simp2_divide(equation, np, va[0].v, fc_level); + simp2_divide(mathomatic, equation, np, va[0].v, fc_level); for (i = 1; i < vc; i++) { - if (factor_divide(equation, np, va[i].v, 0.0)) - simp2_divide(equation, np, va[i].v, fc_level); + if (factor_divide(mathomatic, equation, np, va[i].v, 0.0)) + simp2_divide(mathomatic, equation, np, va[i].v, fc_level); } - simp2_divide(equation, np, 0L, fc_level); + simp2_divide(mathomatic, equation, np, 0L, fc_level); /* factor all sub-expressions in order of most frequently occurring variables */ for (i = 0; i < vc; i++) { - while (factor_plus(equation, np, va[i].v, 0.0)) { - simp2_divide(equation, np, 0L, fc_level); + while (factor_plus(mathomatic, equation, np, va[i].v, 0.0)) { + simp2_divide(mathomatic, equation, np, 0L, fc_level); } } } #if 0 /* Messes up support/gcd.in and tests/quartic.in */ - make_simple_fractions(equation, np); + make_simple_fractions(mathomatic, equation, np); #endif /* make sure equation side is completely factored */ - while (factor_divide(equation, np, MATCH_ANY, 0.0)) { - simp2_divide(equation, np, MATCH_ANY, fc_level); + while (factor_divide(mathomatic, equation, np, MATCH_ANY, 0.0)) { + simp2_divide(mathomatic, equation, np, MATCH_ANY, fc_level); } - while (factor_plus(equation, np, MATCH_ANY, 0.0)) { - simp2_divide(equation, np, 0L, fc_level); + while (factor_plus(mathomatic, equation, np, MATCH_ANY, 0.0)) { + simp2_divide(mathomatic, equation, np, 0L, fc_level); } - simp_ssub(equation, np, MATCH_ANY, 0.0, power_flag, true, fc_level); + simp_ssub(mathomatic, equation, np, MATCH_ANY, 0.0, power_flag, true, fc_level); #if 0 /* Seems to complicate and change constants slightly when enabled. */ if (power_flag) { - make_simple_fractions(equation, np); - factor_power(equation, np); - simp_ssub(equation, np, MATCH_ANY, 0.0, power_flag, true, fc_level); + make_simple_fractions(mathomatic, equation, np); + factor_power(mathomatic, equation, np); + simp_ssub(mathomatic, equation, np, MATCH_ANY, 0.0, power_flag, true, fc_level); } #endif } @@ -638,38 +623,38 @@ int fc_level; /* factor constants code, passed to factor_constants() */ * Globals tlhs[] and trhs[] are wiped out. */ void -simple_frac_side(equation, np) -token_type *equation; /* pointer to the beginning of equation side */ -int *np; /* pointer to length of equation side */ +simple_frac_side(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to the beginning of equation side */ +//int *np; /* pointer to length of equation side */ { if (*np == 1) { - make_simple_fractions(equation, np); - fractions_and_group(equation, np); + make_simple_fractions(mathomatic, equation, np); + fractions_and_group(mathomatic, equation, np); return; } - simp_loop(equation, np); - poly_factor(equation, np, true); + simp_loop(mathomatic, equation, np); + poly_factor(mathomatic, equation, np, true); do { do { do { - simp_ssub(equation, np, 0L, 0.0, false, true, 5); - } while (poly_gcd_simp(equation, np)); - } while (uf_power(equation, np)); - } while (super_factor(equation, np, 3)); - side_debug(2, equation, *np); - - make_simple_fractions(equation, np); - uf_tsimp(equation, np); + simp_ssub(mathomatic, equation, np, 0L, 0.0, false, true, 5); + } while (poly_gcd_simp(mathomatic, equation, np)); + } while (uf_power(mathomatic, equation, np)); + } while (super_factor(mathomatic, equation, np, 3)); + side_debug(mathomatic, 2, equation, *np); + + make_simple_fractions(mathomatic, equation, np); + uf_tsimp(mathomatic, equation, np); #if 0 /* Not really needed, but makes it end up the same as the simplify command. */ - make_simple_fractions(equation, np); - uf_power(equation, np); - integer_root_simp(equation, np); - simpb_side(equation, np, true, true, 3); + make_simple_fractions(mathomatic, equation, np); + uf_power(mathomatic, equation, np); + integer_root_simp(mathomatic, equation, np); + simpb_side(mathomatic, equation, np, true, true, 3); #endif - poly_factor(equation, np, true); - simpb_side(equation, np, true, false, 2); - simpb_side(equation, np, true, false, 2); /* Added for thoroughness, making sure everything is uf_power()ed. */ - fractions_and_group(equation, np); + poly_factor(mathomatic, equation, np, true); + simpb_side(mathomatic, equation, np, true, false, 2); + simpb_side(mathomatic, equation, np, true, false, 2); /* Added for thoroughness, making sure everything is uf_power()ed. */ + fractions_and_group(mathomatic, equation, np); } /* @@ -680,155 +665,155 @@ int *np; /* pointer to length of equation side */ * Globals tlhs[] and trhs[] are wiped out. */ void -simpa_side(equation, np, quick_flag, frac_flag) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of the equation side */ -int quick_flag; /* "simplify quick" option, simpler with no (x+1)^2 expansion */ -int frac_flag; /* "simplify fraction" option, simplify to the ratio of two polynomials */ +simpa_side(MathoMatic* mathomatic, token_type *equation, int *np, int quick_flag, int frac_flag) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of the equation side */ +//int quick_flag; /* "simplify quick" option, simpler with no (x+1)^2 expansion */ +//int frac_flag; /* "simplify fraction" option, simplify to the ratio of two polynomials */ { int i; int flag, poly_flag = true; jmp_buf save_save; if (*np == 1) { /* no need to full simplify a single constant or variable */ - make_simple_fractions(equation, np); - simpb_side(equation, np, true, !frac_flag, 2); + make_simple_fractions(mathomatic, equation, np); + simpb_side(mathomatic, equation, np, true, !frac_flag, 2); return; } - debug_string(2, "Simplify input:"); - side_debug(2, equation, *np); - simp_loop(equation, np); + debug_string(mathomatic, 2, "Simplify input:"); + side_debug(mathomatic, 2, equation, *np); + simp_loop(mathomatic, equation, np); #if 1 do { - simp_ssub(equation, np, 0L, 1.0, false, true, 5); - } while (uf_power(equation, np)); - while (factor_power(equation, np)) { - simp_loop(equation, np); + simp_ssub(mathomatic, equation, np, 0L, 1.0, false, true, 5); + } while (uf_power(mathomatic, equation, np)); + while (factor_power(mathomatic, equation, np)) { + simp_loop(mathomatic, equation, np); } #else - simpb_side(equation, np, false, true, 5); + simpb_side(mathomatic, equation, np, false, true, 5); #endif - if (rationalize_denominators) { - rationalize(equation, np); + if (mathomatic->rationalize_denominators) { + rationalize(mathomatic, equation, np); } - unsimp_power(equation, np); - uf_tsimp(equation, np); + unsimp_power(mathomatic, equation, np); + uf_tsimp(mathomatic, equation, np); /* Here is the only place in Mathomatic that we do complete modulus (%) simplification: */ - uf_pplus(equation, np); - uf_repeat(equation, np); + uf_pplus(mathomatic, equation, np); + uf_repeat(mathomatic, equation, np); do { - elim_loop(equation, np); - } while (mod_simp(equation, np)); + elim_loop(mathomatic, equation, np); + } while (mod_simp(mathomatic, equation, np)); /* Here we try to simplify out unnecessary negative constants and imaginary numbers: */ - simp_i(equation, np); - unsimp_power(equation, np); - uf_times(equation, np); - simp_ssub(equation, np, 0L, 1.0, true, true, 5); - unsimp_power(equation, np); - uf_neg_help(equation, np); - uf_tsimp(equation, np); + simp_i(mathomatic, equation, np); + unsimp_power(mathomatic, equation, np); + uf_times(mathomatic, equation, np); + simp_ssub(mathomatic, equation, np, 0L, 1.0, true, true, 5); + unsimp_power(mathomatic, equation, np); + uf_neg_help(equation, np, mathomatic); + uf_tsimp(mathomatic, equation, np); do { do { - simp_ssub(equation, np, 0L, 1.0, false, true, 6); - } while (uf_power(equation, np)); - } while (!quick_flag && super_factor(equation, np, 2)); - if (poly_gcd_simp(equation, np)) { - simp_ssub(equation, np, 0L, 1.0, false, true, 6); - } - side_debug(2, equation, *np); - unsimp_power(equation, np); - uf_times(equation, np); - factorv(equation, np, IMAGINARY); - uf_pplus(equation, np); - simp_ssub(equation, np, 0L, 1.0, true, false, 5); - if (poly_gcd_simp(equation, np)) { - factorv(equation, np, IMAGINARY); - uf_pplus(equation, np); - simp_ssub(equation, np, 0L, 1.0, true, false, 5); - } - uf_times(equation, np); - uf_pplus(equation, np); - factor_imaginary(equation, np); - uf_power(equation, np); + simp_ssub(mathomatic, equation, np, 0L, 1.0, false, true, 6); + } while (uf_power(mathomatic, equation, np)); + } while (!quick_flag && super_factor(mathomatic, equation, np, 2)); + if (poly_gcd_simp(mathomatic, equation, np)) { + simp_ssub(mathomatic, equation, np, 0L, 1.0, false, true, 6); + } + side_debug(mathomatic, 2, equation, *np); + unsimp_power(mathomatic, equation, np); + uf_times(mathomatic, equation, np); + factorv(mathomatic, equation, np, IMAGINARY); + uf_pplus(mathomatic, equation, np); + simp_ssub(mathomatic, equation, np, 0L, 1.0, true, false, 5); + if (poly_gcd_simp(mathomatic, equation, np)) { + factorv(mathomatic, equation, np, IMAGINARY); + uf_pplus(mathomatic, equation, np); + simp_ssub(mathomatic, equation, np, 0L, 1.0, true, false, 5); + } + uf_times(mathomatic, equation, np); + uf_pplus(mathomatic, equation, np); + factor_imaginary(mathomatic, equation, np); + uf_power(mathomatic, equation, np); do { do { - simp_ssub(equation, np, 0L, 1.0, false, true, 6); - } while (uf_power(equation, np)); - } while (!quick_flag && super_factor(equation, np, 2)); + simp_ssub(mathomatic, equation, np, 0L, 1.0, false, true, 6); + } while (uf_power(mathomatic, equation, np)); + } while (!quick_flag && super_factor(mathomatic, equation, np, 2)); /* Here we do the greatest expansion; if it fails, do less expansion. */ - partial_flag = frac_flag; - n_tlhs = *np; - blt(tlhs, equation, n_tlhs * sizeof(token_type)); - blt(save_save, jmp_save, sizeof(jmp_save)); - if ((i = setjmp(jmp_save)) != 0) { /* trap errors */ - blt(jmp_save, save_save, sizeof(jmp_save)); + mathomatic->partial_flag = frac_flag; + mathomatic->n_tlhs = *np; + blt(mathomatic->tlhs, equation, mathomatic->n_tlhs * sizeof(token_type)); + blt(save_save, mathomatic->jmp_save, sizeof(mathomatic->jmp_save)); + if ((i = setjmp(mathomatic->jmp_save)) != 0) { /* trap errors */ + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); if (i == 13) { /* critical error code */ - longjmp(jmp_save, i); + longjmp(mathomatic->jmp_save, i); } /* an error occurred, restore the original expression */ - *np = n_tlhs; - blt(equation, tlhs, n_tlhs * sizeof(token_type)); + *np = mathomatic->n_tlhs; + blt(equation, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); if (i == 14) { - debug_string(1, "Simplify not expanding fully, due to oversized expression."); + debug_string(mathomatic, 1, "Simplify not expanding fully, due to oversized expression."); } else { - debug_string(0, "Simplify not expanding fully, due to some error."); + debug_string(mathomatic, 0, "Simplify not expanding fully, due to some error."); } - partial_flag = true; /* expand less */ - uf_tsimp(equation, np); + mathomatic->partial_flag = true; /* expand less */ + uf_tsimp(mathomatic, equation, np); } else { if (quick_flag) { - uf_tsimp(equation, np); + uf_tsimp(mathomatic, equation, np); } else { /* expand powers of 2 and higher, might result in error_huge() trap */ do { - uf_power(equation, np); - uf_repeat(equation, np); - } while (uf_tsimp(equation, np)); + uf_power(mathomatic, equation, np); + uf_repeat(mathomatic, equation, np); + } while (uf_tsimp(mathomatic, equation, np)); } - blt(jmp_save, save_save, sizeof(jmp_save)); + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); } - partial_flag = true; + mathomatic->partial_flag = true; - simpb_side(equation, np, true, true, 2); - debug_string(1, "Simplify result before applying polynomial operations:"); - side_debug(1, equation, *np); + simpb_side(mathomatic, equation, np, true, true, 2); + debug_string(mathomatic, 1, "Simplify result before applying polynomial operations:"); + side_debug(mathomatic, 1, equation, *np); for (flag = false;;) { /* divide top and bottom of fractions by any polynomial GCD found */ - if (poly_gcd_simp(equation, np)) { + if (poly_gcd_simp(mathomatic, equation, np)) { flag = false; - simpb_side(equation, np, false, true, 3); + simpb_side(mathomatic, equation, np, false, true, 3); } /* factor polynomials */ - if (!flag && poly_factor(equation, np, true)) { + if (!flag && poly_factor(mathomatic, equation, np, true)) { flag = true; - simpb_side(equation, np, false, true, 3); + simpb_side(mathomatic, equation, np, false, true, 3); continue; } /* simplify algebraic fractions with polynomial and smart division */ - if (!frac_flag && div_remainder(equation, np, poly_flag, quick_flag)) { + if (!frac_flag && div_remainder(mathomatic, equation, np, poly_flag, quick_flag)) { flag = false; - simpb_side(equation, np, false, true, 3); + simpb_side(mathomatic, equation, np, false, true, 3); continue; } break; } - debug_string(2, "Raw simplify result after applying polynomial operations:"); - side_debug(2, equation, *np); - simp_constant_power(equation, np); - simp_ssub(equation, np, 0L, 1.0, true, true, 5); - unsimp_power(equation, np); - make_simple_fractions(equation, np); - factor_power(equation, np); - uf_tsimp(equation, np); - make_simple_fractions(equation, np); - uf_power(equation, np); - integer_root_simp(equation, np); - simpb_side(equation, np, true, true, 3); - poly_factor(equation, np, true); - simpb_side(equation, np, true, !frac_flag, 2); + debug_string(mathomatic, 2, "Raw simplify result after applying polynomial operations:"); + side_debug(mathomatic, 2, equation, *np); + simp_constant_power(mathomatic, equation, np); + simp_ssub(mathomatic, equation, np, 0L, 1.0, true, true, 5); + unsimp_power(mathomatic, equation, np); + make_simple_fractions(mathomatic, equation, np); + factor_power(mathomatic, equation, np); + uf_tsimp(mathomatic, equation, np); + make_simple_fractions(mathomatic, equation, np); + uf_power(mathomatic, equation, np); + integer_root_simp(mathomatic, equation, np); + simpb_side(mathomatic, equation, np, true, true, 3); + poly_factor(mathomatic, equation, np, true); + simpb_side(mathomatic, equation, np, true, !frac_flag, 2); } /* @@ -840,24 +825,24 @@ int frac_flag; /* "simplify fraction" option, simplify to the ratio of two poly * Globals tes[], tlhs[], and trhs[] are wiped out. */ void -simpa_repeat_side(equation, np, quick_flag, frac_flag) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of the equation side */ -int quick_flag; /* "simplify quick" option, simpler fractions with no (x+1)^2 expansion */ -int frac_flag; /* "simplify fraction" option, simplify to the ratio of two polynomials */ +simpa_repeat_side(MathoMatic* mathomatic, token_type *equation, int *np, int quick_flag, int frac_flag) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of the equation side */ +//int quick_flag; /* "simplify quick" option, simpler fractions with no (x+1)^2 expansion */ +//int frac_flag; /* "simplify fraction" option, simplify to the ratio of two polynomials */ { if (*np <= 0) return; - simpa_side(equation, np, quick_flag, frac_flag); - if (repeat_flag && *np > 1) { + simpa_side(mathomatic, equation, np, quick_flag, frac_flag); + if (mathomatic->repeat_flag && *np > 1) { do { - n_tes = *np; - blt(tes, equation, n_tes * sizeof(token_type)); - simpa_side(equation, np, quick_flag, frac_flag); - } while (*np < n_tes); - if (*np != n_tes) { - *np = n_tes; - blt(equation, tes, n_tes * sizeof(token_type)); + mathomatic->n_tes = *np; + blt(mathomatic->tes, equation, mathomatic->n_tes * sizeof(token_type)); + simpa_side(mathomatic, equation, np, quick_flag, frac_flag); + } while (*np < mathomatic->n_tes); + if (*np != mathomatic->n_tes) { + *np = mathomatic->n_tes; + blt(equation, mathomatic->tes, mathomatic->n_tes * sizeof(token_type)); } } } @@ -868,16 +853,16 @@ int frac_flag; /* "simplify fraction" option, simplify to the ratio of two poly * Globals tes[], tlhs[], and trhs[] are clobbered. */ void -simpa_repeat(n, quick_flag, frac_flag) -int n; /* equation space number to simplify */ -int quick_flag; /* "simplify quick" option, simpler fractions with no (x+1)^2 expansion */ -int frac_flag; /* "simplify fraction" option, simplify to the ratio of two polynomials */ +simpa_repeat(MathoMatic* mathomatic, int n, int quick_flag, int frac_flag) +//int n; /* equation space number to simplify */ +//int quick_flag; /* "simplify quick" option, simpler fractions with no (x+1)^2 expansion */ +//int frac_flag; /* "simplify fraction" option, simplify to the ratio of two polynomials */ { - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return; - simpa_repeat_side(lhs[n], &n_lhs[n], quick_flag, frac_flag); - if (n_rhs[n] > 0) { - simpa_repeat_side(rhs[n], &n_rhs[n], quick_flag, frac_flag); + simpa_repeat_side(mathomatic, mathomatic->lhs[n], &mathomatic->n_lhs[n], quick_flag, frac_flag); + if (mathomatic->n_rhs[n] > 0) { + simpa_repeat_side(mathomatic, mathomatic->rhs[n], &mathomatic->n_rhs[n], quick_flag, frac_flag); } } @@ -889,22 +874,22 @@ int frac_flag; /* "simplify fraction" option, simplify to the ratio of two polyn * Globals tes[], tlhs[], and trhs[] are wiped out. */ void -simple_frac_repeat_side(equation, np) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of the equation side */ +simple_frac_repeat_side(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of the equation side */ { if (*np <= 0) return; - simple_frac_side(equation, np); - if (repeat_flag) { + simple_frac_side(mathomatic, equation, np); + if (mathomatic->repeat_flag) { do { - n_tes = *np; - blt(tes, equation, n_tes * sizeof(token_type)); - simple_frac_side(equation, np); - } while (*np < n_tes); - if (*np != n_tes) { - *np = n_tes; - blt(equation, tes, n_tes * sizeof(token_type)); + mathomatic->n_tes = *np; + blt(mathomatic->tes, equation, mathomatic->n_tes * sizeof(token_type)); + simple_frac_side(mathomatic, equation, np); + } while (*np < mathomatic->n_tes); + if (*np != mathomatic->n_tes) { + *np = mathomatic->n_tes; + blt(equation, mathomatic->tes, mathomatic->n_tes * sizeof(token_type)); } } } @@ -915,9 +900,9 @@ int *np; /* pointer to length of the equation side */ * Return true if factor_times() did something. */ int -simp_loop(equation, np) -token_type *equation; /* pointer to the beginning of equation side to simplify */ -int *np; /* pointer to length of equation side */ +simp_loop(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to the beginning of equation side to simplify */ +//int *np; /* pointer to length of equation side */ { int i; int rv = false; @@ -926,14 +911,14 @@ int *np; /* pointer to length of equation side */ do { do { do { - elim_loop(equation, np); - } while (simp2_power(equation, np)); - i = factor_times(equation, np); + elim_loop(mathomatic, equation, np); + } while (simp2_power(mathomatic, equation, np)); + i = factor_times(mathomatic, equation, np); if (i) rv = true; } while (i); - } while (elim_sign(equation, np)); - } while (subtract_itself(equation, np)); + } while (elim_sign(mathomatic, equation, np)); + } while (subtract_itself(mathomatic, equation, np)); return rv; } @@ -949,9 +934,7 @@ int *np; /* pointer to length of equation side */ * Return true if equation side was modified. */ int -simp_pp(equation, np) -token_type *equation; -int *np; +simp_pp(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j, k; int ilevel, jlevel; @@ -961,7 +944,7 @@ int *np; for (i = 1; i < *np; i += 2) { #if DEBUG if (equation[i].kind != OPERATOR) { - error_bug("Bug found in simp_pp(), operators are misplaced."); + error_bug(mathomatic, "Bug found in simp_pp(), operators are misplaced."); } #endif if (equation[i].token.operatr != POWER) @@ -970,12 +953,12 @@ int *np; for (j = i + 2; j < *np; j += 2) { jlevel = equation[j].level; if (jlevel == ilevel - 1 && equation[j].token.operatr == POWER) { - if (!symb_flag && (equation[i-1].level != ilevel || equation[i-1].kind != CONSTANT || equation[i-1].token.constant < 0)) { + if (!mathomatic->symb_flag && (equation[i-1].level != ilevel || equation[i-1].kind != CONSTANT || equation[i-1].token.constant < 0)) { if (jlevel == equation[j+1].level && equation[j+1].kind == CONSTANT) { - f_to_fraction(equation[j+1].token.constant, &numerator, &denominator); + f_to_fraction(mathomatic, equation[j+1].token.constant, &numerator, &denominator); if (fmod(denominator, 2.0) == 0.0) { if ((i + 2) == j && equation[i+1].kind == CONSTANT) { - f_to_fraction(equation[i+1].token.constant, &numerator, &denominator); + f_to_fraction(mathomatic, equation[i+1].token.constant, &numerator, &denominator); if (fmod(numerator, 2.0) == 0.0) { break; } @@ -984,7 +967,7 @@ int *np; } } else { if ((i + 2) == j && equation[i+1].kind == CONSTANT) { - f_to_fraction(equation[i+1].token.constant, &numerator, &denominator); + f_to_fraction(mathomatic, equation[i+1].token.constant, &numerator, &denominator); if (fmod(numerator, 2.0) == 0.0) { break; } @@ -1015,9 +998,7 @@ int *np; * Return true if equation side was modified. */ int -integer_root_simp(equation, np) -token_type *equation; -int *np; +integer_root_simp(MathoMatic* mathomatic, token_type *equation, int *np) { int modified = false; int i, j; @@ -1027,7 +1008,7 @@ int *np; for (i = 1; (i + 3) < *np; i += 2) { #if DEBUG if (equation[i].kind != OPERATOR) { - error_bug("Bug found in integer_root_simp(), operators are misplaced."); + error_bug(mathomatic, "Bug found in integer_root_simp(), operators are misplaced."); } #endif if (equation[i].token.operatr == POWER) { @@ -1053,24 +1034,24 @@ int *np; if (errno) { continue; } - if (!factor_one(d2)) + if (!factor_one(mathomatic, d2)) continue; d1 = 1.0; - for (j = 0; j < uno; j++) { - if (unique[j] > 0.0) { - while (ucnt[j] >= denominator) { - d1 *= unique[j]; - ucnt[j] -= denominator; + for (j = 0; j < mathomatic->uno; j++) { + if (mathomatic->unique[j] > 0.0) { + while (mathomatic->ucnt[j] >= denominator) { + d1 *= mathomatic->unique[j]; + mathomatic->ucnt[j] -= denominator; } } } if (d1 == 1.0) continue; - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } equation[i+1].token.constant = 1.0; - equation[i-1].token.constant = multiply_out_unique(); + equation[i-1].token.constant = multiply_out_unique(mathomatic); for (j = i - 1; j < (i + 4); j++) { equation[j].level++; } @@ -1098,9 +1079,7 @@ int *np; * Return true if equation side was modified. */ int -simp_constant_power(equation, np) -token_type *equation; -int *np; +simp_constant_power(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j; int level; @@ -1113,7 +1092,7 @@ int *np; level = equation[i].level; if (equation[i-1].level != level || equation[i-1].kind != CONSTANT) continue; - if (equation[i-1].token.constant < 0 && !symb_flag) + if (equation[i-1].token.constant < 0 && !mathomatic->symb_flag) continue; if (equation[i+1].level != level + 1 || equation[i+1].kind != CONSTANT || equation[i+1].token.constant == 1.0) @@ -1125,8 +1104,8 @@ int *np; case TIMES: break; case DIVIDE: - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[j+2], &equation[j], (*np - j) * sizeof(token_type)); *np += 2; @@ -1152,9 +1131,7 @@ int *np; * Return true if equation side was modified. */ int -simp2_power(equation, np) -token_type *equation; -int *np; +simp2_power(MathoMatic* mathomatic, token_type *equation, int *np) { int i, i1, j, k; int level; @@ -1183,8 +1160,8 @@ int *np; case 0: case TIMES: case DIVIDE: - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } equation[k].token.constant = -equation[k].token.constant; for (k = i - 2;; k--) { @@ -1237,12 +1214,12 @@ double k1, k2; * Return true if equation side was modified. */ int -combine_constants(equation, np, iflag) -token_type *equation; /* pointer to the beginning of equation side */ -int *np; /* pointer to length of equation side */ -int iflag; /* produce imaginary numbers flag */ +combine_constants(MathoMatic* mathomatic, token_type *equation, int *np, int iflag) +//token_type *equation; /* pointer to the beginning of equation side */ +//int *np; /* pointer to length of equation side */ +//int iflag; /* produce imaginary numbers flag */ { - return const_recurse(equation, np, 0, 1, iflag); + return const_recurse(mathomatic, equation, np, 0, 1, iflag); } /* @@ -1252,11 +1229,11 @@ int iflag; /* produce imaginary numbers flag */ * domain_check must be set to false after this. */ int -calc(op1p, k1p, op2, k2) -int *op1p; /* Pointer to operator 1, which comes immediately before operand 1 if this operator exists. */ -double *k1p; /* Pointer to operand 1 and where to store the result of the calculation. */ -int op2; /* Operator 2; always exists and comes immediately before operand 2, and usually after operand 1. */ -double k2; /* Operand 2; ignored for unary operators. */ +calc(MathoMatic* mathomatic, int *op1p, double *k1p, int op2, double k2) +//int *op1p; /* Pointer to operator 1, which comes immediately before operand 1 if this operator exists. */ +//double *k1p; /* Pointer to operand 1 and where to store the result of the calculation. */ +//int op2; /* Operator 2; always exists and comes immediately before operand 2, and usually after operand 1. */ +//double k2; /* Operand 2; ignored for unary operators. */ { #if _REENTRANT int sign = 1; @@ -1264,7 +1241,7 @@ double k2; /* Operand 2; ignored for unary operators. */ int op1; double d, d1, d2; - domain_check = false; + mathomatic->domain_check = false; errno = 0; if (op1p) { op1 = *op1p; @@ -1278,7 +1255,7 @@ double k2; /* Operand 2; ignored for unary operators. */ d = -(*k1p); else d = *k1p; - d1 = fabs(d) * epsilon; + d1 = fabs(d) * mathomatic->epsilon; if (op2 == PLUS) { d += k2; } else { @@ -1306,28 +1283,28 @@ double k2; /* Operand 2; ignored for unary operators. */ *k1p *= k2; } else { if (op1 == DIVIDE) { - check_divide_by_zero(*k1p); + check_divide_by_zero(mathomatic, *k1p); *k1p = k2 / *k1p; *op1p = TIMES; } else if (op2 == DIVIDE) { - check_divide_by_zero(k2); + check_divide_by_zero(mathomatic, k2); *k1p = *k1p / k2; } } break; case IDIVIDE: - check_divide_by_zero(k2); + check_divide_by_zero(mathomatic, k2); modf(*k1p / k2, k1p); break; case MODULUS: if (k2 == 0) { - warning(_("Modulo 0 encountered.")); + warning(mathomatic, _("Modulo 0 encountered.")); } *k1p = fixed_fmod(*k1p, k2); - if (modulus_mode && *k1p < 0.0) { + if (mathomatic->modulus_mode && *k1p < 0.0) { *k1p += fabs(k2); /* make positive */ } - if (modulus_mode == 1 && k2 < 0.0 && *k1p > 0.0) { + if (mathomatic->modulus_mode == 1 && k2 < 0.0 && *k1p > 0.0) { *k1p += k2; /* make negative */ } /* modulus_mode == 0 result same sign as dividend, @@ -1339,19 +1316,19 @@ double k2; /* Operand 2; ignored for unary operators. */ /* it's probably imaginary; pow() will give a domain error, so skip these calculations */ break; } - domain_check = true; + mathomatic->domain_check = true; if (*k1p == 0.0 && k2 == 0.0) { - warning(_("0^0 encountered, might be considered indeterminate.")); + warning(mathomatic, _("0^0 encountered, might be considered indeterminate.")); d = 1.0; /* 0^0 = 1 */ } else if (*k1p == 0 && k2 < 0.0) { - warning(_("Divide by zero (0 raised to negative power).")); + warning(mathomatic, _("Divide by zero (0 raised to negative power).")); d = INFINITY; } else { d = pow(*k1p, k2); - if (preserve_surds && !approximate_roots) { - if (isfinite(k2) && fmod(k2, 1.0) != 0.0 && f_to_fraction(*k1p, &d1, &d2)) { - if (!f_to_fraction(d, &d1, &d2)) { - domain_check = false; + if (mathomatic->preserve_surds && !mathomatic->approximate_roots) { + if (isfinite(k2) && fmod(k2, 1.0) != 0.0 && f_to_fraction(mathomatic, *k1p, &d1, &d2)) { + if (!f_to_fraction(mathomatic, d, &d1, &d2)) { + mathomatic->domain_check = false; return false; } } @@ -1359,12 +1336,12 @@ double k2; /* Operand 2; ignored for unary operators. */ } #if 1 if (errno == ERANGE) { /* preserve overflowed powers rather than aborting with an error message */ - domain_check = false; + mathomatic->domain_check = false; return false; } #endif - check_err(); - if (domain_check) + check_err(mathomatic); + if (mathomatic->domain_check) *k1p = d; break; case FACTORIAL: @@ -1410,9 +1387,7 @@ double k2; /* Operand 2; ignored for unary operators. */ } static int -const_recurse(equation, np, loc, level, iflag) -token_type *equation; -int *np, loc, level, iflag; +const_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int iflag) { int loc1, old_loc; int const_count = 0; @@ -1430,7 +1405,7 @@ int *np, loc, level, iflag; return modified; } if (equation[loc].level > level) { - modified |= const_recurse(equation, np, loc, level + 1, iflag); + modified |= const_recurse(mathomatic, equation, np, loc, level + 1, iflag); for (; loc < *np && equation[loc].level > level; loc++) ; goto beginning; @@ -1444,18 +1419,18 @@ int *np, loc, level, iflag; op = equation[loc-1].token.operatr; d1 = equation[loc1].token.constant; d2 = equation[loc].token.constant; - if (calc((loc1 <= old_loc) ? NULL : &equation[loc1-1].token.operatr, &d1, op, d2)) { - if (op == POWER && !domain_check) { - if (!f_to_fraction(d2, &numerator, &denominator)) { /* if irrational power */ - if (!iflag || (preserve_surds && !approximate_roots)) + if (calc(mathomatic, (loc1 <= old_loc) ? NULL : &equation[loc1-1].token.operatr, &d1, op, d2)) { + if (op == POWER && !mathomatic->domain_check) { + if (!f_to_fraction(mathomatic, d2, &numerator, &denominator)) { /* if irrational power */ + if (!iflag || (mathomatic->preserve_surds && !mathomatic->approximate_roots)) return modified; cv.re = d1; cv.im = 0.0; p.re = d2; p.im = 0.0; cv = complex_pow(cv, p); - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[loc1+2], &equation[loc1], (*np - loc1) * sizeof(token_type)); *np += 2; @@ -1482,10 +1457,10 @@ int *np, loc, level, iflag; } errno = 0; d3 = pow(-d1, d2); - check_err(); + check_err(mathomatic); if (!always_positive(denominator)) { - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[loc1+2], &equation[loc1], (*np - loc1) * sizeof(token_type)); *np += 2; @@ -1515,8 +1490,8 @@ int *np, loc, level, iflag; } if (!iflag) return modified; - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[loc1+2], &equation[loc1], (*np - loc1) * sizeof(token_type)); *np += 2; @@ -1564,13 +1539,13 @@ int *np, loc, level, iflag; } else { equation[loc1].token.constant = d1; modified = true; - domain_check = false; + mathomatic->domain_check = false; blt(&equation[loc-1], &equation[loc+1], (*np - (loc + 1)) * sizeof(token_type)); *np -= 2; loc -= 2; } } else { - domain_check = false; + mathomatic->domain_check = false; } } } @@ -1582,9 +1557,9 @@ int *np, loc, level, iflag; * Return true if equation side was significantly modified. */ int -elim_k(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +elim_k(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { token_type *p1, *p2, *p3, *p4; token_type *ep; /* end pointer */ @@ -1702,7 +1677,7 @@ int *np; /* pointer to length of equation side */ modified = true; continue; } - if (fabs(p2->token.constant - 1.0) <= epsilon) { + if (fabs(p2->token.constant - 1.0) <= mathomatic->epsilon) { /* Replace 1*x with x. */ blt(p2, p1 + 1, (char *) ep - (char *) (p1 + 1)); *np -= 2; @@ -1751,8 +1726,8 @@ int *np; /* pointer to length of equation side */ p2 = p1 + 1; if (p2->level == level && p2->kind == CONSTANT) { /* Replace division by a constant with times its reciprocal. */ - f_to_fraction(p2->token.constant, &numerator, &denominator); - check_divide_by_zero(numerator); + f_to_fraction(mathomatic, p2->token.constant, &numerator, &denominator); + check_divide_by_zero(mathomatic, numerator); p2->token.constant = denominator / numerator; p1->token.operatr = TIMES; continue; @@ -1779,12 +1754,12 @@ int *np; /* pointer to length of equation side */ if (p1->token.operatr == MODULUS) { if ((p1 + 1)->level == level && (p1 + 1)->kind == CONSTANT) { d = fabs((p1 + 1)->token.constant); - if (d > epsilon && fmod(1.0 / d, 1.0) == 0.0) { + if (d > mathomatic->epsilon && fmod(1.0 / d, 1.0) == 0.0) { for (p2 = p1 - 1; p2 > equation; p2--) { if ((p2 - 1)->level < level) break; } - if (is_integer_expr(p2, p1 - p2)) { + if (is_integer_expr(mathomatic, p2, p1 - p2)) { blt(p2, p1 + 1, (char *) ep - (char *) (p1 + 1)); *np -= (p1 + 1) - p2; p2->token.constant = 0.0; @@ -1829,7 +1804,7 @@ int *np; /* pointer to length of equation side */ modified = true; continue; } - if (fabs(p2->token.constant - 1.0) <= epsilon) { + if (fabs(p2->token.constant - 1.0) <= mathomatic->epsilon) { /* Replace x^1 with x. */ blt(p1, p1 + 2, (char *) ep - (char *) (p1 + 2)); *np -= 2; @@ -1853,12 +1828,12 @@ int *np; /* pointer to length of equation side */ * Otherwise return false. */ int -se_compare(p1, n1, p2, n2, diff_signp) -token_type *p1; /* first sub-expression pointer */ -int n1; /* first sub-expression length */ -token_type *p2; /* second sub-expression pointer */ -int n2; /* second sub-expression length */ -int *diff_signp; /* different sign flag pointer */ +se_compare(MathoMatic* mathomatic, token_type *p1, int n1, token_type *p2, int n2, int *diff_signp) +//token_type *p1; /* first sub-expression pointer */ +//int n1; /* first sub-expression length */ +//token_type *p2; /* second sub-expression pointer */ +//int n2; /* second sub-expression length */ +//int *diff_signp; /* different sign flag pointer */ { int l1, l2; int rv; @@ -1866,7 +1841,7 @@ int *diff_signp; /* different sign flag pointer */ int rv_should_be_false = false; if (n1 < 1 || n2 < 1 || (n1 & 1) != 1 || (n2 & 1) != 1 || diff_signp == NULL || p1 == NULL || p2 == NULL) { - error_bug("Programming error in call to se_compare()."); + error_bug(mathomatic, "Programming error in call to se_compare()."); } #endif if (((n1 > n2) ? ((n1 + 1) / (n2 + 1)) : ((n2 + 1) / (n1 + 1))) > 3) { @@ -1879,12 +1854,12 @@ int *diff_signp; /* different sign flag pointer */ #endif } /* Find the proper ground levels of parentheses for the two sub-expressions: */ - l1 = min_level(p1, n1); - l2 = min_level(p2, n2); - rv = compare_recurse(p1, n1, l1, p2, n2, l2, diff_signp); + l1 = min_level(mathomatic, p1, n1); + l2 = min_level(mathomatic, p2, n2); + rv = compare_recurse(mathomatic, p1, n1, l1, p2, n2, l2, diff_signp); #if DEBUG if (rv && rv_should_be_false) { - error_bug("Expression compare optimization failed in se_compare()."); + error_bug(mathomatic, "Expression compare optimization failed in se_compare()."); } #endif return rv; @@ -1896,13 +1871,9 @@ int *diff_signp; /* different sign flag pointer */ * Optimizing or streamlining this would greatly speed things up. */ static int -compare_recurse(p1, n1, l1, p2, n2, l2, diff_signp) -token_type *p1; -int n1, l1; -token_type *p2; -int n2, l2, *diff_signp; +compare_recurse(MathoMatic* mathomatic, token_type *p1, int n1, int l1, token_type *p2, int n2, int l2, int *diff_signp) { -#define compare_epsilon epsilon +#define compare_epsilon mathomatic->epsilon token_type *pv1, *ep1, *ep2; int i, j; @@ -1922,7 +1893,7 @@ int n2, l2, *diff_signp; } switch (p1->kind) { case VARIABLE: - if (sign_cmp_flag && (p1->token.variable & VAR_MASK) == SIGN) { + if (mathomatic->sign_cmp_flag && (p1->token.variable & VAR_MASK) == SIGN) { return((p2->token.variable & VAR_MASK) == SIGN); } else { return(p1->token.variable == p2->token.variable); @@ -1947,14 +1918,14 @@ int n2, l2, *diff_signp; } break; case OPERATOR: - error_bug("Programming error in call to compare_recurse()."); + error_bug(mathomatic, "Programming error in call to compare_recurse()."); break; } return false; } #if DEBUG if (n1 < 1 || n2 < 1 || (n1 & 1) != 1 || (n2 & 1) != 1) { - error_bug("Programming error in call to compare_recurse()."); + error_bug(mathomatic, "Programming error in call to compare_recurse()."); } #endif ep1 = &p1[n1]; @@ -1999,7 +1970,7 @@ int n2, l2, *diff_signp; if (diff_op) { if (p1->kind == CONSTANT && p1->level == l1 && op1 == TIMES) { if (fabs(fabs(p1->token.constant) - 1.0) <= compare_epsilon) { - if (!compare_recurse(p1 + 2, n1 - 2, min_level(p1 + 2, n1 - 2), p2, n2, l2, diff_signp)) { + if (!compare_recurse(mathomatic, p1 + 2, n1 - 2, min_level(mathomatic, p1 + 2, n1 - 2), p2, n2, l2, diff_signp)) { return false; } if (p1->token.constant < 0.0) { @@ -2010,7 +1981,7 @@ int n2, l2, *diff_signp; } if (p2->kind == CONSTANT && p2->level == l2 && op2 == TIMES) { if (fabs(fabs(p2->token.constant) - 1.0) <= compare_epsilon) { - if (!compare_recurse(p1, n1, l1, p2 + 2, n2 - 2, min_level(p2 + 2, n2 - 2), diff_signp)) { + if (!compare_recurse(mathomatic, p1, n1, l1, p2 + 2, n2 - 2, min_level(mathomatic, p2 + 2, n2 - 2), diff_signp)) { return false; } if (p2->token.constant < 0.0) { @@ -2030,7 +2001,7 @@ int n2, l2, *diff_signp; opa2[oc2] = pv1 + 1; used[oc2] = false; if (++oc2 >= ARR_CNT(opa2)) { - debug_string(1, "Expression too big to compare, because MAX_COMPARE_TERMS exceeded."); + debug_string(mathomatic, 1, "Expression too big to compare, because MAX_COMPARE_TERMS exceeded."); return false; } } @@ -2073,7 +2044,7 @@ int n2, l2, *diff_signp; return false; break; } - if (compare_recurse(pv1, len, (pv1->level <= l1) ? l1 : (l1 + 1), + if (compare_recurse(mathomatic, pv1, len, (pv1->level <= l1) ? l1 : (l1 + 1), opa2[i], (opa2[i+1] - opa2[i]) - 1, (opa2[i]->level <= l2) ? l2 : (l2 + 1), &j)) { switch (op1) { case 0: @@ -2137,9 +2108,7 @@ Also (x-y)^5 should compare identical with different sign to (y-x)^5. * Return true if equation side was modified. */ int -elim_sign(equation, np) -token_type *equation; -int *np; +elim_sign(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j, k; int level; @@ -2151,7 +2120,7 @@ int *np; for (i = 1; i < *np; i += 2) { #if DEBUG if (equation[i].kind != OPERATOR) { - error_bug("Error in elim_sign()."); + error_bug(mathomatic, "Error in elim_sign()."); } #endif level = equation[i].level; @@ -2166,10 +2135,10 @@ int *np; ; if (k <= i + 2) continue; - if (!is_integer_expr(&equation[i+3], k - (i + 3))) + if (!is_integer_expr(mathomatic, &equation[i+3], k - (i + 3))) continue; } - f_to_fraction(equation[i+1].token.constant, &numerator, &denominator); + f_to_fraction(mathomatic, equation[i+1].token.constant, &numerator, &denominator); if (always_positive(numerator)) { if (equation[i-1].level == level && equation[i-1].kind == VARIABLE @@ -2250,9 +2219,7 @@ int *np; * Return true if equation side was modified. */ int -div_imaginary(equation, np) -token_type *equation; -int *np; +div_imaginary(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j, k; int n; @@ -2266,7 +2233,7 @@ int *np; for (i = 1; i < *np; i += 2) { #if DEBUG if (equation[i].kind != OPERATOR) { - error_bug("Error in div_imaginary()."); + error_bug(mathomatic, "Error in div_imaginary()."); } #endif if (equation[i].token.operatr == DIVIDE) { @@ -2276,8 +2243,8 @@ int *np; if (equation[i+1].level == level && equation[i+1].kind == VARIABLE && equation[i+1].token.variable == IMAGINARY) { - if (*np + 2 > n_tokens) { - error_huge(); + if (*np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[i+2], &equation[i], (*np - i) * sizeof(token_type)); *np += 2; @@ -2338,41 +2305,41 @@ int *np; } } } - if ((eloc - (i + 1)) + 5 + (eiloc - biloc) + *np + 2 > n_tokens) - error_huge(); + if ((eloc - (i + 1)) + 5 + (eiloc - biloc) + *np + 2 > mathomatic->n_tokens) + error_huge(mathomatic); n = eloc - (i + 1); - blt(scratch, &equation[i+1], n * sizeof(token_type)); - scratch[iloc-(i+1)].kind = CONSTANT; - scratch[iloc-(i+1)].token.constant = 0.0; + blt(mathomatic->scratch, &equation[i+1], n * sizeof(token_type)); + mathomatic->scratch[iloc-(i+1)].kind = CONSTANT; + mathomatic->scratch[iloc-(i+1)].token.constant = 0.0; for (j = 0; j < n; j++) - scratch[j].level += 2; - scratch[n].level = level + 2; - scratch[n].kind = OPERATOR; - scratch[n].token.operatr = POWER; + mathomatic->scratch[j].level += 2; + mathomatic->scratch[n].level = level + 2; + mathomatic->scratch[n].kind = OPERATOR; + mathomatic->scratch[n].token.operatr = POWER; n++; - scratch[n].level = level + 2; - scratch[n].kind = CONSTANT; - scratch[n].token.constant = 2.0; + mathomatic->scratch[n].level = level + 2; + mathomatic->scratch[n].kind = CONSTANT; + mathomatic->scratch[n].token.constant = 2.0; n++; - scratch[n].level = level + 1; - scratch[n].kind = OPERATOR; - scratch[n].token.operatr = PLUS; + mathomatic->scratch[n].level = level + 1; + mathomatic->scratch[n].kind = OPERATOR; + mathomatic->scratch[n].token.operatr = PLUS; n++; - blt(&scratch[n], &equation[biloc], (eiloc - biloc) * sizeof(token_type)); + blt(&mathomatic->scratch[n], &equation[biloc], (eiloc - biloc) * sizeof(token_type)); j = n; n += (eiloc - biloc); for (k = j; k < n; k++) - scratch[k].level += 2; - scratch[n].level = level + 2; - scratch[n].kind = OPERATOR; - scratch[n].token.operatr = POWER; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[n].level = level + 2; + mathomatic->scratch[n].kind = OPERATOR; + mathomatic->scratch[n].token.operatr = POWER; n++; - scratch[n].level = level + 2; - scratch[n].kind = CONSTANT; - scratch[n].token.constant = 2.0; + mathomatic->scratch[n].level = level + 2; + mathomatic->scratch[n].kind = CONSTANT; + mathomatic->scratch[n].token.constant = 2.0; n++; - scratch[j+(iloc-biloc)].kind = CONSTANT; - scratch[j+(iloc-biloc)].token.constant = 1.0; + mathomatic->scratch[j+(iloc-biloc)].kind = CONSTANT; + mathomatic->scratch[j+(iloc-biloc)].token.constant = 1.0; blt(&equation[iloc+2], &equation[iloc], (*np - iloc) * sizeof(token_type)); *np += 2; ilevel++; @@ -2387,7 +2354,7 @@ int *np; equation[iloc].level = ilevel; blt(&equation[i+1+n], &equation[i], (*np - i) * sizeof(token_type)); *np += n + 1; - blt(&equation[i+1], scratch, n * sizeof(token_type)); + blt(&equation[i+1], mathomatic->scratch, n * sizeof(token_type)); i += n + 1; equation[i].token.operatr = TIMES; modified = true; @@ -2405,19 +2372,13 @@ int *np; * This routine also checks the validity of the equation side. */ int -reorder(equation, np) -token_type *equation; -int *np; +reorder(MathoMatic* mathomatic, token_type *equation, int *np) { - return(order_recurse(equation, np, 0, 1)); + return(order_recurse(mathomatic, equation, np, 0, 1)); } static void -swap(equation, np, level, i1, i2) -token_type *equation; -int *np; -int level; -int i1, i2; +swap(MathoMatic* mathomatic, token_type *equation, int *np, int level, int i1, int i2) { int e1, e2; int n1, n2; @@ -2432,12 +2393,12 @@ int i1, i2; } n1 = e1 - i1; n2 = e2 - i2; - blt(scratch, &equation[i1], (e2 - i1) * sizeof(token_type)); + blt(mathomatic->scratch, &equation[i1], (e2 - i1) * sizeof(token_type)); if ((i1 + n2) != e1) { blt(&equation[i1+n2], &equation[e1], (i2 - e1) * sizeof(token_type)); } - blt(&equation[i1], &scratch[i2-i1], n2 * sizeof(token_type)); - blt(&equation[e2-n1], scratch, n1 * sizeof(token_type)); + blt(&equation[i1], &mathomatic->scratch[i2-i1], n2 * sizeof(token_type)); + blt(&equation[e2-n1], mathomatic->scratch, n1 * sizeof(token_type)); } /* @@ -2445,9 +2406,7 @@ int i1, i2; * which starts at "loc" in an equation side. */ static int -order_recurse(equation, np, loc, level) -token_type *equation; -int *np, loc, level; +order_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level) { int i, j, k, n; int op = 0; @@ -2465,7 +2424,7 @@ int *np, loc, level; break; } if (equation[i].level > level) { - modified |= order_recurse(equation, np, i, level + 1); + modified |= order_recurse(mathomatic, equation, np, i, level + 1); i++; for (; i < *np && equation[i].level > level; i++) ; @@ -2511,7 +2470,7 @@ int *np, loc, level; && (equation[loc+1].token.operatr == TIMES || equation[loc+1].token.operatr == DIVIDE))) { for (j = loc + 1; j < i; j += 2) { if (equation[j].level == level && equation[j].token.operatr == PLUS) { - swap(equation, np, level, loc, j + 1); + swap(mathomatic, equation, np, level, loc, j + 1); modified = true; break; } @@ -2532,9 +2491,9 @@ int *np, loc, level; for (n = k + 2; n < i && equation[n].level > level; n += 2) ; n -= k; - blt(scratch, &equation[k], n * sizeof(token_type)); + blt(mathomatic->scratch, &equation[k], n * sizeof(token_type)); blt(&equation[j+n], &equation[j], (k - j) * sizeof(token_type)); - blt(&equation[j], scratch, n * sizeof(token_type)); + blt(&equation[j], mathomatic->scratch, n * sizeof(token_type)); j += n; k += n; modified = true; @@ -2546,7 +2505,7 @@ int *np, loc, level; } return modified; corrupt: - error_bug("Internal representation of expression is corrupt!"); + error_bug(mathomatic, "Internal representation of expression is corrupt!"); return modified; /* not reached */ } @@ -2559,9 +2518,7 @@ int *np, loc, level; * Unfactoring needs to be done immediately, if this returns true. */ int -rationalize(equation, np) -token_type *equation; -int *np; +rationalize(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j, k; int i1, k1; @@ -2577,7 +2534,7 @@ int *np; break; #if DEBUG if (equation[i].kind != OPERATOR) { - error_bug("Bug in rationalize()."); + error_bug(mathomatic, "Bug in rationalize()."); } #endif if (equation[i].token.operatr == DIVIDE) { @@ -2648,21 +2605,21 @@ int *np; } neg_one_loc = i1 + 1; k = i1 - i; - blt(scratch, &equation[i+1], k * sizeof(token_type)); - scratch[k].level = div_level + 2; - scratch[k].kind = CONSTANT; - scratch[k].token.constant = -1.0; + blt(mathomatic->scratch, &equation[i+1], k * sizeof(token_type)); + mathomatic->scratch[k].level = div_level + 2; + mathomatic->scratch[k].kind = CONSTANT; + mathomatic->scratch[k].token.constant = -1.0; k++; - scratch[k].level = div_level + 2; - scratch[k].kind = OPERATOR; - scratch[k].token.operatr = TIMES; + mathomatic->scratch[k].level = div_level + 2; + mathomatic->scratch[k].kind = OPERATOR; + mathomatic->scratch[k].token.operatr = TIMES; k++; - blt(&scratch[k], &equation[neg_one_loc], (end_loc - neg_one_loc) * sizeof(token_type)); + blt(&mathomatic->scratch[k], &equation[neg_one_loc], (end_loc - neg_one_loc) * sizeof(token_type)); for (k1 = 0; k1 < (j - neg_one_loc); k1++, k++) - scratch[k].level++; + mathomatic->scratch[k].level++; k = end_loc - (i + 1) + 2; - if (*np + 2 * (k + 1) > n_tokens) { - error_huge(); + if (*np + 2 * (k + 1) > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[end_loc+(2*(k+1))], &equation[end_loc], (*np - end_loc) * sizeof(token_type)); *np += 2 * (k + 1); @@ -2671,16 +2628,16 @@ int *np; equation[k1].kind = OPERATOR; equation[k1].token.operatr = TIMES; k1++; - blt(&equation[k1], scratch, k * sizeof(token_type)); + blt(&equation[k1], mathomatic->scratch, k * sizeof(token_type)); k1 += k; equation[k1].level = div_level; equation[k1].kind = OPERATOR; equation[k1].token.operatr = DIVIDE; k1++; - blt(&equation[k1], scratch, k * sizeof(token_type)); + blt(&equation[k1], mathomatic->scratch, k * sizeof(token_type)); k1 += k; - debug_string(1, "Square roots in denominator rationalized:"); - side_debug(1, &equation[i+1], k1 - (i + 1)); + debug_string(mathomatic, 1, "Square roots in denominator rationalized:"); + side_debug(mathomatic, 1, &equation[i+1], k1 - (i + 1)); i = k1; modified = true; goto be_thorough; diff --git a/solve.c b/solve.c index c142a9d..48154c9 100644 --- a/solve.c +++ b/solve.c @@ -26,15 +26,11 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #define MAX_RAISE_POWER 20 /* Maximum number of times to increase power in solve function. */ -static int increase(double d, long v); -static int poly_solve(long v); -static int g_of_f(int op, token_type *operandp, token_type *side1p, int *side1np, token_type *side2p, int *side2np); -static int flip(token_type *side1p, int *side1np, token_type *side2p, int *side2np); +static int increase(MathoMatic* mathomatic, double d, long v); +static int poly_solve(MathoMatic* mathomatic, long v); +static int g_of_f(MathoMatic* mathomatic, int op, token_type *operandp, token_type *side1p, int *side1np, token_type *side2p, int *side2np); +static int flip(MathoMatic* mathomatic, token_type *side1p, int *side1np, token_type *side2p, int *side2np); -static int repeat_count; -static int prev_n1, prev_n2; - -static int last_int_var = 0; /* * Solve using equation spaces. Almost always displays a message. @@ -44,50 +40,50 @@ static int last_int_var = 0; * preferably with "simplify quick". Just plain "simplify" expands too much sometimes. */ int -solve_espace(want, have) -int want; /* equation number containing what to solve for */ -int have; /* equation number to solve */ +solve_espace(MathoMatic* mathomatic, int want, int have) +//int want; /* equation number containing what to solve for */ +//int have; /* equation number to solve */ { int i; jmp_buf save_save; int rv = 0; /* solve_sub() return value */ - if (want == have || !equation_space_is_equation(have)) { + if (want == have || !equation_space_is_equation(mathomatic, have)) { #if LIBRARY || !HELP - error(_("Solving requires an equation.")); + error(mathomatic, _("Solving requires an equation.")); #else - error(_("Please enter an equation to solve, or a command like \"help\".")); + error(mathomatic, _("Please enter an equation to solve, or a command like \"help\".")); #endif printf(_("Solve failed for equation space #%d.\n"), have + 1); return false; } - blt(save_save, jmp_save, sizeof(jmp_save)); - if ((i = setjmp(jmp_save)) != 0) { /* trap errors */ - clean_up(); + blt(save_save, mathomatic->jmp_save, sizeof(mathomatic->jmp_save)); + if ((i = setjmp(mathomatic->jmp_save)) != 0) { /* trap errors */ + clean_up(mathomatic); if (i == 14) { - error(_("Expression too large.")); + error(mathomatic, _("Expression too large.")); } rv = 0; } else { - if (n_lhs[want]) { - if (n_rhs[want]) { + if (mathomatic->n_lhs[want]) { + if (mathomatic->n_rhs[want]) { /* Something in the LHS and RHS of equation number "want". */ - error(_("Can only solve for a single variable or for 0, possibly raised to a power.")); + error(mathomatic, _("Can only solve for a single variable or for 0, possibly raised to a power.")); rv = 0; } else { /* Normal solve: */ - rv = solve_sub(lhs[want], n_lhs[want], lhs[have], &n_lhs[have], rhs[have], &n_rhs[have]); + rv = solve_sub(mathomatic, mathomatic->lhs[want], mathomatic->n_lhs[want], mathomatic->lhs[have], &mathomatic->n_lhs[have], mathomatic->rhs[have], &mathomatic->n_rhs[have]); } } else { /* Solve variable was preceded by an equals sign, solve using reversed equation sides: */ - rv = solve_sub(rhs[want], n_rhs[want], rhs[have], &n_rhs[have], lhs[have], &n_lhs[have]); + rv = solve_sub(mathomatic, mathomatic->rhs[want], mathomatic->n_rhs[want], mathomatic->rhs[have], &mathomatic->n_rhs[have], mathomatic->lhs[have], &mathomatic->n_lhs[have]); } } - blt(jmp_save, save_save, sizeof(jmp_save)); + blt(mathomatic->jmp_save, save_save, sizeof(mathomatic->jmp_save)); if (rv <= 0) { printf(_("Solve failed for equation space #%d.\n"), have + 1); } else { - debug_string(0, _("Solve successful:")); + debug_string(mathomatic, 0, _("Solve successful:")); } return(rv > 0); } @@ -109,13 +105,13 @@ int have; /* equation number to solve */ * Returns -2 if unsolvable in all realms. */ int -solve_sub(wantp, wantn, leftp, leftnp, rightp, rightnp) -token_type *wantp; /* expression to solve for */ -int wantn; /* length of expression to solve for */ -token_type *leftp; /* LHS of equation */ -int *leftnp; /* pointer to length of LHS */ -token_type *rightp; /* RHS of equation */ -int *rightnp; /* pointer to length of RHS */ +solve_sub(MathoMatic* mathomatic, token_type *wantp, int wantn, token_type *leftp, int *leftnp, token_type *rightp, int *rightnp) +//token_type *wantp; /* expression to solve for */ +//int wantn; /* length of expression to solve for */ +//token_type *leftp; /* LHS of equation */ +//int *leftnp; /* pointer to length of LHS */ +//token_type *rightp; /* RHS of equation */ +//int *rightnp; /* pointer to length of RHS */ { int i, j; int found, found_count; @@ -134,14 +130,14 @@ int *rightnp; /* pointer to length of RHS */ double numerator, denominator; int success = 1; - repeat_count = 0; - prev_n1 = 0; - prev_n2 = 0; + mathomatic->repeat_count = 0; + mathomatic->prev_n1 = 0; + mathomatic->prev_n2 = 0; if (*leftnp <= 0 || *rightnp <= 0) { #if LIBRARY || !HELP - error(_("Solving requires an equation.")); + error(mathomatic, _("Solving requires an equation.")); #else - error(_("Please enter an equation to solve, or a command like \"help\".")); + error(mathomatic, _("Please enter an equation to solve, or a command like \"help\".")); #endif return false; } @@ -156,87 +152,87 @@ int *rightnp; /* pointer to length of RHS */ if (wantp[0].kind == VARIABLE) { v = wantp[0].token.variable; } - if (solve_sub(&zero_token, 1, rightp, rightnp, leftp, leftnp) <= 0) + if (solve_sub(mathomatic, &mathomatic->zero_token, 1, rightp, rightnp, leftp, leftnp) <= 0) return false; - n_tlhs = *leftnp; - blt(tlhs, leftp, n_tlhs * sizeof(*leftp)); - n_trhs = *rightnp; - blt(trhs, rightp, n_trhs * sizeof(*rightp)); - uf_simp(tlhs, &n_tlhs); - if (increase(1 / wantp[2].token.constant, v) != true) { - error(_("Unable to isolate root.")); + mathomatic->n_tlhs = *leftnp; + blt(mathomatic->tlhs, leftp, mathomatic->n_tlhs * sizeof(*leftp)); + mathomatic->n_trhs = *rightnp; + blt(mathomatic->trhs, rightp, mathomatic->n_trhs * sizeof(*rightp)); + uf_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + if (increase(mathomatic, 1 / wantp[2].token.constant, v) != true) { + error(mathomatic, _("Unable to isolate root.")); return false; } - list_tdebug(2); - mid_simp_side(tlhs, &n_tlhs); - simp_loop(trhs, &n_trhs); - uf_simp(trhs, &n_trhs); - list_tdebug(1); + list_tdebug(mathomatic, 2); + mid_simp_side(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + simp_loop(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + uf_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + list_tdebug(mathomatic, 1); - blt(leftp, tlhs, n_tlhs * sizeof(*leftp)); - *leftnp = n_tlhs; - blt(rightp, trhs, n_trhs * sizeof(*rightp)); - *rightnp = n_trhs; + blt(leftp, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(*leftp)); + *leftnp = mathomatic->n_tlhs; + blt(rightp, mathomatic->trhs, mathomatic->n_trhs * sizeof(*rightp)); + *rightnp = mathomatic->n_trhs; return true; } - error(_("Can only solve for a single variable or for 0, possibly raised to a power.")); + error(mathomatic, _("Can only solve for a single variable or for 0, possibly raised to a power.")); return false; } /* copy the equation to temporary storage where it will be manipulated */ - n_tlhs = *leftnp; - blt(tlhs, leftp, n_tlhs * sizeof(*leftp)); - n_trhs = *rightnp; - blt(trhs, rightp, n_trhs * sizeof(*rightp)); + mathomatic->n_tlhs = *leftnp; + blt(mathomatic->tlhs, leftp, mathomatic->n_tlhs * sizeof(*leftp)); + mathomatic->n_trhs = *rightnp; + blt(mathomatic->trhs, rightp, mathomatic->n_trhs * sizeof(*rightp)); if (wantp->kind == VARIABLE) { v = wantp->token.variable; - if (!found_var(trhs, n_trhs, v) && !found_var(tlhs, n_tlhs, v)) { + if (!found_var(mathomatic->trhs, mathomatic->n_trhs, v) && !found_var(mathomatic->tlhs, mathomatic->n_tlhs, v)) { /* variable v is 0 or not found */ - error(_("Solve variable not found.")); + error(mathomatic, _("Solve variable not found.")); return false; } zsolve = false; } else { v = 0; if (wantp->kind != CONSTANT || wantp->token.constant != 0.0) { - error(_("Can only solve for a single variable or for 0, possibly raised to a power.")); + error(mathomatic, _("Can only solve for a single variable or for 0, possibly raised to a power.")); return false; } - debug_string(1, _("Solving for zero...")); + debug_string(mathomatic, 1, _("Solving for zero...")); zsolve = true; } - uf_power(tlhs, &n_tlhs); - uf_power(trhs, &n_trhs); + uf_power(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + uf_power(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); simp_again: /* Make sure equation is a bit simplified. */ - list_tdebug(2); - simps_side(tlhs, &n_tlhs, zsolve); + list_tdebug(mathomatic, 2); + simps_side(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, zsolve); if (uf_flag) { - simp_loop(trhs, &n_trhs); - uf_simp(trhs, &n_trhs); - factorv(trhs, &n_trhs, v); + simp_loop(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + uf_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + factorv(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, v); } else { - simps_side(trhs, &n_trhs, zsolve); + simps_side(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, zsolve); } - list_tdebug(1); + list_tdebug(mathomatic, 1); no_simp: /* First selectively move sub-expressions from the RHS to the LHS. */ op = 0; - ep = &trhs[n_trhs]; + ep = &mathomatic->trhs[mathomatic->n_trhs]; if (zsolve) { - for (b1 = p1 = trhs; p1 < ep; p1++) { + for (b1 = p1 = mathomatic->trhs; p1 < ep; p1++) { if (p1->level == 1 && p1->kind == OPERATOR) { op = p1->token.operatr; b1 = p1 + 1; if (op == DIVIDE) { - if (!g_of_f(op, b1, trhs, &n_trhs, tlhs, &n_tlhs)) + if (!g_of_f(mathomatic, op, b1, mathomatic->trhs, &mathomatic->n_trhs, mathomatic->tlhs, &mathomatic->n_tlhs)) return false; goto simp_again; } } } } else { - for (b1 = p1 = trhs; p1 < ep; p1++) { + for (b1 = p1 = mathomatic->trhs; p1 < ep; p1++) { if (p1->kind == VARIABLE && v == p1->token.variable) { if (op == 0) { for (p1++;; p1++) { @@ -266,13 +262,13 @@ int *rightnp; /* pointer to length of RHS */ case TIMES: case DIVIDE: case POWER: - b1 = trhs; + b1 = mathomatic->trhs; op = PLUS; for (p1 = b1; p1 < ep; p1++) p1->level++; break; } - if (!g_of_f(op, b1, trhs, &n_trhs, tlhs, &n_tlhs)) + if (!g_of_f(mathomatic, op, b1, mathomatic->trhs, &mathomatic->n_trhs, mathomatic->tlhs, &mathomatic->n_tlhs)) return false; goto simp_again; } else if (p1->level == 1 && p1->kind == OPERATOR) { @@ -282,33 +278,33 @@ int *rightnp; /* pointer to length of RHS */ } } if (uf_flag) { - simps_side(trhs, &n_trhs, zsolve); + simps_side(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, zsolve); } left_again: worked = true; uf_flag = false; see_work: - if (found_var(trhs, n_trhs, v)) { + if (found_var(mathomatic->trhs, mathomatic->n_trhs, v)) { /* solve variable in RHS */ - debug_string(1, _("Solve variable moved back to RHS, quitting solve routine.")); + debug_string(mathomatic, 1, _("Solve variable moved back to RHS, quitting solve routine.")); return false; } /* See if we have solved the equation. */ - if (se_compare(wantp, wantn, tlhs, n_tlhs, &diff_sign) && !diff_sign) { + if (se_compare(mathomatic, wantp, wantn, mathomatic->tlhs, mathomatic->n_tlhs, &diff_sign) && !diff_sign) { if (zsolve) { - debug_string(1, "Simplifying the zero solve until there are no more divides:"); + debug_string(mathomatic, 1, "Simplifying the zero solve until there are no more divides:"); zero_simp: - list_tdebug(2); - uf_power(trhs, &n_trhs); + list_tdebug(mathomatic, 2); + uf_power(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); do { do { - simp_ssub(trhs, &n_trhs, 0L, 0.0, false, true, 4); - } while (uf_power(trhs, &n_trhs)); - } while (super_factor(trhs, &n_trhs, 1)); - list_tdebug(1); - ep = &trhs[n_trhs]; + simp_ssub(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, 0L, 0.0, false, true, 4); + } while (uf_power(mathomatic, mathomatic->trhs, &mathomatic->n_trhs)); + } while (super_factor(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, 1)); + list_tdebug(mathomatic, 1); + ep = &mathomatic->trhs[mathomatic->n_trhs]; op = 0; - for (p1 = trhs + 1; p1 < ep; p1 += 2) { + for (p1 = mathomatic->trhs + 1; p1 < ep; p1 += 2) { if (p1->level == 1) { op = p1->token.operatr; if (op == DIVIDE) { @@ -321,13 +317,13 @@ int *rightnp; /* pointer to length of RHS */ } switch (op) { case TIMES: - for (p1 = trhs; p1 < ep;) { + for (p1 = mathomatic->trhs; p1 < ep;) { b1 = p1; for (;; p1++) { if (p1 >= ep || (p1->kind == OPERATOR && p1->level == 1)) { blt(b1 + 1, p1, (char *) ep - (char *) p1); - n_trhs -= p1 - (b1 + 1); - *b1 = one_token; + mathomatic->n_trhs -= p1 - (b1 + 1); + *b1 = mathomatic->one_token; goto zero_simp; } if (p1->kind != CONSTANT && p1->kind != OPERATOR @@ -340,7 +336,7 @@ int *rightnp; /* pointer to length of RHS */ ; #if DEBUG if (p1 != ep && (p1->kind != OPERATOR || p1->token.operatr != TIMES)) { - error_bug("Operator mix up in zero_simp."); + error_bug(mathomatic, "Operator mix up in zero_simp."); } #endif if ((p1 - 2) > b1) { @@ -363,21 +359,21 @@ int *rightnp; /* pointer to length of RHS */ /* if ((p1 - 2) <= trhs || (p1 - 2)->token.operatr != POWER || (p1 - 2)->level != 2) { */ p1++; if (p1->level == 1 && p1->kind == CONSTANT && p1->token.constant > 0.0) { - n_trhs -= 2; + mathomatic->n_trhs -= 2; goto zero_simp; } /* } */ break; } - debug_string(1, _("Solve for zero completed:")); + debug_string(mathomatic, 1, _("Solve for zero completed:")); } else { - debug_string(1, _("Solve completed:")); + debug_string(mathomatic, 1, _("Solve completed:")); } - list_tdebug(1); - blt(leftp, tlhs, n_tlhs * sizeof(*leftp)); - *leftnp = n_tlhs; - blt(rightp, trhs, n_trhs * sizeof(*rightp)); - *rightnp = n_trhs; + list_tdebug(mathomatic, 1); + blt(leftp, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(*leftp)); + *leftnp = mathomatic->n_tlhs; + blt(rightp, mathomatic->trhs, mathomatic->n_trhs * sizeof(*rightp)); + *rightnp = mathomatic->n_trhs; return success; } /* Move what we don't want in the LHS to the RHS. */ @@ -385,11 +381,11 @@ int *rightnp; /* pointer to length of RHS */ need_flip = 0; found = 0; op = 0; - ep = &tlhs[n_tlhs]; - for (b1 = p1 = tlhs;; p1++) { + ep = &mathomatic->tlhs[mathomatic->n_tlhs]; + for (b1 = p1 = mathomatic->tlhs;; p1++) { if (p1 >= ep || (p1->level == 1 && p1->kind == OPERATOR)) { if (!found) { - if ((p1 < ep || found_count || zsolve || n_tlhs > 1 || tlhs[0].kind != CONSTANT) + if ((p1 < ep || found_count || zsolve || mathomatic->n_tlhs > 1 || mathomatic->tlhs[0].kind != CONSTANT) && (p1 - b1 != 1 || b1->kind != CONSTANT || b1->token.constant != 1.0 || p1 >= ep || p1->token.operatr != DIVIDE)) { if (op == 0) { @@ -428,23 +424,23 @@ int *rightnp; /* pointer to length of RHS */ } } else { if (op != DIVIDE) { - b1 = tlhs; + b1 = mathomatic->tlhs; op = PLUS; for (p1 = b1; p1 < ep; p1++) p1->level++; } } } - if (!g_of_f(op, b1, tlhs, &n_tlhs, trhs, &n_trhs)) + if (!g_of_f(mathomatic, op, b1, mathomatic->tlhs, &mathomatic->n_tlhs, mathomatic->trhs, &mathomatic->n_trhs)) return false; - list_tdebug(2); + list_tdebug(mathomatic, 2); if (uf_flag) { - simp_loop(tlhs, &n_tlhs); + simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); } else { - simps_side(tlhs, &n_tlhs, zsolve); + simps_side(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, zsolve); } - simps_side(trhs, &n_trhs, zsolve); - list_tdebug(1); + simps_side(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, zsolve); + list_tdebug(mathomatic, 1); goto see_work; } } else if (op == DIVIDE) { @@ -452,74 +448,74 @@ int *rightnp; /* pointer to length of RHS */ } if (p1 >= ep) { if (found_count == 0) { /* if solve variable no longer in LHS */ - if (found_var(trhs, n_trhs, v)) { + if (found_var(mathomatic->trhs, mathomatic->n_trhs, v)) { /* solve variable in RHS */ - debug_string(1, _("Solve variable moved back to RHS, quitting solve routine.")); + debug_string(mathomatic, 1, _("Solve variable moved back to RHS, quitting solve routine.")); return false; } /* The following code determines if we have an identity: */ - calc_simp(tlhs, &n_tlhs); - calc_simp(trhs, &n_trhs); - if (se_compare(tlhs, n_tlhs, trhs, n_trhs, &diff_sign) && !diff_sign) { - error(_("This equation is an identity.")); - debug_string(0, _("That is, the LHS is identical to the RHS.")); + calc_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + calc_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + if (se_compare(mathomatic, mathomatic->tlhs, mathomatic->n_tlhs, mathomatic->trhs, mathomatic->n_trhs, &diff_sign) && !diff_sign) { + error(mathomatic, _("This equation is an identity.")); + debug_string(mathomatic, 0, _("That is, the LHS is identical to the RHS.")); return -1; } found = false; - for (i = 0; i < n_tlhs; i += 2) { - if (tlhs[i].kind == VARIABLE && tlhs[i].token.variable > IMAGINARY) { + for (i = 0; i < mathomatic->n_tlhs; i += 2) { + if (mathomatic->tlhs[i].kind == VARIABLE && mathomatic->tlhs[i].token.variable > IMAGINARY) { found = true; break; } } - for (i = 0; i < n_trhs; i += 2) { - if (trhs[i].kind == VARIABLE && trhs[i].token.variable > IMAGINARY) { + for (i = 0; i < mathomatic->n_trhs; i += 2) { + if (mathomatic->trhs[i].kind == VARIABLE && mathomatic->trhs[i].token.variable > IMAGINARY) { found = true; break; } } if (found) { - error(_("This equation is independent of the solve variable.")); + error(mathomatic, _("This equation is independent of the solve variable.")); } else { - error(_("There are no possible values for the solve variable.")); + error(mathomatic, _("There are no possible values for the solve variable.")); } return -2; } - zflag = (n_trhs == 1 && trhs[0].kind == CONSTANT && trhs[0].token.constant == 0.0); + zflag = (mathomatic->n_trhs == 1 && mathomatic->trhs[0].kind == CONSTANT && mathomatic->trhs[0].token.constant == 0.0); if (zflag) { /* overwrite -0.0 */ - trhs[0].token.constant = 0.0; + mathomatic->trhs[0].token.constant = 0.0; } if (need_flip >= found_count) { - if (!flip(tlhs, &n_tlhs, trhs, &n_trhs)) + if (!flip(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, mathomatic->trhs, &mathomatic->n_trhs)) return false; - list_tdebug(2); - simps_side(tlhs, &n_tlhs, zsolve); - simps_side(trhs, &n_trhs, zsolve); - list_tdebug(1); + list_tdebug(mathomatic, 2); + simps_side(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, zsolve); + simps_side(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, zsolve); + list_tdebug(mathomatic, 1); goto left_again; } if (worked && !uf_flag) { worked = false; - debug_string(1, _("Unfactoring...")); - partial_flag = false; - uf_simp(tlhs, &n_tlhs); - partial_flag = true; - factorv(tlhs, &n_tlhs, v); - list_tdebug(1); + debug_string(mathomatic, 1, _("Unfactoring...")); + mathomatic->partial_flag = false; + uf_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + mathomatic->partial_flag = true; + factorv(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, v); + list_tdebug(mathomatic, 1); uf_flag = true; goto see_work; } if (uf_flag) { - simps_side(tlhs, &n_tlhs, zsolve); + simps_side(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, zsolve); uf_flag = false; goto see_work; } op = 0; - b1 = tlhs; - for (i = 1; i < n_tlhs; i += 2) { - if (tlhs[i].level == 1) { - op_kind = tlhs[i].token.operatr; + b1 = mathomatic->tlhs; + for (i = 1; i < mathomatic->n_tlhs; i += 2) { + if (mathomatic->tlhs[i].level == 1) { + op_kind = mathomatic->tlhs[i].token.operatr; if (op_kind == TIMES || op_kind == DIVIDE) { if (op == 0) { op = TIMES; @@ -530,23 +526,23 @@ int *rightnp; /* pointer to length of RHS */ } if (zflag) { if (op_kind == DIVIDE - || (tlhs[i+1].kind == VARIABLE && tlhs[i+1].token.variable == v - && (tlhs[i+1].level == 1 - || (tlhs[i+1].level == 2 && tlhs[i+2].token.operatr == POWER - && tlhs[i+3].level == 2 && tlhs[i+3].kind == CONSTANT && tlhs[i+3].token.constant > 0.0)))) { + || (mathomatic->tlhs[i+1].kind == VARIABLE && mathomatic->tlhs[i+1].token.variable == v + && (mathomatic->tlhs[i+1].level == 1 + || (mathomatic->tlhs[i+1].level == 2 && mathomatic->tlhs[i+2].token.operatr == POWER + && mathomatic->tlhs[i+3].level == 2 && mathomatic->tlhs[i+3].kind == CONSTANT && mathomatic->tlhs[i+3].token.constant > 0.0)))) { op = op_kind; - b1 = &tlhs[i+1]; + b1 = &mathomatic->tlhs[i+1]; if (op_kind == DIVIDE) break; } } else { if (op_kind == DIVIDE) { - for (j = i + 2; j < n_tlhs && tlhs[j].level > 1; j += 2) { - if (tlhs[j].level == 2) { - op_kind = tlhs[j].token.operatr; + for (j = i + 2; j < mathomatic->n_tlhs && mathomatic->tlhs[j].level > 1; j += 2) { + if (mathomatic->tlhs[j].level == 2) { + op_kind = mathomatic->tlhs[j].token.operatr; if (op_kind == PLUS || op_kind == MINUS) { op = DIVIDE; - b1 = &tlhs[i+1]; + b1 = &mathomatic->tlhs[i+1]; } break; } @@ -564,36 +560,36 @@ int *rightnp; /* pointer to length of RHS */ qtries = 0; /* might be quadratic after removing solution */ success = 2; #if !SILENT - fprintf(gfp, _("Removing possible solution: \"")); - list_proc(b1, 1, false); - fprintf(gfp, " = 0\".\n"); + fprintf(mathomatic->gfp, _("Removing possible solution: \"")); + list_proc(mathomatic, b1, 1, false); + fprintf(mathomatic->gfp, " = 0\".\n"); #endif } else { - debug_string(1, _("Juggling...")); + debug_string(mathomatic, 1, _("Juggling...")); uf_flag = true; } - if (!g_of_f(op, b1, tlhs, &n_tlhs, trhs, &n_trhs)) + if (!g_of_f(mathomatic, op, b1, mathomatic->tlhs, &mathomatic->n_tlhs, mathomatic->trhs, &mathomatic->n_trhs)) return false; goto simp_again; } b1 = NULL; - for (i = 1; i < n_tlhs; i += 2) { - if (tlhs[i].token.operatr == POWER - && tlhs[i+1].level == tlhs[i].level - && tlhs[i+1].kind == CONSTANT - && fabs(tlhs[i+1].token.constant) < 1.0) { - if (!f_to_fraction(tlhs[i+1].token.constant, &numerator, &denominator) + for (i = 1; i < mathomatic->n_tlhs; i += 2) { + if (mathomatic->tlhs[i].token.operatr == POWER + && mathomatic->tlhs[i+1].level == mathomatic->tlhs[i].level + && mathomatic->tlhs[i+1].kind == CONSTANT + && fabs(mathomatic->tlhs[i+1].token.constant) < 1.0) { + if (!f_to_fraction(mathomatic, mathomatic->tlhs[i+1].token.constant, &numerator, &denominator) || fabs(numerator) != 1.0 || denominator < 2.0) { continue; } - for (j = i - 1; j >= 0 && tlhs[j].level >= tlhs[i].level; j--) { - if (tlhs[j].kind == VARIABLE && tlhs[j].token.variable == v) { + for (j = i - 1; j >= 0 && mathomatic->tlhs[j].level >= mathomatic->tlhs[i].level; j--) { + if (mathomatic->tlhs[j].kind == VARIABLE && mathomatic->tlhs[j].token.variable == v) { if (b1) { - if (fabs(b1->token.constant) < fabs(tlhs[i+1].token.constant)) { - b1 = &tlhs[i+1]; + if (fabs(b1->token.constant) < fabs(mathomatic->tlhs[i+1].token.constant)) { + b1 = &mathomatic->tlhs[i+1]; } } else { - b1 = &tlhs[i+1]; + b1 = &mathomatic->tlhs[i+1]; } break; } @@ -606,7 +602,7 @@ int *rightnp; /* pointer to length of RHS */ return false; zero_solved = false; qtries = 0; - if (!increase(b1->token.constant, v)) { + if (!increase(mathomatic, b1->token.constant, v)) { return false; } uf_flag = true; @@ -615,17 +611,17 @@ int *rightnp; /* pointer to length of RHS */ if (qtries) { return false; } - *leftnp = n_tlhs; - blt(leftp, tlhs, n_tlhs * sizeof(*leftp)); - *rightnp = n_trhs; - blt(rightp, trhs, n_trhs * sizeof(*rightp)); - if (solve_sub(&zero_token, 1, leftp, leftnp, rightp, rightnp) <= 0) + *leftnp = mathomatic->n_tlhs; + blt(leftp, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(*leftp)); + *rightnp = mathomatic->n_trhs; + blt(rightp, mathomatic->trhs, mathomatic->n_trhs * sizeof(*rightp)); + if (solve_sub(mathomatic, &mathomatic->zero_token, 1, leftp, leftnp, rightp, rightnp) <= 0) return false; if (zero_solved) { qtries++; } zero_solved = true; - if (poly_solve(v)) { + if (poly_solve(mathomatic, v)) { goto left_again; } else { goto simp_again; @@ -652,9 +648,7 @@ int *rightnp; /* pointer to length of RHS */ * Return true if successful. */ static int -increase(d, v) -double d; -long v; +increase(MathoMatic* mathomatic, double d, long v) { int flag, foundp, found2; int len1, len2; @@ -663,25 +657,25 @@ long v; token_type *ep; #if !SILENT - if (debug_level >= 0) { - fprintf(gfp, _("Raising both equation sides to the power of %.*g and expanding...\n"), precision, 1.0 / d); + if (mathomatic->debug_level >= 0) { + fprintf(mathomatic->gfp, _("Raising both equation sides to the power of %.*g and expanding...\n"), mathomatic->precision, 1.0 / d); } #endif - list_tdebug(2); - partial_flag = false; - ufactor(tlhs, &n_tlhs); - partial_flag = true; + list_tdebug(mathomatic, 2); + mathomatic->partial_flag = false; + ufactor(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + mathomatic->partial_flag = true; /* symb_flag = symblify; */ - simp_ssub(tlhs, &n_tlhs, v, d, true, false, 2); - simp_ssub(tlhs, &n_tlhs, 0L, 1.0, true, true, 2); + simp_ssub(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, v, d, true, false, 2); + simp_ssub(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, 0L, 1.0, true, true, 2); /* symb_flag = false; */ - list_tdebug(1); + list_tdebug(mathomatic, 1); isolate: - ep = &tlhs[n_tlhs]; + ep = &mathomatic->tlhs[mathomatic->n_tlhs]; len2 = len1 = 0; foundp = false; - for (p1 = tlhs + 1;; p1 += 2) { + for (p1 = mathomatic->tlhs + 1;; p1 += 2) { if (p1 >= ep) { return 2; /* power not found */ } @@ -701,7 +695,7 @@ long v; if (b1->kind == VARIABLE && b1->token.variable == v) { flag = true; } - if (b1 == tlhs) + if (b1 == mathomatic->tlhs) break; } if (flag || v == 0) { @@ -728,7 +722,7 @@ long v; if (b1->kind == VARIABLE && b1->token.variable == v) { flag = true; } - if (b1 == tlhs) + if (b1 == mathomatic->tlhs) break; } if (flag || v == 0) { @@ -744,13 +738,13 @@ long v; b1 = p1 + 1; op = p1->token.operatr; if (op == POWER && b1->level == 1 && b1->kind == CONSTANT && b1->token.constant == d) { - return(g_of_f(POWER, b1, tlhs, &n_tlhs, trhs, &n_trhs)); + return(g_of_f(mathomatic, POWER, b1, mathomatic->tlhs, &mathomatic->n_tlhs, mathomatic->trhs, &mathomatic->n_trhs)); } if (!foundp) { - b1 = tlhs; + b1 = mathomatic->tlhs; if (p1 - b1 == 1 && p1->token.operatr == DIVIDE && b1->kind == CONSTANT && b1->token.constant == 1.0) { - if (!flip(tlhs, &n_tlhs, trhs, &n_trhs)) + if (!flip(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs, mathomatic->trhs, &mathomatic->n_trhs)) return false; goto end; } @@ -768,13 +762,13 @@ long v; break; } } - if (!g_of_f(op, b1, tlhs, &n_tlhs, trhs, &n_trhs)) + if (!g_of_f(mathomatic, op, b1, mathomatic->tlhs, &mathomatic->n_tlhs, mathomatic->trhs, &mathomatic->n_trhs)) return false; end: - list_tdebug(2); - simp_loop(tlhs, &n_tlhs); - simp_loop(trhs, &n_trhs); - list_tdebug(1); + list_tdebug(mathomatic, 2); + simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + simp_loop(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + list_tdebug(mathomatic, 1); goto isolate; } @@ -789,8 +783,8 @@ long v; * Return true if successful, with solved equation in tlhs and trhs. */ static int -poly_solve(v) -long v; /* solve variable */ +poly_solve(MathoMatic* mathomatic, long v) +//long v; /* solve variable */ { int i, j, k; token_type *p1, *p2, *ep; @@ -804,22 +798,22 @@ long v; /* solve variable */ int len, alen, blen, aloc, nx1; double high_power = 0.0; - debug_string(1, _("Checking if equation is a polynomial equation:")); + debug_string(mathomatic, 1, _("Checking if equation is a polynomial equation:")); #if DEBUG - if (n_tlhs != 1 || tlhs[0].kind != CONSTANT || tlhs[0].token.constant != 0.0) { - error_bug("poly_solve() called without a zero-solved equation!"); + if (mathomatic->n_tlhs != 1 || mathomatic->tlhs[0].kind != CONSTANT || mathomatic->tlhs[0].token.constant != 0.0) { + error_bug(mathomatic, "poly_solve() called without a zero-solved equation!"); } #endif - uf_simp(trhs, &n_trhs); - while (factor_plus(trhs, &n_trhs, v, 0.0)) { - simp_loop(trhs, &n_trhs); + uf_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + while (factor_plus(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, v, 0.0)) { + simp_loop(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); } - list_tdebug(1); + list_tdebug(mathomatic, 1); found = false; op = 0; - ep = &trhs[n_trhs]; - for (x1tp = p1 = trhs;; p1++) { + ep = &mathomatic->trhs[mathomatic->n_trhs]; + for (x1tp = p1 = mathomatic->trhs;; p1++) { if (p1 >= ep || (p1->level == 1 && p1->kind == OPERATOR)) { if (p1 < ep) { switch (p1->token.operatr) { @@ -891,12 +885,12 @@ long v; /* solve variable */ if (high_power == 0.0) return false; #if !SILENT - if (debug_level >= 0) { - list_var(v, 0); - fprintf(gfp, _("Equation is a degree %.*g polynomial equation in %s.\n"), precision, high_power, var_str); + if (mathomatic->debug_level >= 0) { + list_var(mathomatic, v, 0); + fprintf(mathomatic->gfp, _("Equation is a degree %.*g polynomial equation in %s.\n"), mathomatic->precision, high_power, mathomatic->var_str); } #endif - if (a1p > trhs && (a1p - 1)->token.operatr == MINUS) + if (a1p > mathomatic->trhs && (a1p - 1)->token.operatr == MINUS) opx1 = MINUS; else opx1 = PLUS; @@ -914,9 +908,9 @@ long v; /* solve variable */ } opx2 = 0; op = 0; - for (x2p = p1 = trhs;; p1++) { + for (x2p = p1 = mathomatic->trhs;; p1++) { if (p1 >= ep || (p1->level == 1 && p1->kind == OPERATOR)) { - if (se_compare(x1_storage, nx1, x2p, p1 - x2p, &diff_sign)) { + if (se_compare(mathomatic, x1_storage, nx1, x2p, p1 - x2p, &diff_sign)) { b1p = x2p; b2p = p1; b2ep = b2p; @@ -927,7 +921,7 @@ long v; /* solve variable */ for (b1p = p2 = x2p;; p2++) { if (p2 >= p1 || (p2->level == 2 && p2->kind == OPERATOR)) { if (op2 == 0 || op2 == TIMES) { - if (se_compare(x1_storage, nx1, x2p, p2 - x2p, &diff_sign)) { + if (se_compare(mathomatic, x1_storage, nx1, x2p, p2 - x2p, &diff_sign)) { b2p = p2; b2ep = p1; goto big_bbreak; @@ -972,76 +966,76 @@ long v; /* solve variable */ default: return false; } - blt(scratch, b1p, (char *) x2p - (char *) b1p); + blt(mathomatic->scratch, b1p, (char *) x2p - (char *) b1p); len = x2p - b1p; - scratch[len].level = 7; - scratch[len].kind = CONSTANT; + mathomatic->scratch[len].level = 7; + mathomatic->scratch[len].kind = CONSTANT; if (opx2 == MINUS) - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].token.constant = -1.0; else - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].token.constant = 1.0; len++; - blt(&scratch[len], b2p, (char *) b2ep - (char *) b2p); + blt(&mathomatic->scratch[len], b2p, (char *) b2ep - (char *) b2p); len += (b2ep - b2p); blen = len; - j = min_level(scratch, len); + j = min_level(mathomatic, mathomatic->scratch, len); j = 7 - j; for (i = 0; i < len; i++) - scratch[i].level += j; - scratch[len].level = 6; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = POWER; + mathomatic->scratch[i].level += j; + mathomatic->scratch[len].level = 6; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = POWER; len++; - scratch[len].level = 6; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = 2.0; + mathomatic->scratch[len].level = 6; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = 2.0; len++; - scratch[len].level = 5; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = MINUS; + mathomatic->scratch[len].level = 5; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = MINUS; len++; - scratch[len].level = 6; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = 4.0; + mathomatic->scratch[len].level = 6; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = 4.0; len++; - scratch[len].level = 6; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = 6; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; aloc = len; - blt(&scratch[len], a1p, (char *) x1p - (char *) a1p); + blt(&mathomatic->scratch[len], a1p, (char *) x1p - (char *) a1p); len += (x1p - a1p); - scratch[len].level = 7; - scratch[len].kind = CONSTANT; + mathomatic->scratch[len].level = 7; + mathomatic->scratch[len].kind = CONSTANT; if (opx1 == MINUS) - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].token.constant = -1.0; else - scratch[len].token.constant = 1.0; + mathomatic->scratch[len].token.constant = 1.0; len++; - blt(&scratch[len], a2p, (char *) a2ep - (char *) a2p); + blt(&mathomatic->scratch[len], a2p, (char *) a2ep - (char *) a2p); len += (a2ep - a2p); alen = len - aloc; - j = min_level(&scratch[aloc], len - aloc); + j = min_level(mathomatic, &mathomatic->scratch[aloc], len - aloc); j = 7 - j; for (i = aloc; i < len; i++) - scratch[i].level += j; - scratch[len].level = 6; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[i].level += j; + mathomatic->scratch[len].level = 6; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; k = len; - scratch[len] = zero_token; + mathomatic->scratch[len] = mathomatic->zero_token; len++; - for (p2 = p1 = trhs;; p1++) { + for (p2 = p1 = mathomatic->trhs;; p1++) { if (p1 >= ep || (p1->level == 1 && p1->kind == OPERATOR)) { if (!((p2 <= x1p && p1 > x1p) || (p2 <= x2p && p1 > x2p))) { - if (p2 == trhs) { - scratch[len].level = 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = PLUS; + if (p2 == mathomatic->trhs) { + mathomatic->scratch[len].level = 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = PLUS; len++; } - blt(&scratch[len], p2, (char *) p1 - (char *) p2); + blt(&mathomatic->scratch[len], p2, (char *) p1 - (char *) p2); len += (p1 - p2); } if (p1 >= ep) @@ -1051,59 +1045,59 @@ long v; /* solve variable */ } } for (i = k; i < len; i++) - scratch[i].level += 6; - scratch[len].level = 4; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = POWER; + mathomatic->scratch[i].level += 6; + mathomatic->scratch[len].level = 4; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = POWER; len++; - scratch[len].level = 4; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = 0.5; + mathomatic->scratch[len].level = 4; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = 0.5; len++; - scratch[len].level = 3; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = 3; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - scratch[len].level = 3; - scratch[len].kind = VARIABLE; - next_sign(&scratch[len].token.variable); + mathomatic->scratch[len].level = 3; + mathomatic->scratch[len].kind = VARIABLE; + next_sign(mathomatic, &mathomatic->scratch[len].token.variable); len++; - scratch[len].level = 2; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = MINUS; + mathomatic->scratch[len].level = 2; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = MINUS; len++; - if (len + blen + 3 + alen > n_tokens) { - error_huge(); + if (len + blen + 3 + alen > mathomatic->n_tokens) { + error_huge(mathomatic); } - blt(&scratch[len], scratch, blen * sizeof(token_type)); + blt(&mathomatic->scratch[len], mathomatic->scratch, blen * sizeof(token_type)); len += blen; - scratch[len].level = 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = DIVIDE; + mathomatic->scratch[len].level = 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = DIVIDE; len++; - scratch[len].level = 2; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = 2.0; + mathomatic->scratch[len].level = 2; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = 2.0; len++; - scratch[len].level = 2; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = 2; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - blt(&scratch[len], &scratch[aloc], alen * sizeof(token_type)); + blt(&mathomatic->scratch[len], &mathomatic->scratch[aloc], alen * sizeof(token_type)); len += alen; - if (found_var(scratch, len, v)) + if (found_var(mathomatic->scratch, len, v)) return false; - blt(tlhs, x1_storage, nx1 * sizeof(token_type)); - n_tlhs = nx1; - simp_loop(tlhs, &n_tlhs); - blt(trhs, scratch, len * sizeof(token_type)); - n_trhs = len; - simp_loop(trhs, &n_trhs); - list_tdebug(2); - uf_tsimp(trhs, &n_trhs); /* don't unfactor result so much, just unfactor what will be unfactored anyway */ - simps_side(trhs, &n_trhs, false); - list_tdebug(1); - debug_string(0, _("Equation was solved with the quadratic formula.")); + blt(mathomatic->tlhs, x1_storage, nx1 * sizeof(token_type)); + mathomatic->n_tlhs = nx1; + simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); + blt(mathomatic->trhs, mathomatic->scratch, len * sizeof(token_type)); + mathomatic->n_trhs = len; + simp_loop(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); + list_tdebug(mathomatic, 2); + uf_tsimp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); /* don't unfactor result so much, just unfactor what will be unfactored anyway */ + simps_side(mathomatic, mathomatic->trhs, &mathomatic->n_trhs, false); + list_tdebug(mathomatic, 1); + debug_string(mathomatic, 0, _("Equation was solved with the quadratic formula.")); return true; } @@ -1129,13 +1123,13 @@ long v; /* solve variable */ * Return true unless something is wrong. */ static int -g_of_f(op, operandp, side1p, side1np, side2p, side2np) -int op; /* current operator */ -token_type *operandp; /* operand pointer */ -token_type *side1p; /* equation side pointer */ -int *side1np; /* pointer to the length of "side1p" */ -token_type *side2p; /* equation side pointer */ -int *side2np; /* pointer to the length of "side2p" */ +g_of_f(MathoMatic* mathomatic, int op, token_type *operandp, token_type *side1p, int *side1np, token_type *side2p, int *side2np) +//int op; /* current operator */ +//token_type *operandp; /* operand pointer */ +//token_type *side1p; /* equation side pointer */ +//int *side1np; /* pointer to the length of "side1p" */ +//token_type *side2p; /* equation side pointer */ +//int *side2np; /* pointer to the length of "side2p" */ { token_type *p1, *p2, *ep; int oldn, operandn; @@ -1147,17 +1141,17 @@ int *side2np; /* pointer to the length of "side2p" */ oldn = *side1np; ep = &side1p[oldn]; if (operandp < side1p || operandp >= ep) { - error_bug("g_of_f() called with invalid operandp."); + error_bug(mathomatic, "g_of_f() called with invalid operandp."); } - if (*side1np == prev_n1 && *side2np == prev_n2) { - if (++repeat_count >= 4) { - debug_string(1, _("Infinite loop aborted in solve routine.")); + if (*side1np == mathomatic->prev_n1 && *side2np == mathomatic->prev_n2) { + if (++mathomatic->repeat_count >= 4) { + debug_string(mathomatic, 1, _("Infinite loop aborted in solve routine.")); return false; } } else { - prev_n1 = *side1np; - prev_n2 = *side2np; - repeat_count = 0; + mathomatic->prev_n1 = *side1np; + mathomatic->prev_n2 = *side2np; + mathomatic->repeat_count = 0; } switch (op) { case PLUS: @@ -1185,14 +1179,14 @@ int *side2np; /* pointer to the length of "side2p" */ } operandn = p1 - operandp; if (op == POWER && operandp == side1p) { - if (!parse_complex(side2p, *side2np, &c1)) + if (!parse_complex(mathomatic, side2p, *side2np, &c1)) return false; - if (!parse_complex(operandp, operandn, &c2)) + if (!parse_complex(mathomatic, operandp, operandn, &c2)) return false; - debug_string(1, _("Taking logarithm of both equation sides:")); + debug_string(mathomatic, 1, _("Taking logarithm of both equation sides:")); errno = 0; c1 = complex_div(complex_log(c1), complex_log(c2)); - check_err(); + check_err(mathomatic); *side2np = 0; side2p[*side2np].level = 1; side2p[*side2np].kind = CONSTANT; @@ -1220,68 +1214,68 @@ int *side2np; /* pointer to the length of "side2p" */ return true; } if (op == MODULUS) { - if (get_constant(side2p, *side2np, &d1) && get_constant(operandp, operandn, &d2)) { + if (get_constant(mathomatic, side2p, *side2np, &d1) && get_constant(mathomatic, operandp, operandn, &d2)) { if (fabs(d1) >= fabs(d2)) { - error(_("There are no possible solutions.")); + error(mathomatic, _("There are no possible solutions.")); return false; } } } #if !SILENT - if (debug_level > 0) { + if (mathomatic->debug_level > 0) { switch (op) { case PLUS: - fprintf(gfp, _("Subtracting")); + fprintf(mathomatic->gfp, _("Subtracting")); break; case MINUS: - fprintf(gfp, _("Adding")); + fprintf(mathomatic->gfp, _("Adding")); break; case TIMES: - fprintf(gfp, _("Dividing both sides of the equation by")); + fprintf(mathomatic->gfp, _("Dividing both sides of the equation by")); break; case DIVIDE: - fprintf(gfp, _("Multiplying both sides of the equation by")); + fprintf(mathomatic->gfp, _("Multiplying both sides of the equation by")); break; case POWER: - fprintf(gfp, _("Raising both sides of the equation to the power of")); + fprintf(mathomatic->gfp, _("Raising both sides of the equation to the power of")); break; case MODULUS: - fprintf(gfp, _("Applying inverse modulus of")); + fprintf(mathomatic->gfp, _("Applying inverse modulus of")); break; } if (op == POWER && operandn == 1 && operandp->kind == CONSTANT) { - fprintf(gfp, " %.*g:\n", precision, 1.0 / operandp->token.constant); + fprintf(mathomatic->gfp, " %.*g:\n", mathomatic->precision, 1.0 / operandp->token.constant); } else { - fprintf(gfp, " \""); + fprintf(mathomatic->gfp, " \""); if (op == POWER) - fprintf(gfp, "1/("); - list_proc(operandp, operandn, false); + fprintf(mathomatic->gfp, "1/("); + list_proc(mathomatic, operandp, operandn, false); switch (op) { case PLUS: - fprintf(gfp, _("\" from both sides of the equation:\n")); + fprintf(mathomatic->gfp, _("\" from both sides of the equation:\n")); break; case MINUS: case MODULUS: - fprintf(gfp, _("\" to both sides of the equation:\n")); + fprintf(mathomatic->gfp, _("\" to both sides of the equation:\n")); break; case POWER: - fprintf(gfp, ")"); + fprintf(mathomatic->gfp, ")"); default: - fprintf(gfp, "\":\n"); + fprintf(mathomatic->gfp, "\":\n"); break; } } } #endif - if (*side1np + operandn + 3 > n_tokens || *side2np + operandn + 5 > n_tokens) { - error_huge(); + if (*side1np + operandn + 3 > mathomatic->n_tokens || *side2np + operandn + 5 > mathomatic->n_tokens) { + error_huge(mathomatic); } - if (min_level(side1p, oldn) <= 1) { + if (min_level(mathomatic, side1p, oldn) <= 1) { for (p2 = side1p; p2 < ep; p2++) p2->level++; } ep = &side2p[*side2np]; - if (min_level(side2p, *side2np) <= 1) { + if (min_level(mathomatic, side2p, *side2np) <= 1) { for (p2 = side2p; p2 < ep; p2++) p2->level++; } @@ -1294,12 +1288,12 @@ int *side2np; /* pointer to the length of "side2p" */ p2++; p2->level = 2; p2->kind = VARIABLE; - snprintf(var_name_buf, sizeof(var_name_buf), "%s_any%.0d", V_INTEGER_PREFIX, last_int_var); - if (parse_var(&p2->token.variable, var_name_buf) == NULL) + snprintf(var_name_buf, sizeof(var_name_buf), "%s_any%.0d", V_INTEGER_PREFIX, mathomatic->last_int_var); + if (parse_var(mathomatic, &p2->token.variable, var_name_buf) == NULL) return false; - last_int_var++; - if (last_int_var < 0) { - last_int_var = 0; + mathomatic->last_int_var++; + if (mathomatic->last_int_var < 0) { + mathomatic->last_int_var = 0; } p2++; p2->level = 2; @@ -1361,7 +1355,7 @@ int *side2np; /* pointer to the length of "side2p" */ blt(&side2p[*side2np], &side1p[oldn], (*side1np - oldn) * sizeof(*side1p)); *side2np += *side1np - oldn; if (op == POWER && operandn == 1 && operandp->kind == CONSTANT) { - f_to_fraction(operandp->token.constant, &numerator, &denominator); + f_to_fraction(mathomatic, operandp->token.constant, &numerator, &denominator); if (always_positive(numerator)) { ep = &side2p[*side2np]; for (p2 = side2p; p2 < ep; p2++) @@ -1372,7 +1366,7 @@ int *side2np; /* pointer to the length of "side2p" */ p2++; p2->level = 1; p2->kind = VARIABLE; - next_sign(&p2->token.variable); + next_sign(mathomatic, &p2->token.variable); *side2np += 2; } } @@ -1388,17 +1382,17 @@ int *side2np; /* pointer to the length of "side2p" */ * Return true if successful. */ static int -flip(side1p, side1np, side2p, side2np) -token_type *side1p; /* equation side pointer */ -int *side1np; /* pointer to equation side length */ -token_type *side2p; -int *side2np; +flip(MathoMatic* mathomatic, token_type *side1p, int *side1np, token_type *side2p, int *side2np) +//token_type *side1p; /* equation side pointer */ +//int *side1np; /* pointer to equation side length */ +//token_type *side2p; +//int *side2np; { token_type *p1, *ep; - debug_string(1, _("Taking the reciprocal of both sides of the equation...")); - if (*side1np + 2 > n_tokens || *side2np + 2 > n_tokens) { - error_huge(); + debug_string(mathomatic, 1, _("Taking the reciprocal of both sides of the equation...")); + if (*side1np + 2 > mathomatic->n_tokens || *side2np + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } ep = &side1p[*side1np]; for (p1 = side1p; p1 < ep; p1++) @@ -1411,13 +1405,13 @@ int *side2np; blt(side2p + 2, side2p, *side2np * sizeof(*side2p)); *side2np += 2; - *side1p = one_token; + *side1p = mathomatic->one_token; side1p++; side1p->level = 1; side1p->kind = OPERATOR; side1p->token.operatr = DIVIDE; - *side2p = one_token; + *side2p = mathomatic->one_token; side2p++; side2p->level = 1; side2p->kind = OPERATOR; diff --git a/super.c b/super.c index cc7ff87..d690fc2 100644 --- a/super.c +++ b/super.c @@ -24,15 +24,15 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "includes.h" -static int sf_recurse(token_type *equation, int *np, int loc, int level, int start_flag); -static int sf_sub(token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level, int start_flag); +static int sf_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int start_flag); +static int sf_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level, int start_flag); static void -group_recurse(equation, np, loc, level) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ -int loc; /* starting location within equation side */ -int level; /* current level of parentheses within the sub-expression starting at "loc" */ +group_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ +//int loc; /* starting location within equation side */ +//int level; /* current level of parentheses within the sub-expression starting at "loc" */ { int i; int len; @@ -42,7 +42,7 @@ int level; /* current level of parentheses within the sub-expression starting for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - group_recurse(equation, np, i, level + 1); + group_recurse(mathomatic, equation, np, i, level + 1); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -69,9 +69,9 @@ int level; /* current level of parentheses within the sub-expression starting edi = i; continue; } - blt(scratch, &equation[i], len * sizeof(token_type)); + blt(mathomatic->scratch, &equation[i], len * sizeof(token_type)); blt(&equation[di+len], &equation[di], (i - di) * sizeof(token_type)); - blt(&equation[di], scratch, len * sizeof(token_type)); + blt(&equation[di], mathomatic->scratch, len * sizeof(token_type)); edi += len; i += len - 2; } else { @@ -85,7 +85,7 @@ int level; /* current level of parentheses within the sub-expression starting if (equation[i].level == level && equation[i].kind == OPERATOR) { #if DEBUG if (equation[i].token.operatr != DIVIDE) { - error_bug("Bug in group_recurse()."); + error_bug(mathomatic, "Bug in group_recurse()."); } #endif equation[i].token.operatr = TIMES; @@ -101,11 +101,11 @@ int level; /* current level of parentheses within the sub-expression starting * Not guaranteed to put the grouped divisors last, reorder() puts divisors last. */ void -group_proc(equation, np) -token_type *equation; /* equation side pointer */ -int *np; /* pointer to length of equation side */ +group_proc(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* equation side pointer */ +//int *np; /* pointer to length of equation side */ { - group_recurse(equation, np, 0, 1); + group_recurse(mathomatic, equation, np, 0, 1); } /* @@ -117,17 +117,17 @@ int *np; /* pointer to length of equation side */ * Return true if any fractions were created. */ int -fractions_and_group(equation, np) -token_type *equation; -int *np; +fractions_and_group(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; +//int *np; { int rv = false; - elim_loop(equation, np); - if (fractions_display) { - rv = make_fractions(equation, np); + elim_loop(mathomatic, equation, np); + if (mathomatic->fractions_display) { + rv = make_fractions(mathomatic, equation, np); } - group_proc(equation, np); + group_proc(mathomatic, equation, np); return rv; } @@ -138,17 +138,17 @@ int *np; * Return true if any fractions were created. */ int -make_fractions_and_group(n) -int n; /* equation space number */ +make_fractions_and_group(MathoMatic* mathomatic, int n) +//int n; /* equation space number */ { int rv = false; - if (empty_equation_space(n)) + if (empty_equation_space(mathomatic, n)) return false; - if (fractions_and_group(lhs[n], &n_lhs[n])) + if (fractions_and_group(mathomatic, mathomatic->lhs[n], &mathomatic->n_lhs[n])) rv = true; - if (n_rhs[n] > 0) { - if (fractions_and_group(rhs[n], &n_rhs[n])) + if (mathomatic->n_rhs[n] > 0) { + if (fractions_and_group(mathomatic, mathomatic->rhs[n], &mathomatic->n_rhs[n])) rv = true; } return rv; @@ -184,23 +184,21 @@ int n; /* equation space number */ * Return true if the equation side was modified. */ int -super_factor(equation, np, start_flag) -token_type *equation; /* pointer to the beginning of the equation side to process */ -int *np; /* pointer to the length of the equation side */ -int start_flag; +super_factor(MathoMatic* mathomatic, token_type *equation, int *np, int start_flag) +//token_type *equation; /* pointer to the beginning of the equation side to process */ +//int *np; /* pointer to the length of the equation side */ +//int start_flag; { int rv; - group_proc(equation, np); - rv = sf_recurse(equation, np, 0, 1, start_flag); - organize(equation, np); + group_proc(mathomatic, equation, np); + rv = sf_recurse(mathomatic, equation, np, 0, 1, start_flag); + organize(mathomatic, equation, np); return rv; } static int -sf_recurse(equation, np, loc, level, start_flag) -token_type *equation; -int *np, loc, level, start_flag; +sf_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int start_flag) { int modified = false; int i, j, k; @@ -218,7 +216,7 @@ int *np, loc, level, start_flag; op = 0; for (i = loc; i < *np && equation[i].level >= level;) { if (equation[i].level > level) { - modified |= sf_recurse(equation, np, i, level + 1, start_flag); + modified |= sf_recurse(mathomatic, equation, np, i, level + 1, start_flag); i++; for (; i < *np && equation[i].level > level; i += 2) ; @@ -250,11 +248,11 @@ int *np, loc, level, start_flag; side_debug(0, &equation[i], len1); side_debug(0, &equation[j], len2); #endif - if (sf_sub(equation, np, loc, i, len1, j, len2, level + 1, start_flag)) { + if (sf_sub(mathomatic, equation, np, loc, i, len1, j, len2, level + 1, start_flag)) { #if 0 int junk; printf("start_flag = %d\n", start_flag); - debug_string(0, "super_factor() successful:"); + debug_string(mathomatic, 0, "super_factor() successful:"); for (junk = 1; (loc + junk) < *np && equation[loc+junk].level > level; junk += 2) ; side_debug(0, &equation[loc], junk); @@ -267,9 +265,7 @@ int *np, loc, level, start_flag; } static int -sf_sub(equation, np, loc, i1, n1, i2, n2, level, start_flag) -token_type *equation; -int *np, loc, i1, n1, i2, n2, level, start_flag; +sf_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int i1, int n1, int i2, int n2, int level, int start_flag) { int i, j, k; int b1, b2; @@ -339,30 +335,30 @@ int *np, loc, i1, n1, i2, n2, level, start_flag; #endif if (start_flag >= 2 && div_flag1 && div_flag2) { #if DEBUG - debug_string(1, "Trying to find a polynomial GCD between 2 denominators in sf_sub():"); - side_debug(1, &equation[b1], i - b1); - side_debug(1, &equation[b2], j - b2); + debug_string(mathomatic, 1, "Trying to find a polynomial GCD between 2 denominators in sf_sub():"); + side_debug(mathomatic, 1, &equation[b1], i - b1); + side_debug(mathomatic, 1, &equation[b2], j - b2); #endif - if ((rv = poly2_gcd(&equation[b1], i - b1, &equation[b2], j - b2, 0L, true)) > 0) { - p1 = tlhs; - np1 = n_tlhs; - p2 = trhs; - np2 = n_trhs; + if ((rv = poly2_gcd(mathomatic, &equation[b1], i - b1, &equation[b2], j - b2, 0L, true)) > 0) { + p1 = mathomatic->tlhs; + np1 = mathomatic->n_tlhs; + p2 = mathomatic->trhs; + np2 = mathomatic->n_trhs; goto do_gcd_super; } - if (rv == 0 && poly2_gcd(&equation[b2], j - b2, &equation[b1], i - b1, 0L, true) > 0) { - p1 = trhs; - np1 = n_trhs; - p2 = tlhs; - np2 = n_tlhs; + if (rv == 0 && poly2_gcd(mathomatic, &equation[b2], j - b2, &equation[b1], i - b1, 0L, true) > 0) { + p1 = mathomatic->trhs; + np1 = mathomatic->n_trhs; + p2 = mathomatic->tlhs; + np2 = mathomatic->n_tlhs; goto do_gcd_super; } #if DEBUG - debug_string(1, "Done; polynomial GCD not found."); + debug_string(mathomatic, 1, "Done; polynomial GCD not found."); #endif } - if (n1 + n2 + (i - b1) + (j - b2) + 8 > n_tokens) { - error_huge(); + if (n1 + n2 + (i - b1) + (j - b2) + 8 > mathomatic->n_tokens) { + error_huge(mathomatic); } if (!div_flag1) { for (k = i1; k < e1; k++) @@ -373,76 +369,76 @@ int *np, loc, i1, n1, i2, n2, level, start_flag; equation[k].level++; } len = (b1 - i1) - 1; - blt(scratch, &equation[i1], len * sizeof(token_type)); + blt(mathomatic->scratch, &equation[i1], len * sizeof(token_type)); if (op1 == MINUS) { - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - scratch[len].level = level; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = -1.0; len++; } if (div_flag1) { - blt(&scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); len += e1 - i; } if (div_flag2) { - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - blt(&scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); len += j - b2; } for (k = 0; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = op2; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = op2; len++; k = len; - blt(&scratch[len], &equation[i2], (b2 - i2 - 1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i2], (b2 - i2 - 1) * sizeof(token_type)); len += b2 - i2 - 1; if (div_flag2) { - blt(&scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); len += e2 - j; } if (div_flag1) { - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - blt(&scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); len += i - b1; } for (; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = DIVIDE; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = DIVIDE; len++; k = len; if (div_flag1) { - blt(&scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); len += i - b1; } if (div_flag1 && div_flag2) { - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; } if (div_flag2) { - blt(&scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b2], (j - b2) * sizeof(token_type)); len += j - b2; } for (; k < len; k++) - scratch[k].level++; + mathomatic->scratch[k].level++; end_mess: - if (*np + len - n1 - (n2 + 1) > n_tokens) { - error_huge(); + if (*np + len - n1 - (n2 + 1) > mathomatic->n_tokens) { + error_huge(mathomatic); } if (op1 == MINUS) { equation[i1-1].token.operatr = PLUS; @@ -451,16 +447,16 @@ int *np, loc, i1, n1, i2, n2, level, start_flag; *np -= n2 + 1; blt(&equation[i1+len], &equation[e1], (*np - e1) * sizeof(token_type)); *np += len - n1; - blt(&equation[i1], scratch, len * sizeof(token_type)); + blt(&equation[i1], mathomatic->scratch, len * sizeof(token_type)); return true; do_gcd_super: #if DEBUG - debug_string(1, "Found a polynomial GCD between 2 denominators in sf_sub()."); + debug_string(mathomatic, 1, "Found a polynomial GCD between 2 denominators in sf_sub()."); #endif - if (5 - i1 + e1 + (2*np2) + b2 - i2 + e2 - j + np1 > n_tokens) { - error_huge(); + if (5 - i1 + e1 + (2*np2) + b2 - i2 + e2 - j + np1 > mathomatic->n_tokens) { + error_huge(mathomatic); } for (k = 0; k < np1; k++) { p1[k].level += level; @@ -469,72 +465,72 @@ int *np, loc, i1, n1, i2, n2, level, start_flag; p2[k].level += level; } len = (b1 - i1) - 1; - blt(scratch, &equation[i1], len * sizeof(token_type)); + blt(mathomatic->scratch, &equation[i1], len * sizeof(token_type)); if (op1 == MINUS) { - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - scratch[len].level = level; - scratch[len].kind = CONSTANT; - scratch[len].token.constant = -1.0; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = CONSTANT; + mathomatic->scratch[len].token.constant = -1.0; len++; } /* if (div_flag1) { */ - blt(&scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i], (e1 - i) * sizeof(token_type)); len += e1 - i; /* } */ /* if (div_flag2) { */ - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - blt(&scratch[len], p2, np2 * sizeof(token_type)); + blt(&mathomatic->scratch[len], p2, np2 * sizeof(token_type)); len += np2; /* } */ for (k = 0; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level + 1; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = op2; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level + 1; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = op2; len++; k = len; - blt(&scratch[len], &equation[i2], (b2 - i2 - 1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[i2], (b2 - i2 - 1) * sizeof(token_type)); len += b2 - i2 - 1; /* if (div_flag2) { */ - blt(&scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[j], (e2 - j) * sizeof(token_type)); len += e2 - j; /* } */ /* if (div_flag1) { */ - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; - blt(&scratch[len], p1, np1 * sizeof(token_type)); + blt(&mathomatic->scratch[len], p1, np1 * sizeof(token_type)); len += np1; /* } */ for (; k < len; k++) - scratch[k].level += 2; - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = DIVIDE; + mathomatic->scratch[k].level += 2; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = DIVIDE; len++; k = len; /* if (div_flag1) { */ - blt(&scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (i - b1) * sizeof(token_type)); len += (i - b1); /* } */ /* if (div_flag1 && div_flag2) { */ - scratch[len].level = level; - scratch[len].kind = OPERATOR; - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; + mathomatic->scratch[len].token.operatr = TIMES; len++; /* } */ /* if (div_flag2) { */ - blt(&scratch[len], p2, np2 * sizeof(token_type)); + blt(&mathomatic->scratch[len], p2, np2 * sizeof(token_type)); len += np2; /* } */ for (; k < len; k++) - scratch[k].level++; + mathomatic->scratch[k].level++; goto end_mess; } diff --git a/unfactor.c b/unfactor.c index b572611..a9c8caa 100644 --- a/unfactor.c +++ b/unfactor.c @@ -24,7 +24,7 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "includes.h" -static int unf_sub(token_type *equation, int *np, int b1, int loc, int e1, int level, int ii); +static int unf_sub(MathoMatic* mathomatic, token_type *equation, int *np, int b1, int loc, int e1, int level, int ii); /* * Unfactor times and divide only (products of sums) and simplify. @@ -32,17 +32,15 @@ static int unf_sub(token_type *equation, int *np, int b1, int loc, int e1, int l * Return true if equation side was unfactored. */ int -uf_tsimp(equation, np) -token_type *equation; -int *np; +uf_tsimp(MathoMatic* mathomatic, token_type *equation, int *np) { int rv; - rv = uf_times(equation, np); - simp_loop(equation, np); - while (uf_times(equation, np)) { + rv = uf_times(mathomatic, equation, np); + simp_loop(mathomatic, equation, np); + while (uf_times(mathomatic, equation, np)) { rv = true; - simp_loop(equation, np); + simp_loop(mathomatic, equation, np); } return rv; } @@ -54,17 +52,15 @@ int *np; * Return true if equation side was unfactored. */ int -uf_power(equation, np) -token_type *equation; -int *np; +uf_power(MathoMatic* mathomatic, token_type *equation, int *np) { int count = -1; do { - organize(equation, np); + organize(mathomatic, equation, np); if (++count > 0) break; - } while (sub_ufactor(equation, np, 2)); + } while (sub_ufactor(mathomatic, equation, np, 2)); return count; } @@ -75,17 +71,15 @@ int *np; * Return true if equation side was unfactored. */ int -uf_pplus(equation, np) -token_type *equation; -int *np; +uf_pplus(MathoMatic* mathomatic, token_type *equation, int *np) { int count = -1; do { - organize(equation, np); + organize(mathomatic, equation, np); if (++count > 0) break; - } while (sub_ufactor(equation, np, 4)); + } while (sub_ufactor(mathomatic, equation, np, 4)); return count; } @@ -94,13 +88,11 @@ int *np; * Same as a call to uf_pplus() and uf_power(), only faster. */ void -uf_allpower(equation, np) -token_type *equation; -int *np; +uf_allpower(MathoMatic* mathomatic, token_type *equation, int *np) { do { - organize(equation, np); - } while (sub_ufactor(equation, np, 0)); + organize(mathomatic, equation, np); + } while (sub_ufactor(mathomatic, equation, np, 0)); } /* @@ -112,18 +104,16 @@ int *np; * uf_times() is usually called after this to complete the expansion. */ void -uf_repeat(equation, np) -token_type *equation; -int *np; +uf_repeat(MathoMatic* mathomatic, token_type *equation, int *np) { int count = -1; do { - organize(equation, np); + organize(mathomatic, equation, np); if (++count > 0) break; - } while (sub_ufactor(equation, np, 6)); - patch_root_div(equation, np); + } while (sub_ufactor(mathomatic, equation, np, 6)); + patch_root_div(mathomatic, equation, np); } /* @@ -132,31 +122,29 @@ int *np; * Useful for removing all integer powers. */ void -uf_repeat_always(equation, np) -token_type *equation; -int *np; +uf_repeat_always(MathoMatic* mathomatic, token_type *equation, int *np) { int count = -1; do { - organize(equation, np); + organize(mathomatic, equation, np); if (++count > 0) break; - } while (sub_ufactor(equation, np, 8)); + } while (sub_ufactor(mathomatic, equation, np, 8)); } /* * Totally unfactor equation side and simplify. */ void -uf_simp(equation, np) -token_type *equation; /* pointer to beginning of equation side */ -int *np; /* pointer to length of equation side */ +uf_simp(MathoMatic* mathomatic, token_type *equation, int *np) +//token_type *equation; /* pointer to beginning of equation side */ +//int *np; /* pointer to length of equation side */ { - uf_tsimp(equation, np); - uf_power(equation, np); - uf_repeat(equation, np); - uf_tsimp(equation, np); + uf_tsimp(mathomatic, equation, np); + uf_power(mathomatic, equation, np); + uf_repeat(mathomatic, equation, np); + uf_tsimp(mathomatic, equation, np); } /* @@ -164,27 +152,23 @@ int *np; /* pointer to length of equation side */ * Don't call uf_repeat(). */ void -uf_simp_no_repeat(equation, np) -token_type *equation; -int *np; +uf_simp_no_repeat(MathoMatic* mathomatic, token_type *equation, int *np) { - uf_power(equation, np); - uf_tsimp(equation, np); + uf_power(mathomatic, equation, np); + uf_tsimp(mathomatic, equation, np); } /* * Totally unfactor equation side with no simplification. */ int -ufactor(equation, np) -token_type *equation; -int *np; +ufactor(MathoMatic* mathomatic, token_type *equation, int *np) { int rv; - uf_repeat(equation, np); - rv = uf_times(equation, np); - uf_allpower(equation, np); + uf_repeat(mathomatic, equation, np); + rv = uf_times(mathomatic, equation, np); + uf_allpower(mathomatic, equation, np); return rv; } @@ -192,9 +176,7 @@ int *np; * Increase the level of numerators by 2, so that the divide operator is not unfactored. */ static void -no_divide(equation, np) -token_type *equation; -int *np; +no_divide(MathoMatic* mathomatic, token_type *equation, int *np) { int i, j; int level; @@ -219,26 +201,24 @@ int *np; * Return true if equation side was unfactored. */ int -uf_times(equation, np) -token_type *equation; -int *np; +uf_times(MathoMatic* mathomatic, token_type *equation, int *np) { int i; int rv = false; do { - organize(equation, np); - if (reorder(equation, np)) { - organize(equation, np); + organize(mathomatic, equation, np); + if (reorder(mathomatic, equation, np)) { + organize(mathomatic, equation, np); } - group_proc(equation, np); - if (partial_flag) { - no_divide(equation, np); + group_proc(mathomatic, equation, np); + if (mathomatic->partial_flag) { + no_divide(mathomatic, equation, np); } - i = sub_ufactor(equation, np, 1); + i = sub_ufactor(mathomatic, equation, np, 1); rv |= i; } while (i); - organize(equation, np); + organize(mathomatic, equation, np); return rv; } @@ -250,10 +230,7 @@ int *np; * Return true if equation side was modified. */ int -sub_ufactor(equation, np, ii) -token_type *equation; -int *np; -int ii; +sub_ufactor(MathoMatic* mathomatic, token_type *equation, int *np, int ii) { int modified = false; int i; @@ -283,7 +260,7 @@ int ii; if (equation[e1].level < level) break; } - if (unf_sub(equation, np, b1, i, e1, level, ii)) { + if (unf_sub(mathomatic, equation, np, b1, i, e1, level, ii)) { modified = true; i = b1 - 1; continue; @@ -293,11 +270,7 @@ int ii; } static int -unf_sub(equation, np, b1, loc, e1, level, ii) -token_type *equation; -int *np; -int b1, loc, e1, level; -int ii; +unf_sub(MathoMatic* mathomatic, token_type *equation, int *np, int b1, int loc, int e1, int level, int ii) { int i, j, k; int b2, eb1, be1; @@ -332,24 +305,24 @@ int ii; } len = 0; u_again: - if (len + (eb1 - b1) + (i - b2) + (e1 - be1) + 1 > n_tokens) { - error_huge(); + if (len + (eb1 - b1) + (i - b2) + (e1 - be1) + 1 > mathomatic->n_tokens) { + error_huge(mathomatic); } - blt(&scratch[len], &equation[b1], (eb1 - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (eb1 - b1) * sizeof(token_type)); j = len; len += (eb1 - b1); for (; j < len; j++) - scratch[j].level++; - blt(&scratch[len], &equation[b2], (i - b2) * sizeof(token_type)); + mathomatic->scratch[j].level++; + blt(&mathomatic->scratch[len], &equation[b2], (i - b2) * sizeof(token_type)); len += (i - b2); - blt(&scratch[len], &equation[be1], (e1 - be1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[be1], (e1 - be1) * sizeof(token_type)); j = len; len += (e1 - be1); for (; j < len; j++) - scratch[j].level++; + mathomatic->scratch[j].level++; if (i < be1) { - scratch[len] = equation[i]; - scratch[len].level--; + mathomatic->scratch[len] = equation[i]; + mathomatic->scratch[len].level--; len++; b2 = i + 1; for (i += 2; i < be1; i += 2) { @@ -358,12 +331,12 @@ int ii; } goto u_again; } else { - if (*np - (e1 - b1) + len > n_tokens) { - error_huge(); + if (*np - (e1 - b1) + len > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[b1+len], &equation[e1], (*np - e1) * sizeof(token_type)); *np += len - (e1 - b1); - blt(&equation[b1], scratch, len * sizeof(token_type)); + blt(&equation[b1], mathomatic->scratch, len * sizeof(token_type)); return true; } } @@ -396,19 +369,19 @@ int ii; b2 = b1; len = 0; u1_again: - if (len + (i - b2) + (e1 - loc) + 1 > n_tokens) { - error_huge(); + if (len + (i - b2) + (e1 - loc) + 1 > mathomatic->n_tokens) { + error_huge(mathomatic); } - blt(&scratch[len], &equation[b2], (i - b2) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b2], (i - b2) * sizeof(token_type)); len += (i - b2); - blt(&scratch[len], &equation[loc], (e1 - loc) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[loc], (e1 - loc) * sizeof(token_type)); j = len; len += (e1 - loc); for (; j < len; j++) - scratch[j].level++; + mathomatic->scratch[j].level++; if (i < loc) { - scratch[len] = equation[i]; - scratch[len].level--; + mathomatic->scratch[len] = equation[i]; + mathomatic->scratch[len].level--; len++; b2 = i + 1; for (i += 2; i < loc; i += 2) { @@ -417,12 +390,12 @@ int ii; } goto u1_again; } else { - if (*np - (e1 - b1) + len > n_tokens) { - error_huge(); + if (*np - (e1 - b1) + len > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[b1+len], &equation[e1], (*np - e1) * sizeof(token_type)); *np += len - (e1 - b1); - blt(&equation[b1], scratch, len * sizeof(token_type)); + blt(&equation[b1], mathomatic->scratch, len * sizeof(token_type)); return true; } } @@ -442,23 +415,23 @@ int ii; b2 = loc + 1; len = 0; u2_again: - if (len + (loc - b1) + (i - b2) + 2 > n_tokens) { - error_huge(); + if (len + (loc - b1) + (i - b2) + 2 > mathomatic->n_tokens) { + error_huge(mathomatic); } j = len; - blt(&scratch[len], &equation[b1], (loc + 1 - b1) * sizeof(token_type)); + blt(&mathomatic->scratch[len], &equation[b1], (loc + 1 - b1) * sizeof(token_type)); len += (loc + 1 - b1); for (; j < len; j++) - scratch[j].level++; - blt(&scratch[len], &equation[b2], (i - b2) * sizeof(token_type)); + mathomatic->scratch[j].level++; + blt(&mathomatic->scratch[len], &equation[b2], (i - b2) * sizeof(token_type)); len += (i - b2); if (i < e1) { - scratch[len].level = level; - scratch[len].kind = OPERATOR; + mathomatic->scratch[len].level = level; + mathomatic->scratch[len].kind = OPERATOR; if (equation[i].token.operatr == PLUS) - scratch[len].token.operatr = TIMES; + mathomatic->scratch[len].token.operatr = TIMES; else - scratch[len].token.operatr = DIVIDE; + mathomatic->scratch[len].token.operatr = DIVIDE; len++; b2 = i + 1; for (i += 2; i < e1; i += 2) { @@ -467,12 +440,12 @@ int ii; } goto u2_again; } else { - if (*np - (e1 - b1) + len > n_tokens) { - error_huge(); + if (*np - (e1 - b1) + len > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[b1+len], &equation[e1], (*np - e1) * sizeof(token_type)); *np += len - (e1 - b1); - blt(&equation[b1], scratch, len * sizeof(token_type)); + blt(&equation[b1], mathomatic->scratch, len * sizeof(token_type)); return true; } } @@ -497,7 +470,7 @@ int ii; } d1 = ceil(d1) - 1.0; d2 = d1 * ((i - b1) + 1.0); - if ((*np + d2) > (n_tokens - 10)) { + if ((*np + d2) > (mathomatic->n_tokens - 10)) { break; /* too big to expand, do nothing */ } j = d1; @@ -526,9 +499,7 @@ int ii; } static int -usp_sub(equation, np, i) -token_type *equation; -int *np, i; +usp_sub(MathoMatic* mathomatic, token_type *equation, int *np, int i) { int level; int j; @@ -544,8 +515,8 @@ int *np, i; return false; } } - if ((*np + 2) > n_tokens) { - error_huge(); + if ((*np + 2) > mathomatic->n_tokens) { + error_huge(mathomatic); } equation[j].token.operatr = TIMES; for (j = i + 1;; j++) { @@ -573,9 +544,7 @@ int *np, i; * Return true if equation side is modified. */ int -unsimp_power(equation, np) -token_type *equation; -int *np; +unsimp_power(MathoMatic* mathomatic, token_type *equation, int *np) { int modified = false; int i; @@ -585,7 +554,7 @@ int *np; if (equation[i].level == equation[i+1].level && equation[i+1].kind == CONSTANT) continue; - modified |= usp_sub(equation, np, i); + modified |= usp_sub(mathomatic, equation, np, i); } } return modified; @@ -599,9 +568,7 @@ int *np; * Return true if equation side is modified. */ int -unsimp2_power(equation, np) -token_type *equation; -int *np; +unsimp2_power(token_type *equation, int *np) { int modified = false; int i; @@ -615,9 +582,7 @@ int *np; } int -usp2_sub(equation, np, i) -token_type *equation; -int *np, i; +usp2_sub(token_type *equation, int *np, int i) { int level; int j, k; @@ -636,8 +601,8 @@ int *np, i; return false; } } - if ((*np + 2) > n_tokens) { - error_huge(); + if ((*np + 2) > mathomatic->n_tokens) { + error_huge(mathomatic); } equation[j].token.operatr = TIMES; j++; @@ -664,9 +629,7 @@ int *np, i; * attempted to be negated, possibly getting rid of unneeded times -1. */ void -uf_neg_help(equation, np) -token_type *equation; -int *np; +uf_neg_help(token_type *equation, int *np, MathoMatic* mathomatic) { int i; int level; @@ -678,8 +641,8 @@ int *np; switch (equation[i+1].token.operatr) { case TIMES: case DIVIDE: - if ((*np + 2) > n_tokens) { - error_huge(); + if ((*np + 2) > mathomatic->n_tokens) { + error_huge(mathomatic); } blt(&equation[i+3], &equation[i+1], (*np - (i + 1)) * sizeof(token_type)); *np += 2; @@ -707,9 +670,7 @@ int *np; * Return true if equation side was modified. */ int -patch_root_div(equation, np) -token_type *equation; -int *np; +patch_root_div(MathoMatic* mathomatic, token_type *equation, int *np) { int i; int level; @@ -724,14 +685,14 @@ int *np; && equation[i+3].level == level && equation[i+3].kind == CONSTANT) { if (fmod(equation[i+1].token.constant, 1.0) == 0.0) { - if (!rationalize_denominators + if (!mathomatic->rationalize_denominators || !isfinite(equation[i+3].token.constant) || equation[i+3].token.constant <= 0.0 || equation[i+3].token.constant >= 1.0) { continue; } - if (*np + 2 > n_tokens) - error_huge(); + if (*np + 2 > mathomatic->n_tokens) + error_huge(mathomatic); equation[i+3].token.constant -= 1.0; blt(&equation[i+2], &equation[i], (*np - i) * sizeof(token_type)); *np += 2; From 4425938f0bc94a882505495ecbeac7d2dc0786cc Mon Sep 17 00:00:00 2001 From: mingodad Date: Mon, 23 Sep 2019 09:49:40 +0200 Subject: [PATCH 2/3] Fix some globals still around, and add "const" qualifier to others --- externs.h | 16 +++++ help.c | 16 ++--- poly.c | 184 +++++++++++++++++++++++++++--------------------------- 3 files changed, 116 insertions(+), 100 deletions(-) diff --git a/externs.h b/externs.h index 17580a6..e1e4fd4 100644 --- a/externs.h +++ b/externs.h @@ -170,6 +170,22 @@ typedef struct { int cur_line; /* current line */ int cur_pos; /* current position in the current line on the screen */ + /* from poly.c*/ +/* + * The following static expression storage areas are of non-standard size + * and must only be used for temporary storage. + * Most Mathomatic expression manipulation and simplification routines should not be used + * on non-standard or constant size expression storage areas. + * Standard size expression storage areas that may be + * manipulated or simplified are the equation spaces, tlhs[], trhs[], and tes[] only. + */ + token_type divisor[DIVISOR_SIZE]; /* static expression storage areas for polynomial and smart division */ + int n_divisor; /* length of expression in divisor[] */ + token_type quotient[DIVISOR_SIZE]; + int n_quotient; /* length of expression in quotient[] */ + token_type gcd_divisor[DIVISOR_SIZE]; /* static expression storage area for polynomial GCD routine */ + int len_d; /* length of expression in gcd_divisor[] */ + } MathoMatic; //extern MathoMatic *mathomatic; diff --git a/help.c b/help.c index 21add31..7622d2a 100644 --- a/help.c +++ b/help.c @@ -34,13 +34,13 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. * The following structure is used for each Mathomatic command. */ typedef struct { - char *name; /* command name to be typed by user (must not contain any spaces) */ - char *secondary_name; /* another name for this command */ + const char *name; /* command name to be typed by user (must not contain any spaces) */ + const char *secondary_name; /* another name for this command */ int (*func)(); /* function that handles this command */ /* function is passed a char pointer and returns true if successful */ - char *usage; /* command syntax text */ - char *info; /* one line description of command */ - char *extra; /* one line extra info on command */ + const char *usage; /* command syntax text */ + const char *info; /* one line description of command */ + const char *extra; /* one line extra info on command */ } com_type; /* @@ -112,7 +112,7 @@ static const com_type com_list[] = { }; #if HELP -char *example_strings[] = { +const char *example_strings[] = { "; Example 1:\n", "; Here the derivative of the absolute value function is computed.\n", "; Expressions are entered by just typing them in:\n", @@ -149,7 +149,7 @@ char *example_strings[] = { #endif #if HELP -char *geometry_strings[] = { +const char *geometry_strings[] = { "; Triangle area, \"b\" is the \"base\" side:\n", "triangle_area = b*height/2\n", "; Here is Heron's formula for the area of any triangle\n", @@ -187,7 +187,7 @@ char *geometry_strings[] = { NULL }; -char *conversion_strings[] = { +const char *conversion_strings[] = { "; Temperature\n", "fahrenheit = (9*celsius/5) + 32\n", "kelvin = celsius + 273.15\n", diff --git a/poly.c b/poly.c index 3f8600f..748eb8c 100644 --- a/poly.c +++ b/poly.c @@ -51,12 +51,12 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. * Standard size expression storage areas that may be * manipulated or simplified are the equation spaces, tlhs[], trhs[], and tes[] only. */ -token_type divisor[DIVISOR_SIZE]; /* static expression storage areas for polynomial and smart division */ -int n_divisor; /* length of expression in divisor[] */ -token_type quotient[DIVISOR_SIZE]; -int n_quotient; /* length of expression in quotient[] */ -token_type gcd_divisor[DIVISOR_SIZE]; /* static expression storage area for polynomial GCD routine */ -int len_d; /* length of expression in gcd_divisor[] */ +//token_type divisor[DIVISOR_SIZE]; /* static expression storage areas for polynomial and smart division */ +//int n_divisor; /* length of expression in divisor[] */ +//token_type quotient[DIVISOR_SIZE]; +//int n_quotient; /* length of expression in quotient[] */ +//token_type gcd_divisor[DIVISOR_SIZE]; /* static expression storage area for polynomial GCD routine */ +//int len_d; /* length of expression in gcd_divisor[] */ static int pf_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int do_repeat); static int pf_sub(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int len, int level, int do_repeat); @@ -621,25 +621,25 @@ do_gcd(MathoMatic* mathomatic, long *vp) int count; for (count = 1; count < 50; count++) { - switch (poly_div(mathomatic, mathomatic->trhs, mathomatic->n_trhs, gcd_divisor, len_d, vp)) { + switch (poly_div(mathomatic, mathomatic->trhs, mathomatic->n_trhs, mathomatic->gcd_divisor, mathomatic->len_d, vp)) { case 0: /* divide failed */ return(1 - count); case 2: /* Total success! Remainder is zero. */ debug_string(mathomatic, 2, "Found raw polynomial GCD:"); - side_debug(mathomatic, 2, gcd_divisor, len_d); + side_debug(mathomatic, 2, mathomatic->gcd_divisor, mathomatic->len_d); return count; } /* Do the Euclidean shuffle: swap trhs[] (remainder) and gcd_divisor[] */ - if (len_d > mathomatic->n_tokens || mathomatic->n_trhs > DIVISOR_SIZE) + if (mathomatic->len_d > mathomatic->n_tokens || mathomatic->n_trhs > DIVISOR_SIZE) return 0; blt(mathomatic->scratch, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); - blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); - blt(gcd_divisor, mathomatic->scratch, mathomatic->n_trhs * sizeof(token_type)); + blt(mathomatic->trhs, mathomatic->gcd_divisor, mathomatic->len_d * sizeof(token_type)); + blt(mathomatic->gcd_divisor, mathomatic->scratch, mathomatic->n_trhs * sizeof(token_type)); i = mathomatic->n_trhs; - mathomatic->n_trhs = len_d; - len_d = i; + mathomatic->n_trhs = mathomatic->len_d; + mathomatic->len_d = i; } return 0; } @@ -667,7 +667,7 @@ poly_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *small debug_string(mathomatic, 3, "Entering poly_gcd():"); side_debug(mathomatic, 3, larger, llen); side_debug(mathomatic, 3, smaller, slen); - if (llen > mathomatic->n_tokens || slen > min(ARR_CNT(gcd_divisor), mathomatic->n_tokens)) + if (llen > mathomatic->n_tokens || slen > min(ARR_CNT(mathomatic->gcd_divisor), mathomatic->n_tokens)) return 0; if (mathomatic->trhs != larger) { blt(mathomatic->trhs, larger, llen * sizeof(token_type)); @@ -679,33 +679,33 @@ poly_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *small mathomatic->n_tlhs = slen; if (!remove_factors(mathomatic)) return 0; - if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) + if (mathomatic->n_tlhs > ARR_CNT(mathomatic->gcd_divisor)) return 0; - blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - len_d = mathomatic->n_tlhs; + blt(mathomatic->gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->len_d = mathomatic->n_tlhs; count = do_gcd(mathomatic, &v); if (count <= 0) return 0; if (count > 1) { - if (len_d > mathomatic->n_tokens) + if (mathomatic->len_d > mathomatic->n_tokens) return 0; - blt(mathomatic->tlhs, gcd_divisor, len_d * sizeof(token_type)); - mathomatic->n_tlhs = len_d; + blt(mathomatic->tlhs, mathomatic->gcd_divisor, mathomatic->len_d * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->len_d; if (!remove_factors(mathomatic)) return 0; - if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) + if (mathomatic->n_tlhs > ARR_CNT(mathomatic->gcd_divisor)) return 0; - blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - len_d = mathomatic->n_tlhs; - if (poly_div(mathomatic, larger, llen, gcd_divisor, len_d, &v) != 2) { + blt(mathomatic->gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->len_d = mathomatic->n_tlhs; + if (poly_div(mathomatic, larger, llen, mathomatic->gcd_divisor, mathomatic->len_d, &v) != 2) { debug_string(mathomatic, 1, "Polynomial GCD found, but larger divide failed in poly_gcd()."); return 0; } } - if (len_d > mathomatic->n_tokens) + if (mathomatic->len_d > mathomatic->n_tokens) return 0; - blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); - mathomatic->n_trhs = len_d; + blt(mathomatic->trhs, mathomatic->gcd_divisor, mathomatic->len_d * sizeof(token_type)); + mathomatic->n_trhs = mathomatic->len_d; uf_simp(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); uf_simp(mathomatic, mathomatic->trhs, &mathomatic->n_trhs); debug_string(mathomatic, 3, "poly_gcd() successful."); @@ -758,7 +758,7 @@ poly2_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *smal debug_string(mathomatic, 3, "Entering poly2_gcd():"); side_debug(mathomatic, 3, larger, llen); side_debug(mathomatic, 3, smaller, slen); - if (llen > mathomatic->n_tokens || slen > min(ARR_CNT(gcd_divisor), mathomatic->n_tokens)) + if (llen > mathomatic->n_tokens || slen > min(ARR_CNT(mathomatic->gcd_divisor), mathomatic->n_tokens)) return 0; blt(mathomatic->trhs, larger, llen * sizeof(token_type)); mathomatic->n_trhs = llen; @@ -781,34 +781,34 @@ poly2_gcd(MathoMatic* mathomatic, token_type *larger, int llen, token_type *smal return 0; } #endif - if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) + if (mathomatic->n_tlhs > ARR_CNT(mathomatic->gcd_divisor)) return 0; - blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - len_d = mathomatic->n_tlhs; + blt(mathomatic->gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->len_d = mathomatic->n_tlhs; count = do_gcd(mathomatic, &v); if (count <= 0) return count; if (count > 1) { - if (require_additive && level1_plus_count(mathomatic, gcd_divisor, len_d) == 0) + if (require_additive && level1_plus_count(mathomatic, mathomatic->gcd_divisor, mathomatic->len_d) == 0) return 0; - if (poly_div(mathomatic, smaller, slen, gcd_divisor, len_d, &v) != 2) { + if (poly_div(mathomatic, smaller, slen, mathomatic->gcd_divisor, mathomatic->len_d, &v) != 2) { debug_string(mathomatic, 1, "Polynomial GCD found, but smaller divide failed in poly2_gcd()."); return 0; } - blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); - mathomatic->n_trhs = len_d; - if (mathomatic->n_tlhs > ARR_CNT(gcd_divisor)) + blt(mathomatic->trhs, mathomatic->gcd_divisor, mathomatic->len_d * sizeof(token_type)); + mathomatic->n_trhs = mathomatic->len_d; + if (mathomatic->n_tlhs > ARR_CNT(mathomatic->gcd_divisor)) return 0; - blt(gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - len_d = mathomatic->n_tlhs; + blt(mathomatic->gcd_divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->len_d = mathomatic->n_tlhs; blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); mathomatic->n_tlhs = mathomatic->n_trhs; if (poly_div(mathomatic, larger, llen, mathomatic->tlhs, mathomatic->n_tlhs, &v) != 2) { debug_string(mathomatic, 1, "Polynomial GCD found, but larger divide failed in poly2_gcd()."); return 0; } - blt(mathomatic->trhs, gcd_divisor, len_d * sizeof(token_type)); - mathomatic->n_trhs = len_d; + blt(mathomatic->trhs, mathomatic->gcd_divisor, mathomatic->len_d * sizeof(token_type)); + mathomatic->n_trhs = mathomatic->len_d; } else { mathomatic->n_trhs = 1; mathomatic->trhs[0] = mathomatic->one_token; @@ -1460,21 +1460,21 @@ poly_div_sub(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, i return false; /* Initialize the quotient. */ - n_quotient = 1; - quotient[0] = mathomatic->zero_token; + mathomatic->n_quotient = 1; + mathomatic->quotient[0] = mathomatic->zero_token; /* Store the divisor. */ - if (mathomatic->n_tlhs > ARR_CNT(divisor)) + if (mathomatic->n_tlhs > ARR_CNT(mathomatic->divisor)) return false; - blt(divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - n_divisor = mathomatic->n_tlhs; - sum_size = mathomatic->n_trhs + n_quotient; + blt(mathomatic->divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_divisor = mathomatic->n_tlhs; + sum_size = mathomatic->n_trhs + mathomatic->n_quotient; /* Loop until polynomial division is finished. */ for (;;) { if (t1 > 0 && mathomatic->trhs[t1-1].token.operatr == MINUS) sign = MINUS; else sign = PLUS; - if (t2 > 0 && divisor[t2-1].token.operatr == MINUS) { + if (t2 > 0 && mathomatic->divisor[t2-1].token.operatr == MINUS) { if (sign == MINUS) sign = PLUS; else @@ -1490,24 +1490,24 @@ poly_div_sub(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, i mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; mathomatic->n_tlhs++; - blt(&mathomatic->tlhs[mathomatic->n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); + blt(&mathomatic->tlhs[mathomatic->n_tlhs], &mathomatic->divisor[t2], len_t2 * sizeof(token_type)); i = mathomatic->n_tlhs; mathomatic->n_tlhs += len_t2; for (; i < mathomatic->n_tlhs; i++) mathomatic->tlhs[i].level++; if (!simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs)) return false; - if ((n_quotient + 1 + mathomatic->n_tlhs) > min(ARR_CNT(quotient), mathomatic->n_tokens)) + if ((mathomatic->n_quotient + 1 + mathomatic->n_tlhs) > min(ARR_CNT(mathomatic->quotient), mathomatic->n_tokens)) return false; for (i = 0; i < mathomatic->n_tlhs; i++) mathomatic->tlhs[i].level++; - quotient[n_quotient].level = 1; - quotient[n_quotient].kind = OPERATOR; - quotient[n_quotient].token.operatr = sign; - n_quotient++; - blt("ient[n_quotient], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - n_quotient += mathomatic->n_tlhs; - if ((mathomatic->n_trhs + mathomatic->n_tlhs + n_divisor + 2) > mathomatic->n_tokens) + mathomatic->quotient[mathomatic->n_quotient].level = 1; + mathomatic->quotient[mathomatic->n_quotient].kind = OPERATOR; + mathomatic->quotient[mathomatic->n_quotient].token.operatr = sign; + mathomatic->n_quotient++; + blt(&mathomatic->quotient[mathomatic->n_quotient], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_quotient += mathomatic->n_tlhs; + if ((mathomatic->n_trhs + mathomatic->n_tlhs + mathomatic->n_divisor + 2) > mathomatic->n_tokens) return false; blt(&mathomatic->trhs[t1+1], &mathomatic->trhs[t1+len_t1], (mathomatic->n_trhs - (t1 + len_t1)) * sizeof(token_type)); mathomatic->n_trhs -= len_t1 - 1; @@ -1531,12 +1531,12 @@ poly_div_sub(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, i mathomatic->trhs[mathomatic->n_trhs].token.operatr = TIMES; mathomatic->n_trhs++; i = mathomatic->n_trhs; - blt(&mathomatic->trhs[mathomatic->n_trhs], divisor, t2 * sizeof(token_type)); + blt(&mathomatic->trhs[mathomatic->n_trhs], mathomatic->divisor, t2 * sizeof(token_type)); mathomatic->n_trhs += t2; mathomatic->trhs[mathomatic->n_trhs] = mathomatic->zero_token; mathomatic->n_trhs++; - blt(&mathomatic->trhs[mathomatic->n_trhs], &divisor[t2+len_t2], (n_divisor - (t2 + len_t2)) * sizeof(token_type)); - mathomatic->n_trhs += (n_divisor - (t2 + len_t2)); + blt(&mathomatic->trhs[mathomatic->n_trhs], &mathomatic->divisor[t2+len_t2], (mathomatic->n_divisor - (t2 + len_t2)) * sizeof(token_type)); + mathomatic->n_trhs += (mathomatic->n_divisor - (t2 + len_t2)); for (; i < mathomatic->n_trhs; i++) mathomatic->trhs[i].level += 2; side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); @@ -1547,16 +1547,16 @@ poly_div_sub(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, i if (d < divisor_power) { /* Success! Polynomial division ends here. */ debug_string(mathomatic, 3, "Successful polynomial division!"); - blt(mathomatic->tlhs, quotient, n_quotient * sizeof(token_type)); - mathomatic->n_tlhs = n_quotient; + blt(mathomatic->tlhs, mathomatic->quotient, mathomatic->n_quotient * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_quotient; debug_string(mathomatic, 3, "Quotient:"); side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); debug_string(mathomatic, 3, "Remainder:"); side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); if (REMAINDER_IS_ZERO()) return 2; - if ((mathomatic->n_trhs + n_quotient) >= (sum_size /* - (sum_size / 10) */)) { - if ((mathomatic->n_trhs + 1) > sum_size && mathomatic->n_trhs > n_divisor) + if ((mathomatic->n_trhs + mathomatic->n_quotient) >= (sum_size /* - (sum_size / 10) */)) { + if ((mathomatic->n_trhs + 1) > sum_size && mathomatic->n_trhs > mathomatic->n_divisor) return -2; else return -1; @@ -1650,16 +1650,16 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int if (len_t2 <= 0) return false; /* Initialize the quotient. */ - n_quotient = 1; - quotient[0] = mathomatic->zero_token; - if (mathomatic->n_tlhs > ARR_CNT(divisor)) + mathomatic->n_quotient = 1; + mathomatic->quotient[0] = mathomatic->zero_token; + if (mathomatic->n_tlhs > ARR_CNT(mathomatic->divisor)) return false; - blt(divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - n_divisor = mathomatic->n_tlhs; + blt(mathomatic->divisor, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_divisor = mathomatic->n_tlhs; try_one: trhs_size = mathomatic->n_trhs; for (skip_count = 0, count = 0;;) { - sum_size = mathomatic->n_trhs + n_quotient; + sum_size = mathomatic->n_trhs + mathomatic->n_quotient; for (term_count = 1, q_size = 0;; term_count++) { if (!get_term(mathomatic->trhs, mathomatic->n_trhs, term_count, &t1, &len_t1)) break; @@ -1682,7 +1682,7 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; mathomatic->n_tlhs++; - blt(&mathomatic->tlhs[mathomatic->n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); + blt(&mathomatic->tlhs[mathomatic->n_tlhs], &mathomatic->divisor[t2], len_t2 * sizeof(token_type)); i = mathomatic->n_tlhs; mathomatic->n_tlhs += len_t2; for (; i < mathomatic->n_tlhs; i++) @@ -1701,20 +1701,20 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int if (dcount > 1) { dcount = 1; t2 = 0; - len_t2 = n_divisor; + len_t2 = mathomatic->n_divisor; goto try_one; /* Try using the whole divisor as the divisor term. */ } return false; } end_div: if (dcount > 1) { - if (n_quotient + mathomatic->n_trhs >= trhs_size + 1) { + if (mathomatic->n_quotient + mathomatic->n_trhs >= trhs_size + 1) { return false; } } end_div2: - blt(mathomatic->tlhs, quotient, n_quotient * sizeof(token_type)); - mathomatic->n_tlhs = n_quotient; + blt(mathomatic->tlhs, mathomatic->quotient, mathomatic->n_quotient * sizeof(token_type)); + mathomatic->n_tlhs = mathomatic->n_quotient; side_debug(mathomatic, 3, mathomatic->tlhs, mathomatic->n_tlhs); side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); return true; /* Success! */ @@ -1725,7 +1725,7 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int sign = MINUS; else sign = PLUS; - if (t2 > 0 && divisor[t2-1].token.operatr == MINUS) { + if (t2 > 0 && mathomatic->divisor[t2-1].token.operatr == MINUS) { if (sign == MINUS) sign = PLUS; else @@ -1741,26 +1741,26 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int mathomatic->tlhs[mathomatic->n_tlhs].kind = OPERATOR; mathomatic->tlhs[mathomatic->n_tlhs].token.operatr = DIVIDE; mathomatic->n_tlhs++; - blt(&mathomatic->tlhs[mathomatic->n_tlhs], &divisor[t2], len_t2 * sizeof(token_type)); + blt(&mathomatic->tlhs[mathomatic->n_tlhs], &mathomatic->divisor[t2], len_t2 * sizeof(token_type)); i = mathomatic->n_tlhs; mathomatic->n_tlhs += len_t2; for (; i < mathomatic->n_tlhs; i++) mathomatic->tlhs[i].level++; simp_loop(mathomatic, mathomatic->tlhs, &mathomatic->n_tlhs); - if ((n_quotient + 1 + mathomatic->n_tlhs) > min(ARR_CNT(quotient), mathomatic->n_tokens)) + if ((mathomatic->n_quotient + 1 + mathomatic->n_tlhs) > min(ARR_CNT(mathomatic->quotient), mathomatic->n_tokens)) return false; for (i = 0; i < mathomatic->n_tlhs; i++) mathomatic->tlhs[i].level++; - old_n_quotient = n_quotient; - quotient[n_quotient].level = 1; - quotient[n_quotient].kind = OPERATOR; - quotient[n_quotient].token.operatr = sign; - n_quotient++; - qp = "ient[n_quotient]; + old_n_quotient = mathomatic->n_quotient; + mathomatic->quotient[mathomatic->n_quotient].level = 1; + mathomatic->quotient[mathomatic->n_quotient].kind = OPERATOR; + mathomatic->quotient[mathomatic->n_quotient].token.operatr = sign; + mathomatic->n_quotient++; + qp = &mathomatic->quotient[mathomatic->n_quotient]; q_size = mathomatic->n_tlhs; - blt("ient[n_quotient], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); - n_quotient += mathomatic->n_tlhs; - if ((mathomatic->n_trhs + q_size + n_divisor + 2) > mathomatic->n_tokens) + blt(&mathomatic->quotient[mathomatic->n_quotient], mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); + mathomatic->n_quotient += mathomatic->n_tlhs; + if ((mathomatic->n_trhs + q_size + mathomatic->n_divisor + 2) > mathomatic->n_tokens) return false; blt(mathomatic->tlhs, mathomatic->trhs, mathomatic->n_trhs * sizeof(token_type)); mathomatic->n_tlhs = mathomatic->n_trhs; @@ -1786,12 +1786,12 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int mathomatic->trhs[mathomatic->n_trhs].token.operatr = TIMES; mathomatic->n_trhs++; i = mathomatic->n_trhs; - blt(&mathomatic->trhs[mathomatic->n_trhs], divisor, t2 * sizeof(token_type)); + blt(&mathomatic->trhs[mathomatic->n_trhs], mathomatic->divisor, t2 * sizeof(token_type)); mathomatic->n_trhs += t2; mathomatic->trhs[mathomatic->n_trhs] = mathomatic->zero_token; mathomatic->n_trhs++; - blt(&mathomatic->trhs[mathomatic->n_trhs], &divisor[t2+len_t2], (n_divisor - (t2 + len_t2)) * sizeof(token_type)); - mathomatic->n_trhs += (n_divisor - (t2 + len_t2)); + blt(&mathomatic->trhs[mathomatic->n_trhs], &mathomatic->divisor[t2+len_t2], (mathomatic->n_divisor - (t2 + len_t2)) * sizeof(token_type)); + mathomatic->n_trhs += (mathomatic->n_divisor - (t2 + len_t2)); for (; i < mathomatic->n_trhs; i++) mathomatic->trhs[i].level += 2; side_debug(mathomatic, 3, mathomatic->trhs, mathomatic->n_trhs); @@ -1800,12 +1800,12 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int if (REMAINDER_IS_ZERO()) goto end_div2; if (dcount > 1) { - if ((mathomatic->n_trhs + n_quotient) >= sum_size) { + if ((mathomatic->n_trhs + mathomatic->n_quotient) >= sum_size) { if (skip_count >= ARR_CNT(skip_terms)) { if (count == 0) { return false; } else { - n_quotient = old_n_quotient; + mathomatic->n_quotient = old_n_quotient; blt(mathomatic->trhs, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); mathomatic->n_trhs = mathomatic->n_tlhs; goto end_div; @@ -1813,7 +1813,7 @@ smart_div(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int } skip_terms[skip_count] = term_pos; skip_count++; - n_quotient = old_n_quotient; + mathomatic->n_quotient = old_n_quotient; blt(mathomatic->trhs, mathomatic->tlhs, mathomatic->n_tlhs * sizeof(token_type)); mathomatic->n_trhs = mathomatic->n_tlhs; debug_string(mathomatic, 3, "Skipping last operation."); From 938d83c21fbbcb6cf72bca29f5f2421853c091ad Mon Sep 17 00:00:00 2001 From: mingodad Date: Tue, 27 Sep 2022 13:37:57 +0200 Subject: [PATCH 3/3] Fixes to build amalgamation and compile with https://github.com/jart/cosmopolitan --- am.c | 8 +-- cmds.c | 6 +- complex_lib.c | 4 ++ help.c | 2 +- includes.h | 2 + main.c | 16 ++--- mk-mathomatic-amalgamation.lua | 120 +++++++++++++++++++++++++++++++++ mk-mathomatic.sh | 16 +++++ poly.c | 5 +- proto.h | 2 +- 10 files changed, 159 insertions(+), 22 deletions(-) create mode 100644 mk-mathomatic-amalgamation.lua create mode 100755 mk-mathomatic.sh diff --git a/am.c b/am.c index 37403df..a57d651 100644 --- a/am.c +++ b/am.c @@ -155,8 +155,7 @@ error_bug(MathoMatic* mathomatic, const char *str) void check_err(MathoMatic* mathomatic) { - switch (errno) { - case EDOM: + if(errno == EDOM) { errno = 0; if (mathomatic->domain_check) { mathomatic->domain_check = false; @@ -164,12 +163,11 @@ check_err(MathoMatic* mathomatic) error(mathomatic, _("Domain error in constant.")); longjmp(mathomatic->jmp_save, 2); } - break; - case ERANGE: + } + if(errno == ERANGE) { errno = 0; error(mathomatic, _("Floating point constant out of range.")); longjmp(mathomatic->jmp_save, 2); - break; } } diff --git a/cmds.c b/cmds.c index 3bb62ab..687715d 100644 --- a/cmds.c +++ b/cmds.c @@ -193,6 +193,7 @@ plot_cmd(MathoMatic* mathomatic, char *cp) printf(_("Shell command-line = %s\n"), cl); } return true; +#undef APPEND } #endif @@ -3431,7 +3432,8 @@ code_cmd(MathoMatic* mathomatic, char *cp) } while (*cp); return displayed; } - +#ifndef VCMP_DEFINED +#define VCMP_DEFINED /*there is a copy elsewhere */ /* * Compare function for qsort(3). */ @@ -3448,7 +3450,7 @@ sort_type *p1, *p2; } return(p2->count - p1->count); } - +#endif /*VCMP_DEFINED*/ /* * The variables command. */ diff --git a/complex_lib.c b/complex_lib.c index 020af71..8b19467 100644 --- a/complex_lib.c +++ b/complex_lib.c @@ -27,8 +27,10 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. #include "complex.h" #include +#ifndef true #define true 1 #define false 0 +#endif #define epsilon 0.00000000000005 /* a good value for doubles */ @@ -165,3 +167,5 @@ complexs a, b; complex_fixup(&r); return(r); } + +#undef epsilon diff --git a/help.c b/help.c index 7622d2a..10cf6de 100644 --- a/help.c +++ b/help.c @@ -917,7 +917,7 @@ display_repeat_command(MathoMatic* mathomatic) } int -read_examples(MathoMatic* mathomatic, char **cpp) +read_examples(MathoMatic* mathomatic, const char **cpp) { int i; char *cp; diff --git a/includes.h b/includes.h index 02164b8..c936c5d 100644 --- a/includes.h +++ b/includes.h @@ -24,8 +24,10 @@ George Gesslein II, P.O. Box 224, Lansing, NY 14882-0224 USA. */ +#ifndef true #define true 1 #define false 0 +#endif #if 0 #define _REENTRANT 1 /* Can be defined before including math.h for Mac OS X. Mac OS X allows a few re-entrant functions with this. iOS requires this commented out. */ diff --git a/main.c b/main.c index 8b09a25..2ba7d5a 100644 --- a/main.c +++ b/main.c @@ -113,9 +113,7 @@ usage(FILE *fp) } int -main(argc, argv) -int argc; -char **argv; +main(int argc, char *argv[]) { #if NO_GETOPT_H /* if no getopt.h is available */ extern char *optarg; /* set by getopt(3) */ @@ -426,8 +424,7 @@ main_io_loop(void) * Return zero on success, or a non-zero unsettable signal number on error. */ int -set_signals(time_out_seconds) -unsigned int time_out_seconds; +set_signals(unsigned int time_out_seconds) { int rv = 0; @@ -466,8 +463,7 @@ unsigned int time_out_seconds; * Floating point exceptions are currently ignored. */ void -fphandler(sig) -int sig; +fphandler(int sig) { #if DEBUG warning(mathomatic, "Floating point exception."); @@ -480,8 +476,7 @@ int sig; * If it can't, repeated calls terminate this program. */ void -inthandler(sig) -int sig; +inthandler(int sig) { matho_inc_abort_flag(mathomatic); switch (matho_get_abort_flag(mathomatic)) { @@ -505,8 +500,7 @@ int sig; * Alarm signal handler. */ void -alarmhandler(sig) -int sig; +alarmhandler(int sig) { printf(_("\nTimeout, quitting...\n")); exit_program(mathomatic, 1); diff --git a/mk-mathomatic-amalgamation.lua b/mk-mathomatic-amalgamation.lua new file mode 100644 index 0000000..f990be4 --- /dev/null +++ b/mk-mathomatic-amalgamation.lua @@ -0,0 +1,120 @@ +local base_dir = "./"; +local includes_base = {"lib/"} +local sq_sources = [==[ +globals.c +am.c +solve.c +help.c +parse.c +cmds.c +simplify.c +factor.c +super.c +unfactor.c +poly.c +diff.c +integrate.c +complex.c +complex_lib.c +list.c +gcd.c +factor_int.c +main.c +]==]; + +local included = {}; +local inc_sys = {}; +local inc_sys_count = 0; +local out = io.stdout + +function CopyWithInline(prefix, filename) + if included[filename] then return end + included[filename] = true + print('//--Start of', filename); + --if(filename:match("luac?.c")) + local inp = io.open(prefix .. filename, "r") + if not inp then + for idx in ipairs(includes_base) do + local sdir = includes_base[idx] + local fn = prefix .. sdir .. filename + --print(fn) + inp = io.open(fn, "r") + if inp then break end + end + end + if not inp then + if filename == "fzn_picat_sat_bc.h" then + print('//--End of', filename); + end + else + assert(inp) + for line in inp:lines() do + if line:match('#define LUA_USE_READLINE') then + out:write("//" .. line .. "\n") + else + local inc = line:match('#include%s+(["<].-)[">]') + if inc then + out:write("//" .. line .. "\n") + if inc:sub(1,1) == '"' or inc:match('[<"]sq') then + CopyWithInline(prefix, inc:sub(2)) + else + local fn = inc:sub(2) + if inc_sys[fn] == null then + inc_sys_count = inc_sys_count +1 + inc_sys[fn] = inc_sys_count + end + end + else + out:write(line .. "\n") + end + end + end + print('//--End of', filename); + end +end + +print([==[ +#ifdef WITH_COSMOPOLITAN + +STATIC_STACK_SIZE(0x400000); + +#endif + +#ifndef __COSMOPOLITAN__ +//gcc -Wall -DUNIX -DVERSION=\"16.0.5\" -o mathomatic mathomatic-am.c -lm +#include //7 +#include //21 +#include //3 +#include //8 +#include //11 +#include //27 +//#include //26 +#include //20 +#include //10 +#include //22 +#include //13 +//#include //25 +#include //9 +#include //4 +#include //24 +#include //16 +#include //19 +#include //18 +#include //17 +#include //12 +#include //2 +#include //23 +#include //14 +#include //15 +#include //1 +//#include //5 +#include //6 + +#endif +]==]) + +local prefix = base_dir; local src_files = sq_sources; +for filename in src_files:gmatch('([^\n]+)') do + CopyWithInline(prefix, filename); +end +--for k, v in pairs(inc_sys) do print("#include <" .. k .. "> //" .. v ) end diff --git a/mk-mathomatic.sh b/mk-mathomatic.sh new file mode 100755 index 0000000..50cb07e --- /dev/null +++ b/mk-mathomatic.sh @@ -0,0 +1,16 @@ +# run gcc compiler in freestanding mode +gcc -g -Os -static -fno-pie -no-pie -nostdlib -nostdinc \ + -fno-omit-frame-pointer -pg -mnop-mcount -mno-tls-direct-seg-refs \ + -o mathomatic.com.dbg mathomatic-am.c \ + -DUNIX -DVERSION=\"16.0.5\" \ + -DWITH_COSMOPOLITAN \ + -Wl,--gc-sections -fuse-ld=bfd -Wl,--gc-sections \ + -Wl,-T,ape.lds -include cosmopolitan.h crt.o ape-no-modify-self.o cosmopolitan.a +objcopy -S -O binary mathomatic.com.dbg mathomatic.com + + +# NOTE: scp it to windows/mac/etc. *before* you run it! +# ~40kb static binary (can be ~16kb w/ MODE=tiny) +./ape.elf ./mathomatic.com +# -DSTACK_FRAME_UNLIMITED \ +# -fno-gcse -ffunction-sections -fdata-sections \ diff --git a/poly.c b/poly.c index 748eb8c..c544bc8 100644 --- a/poly.c +++ b/poly.c @@ -67,7 +67,8 @@ static int polydiv_recurse(MathoMatic* mathomatic, token_type *equation, int *np static int pdiv_recurse(MathoMatic* mathomatic, token_type *equation, int *np, int loc, int level, int code); static int poly_div_sub(MathoMatic* mathomatic, token_type *d1, int len1, token_type *d2, int len2, long *vp); static int find_highest_count(token_type *p1, int n1, token_type *p2, int n2, long *vp1); - +#ifndef VCMP_DEFINED +#define VCMP_DEFINED /*there is a copy elsewhere */ /* * Compare function for qsort(3). */ @@ -84,7 +85,7 @@ sort_type *p1, *p2; } return(p2->count - p1->count); } - +#endif /*VCMP_DEFINED*/ /* * Return true if passed expression is strictly a single polynomial term in variable v. * The general form of a polynomial term is c*(v^d) diff --git a/proto.h b/proto.h index df9c0d0..31d5441 100644 --- a/proto.h +++ b/proto.h @@ -166,7 +166,7 @@ char *parse_var2(MathoMatic* mathomatic, long *vp, char *cp); int display_usage(MathoMatic* mathomatic, char *pstr, int i); int display_command(MathoMatic* mathomatic, int i); int display_repeat_command(MathoMatic* mathomatic); -int read_examples(MathoMatic* mathomatic, char **cpp); +int read_examples(MathoMatic* mathomatic, const char **cpp); void underline_title(MathoMatic* mathomatic, int count); int help_cmd(MathoMatic* mathomatic, char *cp); /* integrate.c */