Sindbad~EG File Manager
/* 1.17.06 removed calls to SetFontSize and all mention of display_control so
this can be compiled without symsout.dll.
3.20.06 made include files lowercase and removed a superfluous include.
*/
#ifdef __WIN32
#define EXTERNALSIMP_DLL
#endif
#include <malloc.h>
#include <assert.h>
#include <string.h>
#include "export.h"
#include "globals.h"
#include "graphstr.h"
#include "document.h"
#include "userfunc.h"
#include "parser.h"
#include "heaps.h"
#include "ssolve.h"
#include "activate.h"
#include "cflags.h"
#include "mpmem.h"
#include "mathpertlink.h"
static parser_control parser_flags = { 2, /* separator, see display.c */
'.', /* decimalchar */
0, /* unwritten_mult */
1, /* complex */
2, /* long identifiers not allowed */
0, /* letflag */
"fFgGhH "
};
/* remaining fields have to be dynamically initialized */
int mparse(term *t, char *in, char **rest)
{ return bparse(&parser_flags,t,in,rest);
}
/*___________________________________________________________*/
static int nextdocument = 1; /* next document will get this number */
static int ndocuments; /* total number of open documents */
/* you might have documents 1,3,9 open for example, then
ndocuments is 3 and nextdocument is 2 */
typedef struct
{ unsigned long hwnd;
int docnumber;
} docstruct;
static docstruct documents[MAXDOCUMENTS];
/*________________________________________________*/
static void add_document(unsigned long hwnd)
/* adjust the documents array, and the variables ndocuments and
nextdocument. Presumes that ndocuments < MAXDOCUMENTS so that there
is room to add a new document. */
{ int i,j;
if(ndocuments >= MAXDOCUMENTS)
assert(0);
/* Now insert nextdocument into the documents array in the right
place to maintain sorted order. */
for(i=0;i<=ndocuments;i++)
{ if(documents[i].docnumber > nextdocument)
break;
}
if(i==ndocuments+1)
/* nextdocument is larger than all in-use document numbers,
so it goes at the end */
{ documents[ndocuments].docnumber = nextdocument;
documents[ndocuments].hwnd = (unsigned long) hwnd;
}
else /* nextdocument comes just before documents[i]. So we
move documents[i] and all subsequent entries down
one in the documents array and put nextdocument in at
documents[i] */
{ for(j=ndocuments-1;j >= i; j--)
documents[j+1] = documents[j];
documents[i].docnumber = nextdocument;
documents[i].hwnd = (unsigned long) hwnd;
}
++ndocuments;
/* Now set the new value of nextdocument */
/* It should be the least positive integer not in the array documents */
for(i=1;i<=MAXDOCUMENTS;i++)
{ /* is i in the documents array? */
for(j=0;j<ndocuments;j++)
{ if(documents[j].docnumber == i)
break;
if(documents[j].docnumber > i)
{ /* i is the answer, since documents is in sorted order */
nextdocument = i;
return;
}
}
if(j < ndocuments)
continue;
/* i was larger than all elements of the documents array */
nextdocument = i;
return;
}
}
/*______________________________________________________________________*/
static void delete_document(int k)
/* remove document number k, adjusting nextdocument and the
documents array and decrementing ndocuments */
{ int i,j;
for(i=0;i<ndocuments;i++)
{ if(documents[i].docnumber == k)
break;
}
assert(i < ndocuments);
if(k < nextdocument)
nextdocument = k;
/* Next compact the documents array to fill the gap */
for(j=i;j<ndocuments-1;j++)
documents[j] = documents[j+1];
documents[ndocuments-1].docnumber = 0; // 7.14.2004
documents[ndocuments-1].hwnd = 0; // 7.14.2004
--ndocuments;
}
/*___________________________________________________________________*/
static int allocate_doc_data(PSYMBOLDATA pdata)
/* initialize the data required for a document */
/* Do NOT assume the document is active */
/* When this is called, mainchoice and problemtype have
already been initialized, and must get stored in the
document data structure. */
/* allocate the document's heap */
/* allocate the following fields of the document structure:
varlist, varinfo, model, assumptions, defns, parameters,
history, permspace, permhistory. Memory for these structures is
allocated on the Windows global heap, where it can be
realloc'd if necessary so that in essence these arrays have
no fixed dimension.
Does not allocate 'graphs' (which is an array of fixed
dimension MAXGRAPHS) and does not allocate the graph
structures in that array either (setupdata does that).
Return 0 for success,
1 for too many documents already,
2 for not enough memory to allocate the heap or other structures
*/
{ int err;
unsigned long heapsize_in_bytes;
pdata->docnumber = nextdocument;
/* adjust ndocuments and nextdocument and the documents array */
add_document(0); /* it hasn't got a window handle yet */
pdata->DocVarData.maxvariables = 32;
pdata->DocVarData.nvariables = 0;
pdata->DocVarData.eigenvariable = 0;
pdata->DocVarData.maxparameters = MAXPARAMS;
pdata->DocVarData.nparameters = 0;
pdata->DocVarData.maxdefns = 32;
pdata->DocVarData.nextdefn = 0;
pdata->DocProverData.solver = ssolve;
pdata->DocProverData.maxassumptions = 64;
pdata->DocProverData.nextassumption = 0;
pdata->DocProverData.maxtheorems = 10;
pdata->DocProverData.nexttheorem = 0;
pdata->DocProverData.maxhistory = 512;
pdata->DocProverData.maxworkspace = 0xffffU; /* almost 64 K, but in longs, so = 256K bytes */
pdata->DocProverData.nextworkspace = 0;
pdata->ngraphs = 0; /* in the the case of a graph document,
setupdata will change this. */
pdata->heapsize = (2 << 15); /* in units, yielding a one-megabyte = 2L << 18 heap */
heapsize_in_bytes = (((unsigned long) (pdata->heapsize)) << 4);
pdata->heap = (unit *) malloc(heapsize_in_bytes);
if(pdata->heap==NULL)
{ pdata->heapsize =0;
return 2;
}
err = create_heap(pdata->docnumber,pdata->heap,pdata->heapsize);
if(err)
return err;
pdata->DocVarData.varlist = (term *) malloc(pdata->DocVarData.maxvariables * sizeof(term));
if(pdata->DocVarData.varlist == NULL)
return 2;
pdata->DocVarData.varinfo = (varinf *) malloc(pdata->DocVarData.maxvariables * sizeof(varinf));
if(pdata->DocVarData.varinfo == NULL)
return 2;
pdata->DocVarData.parameters = (parameter *) malloc(pdata->DocVarData.maxparameters * sizeof(parameter));
if(pdata->DocVarData.parameters == NULL)
return 2;
pdata->DocVarData.defns = (defn *) malloc(pdata->DocVarData.maxdefns * sizeof(defn));
if(pdata->DocVarData.defns == NULL)
return 2;
pdata->DocProverData.assumptions = (assumption **) malloc(pdata->DocProverData.maxassumptions * sizeof(assumption *));
if(pdata->DocProverData.assumptions == NULL)
return 2;
pdata->DocProverData.theorems = (term *) malloc(pdata->DocProverData.maxtheorems * sizeof(term));
if(pdata->DocProverData.theorems == NULL)
return 2;
pdata->DocProverData.history = (term *) malloc(pdata->DocProverData.maxhistory * sizeof(term));
if(pdata->DocProverData.history == NULL)
return 2;
pdata->DocProverData.workspace = (unsigned long *) malloc(sizeof(long) * pdata->DocProverData.maxworkspace);
if(pdata->DocProverData.workspace == NULL)
return 2;
pdata->DocProverData.permhistory = (unsigned *) malloc(pdata->DocProverData.maxhistory*sizeof(unsigned));
if(pdata->DocProverData.permhistory == NULL)
return 2;
pdata->DocControlData.opseq = (operation *) malloc(pdata->DocProverData.maxhistory* sizeof(operation));
if(pdata->DocControlData.opseq == NULL)
return 2;
pdata->DocControlData.nlinedata = pdata->DocProverData.maxhistory + 5;
pdata->DocControlData.linedatahistory = (linedata *) malloc(pdata->DocControlData.nlinedata * sizeof(linedata));
if(pdata->DocControlData.linedatahistory == NULL)
return 2;
/* pdata->DocPolydata is not yet initialized */
return 0;
}
/*___________________________________________________________________*/
void release_doc_data(PSYMBOLDATA pdata)
/* free all the space allocated by allocate_doc_data.
In the case of a graph document, setupdata allocates some space
but only on the document heap, and the document heap is here
given back to the operating system anyway, so there's no need
to worry about calling free2 here to undo setupdata.
This must not be called while pdata is the active document.
*/
{ int k = pdata->docnumber;
free(pdata->heap);
remove_heap(pdata->docnumber);
free(pdata->DocVarData.varlist);
free(pdata->DocVarData.varinfo);
free(pdata->DocProverData.assumptions);
free(pdata->DocProverData.theorems);
free(pdata->DocProverData.history);
free(pdata->DocProverData.workspace);
free(pdata->DocVarData.parameters);
free(pdata->DocVarData.defns);
free(pdata->DocProverData.permhistory);
free(pdata->DocControlData.opseq);
free(pdata->DocControlData.linedatahistory);
delete_document(k);
}
/*________________________________________________________*/
int init_doc_data(int kind, PDOCDATA pdata)
/* This is done under WM_CREATE for a symbol or graph document.
It may NOT assume the document is active.
'kind' is either GRAPHDOC or SYMBOLDOC.
pdata->currenttopic has already been set when a menu choice was
made, in symproc.c.
*/
{ int err;
pdata->problemtype = EPSILON_DELTA;
err = allocate_doc_data(pdata);
if(err)
return 1;
/* problemtype and currenttopic go to symbols.dll via DocControlData: */
pdata->DocControlData.problemtype = pdata->problemtype;
pdata->DocControlData.currenttopic = pdata->currenttopic;
/* No need to set this stuff as output from the document is not used in Otter-lambda */
#if 0
pdata->DocControlData.linebreaks = 1;
pdata->magnification = 19;
pdata->backgroundcolor = RGB(255,255,255); /* white */
pdata->textcolor = 0; /* black */
pdata->reasoncolor = 0; /* black */
pdata->highlightcolor = RGB(0,0,255); /* blue, in 3-bit RGB as used by display */
pdata->textweight = 0; /* not boldface */
pdata->DocControlData.linebreaks = (kind != GRAPHDOC);
/* linebreaks ON in symbol documents but off in graph documents */
pdata->progresshwnd = 0;
#endif
gensym(1); /* reset indexing of subscripted variables */
set_cofi_index(1); /* start numbering constants of integration from 1 */
// reset_induction(); /* reset static variables in induct.c */
init_model(pdata->currenttopic,pdata->DocControlData.model);
init_polyvalflags(&pdata->DocPolyData);
pdata->DocPolyData.arith = get_arithflag(); // it's set during init_model
pdata->DocControlData.inhibitions = NULL;
pdata->DocVarData.currentline = -1;
return 0;
}
/*____________________________________________________________________*/
void activate( PDOCDATA pdoc)
/* pdoc is a pointer to a DOCDATA structure */
/* Deactivate the current active document, if any.
Extract the values of the document variables from pdoc
and assign them to the corresponding global variables.
Switch the heap manager to the heap of pdoc. */
/* This gets called whenever we create or activate a symbol
document, i.e. under WM_CREATE, WM_MDIACTIVATE or WM_PAINT in
SymbolWndProc or GraphWndProc. */
{
switch_heaps(pdoc->docnumber);
activate_polyvalDLL(&(pdoc->DocPolyData));
activate_symbolDLL(&(pdoc->DocControlData));
pdoc->DocPolyData.hwnd= pdoc->hwnd;
pdoc->DocControlData.hwnd = pdoc->hwnd;
/* docnumber, heap, and heapsize are not made global */
init_varDLL(&(pdoc->DocVarData));
init_proverDLL(&(pdoc->DocProverData));
/* saveas is never made global */
/* neither are magnification and the color fields */
if(pdoc->kind == SYMBOLDOC && !pdoc->initialized)
{
#if 0
reset_induction(); /* reset static variables in induct.c */
#endif
set_control_flags(pdoc->problemtype, pdoc->currenttopic);
pdoc->initialized = 1;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists