/* Auto: smake MCalc */ /* $Revision Header built automatically *************** (do not edit) ************ ** ** © Copyright by GuntherSoft ** ** File : SnakeSYS:CPrgs/MUICalc/MCalcARexx.c ** Created on : Sunday, 05.12.93 14:37:01 ** Created by : Kai Iske ** Current revision : V1.0 ** ** ** Purpose ** ------- ** - ARexx support for MUIProCalc ** ** Revision V1.0 ** -------------- ** created on Sunday, 05.12.93 14:37:01 by Kai Iske. LogMessage : ** --- Initial release --- ** *********************************************************************************/ /**********************************************************************/ /* Routines for that module */ /**********************************************************************/ static APTR __saveds __asm DoRXCalc(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm DoRXCalcTeX(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm GetOutput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm GetTeXOutput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm GetInput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm GetTeXInput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm DoFormatTeX(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm SetMode(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR __saveds __asm DeleteHistoryFunc(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms); static APTR ReturnEntry(UWORD Mode, UWORD OutMode, LONG Pos); static void FormatTeX(char *Source, char *Dest); /**********************************************************************/ /* external references to main programs variables */ /**********************************************************************/ extern APTR AppObject; extern APTR InputString; extern APTR OutputBox; extern UWORD IntType; extern UWORD IntBase; extern UWORD IntSign; extern UWORD IntAngle; /**********************************************************************/ /* Hooks */ /**********************************************************************/ static struct Hook CalcHook = { {NULL}, (APTR)DoRXCalc, NULL, NULL }; static struct Hook CalcTeXHook = { {NULL}, (APTR)DoRXCalcTeX, NULL, NULL }; static struct Hook GetOutputHook = { {NULL}, (APTR)GetOutput, NULL, NULL }; static struct Hook GetTeXOutputHook = { {NULL}, (APTR)GetTeXOutput, NULL, NULL }; static struct Hook GetInputHook = { {NULL}, (APTR)GetInput, NULL, NULL }; static struct Hook GetTeXInputHook = { {NULL}, (APTR)GetTeXInput, NULL, NULL }; static struct Hook FormatTeXHook = { {NULL}, (APTR)DoFormatTeX, NULL, NULL }; static struct Hook SetModeHook = { {NULL}, (APTR)SetMode, NULL, NULL }; static struct Hook DeleteHistoryHook = { {NULL}, (APTR)DeleteHistoryFunc, NULL, NULL }; /**********************************************************************/ /* This is for our modes */ /**********************************************************************/ UWORD RXIntType; UWORD RXIntBase; UWORD RXIntSign; UWORD RXIntAngle; /**********************************************************************/ /* Array of ARexx commands for MUIProCalc */ /**********************************************************************/ struct MUI_Command RXCommands[] = { // Calculate an expression (normal output) { "CALC", "EXPRESSION/A/M", 1, &CalcHook }, // Calculate an expression (TeX output) { "CALCTEX", "EXPRESSION/A/M", 1, &CalcTeXHook }, // Select output from history (normal output; as is) { "GETOUTPUT", "ENTRYNUM/N", 1, &GetOutputHook }, // Select output from history (TeX output) { "GETTEXOUTPUT", "ENTRYNUM/N", 1, &GetTeXOutputHook }, // Select input from history (normal output; as is) { "GETINPUT", "ENTRYNUM/N", 1, &GetInputHook }, // Select input from history (TeX output) { "GETTEXINPUT", "ENTRYNUM/N", 1, &GetTeXInputHook }, // Format an expression to TeX format { "FORMATTEX", "EXPRESSION/A/M", 1, &FormatTeXHook }, // Set output mode { "SETMODE", "BASE/K,SIZE/K,SIGN/K,ANGLE/K", 4, &SetModeHook }, // Delete an entry from history { "DELETEHISTORY", "ENTRYNUM/N", 1, &DeleteHistoryHook }, // Delimiter { NULL, NULL, NULL, NULL } }; /**********************************************************************/ /* Let MUIProCalc (normal output) calculate through ARexx */ /* ------------------------------------------------------ */ /* Parameters must be : */ /* Expr = Expression to calculate */ /**********************************************************************/ static APTR __saveds __asm DoRXCalc(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { UWORD BackIntType, BackIntBase, BackIntSign, BackIntAngle; char NewBuff[258], **Exprs; BOOL GoOn = TRUE; // Build expression from partial input strcpy(NewBuff, ""); Exprs = (char **)Parms[0]; while(*Exprs && GoOn) { if((strlen(*Exprs) + strlen(NewBuff)) < 256) strcat(NewBuff, *Exprs); else GoOn = FALSE; Exprs++; } // Set input string to current expression set(InputString, MUIA_String_Contents, NewBuff); // Calculate expression (with ARexx settings) BackIntType = IntType; BackIntBase = IntBase; BackIntSign = IntSign; BackIntAngle = IntAngle; IntType = RXIntType; IntBase = RXIntBase; IntSign = RXIntSign; IntAngle = RXIntAngle; GoOn = FormatOutput(FALSE); IntType = BackIntType; IntBase = BackIntBase; IntSign = BackIntSign; IntAngle = BackIntAngle; if(GoOn) { // Return output return(ReturnEntry(GET_OUTPUT, NORMAL_OUTPUT, GET_ACTIVE)); } else return((APTR)set(AppObject, MUIA_Application_RexxString, " ")); } /**********************************************************************/ /* Let MUIProCalc (TeX output) calculate through ARexx */ /* --------------------------------------------------- */ /* Parameters must be : */ /* Expr = Expression to calculate */ /**********************************************************************/ static APTR __saveds __asm DoRXCalcTeX(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { UWORD BackIntType, BackIntBase, BackIntSign, BackIntAngle; char NewBuff[258], **Exprs; BOOL GoOn = TRUE; // Build expression from partial input strcpy(NewBuff, ""); Exprs = (char **)Parms[0]; while(*Exprs && GoOn) { if((strlen(*Exprs) + strlen(NewBuff)) < 256) strcat(NewBuff, *Exprs); else GoOn = FALSE; Exprs++; } // Set input string to current expression set(InputString, MUIA_String_Contents, NewBuff); // Calculate expression (with ARexx settings) BackIntType = IntType; BackIntBase = IntBase; BackIntSign = IntSign; BackIntAngle = IntAngle; IntType = RXIntType; IntBase = RXIntBase; IntSign = RXIntSign; IntAngle = RXIntAngle; GoOn = FormatOutput(FALSE); IntType = BackIntType; IntBase = BackIntBase; IntSign = BackIntSign; IntAngle = BackIntAngle; if(GoOn) { // Return output return(ReturnEntry(GET_OUTPUT, TEX_OUTPUT, GET_ACTIVE)); } else return((APTR)set(AppObject, MUIA_Application_RexxString, " ")); } /**********************************************************************/ /* GetOutput (normal output) from History */ /* -------------------------------------- */ /* Parameters may be : */ /* n = Nth entry */ /* -1 = Active entry */ /* -2 = TopMost entry */ /* -3 = BottomMost entry */ /* default : */ /* get active entry */ /**********************************************************************/ static APTR __saveds __asm GetOutput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { LONG *ValuePtr = (LONG *)Parms[0], Value; if(ValuePtr) Value = *ValuePtr; else Value = -1; return(ReturnEntry(GET_OUTPUT, NORMAL_OUTPUT, Value)); } /**********************************************************************/ /* GetOutput (TeX output) from History */ /* ----------------------------------- */ /* Parameters may be : */ /* n = Nth entry */ /* -1 = Active entry */ /* -2 = TopMost entry */ /* -3 = BottomMost entry */ /* default : */ /* get active entry */ /**********************************************************************/ static APTR __saveds __asm GetTeXOutput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { LONG *ValuePtr = (LONG *)Parms[0], Value; if(ValuePtr) Value = *ValuePtr; else Value = -1; return(ReturnEntry(GET_OUTPUT, TEX_OUTPUT, Value)); } /**********************************************************************/ /* GetInput (normal input) from History */ /* ------------------------------------ */ /* Parameters may be : */ /* n = Nth entry */ /* -1 = Active entry */ /* -2 = TopMost entry */ /* -3 = BottomMost entry */ /* default : */ /* get active entry */ /**********************************************************************/ static APTR __saveds __asm GetInput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { LONG *ValuePtr = (LONG *)Parms[0], Value; if(ValuePtr) Value = *ValuePtr; else Value = -1; return(ReturnEntry(GET_INPUT, NORMAL_OUTPUT, Value)); } /**********************************************************************/ /* GetInput (TeX input) from History */ /* --------------------------------- */ /* Parameters may be : */ /* n = Nth entry */ /* -1 = Active entry */ /* -2 = TopMost entry */ /* -3 = BottomMost entry */ /* default : */ /* get active entry */ /**********************************************************************/ static APTR __saveds __asm GetTeXInput(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { LONG *ValuePtr = (LONG *)Parms[0], Value; if(ValuePtr) Value = *ValuePtr; else Value = -1; return(ReturnEntry(GET_INPUT, TEX_OUTPUT, Value)); } /**********************************************************************/ /* Format an expression to TeX format */ /* ---------------------------------- */ /* Parameters must be */ /* Expr = Expression to convert */ /**********************************************************************/ static APTR __saveds __asm DoFormatTeX(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { char NewBuff[512], **Exprs; char OutBuff[840]; BOOL GoOn = TRUE; // Build expression from partial input strcpy(NewBuff, ""); Exprs = (char **)Parms[0]; while(*Exprs && GoOn) { if((strlen(*Exprs) + strlen(NewBuff)) < 256) strcat(NewBuff, *Exprs); else GoOn = FALSE; Exprs++; } // Format output FormatTeX(NewBuff, OutBuff); // Return RexxString return((APTR)set(AppObject, MUIA_Application_RexxString, OutBuff)); } /**********************************************************************/ /* Set outputmodes for ARexx Calculation */ /* ------------------------------------- */ /* Parameters may be : */ /* BASE = Set the output base */ /* SIZE = Set output size */ /* SIGN = Set signed/unsigned output */ /* ANGLE = Set default angle */ /**********************************************************************/ static APTR __saveds __asm SetMode(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { char *ThisVal; // Check for BASE keyword if((ThisVal = (char *)Parms[0])) { if(MatchToolValue(ThisVal, "DEC")) RXIntType = ID_DECIMAL; else if(MatchToolValue(ThisVal, "HEX")) RXIntType = ID_HEXDECIMAL; else if(MatchToolValue(ThisVal, "OCT")) RXIntType = ID_OCTAL; else if(MatchToolValue(ThisVal, "BIN")) RXIntType = ID_BINARY; } // Check for SIZE keyword if((ThisVal = (char *)Parms[1])) { if(MatchToolValue(ThisVal, "8")) RXIntBase = ID_8BIT; else if(MatchToolValue(ThisVal, "16")) RXIntBase = ID_16BIT; else if(MatchToolValue(ThisVal, "32")) RXIntBase = ID_32BIT; } // Check for SIGN keyword if((ThisVal = (char *)Parms[2])) { if(MatchToolValue(ThisVal, "SIGNED")) RXIntSign = ID_SIGNED; else if(MatchToolValue(ThisVal, "UNSIGNED")) RXIntSign = ID_UNSIGNED; } // Check for ANGLE keyword if((ThisVal = (char *)Parms[3])) { if(MatchToolValue(ThisVal, "RAD")) RXIntAngle = ID_RAD; else if(MatchToolValue(ThisVal, "DEG")) RXIntAngle = ID_DEG; else if(MatchToolValue(ThisVal, "GRA")) RXIntAngle = ID_GRAD; } return(NULL); } /**********************************************************************/ /* Delete an entry from history */ /* ---------------------------- */ /* Parameters may be: */ /* n = n-th entry */ /* -1 = active entry */ /* -2 = topmost entry */ /* -3 = bottommost entry */ /* default */ /* remove active entry */ /**********************************************************************/ static APTR __saveds __asm DeleteHistoryFunc(register __a0 struct Hook *MyHook, register __a2 APTR *MyObject, register __a1 ULONG *Parms) { LONG *ValuePtr = (LONG *)Parms[0], Value; if(ValuePtr) Value = *ValuePtr; else Value = -1; DeleteHistory(Value); return(NULL); } /**********************************************************************/ /* Return a normal entry */ /**********************************************************************/ static APTR ReturnEntry(UWORD Mode, UWORD OutMode, LONG Pos) { struct ListStruct *LSV = NULL; char *Source; char OutBuffer[300]; // Get appropriate entry if(Pos == GET_ACTIVE) DoMethod(OutputBox, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &LSV); else if(Pos == GET_TOPMOST) DoMethod(OutputBox, MUIM_List_GetEntry, 0, &LSV); else if(Pos == GET_BOTTOMMOST) { struct ListStruct *Dummy; ULONG i; // Move to end of list for(i = 0;; i++) { DoMethod(OutputBox, MUIM_List_GetEntry, i, &Dummy); if(Dummy) LSV = Dummy; else break; } } else { ULONG NumEntries; // First check, whether entry argument is appropriate get(OutputBox, MUIA_List_Entries, &NumEntries); if(Pos < GET_BOTTOMMOST || Pos >= NumEntries) Pos = MUIV_List_GetEntry_Active; DoMethod(OutputBox, MUIM_List_GetEntry, Pos, &LSV); } if(LSV) { // Get correct source of input Source = ((Mode == GET_OUTPUT) ? LSV->Output : LSV->Input); if(OutMode == NORMAL_OUTPUT) strncpy(OutBuffer, Source, 299); else FormatTeX(Source, OutBuffer); // Not to return Error message ?!? if(strncmp(Source, "\0338", 2)) { // Return RexxString return((APTR)set(AppObject, MUIA_Application_RexxString, OutBuffer)); } else return((APTR)set(AppObject, MUIA_Application_RexxString, " ")); } else return((APTR)set(AppObject, MUIA_Application_RexxString, " ")); } /**********************************************************************/ /* Format a given entry according to TeX rules */ /**********************************************************************/ static void FormatTeX(char *Source, char *Dest) { char *CopyDest = Dest; BOOL HexMode = FALSE; BOOL PowMode = FALSE; UWORD BraceMode = 0; while(*Source) { if(*Source == '$') { *Dest++ = '\\'; *Dest++ = '$'; Source++; HexMode = TRUE; } if(*Source == '0' && (*(Source + 1) == 'x' || *(Source + 1) == 'X')) { *Dest++ = '\\'; *Dest++ = '$'; Source++; Source++; HexMode = TRUE; } else if(*Source == '*') { *Dest = '\0'; strcat(CopyDest, "\\cdot "); Dest = CopyDest + strlen(CopyDest); Source++; HexMode = FALSE; } else if(*Source == '\\') { *Dest++ = '\\'; HexMode = FALSE; } else if(*Source == '&') { *Dest++ = '\\'; *Dest++ = *Source++; HexMode = FALSE; } else if(*Source == '%') { *Dest++ = '\\'; *Dest++ = *Source++; HexMode = FALSE; } else if(*Source == '(') { *Dest++ = *Source++; BraceMode++; } else if(*Source == ')') { *Dest++ = *Source++; BraceMode--; if(PowMode && !BraceMode) { *Dest++ = '}'; PowMode = FALSE; } } else if(*Source == '^') { *Dest++ = *Source++; *Dest++ = '{'; PowMode = TRUE; } else if((*Source == 'e' || *Source == 'E') && !HexMode) { *Dest = '\0'; strcat(CopyDest, "\\cdot 10^{"); Dest = CopyDest + strlen(CopyDest); Source++; while(*Source == '-' || (*Source >= '0' && *Source <= '9')) *Dest++ = *Source++; *Dest++ = '}'; } else if((*Source >= '0' && *Source <= '9') || *Source == '.' || *Source == '/' || *Source == '+' || *Source == '-' || *Source == ' ' || (*Source >= 'a' && *Source <= 'f') || (*Source >= 'A' && *Source <= 'F')) { *Dest++ = *Source++; if(*Source == ' ' && PowMode && !BraceMode) { *Dest++ = '}'; PowMode = FALSE; } } else Source++; } *Dest = '\0'; }