From: Mapi B. <ma...@us...> - 2009-06-24 21:44:25
|
Update of /cvsroot/easycalc/PPCport/core/mlib In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv18295 Added Files: calcDB.cpp calcDB.h fp.cpp fp.h Log Message: 2nd upload, getting closer --- NEW FILE: fp.h --- /* * $Id: fp.h,v 1.1 2009/06/24 21:44:22 mapibid Exp $ * * Scientific Calculator for Palms. * Copyright (C) 2000 Ondrej Palkovsky * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * You can contact me at 'on...@pe...'. */ #ifndef _FP_H_ #define _FP_H_ void fp_setup_flpoint(void) PARSER; void fp_print_double(TCHAR *strP, double value) PARSER; void fp_print_g_double(TCHAR *s, double value, Int16 prec) PARSER; void fp_set_base(Tbase base) PARSER; TdispPrefs fp_set_prefs(TdispPrefs prefs) PARSER; Tdisp_mode fp_set_dispmode(Tdisp_mode newmode) PARSER; extern TCHAR flSpaceChar, flPointChar; #endif --- NEW FILE: fp.cpp --- /* * $Id: fp.cpp,v 1.1 2009/06/24 21:44:22 mapibid Exp $ * * Scientific Calculator for Palms. * Copyright (C) 1999 Ondrej Palkovsky * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * You can contact me at 'on...@pe...'. */ #include "stdafx.h" #ifdef UNIX #define StrChr(x,y) strchr(x,y) #define StrCopy(x,y) strcpy(x,y) #define StrLen(x) strlen(x) #include <stdlib.h> #include <string.h> #else #include "compat/PalmOS.h" //#include <StringMgr.h> #include <MathLib.h> #endif #include "defuns.h" #include "display.h" #include "fp.h" #include "compat/FloatManager.h" static double SCI_LIMIT_MAX; /* Above this number show it as xEy */ static double SCI_LIMIT_MIN; /* Under this number show as xE-y */ //static double DISP_MIN_LIMIT = 1E-15; /* Show numbers as sin(pi) as 1E-16, // it's 0 */ //static double DISP_MAX_LIMIT = 1E300; /* Don't show bigger numbers, it // * makes problems */ static double BASE = 10.0; TCHAR flPointChar = _T('.'); TCHAR flSpaceChar = _T(' '); /* If the number is smaller, reduce the number of * decimal points, so we do not get something like * 9.999999987E-10 */ //static double REDUCE_PREC = 1E-6; #define REDUCE_TO 6 void fp_setup_flpoint(void) PARSER; void fp_setup_flpoint(void) { /* Set the floating 'point' to '.' or ',' */ switch (PrefGetPreference(prefNumberFormat)) { case nfCommaPeriod: flSpaceChar=_T(','); flPointChar=_T('.'); break; case nfApostrophePeriod: flSpaceChar=_T('\''); flPointChar=_T('.'); break; case nfPeriodComma: flSpaceChar=_T('.'); flPointChar=_T(','); break; case nfSpaceComma: flSpaceChar=_T(' '); flPointChar=_T(','); break; case nfApostropheComma: default: flSpaceChar=_T('\''); flPointChar=_T(','); break; } } /*********************************************************************** * * FUNCTION: fp_reread_prefs * * DESCRIPTION: Setups some maximum/miniums according to displayPrefs * * PARAMETERS: Nothing * * RETURN: Nothing * ***********************************************************************/ static void fp_reread_prefs(void) PARSER; static void fp_reread_prefs(void) { BASE = dispPrefs.base; switch (dispPrefs.mode) { case disp_normal: // SCI_LIMIT_MAX=1E10; SCI_LIMIT_MAX=pow(BASE,10); // SCI_LIMIT_MIN=1E-5; SCI_LIMIT_MIN=pow(BASE,-5); break; case disp_sci: case disp_eng: SCI_LIMIT_MAX=1.00; SCI_LIMIT_MIN=1.01; break; } // if (dispPrefs.reducePrecision) { // DISP_MIN_LIMIT = 1E-15; // REDUCE_PREC = 1E-6; // } else { // DISP_MIN_LIMIT = 1E-100; // REDUCE_PREC = 1E-90; // } } TdispPrefs fp_set_prefs(TdispPrefs prefs) PARSER; TdispPrefs fp_set_prefs(TdispPrefs prefs) { TdispPrefs oldprefs = dispPrefs; dispPrefs = prefs; fp_reread_prefs(); return oldprefs; } void fp_set_base(Tbase base) PARSER; void fp_set_base(Tbase base) { dispPrefs.base = base; fp_reread_prefs(); } Tdisp_mode fp_set_dispmode(Tdisp_mode newmode) PARSER; Tdisp_mode fp_set_dispmode(Tdisp_mode newmode) { Tdisp_mode oldmode = dispPrefs.mode; dispPrefs.mode = newmode; return oldmode; } /*********************************************************************** * * FUNCTION: cvt_fltoa * * DESCRIPTION: Convert a truncated float to ascii * * PARAMETERS: value * * RETURN: strP - converted value * ***********************************************************************/ static void cvt_fltoa(TCHAR *strP,double value) PARSER; static void cvt_fltoa(TCHAR *strP,double value) { TCHAR *cP; TCHAR tmpstr[MAX_FP_NUMBER+3]; Int16 i,ichar; if (value==0.0) { StrCopy(strP,_T("0")); return; } /* We convert the number backwards */ for (i=MAX_FP_NUMBER-2;i>=0;i--) { ichar = (Int16)fmod(value,BASE) + _T('0'); tmpstr[i] = ichar>_T('9')?ichar-_T('9')-1+_T('A'):ichar; value /= BASE; value=trunc(value); } tmpstr[MAX_FP_NUMBER-1] = _T('\0'); for( cP = tmpstr; *cP && (*cP == _T('0')); ) ++cP; StrCopy(strP,cP); } /*********************************************************************** * * FUNCTION: fp_print * * DESCRIPTION: Prints a double to string * * PARAMETERS: value * * RETURN: strP - converted value * ***********************************************************************/ static void fp_print(TCHAR *strP,double value,Int16 myfrac) PARSER; static void fp_print(TCHAR *strP,double value,Int16 myfrac) { Int16 i; double ipart; double fpart; double limit; TCHAR str[MAX_FP_NUMBER*2]; if (isinf(value)) { if (isinf(value)>0) StrCopy(strP,_T("+Inf")); else StrCopy(strP,_T("-Inf")); return; } if (!finite(value)) { StrCopy(strP,_T("NaN")); return; } if( value < 0.0 ) { *strP++ = _T('-'); value = -value; } ipart = trunc(value); value -= ipart; /* recover frac part */ for (limit = 1.0,i=myfrac; i> 0;i--) { value *= BASE; limit *= BASE; } value += 0.5; if( value >= limit ) { fpart = 0.0; /* overflowed */ ipart++; } else fpart = value; cvt_fltoa(strP,ipart); if (myfrac || !dispPrefs.stripZeros) { cvt_fltoa(str,fpart); strP += StrLen(strP); if (!dispPrefs.stripZeros && fpart < 1.0) { *strP++ = flPointChar; for (i = 0; i < myfrac; i++) { *strP++ = _T('0'); } *strP++ = _T('\0'); } if (dispPrefs.stripZeros) { /* remove trailing 0's */ for (i = StrLen(str)-1;i>=0 && str[i]==_T('0');i--) { str[i]=_T('\0'); myfrac--; } } if (StrLen(str)>0) { *strP++ = flPointChar; for(i=StrLen(str); i<myfrac;i++ ) *strP++ = _T('0'); /* need some padding at the beginning */ StrCopy(strP,str); /* and now the value */ } } } static const TCHAR expNames[] = {_T('f'),_T('p'),_T('n'),_T('u'),_T('m'),0,_T('k'),_T('M'),_T('G'),_T('T')}; static void fp_print_exp(TCHAR *str,Int16 expon) PARSER; static void fp_print_exp(TCHAR *str,Int16 expon) { Int16 i; if (dispPrefs.base == disp_decimal) { if (dispPrefs.mode == disp_eng && dispPrefs.cvtUnits) { i = expon/3 + 5; if (i<0 || i>9) StrPrintF(str,_T("E%d"),expon); else StrPrintF(str,_T("%c"),expNames[i]); } else StrPrintF(str,_T("E%d"),expon); } else StrPrintF(str, _T("*%d^%d"),(Int16)dispPrefs.base, expon); } /*********************************************************************** * * FUNCTION: fp_print_double * * DESCRIPTION: Function used for general number formatting according * all rules from dispPrefs, adds the 'E+-' things * for too big numbers, scientific & engineer purposes * * PARAMETERS: value * * RETURN: strP - converted value * ***********************************************************************/ void fp_print_double(TCHAR *strP,double value) PARSER; void fp_print_double(TCHAR *strP, double value) { Int16 ex; TCHAR tmpstr[MAX_FP_NUMBER*2]; if (!finite(value)) { /* Handle the NaN, +Inf & -Inf cases */ fp_print(strP,value,dispPrefs.decPoints); } // else if (fabs(value)>DISP_MAX_LIMIT) { // StrCopy(strP,_T("It's too big")); // } // else if (fabs(value)<DISP_MIN_LIMIT) { // /* Don't show too small numbers */ // fp_print(strP,0,dispPrefs.decPoints); // if (dispPrefs.mode!=disp_normal) // fp_print_exp(strP+StrLen(strP),0); // } else if (fabs(value)>=1 && dispPrefs.mode==disp_eng) { /* Engineer mode selected */ Int16 mydec = dispPrefs.decPoints - 1; for (ex=0;fabs(value)>=pow(BASE,3) || (ex % 3);ex++,value/=BASE) ; if (fabs(value) >= 100.0) mydec -= 2; else if (fabs(value) >= 10.0) mydec -= 1; if (mydec < 0) mydec = 0; fp_print(strP,value,mydec); fp_print_exp(tmpstr,ex); StrCat(strP,tmpstr); } else if (fabs(value)<1.0 && dispPrefs.mode==disp_eng) { Int16 mydec = dispPrefs.decPoints - 1; /* Engineer mode selected */ for (ex=0;fabs(value)<0.99999999 || (ex % 3);ex++,value*=BASE) ; if (fabs(value) >= 100.0) mydec -= 2; else if (fabs(value) >= 10.0) mydec -= 1; if (mydec < 0) mydec = 0; fp_print(strP,value,mydec); fp_print_exp(tmpstr,-ex); StrCat(strP,tmpstr); } else if (dispPrefs.base == disp_binary || dispPrefs.base == disp_octal || dispPrefs.base == disp_hexa) { if (fabs(value) > 1E14) StrCopy(strP,_T("Cannot display number.")); else fp_print(strP,value,dispPrefs.decPoints); } else if (fabs(value)>SCI_LIMIT_MAX) { /* Normal/Scientific mode */ for (ex=0;fabs(value)>=BASE;value/=BASE,ex++) ; fp_print(strP,value,dispPrefs.decPoints); fp_print_exp(tmpstr,ex); StrCat(strP,tmpstr); } else if(fabs(value)<SCI_LIMIT_MIN && fabs(value)>0) { /* Normal/Scientific mode */ for (ex=0;fabs(value)<0.99999999;value*=BASE,ex--) ; fp_print(strP,value,dispPrefs.decPoints); fp_print_exp(tmpstr,ex); StrCat(strP,tmpstr); } else { /* No special formatting required */ fp_print(strP,value,dispPrefs.decPoints); } } /*********************************************************************** * * FUNCTION: fp_print_g_double * * DESCRIPTION: Formats double numbers for output on the graph screen * using a Fortran like %g format. * The code is derived from the printDouble function in lispme: * http://www.lispme.de/lispme/gcc/tech.html#fpio * * PARAMETERS: s - output string * value - value to be formatted * * RETURN: nothing * ***********************************************************************/ /* Conversion constants */ static double pow1[] = { 1e256, 1e128, 1e064, 1e032, 1e016, 1e008, 1e004, 1e002, 1e001 }; static double pow2[] = { 1e-256, 1e-128, 1e-064, 1e-032, 1e-016, 1e-008, 1e-004, 1e-002, 1e-001 }; void fp_print_g_double(Char *s, double value, Int16 prec) PARSER; void fp_print_g_double(Char *s, double value, Int16 prec) { FlpCompDouble fcd; double round_factor; short e, e1, i; double *pd, *pd1; TCHAR sign = _T('\0'); short dec = 0; /* Check for reasonable value of prec. IEEE double. IEEE double * precision has about 16 significant decimal digits */ if (prec < 0 || prec > 16) prec = 7; /* Initialize round_factor */ round_factor = 0.5; for (i = 0; i < prec; i++) round_factor /= 10.0; /* Check for NaN, +Inf, -Inf, 0 */ fcd.d = value; if ((fcd.ul[0] & 0x7ff00000) == 0x7ff00000) { if (fcd.fdb.manH == 0 && fcd.fdb.manL == 0) { if (fcd.fdb.sign) StrCopy(s, _T("-Inf")); else StrCopy(s, _T("Inf")); } else { StrCopy(s, _T("NaN")); } return; } if (FlpIsZero(fcd)) { StrCopy(s, _T("0")); return; } /* Make positive and store sign */ if (FlpGetSign(fcd)) { *s++ = _T('-'); FlpSetPositive(fcd); value = fcd.d; } /* Compute round_factor */ if ((unsigned) fcd.fdb.exp < 0x3ff) { /* round_factor for value < 1.0 */ for (e = 1, e1 = 256, pd = pow1, pd1 = pow2; e1; e1 >>= 1, ++pd, ++pd1) { if (*pd1 > fcd.d) { e += e1; fcd.d *= *pd; round_factor *= *pd1; } } } else { /* round_factor for value >= 1.0 */ for (e = 0, e1 = 256, pd = pow1, pd1 = pow2; e1; e1 >>= 1, ++pd, ++pd1) { if (*pd <= fcd.d) { e += e1; fcd.d *= *pd1; round_factor *= *pd; } } round_factor *= 10.0; } fcd.d = value + round_factor; if ((unsigned) fcd.fdb.exp < 0x3ff) { /* Build negative exponent */ for (e = 1, e1 = 256, pd = pow1, pd1 = pow2; e1; e1 >>= 1, ++pd, ++pd1) { if (*pd1 > fcd.d) { e += e1; fcd.d = fcd.d * *pd; } } fcd.d = fcd.d * 10.0; /* Do not print exponent for the -0.xxxx case */ if (e <= 1) { *s++ = _T('0'); *s++ = _T('.'); dec = -1; } else sign = _T('-'); } else { /* Build positive exponent */ for (e = 0, e1 = 256, pd = pow1, pd1 = pow2; e1; e1 >>= 1, ++pd, ++pd1) { if (*pd <= fcd.d) { e += e1; fcd.d = fcd.d * *pd1; } } if (e < prec) dec = e; else sign = _T('+'); } /* Extract decimal digits of mantissa */ for (i = 0; i < prec; ++i, --dec) { Int32 d = fcd.d; *s++ = d + _T('0'); if (!dec) *s++ = _T('.'); fcd.d = fcd.d - (double)d; fcd.d = fcd.d * 10.0; } /* Remove trailing zeros and decimal point */ while (s[-1] == _T('0')) *--s = _T('\0'); if (s[-1] == _T('.')) *--s = _T('\0'); /* Append exponent */ if (sign) { *s++ = _T('E'); *s++ = sign; StrIToA(s, e); } else *s = _T('\0'); } --- NEW FILE: calcDB.cpp --- /* * $Id: calcDB.cpp,v 1.1 2009/06/24 21:44:22 mapibid Exp $ * * Scientific Calculator for Palms. * Copyright (C) 1999,2000 Ondrej Palkovsky * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * You can contact me at 'on...@pe...'. */ #include "stdafx.h" #include "compat/PalmOS.h" #include <string.h> #include "defuns.h" #include "konvert.h" #include "calcDB.h" #include "stack.h" #include "dbutil.h" static DmOpenRef gDB; static Int16 CompareRecordFunc(dbPackedRecord *rec1,dbPackedRecord *rec2, Int16 unesedInt16,SortRecordInfoPtr unused1,SortRecordInfoPtr unused2, MemHandle appInfoH) MLIB; static Int16 CompareRecordFunc(dbPackedRecord *rec1,dbPackedRecord *rec2, Int16 unesedInt16,SortRecordInfoPtr unused1,SortRecordInfoPtr unused2, MemHandle appInfoH) { Int16 tmp; /* This will sort it somewhat intelligently, regardless of capitalized * letters */ tmp=StrCaselessCompare(rec1->name,rec2->name); if (tmp) return tmp; return StrCompare(rec1->name,rec2->name); } /*********************************************************************** * * FUNCTION: db_create_record * * DESCRIPTION: Create a record in a database, possibly overwriting * an existing one * * PARAMETERS: newRecord - pointer to a new record * size - size of a new record * * RETURN: Nothing * ***********************************************************************/ static CError db_create_record(dbPackedRecord *newRecord,UInt16 size) MLIB; static CError db_create_record(dbPackedRecord *newRecord,UInt16 size) { UInt16 recordNumber; MemHandle myRecordMemHandle; dbPackedRecord *newRecordPtr; CError err = c_noerror; recordNumber = DmFindSortPosition(gDB,newRecord,0, (DmComparF *)CompareRecordFunc,0); if (recordNumber > 0) { /* We might modify the record */ dbPackedRecord *record; MemHandle recordMemHandle; Int16 foundIt; recordMemHandle = DmQueryRecord(gDB,recordNumber - 1); record = (dbPackedRecord *) MemHandleLock(recordMemHandle); foundIt = StrCompare(newRecord->name,record->name) == 0; MemHandleUnlock(recordMemHandle); if (foundIt) { /* OK, we have to modify existing record */ MemHandle modRecord = DmGetRecord(gDB,recordNumber-1); /* resize the handle */ if (!MemHandleResize(modRecord,size)) { record = (dbPackedRecord *) MemHandleLock(modRecord); DmWrite(record,0,newRecord,size); MemHandleUnlock(modRecord); } else err = c_memory; DmReleaseRecord(gDB,recordNumber-1,true); return err; } } myRecordMemHandle = DmNewRecord(gDB,&recordNumber,size); if (myRecordMemHandle ) { newRecordPtr = (dbPackedRecord *) MemHandleLock(myRecordMemHandle); DmWrite(newRecordPtr,0,newRecord,size); MemHandleUnlock(myRecordMemHandle); DmReleaseRecord(gDB,recordNumber,true); /* Now the recordNumber contains real index */ } else err = c_memory; return err; } /*********************************************************************** * * FUNCTION: db_recompile_all * * DESCRIPTION: Recompiles functions stored in database and removes * functions where a recompile fails. It should be called * whenever a function is inserted into konvert.c * * PARAMETERS: None * * RETURN: Nothing * ***********************************************************************/ void db_recompile_all(void) { dbList *list; Int16 i; TCHAR *origtext; CError err; CodeStack *stack; TCHAR oldparam[MAX_FUNCNAME+1]; /* Save the default parameter name */ StrCopy(oldparam,parameter_name); list = db_get_list(function); for (i=0;i<list->size;i++) { err = db_func_description(list->list[i],&origtext,parameter_name); if (err) { db_delete_record(list->list[i]); continue; } stack = text_to_stack(origtext,&err); if (err) { MemPtrFree(origtext); db_delete_record(list->list[i]); continue; } db_write_function(list->list[i],stack,origtext); stack_delete(stack); MemPtrFree(origtext); } db_delete_list(list); StrCopy(parameter_name,oldparam); } /*********************************************************************** * * FUNCTION: db_write_function * * DESCRIPTION: Write a defined piece of code into database * * PARAMETERS: name - name of function * stack - compiled code * origtext - original uncompiled code * * RETURN: Nothing * ***********************************************************************/ CError db_write_function(const TCHAR *name,CodeStack *stack,TCHAR *origtext) MLIB; CError db_write_function(const TCHAR *name,CodeStack *stack,TCHAR *origtext) { dbPackedRecord *record; dbPackedStack *pstack; UInt16 psize,rsize; TCHAR *ptr; CError err; pstack = stack_pack(stack,&psize); record = (dbPackedRecord *) MemPtrNew(sizeof(*record)+psize+StrLen(origtext)+1); if (!record) return c_memory; record->type = function; StrCopy(record->name,name); memcpy(&record->u.stack,pstack,psize); StrCopy(record->u.stack.header.param_name,parameter_name); // ptr = &record->u.stack.data; ptr = record->u.stack.data; ptr += record->u.stack.header.orig_offset; StrCopy(ptr,origtext); rsize = sizeof(*record)+psize+StrLen(origtext)+1; rsize -= sizeof(dbStackItem)>sizeof(dbPackedStack)?sizeof(dbStackItem):sizeof(dbPackedStack); err = db_create_record(record,rsize); MemPtrFree(record); MemPtrFree(pstack); return err; } /*********************************************************************** * * FUNCTION: db_read_function * * DESCRIPTION: Read a compiled function from database * * PARAMETERS: name - name of the function * * RETURN: CodeStack - compiled code * err - error code or 0 * ***********************************************************************/ CodeStack * db_read_function(const TCHAR *name,CError *err) MLIB; CodeStack * db_read_function(const TCHAR *name,CError *err) { dbPackedRecord *record; CodeStack *result; *err = c_noerror; record = db_read_record(name); if (!record || record->type!=function) { if (record) MemPtrFree(record); *err = c_notvar; return NULL; } result = stack_unpack(&record->u.stack); MemPtrFree(record); return result; } /*********************************************************************** * * FUNCTION: db_write_variable * * DESCRIPTION: Write variable to database * * PARAMETERS: name - name of the variable * contents - the value of the variable * * RETURN: Nothing * ***********************************************************************/ CError db_write_variable(const TCHAR *name,Trpn contents) MLIB; CError db_write_variable(const TCHAR *name,Trpn contents) { dbPackedRecord *record; dbStackItem *packitem; UInt16 adatalen; /* Additional data size */ CError err; packitem = rpn_pack_record(contents); if(!packitem) return c_memory; adatalen = packitem->datasize; record = (dbPackedRecord *) MemPtrNew(sizeof(*record) + adatalen); if (!record) { MemPtrFree(packitem); return c_memory; } record->type = variable; StrCopy(record->name,name); memcpy(record->u.data,packitem,sizeof(*packitem)+adatalen); MemPtrFree(packitem); err = db_create_record(record,sizeof(*record)+adatalen); MemPtrFree(record); return err; } /*********************************************************************** * * FUNCTION: db_read_variable * * DESCRIPTION: Read a variable value from database * * PARAMETERS: name - name of the requested variable * * RETURN: Trpn - value of the variable * err - error code or zero * ***********************************************************************/ Trpn db_read_variable(const TCHAR *name,CError *err) MLIB; Trpn db_read_variable(const TCHAR *name,CError *err) { Trpn result; dbPackedRecord *record; *err = c_noerror; record = db_read_record(name); if (!record || record->type!=variable) { if (record) MemPtrFree(record); *err = c_notvar; return result; } result = rpn_unpack_record(record->u.data); MemPtrFree(record); return result; } /*********************************************************************** * * FUNCTION: db_delete_list * * DESCRIPTION: Free memory allocated by list * * PARAMETERS: list - list to free * * RETURN: Nothing * ***********************************************************************/ void db_delete_list(dbList *list) { Int16 i; for (i=0;i<list->size;i++) MemPtrFree(list->list[i]); if (list->type) MemPtrFree(list->type); MemPtrFree(list); } /*********************************************************************** * * FUNCTION: db_get_list * * DESCRIPTION: Creates a dynamic list of all requested records * * PARAMETERS: type - type of records to build a list * or 0 for all types * * RETURN: dbList - array of all records of given type * ***********************************************************************/ dbList * db_get_list(rpntype type) { UInt16 totalItems = DmNumRecords(gDB); UInt16 count,i; MemHandle recordHandle; dbPackedRecord *record; dbList *result; result = (dbList *) MemPtrNew(sizeof(dbList)+totalItems*sizeof(result->list[0])); result->type = (rpntype *) MemPtrNew(sizeof(result->type[0])*totalItems); for (i=0,count=0;i<totalItems;i++) { recordHandle = DmQueryRecord(gDB,i); record = (dbPackedRecord *) MemHandleLock(recordHandle); if (!type || record->type == type || (record->type == variable && record->u.data[0].rpn.type == type)) { result->type[count] = record->type; result->list[count] = (TCHAR *) MemPtrNew(StrLen(record->name)+1); StrCopy(result->list[count],record->name); count++; } MemHandleUnlock(recordHandle); } result->size = count; return result; } /*********************************************************************** * * FUNCTION: db_func_description * * DESCRIPTION: Return function pre-compilation text * * PARAMETERS: funcname - name of the requested function * * RETURN: CError - c_noerror on success * dest - pointer to a dynamically allocated chunk of memory * param - parameter name ('x'), that was used for compialtion * ***********************************************************************/ CError db_func_description(const TCHAR *funcname,TCHAR **dest,TCHAR *param) MLIB; CError db_func_description(const TCHAR *funcname,TCHAR **dest,TCHAR *param) { dbPackedRecord *tmp; tmp = db_read_record(funcname); if (!tmp) return c_notvar; if (tmp->type != function) { MemPtrFree(tmp); return c_badarg; } *dest = (TCHAR *) MemPtrNew(StrLen(&tmp->u.stack.data[tmp->u.stack.header.orig_offset])+1); StrCopy(*dest,&tmp->u.stack.data[tmp->u.stack.header.orig_offset]); if (param) StrCopy(param,tmp->u.stack.header.param_name); MemPtrFree(tmp); return c_noerror; } void db_save_real(const TCHAR *name, double number) { CodeStack *stack; Trpn item; stack = stack_new(1); stack_add_val(stack,&number,real); item = stack_pop(stack); stack_delete(stack); db_write_variable(name,item); rpn_delete(item); } /*********************************************************************** * * FUNCTION: db_read_record * * DESCRIPTION: Reads a record from a database * * PARAMETERS: name - name of the record (variable or function) * * RETURN: pointer to a dynamical record or NULL on error * ***********************************************************************/ dbPackedRecord * db_read_record(const TCHAR *name) MLIB; dbPackedRecord * db_read_record(const TCHAR *name) { UInt16 recordNumber; Int16 foundIt=0; dbPackedRecord tmp; StrCopy(tmp.name,name); recordNumber=DmFindSortPosition(gDB,&tmp,0, (DmComparF *)CompareRecordFunc,0); if (recordNumber >0) { MemHandle theRecordMemHandle; dbPackedRecord *record; theRecordMemHandle = DmQueryRecord(gDB,recordNumber - 1); record = (dbPackedRecord *) MemHandleLock(theRecordMemHandle); foundIt = StrCompare(name,record->name)==0; if (foundIt) { dbPackedRecord *result; result = MemPtrNew(MemHandleSize(theRecordMemHandle)); if (result) memcpy(result,record,MemHandleSize(theRecordMemHandle)); MemHandleUnlock(theRecordMemHandle); return result; } MemHandleUnlock(theRecordMemHandle); } return NULL; } /*********************************************************************** * * FUNCTION: db_record_exists * * DESCRIPTION: Check, if there is a corresponding record in the * database * * PARAMETERS: name - name of the record * * RETURN: true - record exists, otherwise false * ***********************************************************************/ Boolean db_record_exists(const TCHAR *name) MLIB; Boolean db_record_exists(const TCHAR *name) { UInt16 recordNumber; bool foundIt=false; dbPackedRecord tmprec; StrCopy(tmprec.name,name); recordNumber=DmFindSortPosition(gDB,&tmprec,0, (DmComparF *)CompareRecordFunc,0); if (recordNumber >0) { MemHandle theRecordMemHandle; dbPackedRecord *record; theRecordMemHandle = DmQueryRecord(gDB,recordNumber - 1); record = (dbPackedRecord *) MemHandleLock(theRecordMemHandle); foundIt = (StrCompare(tmprec.name,record->name)==0); MemHandleUnlock(theRecordMemHandle); } return foundIt; } /*********************************************************************** * * FUNCTION: db_delete_record * * DESCRIPTION: Deletes a record of a given name from the database * * PARAMETERS: name - name of the record * * RETURN: true - record existed in database * false - there was no such record * ***********************************************************************/ Int16 db_delete_record(const TCHAR *name) MLIB; Int16 db_delete_record(const TCHAR *name) { UInt16 recordNumber; Int16 foundIt=0; dbPackedRecord tmprec; StrCopy(tmprec.name,name); recordNumber=DmFindSortPosition(gDB,&tmprec,0, (DmComparF *)CompareRecordFunc,0); if (recordNumber >0) { MemHandle theRecordMemHandle; dbPackedRecord *record; theRecordMemHandle = DmQueryRecord(gDB,recordNumber - 1); record = (dbPackedRecord *) MemHandleLock(theRecordMemHandle); foundIt = StrCompare(tmprec.name,record->name)==0; MemHandleUnlock(theRecordMemHandle); if (foundIt) DmRemoveRecord(gDB,recordNumber-1); } return foundIt; } /*********************************************************************** * * FUNCTION: db_open * * DESCRIPTION: Open a main database for EasyCalc, creates a new one, * if there isn't such a database or if the old database * is bad version * * PARAMETERS: Nothing * * RETURN: 0 - on success * other - on error * ***********************************************************************/ Int16 db_open() MLIB; Int16 db_open() { return open_db(DBNAME, DBVERSION, LIB_ID, DBTYPE, &gDB); } Int16 db_close() MLIB; Int16 db_close() { return DmCloseDatabase(gDB); } --- NEW FILE: calcDB.h --- /* * $Id: calcDB.h,v 1.1 2009/06/24 21:44:22 mapibid Exp $ * * Scientific Calculator for Palms. * Copyright (C) 1999 Ondrej Palkovsky * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * You can contact me at 'on...@pe...'. */ #ifndef _CALCDB_H_ #define _CALCDB_H_ #include "compat/PalmOS.h" #include "konvert.h" typedef struct { Int16 size; rpntype *type; TCHAR **list; /* Do not add anything here, it gets overwritten */ }dbList; typedef struct { Int16 count; Int16 orig_offset; TCHAR param_name[MAX_FUNCNAME+1]; }dbStackHeader; typedef struct { Trpn rpn; UInt16 datasize; /* size of additional packed data */ TCHAR *data; }dbStackItem; typedef struct { dbStackHeader header; TCHAR *data; }dbPackedStack; typedef struct { rpntype type; /* This can be ONLY variable/function, nothing else can be * stored in databases */ TCHAR name[MAX_FUNCNAME+1]; union { dbStackItem data[1]; /* Variable */ dbPackedStack stack; }u; }dbPackedRecord; CError db_write_function(const TCHAR *name,CodeStack *stack,TCHAR *origtext) MLIB; CodeStack * db_read_function(const TCHAR *name,CError *err) MLIB; CError db_write_variable(const TCHAR *name,Trpn contents) MLIB; Trpn db_read_variable(const TCHAR *name,CError *err) MLIB; CError db_func_description(const TCHAR *funcname,TCHAR **dest,TCHAR *param) MLIB; dbPackedRecord * db_read_record(const TCHAR *name) MLIB; Int16 db_delete_record(const TCHAR *name) MLIB; void db_recompile_all(void) MLIB; Int16 db_open() MLIB; Int16 db_close() MLIB; Boolean db_record_exists(const TCHAR *name) MLIB; void db_delete_list(dbList *list) MLIB; dbList * db_get_list(rpntype type) MLIB; void db_save_real(const TCHAR *name, double number) MLIB; #endif |