home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************/
- /* REXX SGML interpreter. */
- /* Provides an SGML "application environment" for Personal REXX. */
- /* */
- /* Author: Roy Engehausen */
- /* Mods: Jack Steitz 1. Bring code to ANSI Standard */
- /* Mods: Charles F. Goldfarb 2. Convert to Borland C */
- /* */
- /* */
- /*****************************************************************************/
-
- /*===========================================================================*/
- /* External files */
- /*===========================================================================*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
-
- #pragma option -a- /* Borland C: force byte alignment */
- #include "rexxcall.h"
- #pragma option -a. /* Borland C: restore previous alignment */
-
- /*****************************************************************************/
- /* REXX SGML interpreter. */
- /* Subroutines */
- /*****************************************************************************/
-
- int words(char *);
-
- char *subword(char *, int, int);
-
- /*---------------------------------------------------------------------------*/
- /* Defines */
- /*---------------------------------------------------------------------------*/
-
- #define MAKE_LONG(hi, low) \
- ((long) ((((unsigned long) (unsigned) (hi)) << 16) + \
- (unsigned long) (unsigned) (low)))
- #define HIGH_WORD(l) ((unsigned) (((unsigned long) (l)) >> 16))
- #define LOW_WORD(l) ((unsigned) (((unsigned long) (l)) & 0xffff))
-
- #ifdef __SMALL__ /* small model */
- #define FINDINT findints
- #endif
- #ifdef __MEDIUM__ /* medium model */
- #define FINDINT findintm
- #endif
- #ifdef __LARGE__ /* large model */
- #define FINDINT findintl
- #endif
-
- /*---------------------------------------------------------------------------*/
- /* These are assembler language interfaces to REXX supplied as part */
- /* of Mansfield's Personal REXX */
- /*---------------------------------------------------------------------------*/
-
- int rexxcall(void),
- FINDINT(int *);
-
- /*---------------------------------------------------------------------------*/
- /* Prototype for SGML */
- /*---------------------------------------------------------------------------*/
-
- void sgmlapir(int, char **);
-
- /*---------------------------------------------------------------------------*/
- /* Function prototypes */
- /*---------------------------------------------------------------------------*/
-
- unsigned showsp(void);
-
- int proc(char *, char *, int *);
-
- int execute(FARP, size_t);
-
- void rexxerr(char *);
-
- /*---------------------------------------------------------------------------*/
- /* Global variables */
- /*---------------------------------------------------------------------------*/
-
- unsigned data_segment;
-
- char *arg_array[5];
- char arg_array1[20];
- char arg_array2[20];
-
- /*===========================================================================*/
- /* Main entry point */
- /*===========================================================================*/
-
- int main(int argc, char **argv)
- {
-
- char *execn = NULL;
- int retcode;
-
- /*-----------------------------------------------------------------------*/
- /* Check parameter count */
- /*-----------------------------------------------------------------------*/
-
- if (argc < 2)
- {
- printf("\nExec name parameter is missing -- %d\n", argc);
- exit(1);
- };
-
- /*-----------------------------------------------------------------------*/
- /* The exec name is the first item. */
- /*-----------------------------------------------------------------------*/
-
- execn = argv[1];
-
- proc(execn,argv[2],&retcode);
-
- return(retcode);
-
- }
-
- /*===========================================================================*/
- /* Interface to REXX interpreter */
- /*===========================================================================*/
-
- int proc(char *name, char *argstring, int *rcode)
- {
- char result[257];
-
- union REGS inregs,
- outregs;
-
- struct SREGS segregs;
-
- /*-----------------------------------------------------------------------*/
- /* REXX control blocks */
- /*-----------------------------------------------------------------------*/
-
- struct call_block cb, *cbp = &cb;
- struct arg_block arg_list;
- struct env_block eb;
-
- /*-----------------------------------------------------------------------*/
- /* REXX information */
- /*-----------------------------------------------------------------------*/
-
- int rexx_interrupt,
- unload = 0,
- interrupt_status;
-
- /*-----------------------------------------------------------------------*/
- /* Find REXX */
- /*-----------------------------------------------------------------------*/
-
- rexx_interrupt = FINDINT(&interrupt_status);
-
- if (interrupt_status != 0)
- rexxerr("RXINTMGR not installed.\n");
-
- /*-----------------------------------------------------------------------*/
- /* Verify REXX is loaded */
- /*-----------------------------------------------------------------------*/
-
- inregs.h.ah = REXX_VERSION;
- inregs.h.al = 0;
- int86(rexx_interrupt, &inregs, &outregs);
-
- if (outregs.h.al == 0)
- {
- if (system("REXX /R") !=0)
- rexxerr("REXX not loaded\n");
- else
- unload = 1;
- }
-
- /*-----------------------------------------------------------------------*/
- /* Build the CALL BLOCK */
- /*-----------------------------------------------------------------------*/
-
- segread(&segregs);
- data_segment = segregs.ds;
-
- memset(&cb, 0, sizeof(struct call_block));
-
- cb.arg_list_addr = (FARP) &arg_list;
- cb.arg_count = 1;
- cb.ret_size = 256;
- cb.ret_count = 0;
- cb.ret_addr = (FARP) result;
- cb.envblock_addr = (FARP) &eb;
- cb.name_addr = (FARP) name;
- cb.name_length = strlen(name);
-
- /*-----------------------------------------------------------------------*/
- /* Build the argument block */
- /*-----------------------------------------------------------------------*/
-
- arg_list.arg_addr = (FARP) argstring;
- arg_list.arg_length = strlen(argstring);
-
- /*-----------------------------------------------------------------------*/
- /* Build the environment block */
- /*-----------------------------------------------------------------------*/
-
- memset(&eb, 0, sizeof(struct env_block));
- memcpy(eb.env_name, "SGML ", 8); /* name of our environment */
- memcpy(eb.env_extension, "REX" , 3); /* extension of our macros */
- eb.env_entry_addr = (FARP) rexxcall; /* interface to command handler*/
- /*-----------------------------------------------------------------------*/
- /* Set the address of the command handler. If this is small model then */
- /* we use a SEGMENT of zero to indicate that NEAR CALLs are to be used. */
- /*-----------------------------------------------------------------------*/
-
- #ifdef __SMALL__
- eb.env_exec_addr = (FARP) MAKE_LONG(0, execute);
- #else
- #if 0
- eb.env_exec_addr = (FARP) execute;
- #endif
- eb.env_exec_addr = execute;
- #endif
-
- /*-----------------------------------------------------------------------*/
- /* Set the segment addresses */
- /*-----------------------------------------------------------------------*/
-
- eb.env_dseg = data_segment;
- eb.env_sseg = segregs.ss;
-
- /*-----------------------------------------------------------------------*/
- /* Set the address of the stack. Take off a few byte to make sure we */
- /* never overlay anything */
- /*-----------------------------------------------------------------------*/
-
- eb.env_sp = showsp() - 40;
-
- /*-----------------------------------------------------------------------*/
- /* Now call REXX */
- /*-----------------------------------------------------------------------*/
-
- inregs.h.ah = REXX_CALL;
- #ifdef __LARGE__
- inregs.x.bx = FP_SEG(cbp);
- inregs.x.dx = FP_OFF(cbp);
- #else
- inregs.x.bx = data_segment;
- inregs.x.dx = (unsigned) cbp;
- #endif
-
- int86x(rexx_interrupt, &inregs, &outregs, &segregs);
-
- /*-----------------------------------------------------------------------*/
- /* Set the results */
- /*-----------------------------------------------------------------------*/
-
- result[(int)cb.ret_count] = '\0';
- *rcode = atoi(result);
-
- /*-----------------------------------------------------------------------*/
- /* We are done! */
- /*-----------------------------------------------------------------------*/
- if (unload)
- {
- inregs.h.ah = REXX_UNLOAD;
- inregs.h.al = 0;
- inregs.x.bx = _psp;
- int86(rexx_interrupt, &inregs, &outregs);
- }
- return(0);
-
- }
-
- /*===========================================================================*/
- /* Return the current stack pointer */
- /*===========================================================================*/
-
- unsigned showsp(void)
- {
- #ifdef __LARGE__
- int dummy, *dummyp = &dummy;
-
- return (FP_OFF(dummyp));
- #else
- int dummy; /* dummy variable allocated on stack so we can get its address */
-
- return ((unsigned) &dummy);
- #endif
- }
-
- /*===========================================================================*/
- /* Execute a command. This routine is called (via the REXXCALL assembler */
- /* interface) when REXX encounters a command to be processed by our */
- /* environment */
- /*===========================================================================*/
-
- int execute(FARP s, size_t l)
- {
- char *command;
- int arg_cnt;
-
- /*-----------------------------------------------------------------------*/
- /* Copy the command into a C-style null terminated string */
- /*-----------------------------------------------------------------------*/
-
- command = malloc(l + 1);
-
- #ifdef __LARGE__
- strncpy(command, s, l);
- #else
- movedata(HIGH_WORD(s), LOW_WORD(s), data_segment, (unsigned)command, l);
- #endif
- command[l] = '\0';
-
- /*-----------------------------------------------------------------------*/
- /* Change the command format */
- /*-----------------------------------------------------------------------*/
-
- arg_cnt = words(command) + 1;
- if (arg_cnt > 3)
- arg_cnt = 3;
-
- strcpy(arg_array1, subword(command, 1, 1));
- strcpy(arg_array2, subword(command, 2, 1));
-
- arg_array[0] = command;
- arg_array[1] = arg_array1;
- arg_array[2] = arg_array2;
-
- /*-----------------------------------------------------------------------*/
- /* OK. Call the SGMLAPI for REXX */
- /*-----------------------------------------------------------------------*/
- sgmlapir(arg_cnt, arg_array);
-
- /*-----------------------------------------------------------------------*/
- /* All done */
- /*-----------------------------------------------------------------------*/
-
- return(0);
-
- }
-
- /*===========================================================================*/
- /* Display error message and terminate */
- /*===========================================================================*/
-
- void rexxerr(char *s)
- {
- printf("ABORT:- %s\n",s);
- exit(255);
- }
- /*****************************************************************************/
- /* REXX SGML interpreter. */
- /* Subroutines */
- /* */
- /* Author: Roy Engehausen */
- /* Mods: Jack Steitz 1. Bring code to ANSI standard */
- /* */
- /* */
- /*****************************************************************************/
-
- /*===========================================================================*/
- /* Local Macros */
- /*===========================================================================*/
-
- #define skip2nb(p) while( *p == ' ') ++p
- #define skip2ws(p) while( (*p != ' ') && (*p != '\0') )++p
-
- /*===========================================================================*/
- /* WORDS */
- /*===========================================================================*/
-
- int words(char *input_string)
- {
- int word_count = 0;
-
- skip2nb(input_string);
- if (*input_string)
- while(*input_string)
- {
- ++word_count;
- skip2ws(input_string);
- skip2nb(input_string);
- }
-
- return (word_count);
- }
-
- /*===========================================================================*/
- /* SUBWORD */
- /*===========================================================================*/
-
- char *subword(char *input_string, int start_word, int number_words)
- {
- static char answer[100];
-
- char *substart;
- int out_index = 0;
- int end_word;
- int word_count = 0;
-
- answer[0] = '\0'; /* Start with a zero-length string */
-
- if (number_words == 0)
- end_word = words(input_string) + 1;
- else
- end_word = start_word + number_words;
-
- /* Skip leading white space */
- skip2nb(input_string);
-
- if (*input_string && start_word > 0 )
- /* Do the rest only if we don't have an empty string */
- {
-
- while (++word_count < start_word) /* Find the starting word */
- {
- skip2ws(input_string); /* Find the next blank or end of string */
- skip2nb(input_string); /* Find the start of the next word */
- }
- substart = input_string;
-
- while ( (word_count < end_word) &&
- *input_string ) /* Find end of substring */
- {
- skip2ws(input_string);
- if (++word_count < end_word)
- skip2nb(input_string);
- }
- /* Now extract the substring into answer */
- out_index = min(input_string - substart, sizeof(answer) - 1);
- strncpy(answer, substart, out_index);
- answer[out_index] = '\0';
- }
-
- return answer;
- }
-
-