tldm-universe/Ardent/UV/gcidir/include/pi.decomp.h
2024-09-09 17:51:08 -04:00

487 lines
20 KiB
C
Executable File

/******************************************************************************
*
* INFO/BASIC de-compiler main include file
*
* Module %M% Version %I% Date %H%
*
* (c) Copyright 1998 Ardent Software Inc. - All Rights Reserved
* This is unpublished proprietary source code of Ardent Software Inc.
* The copyright notice above does not evidence any actual or intended
* publication of such source code.
*
*******************************************************************************
*
* Maintenence log - insert most recent change descriptions at top
*
* Date.... GTAR# WHO Description.........................................
* 10/14/98 23801 SAP Change copyrights.
* 07/14/94 14444 NDP Removed __MODULE__ and __SCCSID__ definitions.
* 06/23/94 14421 PGW Initial implementation
*
******************************************************************************/
/*
* This is the header file for the INFO/BASIC de-compiler, defining the
* major data structures, global variables, and procedure declarations.
*/
/***********************************************************************
*
* Macros and constants
*
***********************************************************************/
/*
* The following 'proto' macro allows the defining of function prototypes
* such that the code still compiles for non-prototype supporting compilers.
* Example usage of the macro for printf is:
* void printf proto((char *, ...));
* Note: The usage of the double parenthesis is necessary!
*/
#ifdef __STDC__
#define proto(args) args /* for prototypers */
#else
#define proto(args) () /* for non-prototypers */
#endif
#define TEXT_MARK '\373'
#define SUBVALUE_MARK '\374'
#define VALUE_MARK '\375'
#define FIELD_MARK '\376'
#define ITEM_MARK '\377'
/* Real_Char is a macro to convert a PRIMOS char (found in
object files) to a printable ASCII char. */
#define Real_Char(x) (((char)(x)) ^ 0x80)
/* Limits */
#define MAXSTRING 258 /* Maximum size of a string literal */
#define MAXNAME 1024 /* Maximum length of a file name */
/* Is there an ANSI form? */
#define MAX_OBJECT_SIZE 65536 /* Maximum size of object code */
#define MAXSOURCE 2048 /* Maximum source line length */
#define MAX_OPCODE_ARGS 8 /* Maximum stack args to opcode */
#define MAX_DATE_STRING 64 /* Maximum length of date string */
#define MAX_COMMONS 256 /* Maximum number of COMMON areas */
#define MAX_INTEGER_TEXT 20 /* Max length of integer constant */
#define MAX_CALL_ARGS 256 /* Maximum args to CALL */
#define OP_STORE_OPCODE 5 /* Value of STORE opcode */
#define OP_RETURN_OPCODE 10 /* Value of RETURN opcode */
#define OP_BRLFALS_OPCODE 39 /* Value of BRLFALS opcode */
#define OP_BRLTRUE_OPCODE 48 /* Value of BRLTRUE opcode */
#define OP_LDVAR_OPCODE 94 /* Value of LDVAR opcode */
#define OP_EXTENDED_OPCODE 95 /* prefix byte for extended opcodes */
#define OP_LOCATE_OPCODE 7 /* Value of LOCATE opcode (after 95) */
#define OP_CONSTANT_BASE 99 /* value for "Load constant zero" */
#define OP_LDVAR_LIMIT 128 /* Start of "load variable" opcodes */
#define OP_45_LIMIT 11 /* Maximum OP45 extension */
#define OP_95_LIMIT 178 /* Maximum OP95 extension */
#define QUOTE_CHAR '"' /* Used for string constants */
/* This is the value for the sign bit in a 3-byte signed number */
#define ADDRESS_SIGN_VALUE 0x800000
/* This is the value for the sign bit in a 4-byte signed number */
#define LONG_SIGN_VALUE 0x80000000
/* Fields in the variable header data */
#define VAR_HDR_PATH 0
#define VAR_HDR_PI_REV 1
#define VAR_HDR_IB_REV 2
#define VAR_HDR_USER 3
#define VAR_HDR_DATETIME 4
#define VAR_HDR_COPYRIGHT 5
#define VAR_HDR_SERIAL 6
#define VAR_HDR_COMMENTS 7
/* Number of fields to be extracted */
#define VAR_HDR_FIELDS 8
/* Bits in the options word of the INFO/BASIC header */
/* (extracted from ib_options.h in the PI/open source) */
#define BRIEF_OPTION 0x00000001
#define CASE_OPTION 0x00000002
#define DEBUGGING_OPTION 0x00000004
#define DETAIL_OPTION 0x00000008
#define INTERNAL_DEBUGGING_OPTION 0x00000010
#define ITYPE_OPTION 0x00000020
#define IXREF_OPTION 0x00000040
#define LISTING_OPTION 0x00000080
#define OBJECT_OPTION 0x00000100
#define OPTIMIZE_OPTION 0x00000200
#define PRIME_OPTION 0x00000400
/* Option bit with value 0x00000800 not used */
#define IB_REALITY_OPTION 0x00001000
#define IB_SMA_OPTION 0x00002000
#define VERSION_OPTION 0x00004000
#define XREF_OPTION 0x00008000
#define NO_WARNINGS_OPTION 0x00010000
#define MONITOR_OPTION 0x00020000
#define CMAN_OPTION 0x00040000
#define SMA_COMMON_OPTION 0x00080000
#define IB_RAW_INPUT_OPTION 0x00100000
#define IB_RAW_OUTPUT_OPTION 0x00200000
#define IB_SMA_SEQ_OPTION 0x00400000
#define IB_SMA_FOR_NEXT_OPTION 0x00800000
#define IB_SMA_READ_ELSE_OPTION 0x01000000
#define IB_SMA_HEADING_OPTION 0x02000000
/* Options bits for INPUT opcodes */
/* The first three are used by both INPUTOP and INPUTAT */
#define INPUT_UNDERSCORE_OPTION 1
#define INPUT_COLON_OPTION 2
#define INPUT_PRIME_OPTION 4
/* This one is only used by INPUTOP */
#define INPUT_KEYIN_OPTION 8
/* These are only used by INPUTAT */
#define INPUT_DISPLAY_OPTION 8
#define INPUT_FORMAT_OPTION 16
#define INPUT_ELSE_OPTION 32
#define INPUT_THEN_OPTION 64
/***********************************************************************
* Status codes
***********************************************************************/
#define DC_INVALID_OPCODE 1001 /* Invalid opcode */
#define DC_UNSUPPORTED_OPCODE 1002 /* Unsupported opcode */
#define DC_INVALID_INDXARY 1003 /* INDXARY without array name */
#define DC_DIMCOM_ERROR 1004 /* DIMCOM: missing variable */
#define DC_BRLNERR 1005 /* Unexpected BRLNERR */
#define DC_MISSING_TARGET 1006 /* No target for branch */
#define DC_MEMORY 1007 /* Out of memory */
#define DC_DIMLCL_ERROR 1008 /* DIMLCL: missing variable */
#define DC_READL_ERROR 1009 /* READL: missing lock type */
#define DC_RSTACK_UNDERFLOW 1010 /* rstack exhausted */
#define DC_INVALID_COMMON 1011 /* Invalid COMMON reference */
#define DC_INVALID_RSTACK 1012 /* Invalid rstack entry */
#define DC_INVALID_SELIND 1013 /* SELECTINDEX: invalid type */
#define DC_READNX2_ERROR 1014 /* READNX2: invalid arg count */
#define DC_INVALID_INPUTOP 1015 /* INPUTOP: invalid options */
#define DC_INVALID_INPUTAT 1016 /* INPUTAT: invalid options */
#define DC_INVALID_DEVSYS 1017 /* Invalid DEVSYS reference */
#define DC_INVALID_ONERR 1018 /* ONERR/store with arg not 0 */
#define DC_ERROR_IFEXPR 1019 /* IF-expr with no text */
#define DC_DUPLICATE 1020 /* Unexpected DUP */
#define DC_MISSING_STORE 1021 /* Expected STORE missing */
#define DC_DEVSYS_FORBIDDEN 1022 /* COMMON /DEVSYS/ not allowed */
#define DC_STORE_STACK 1023 /* STORE left entry on stack */
#define DC_STMT_STACK 1024 /* Statement left entry on stack */
#define DC_MISSING_LDVAR 1025 /* Expected LDVAR missing */
#define DC_INVALID_SMA 1026 /* Invalid use of SMA opcode */
#define DC_DIMICOM_ERROR 1027 /* DIMICOM: argument error */
#define DC_MISSING_SUBR 1028 /* CALL: no subroutine reference */
#define DC_RESOLVE_ERROR 1029 /* pop_stack_and_resolve error */
/* Command line errors */
#define DC_OPT_NOFILE 2001 /* No input file given */
#define DC_OPT_UNKNOWN 2002 /* Unknown option */
#define DC_OPT_INVALID 2003 /* Invalid option */
#define DC_OPT_SYNTAX 2004 /* Too many non-hyphen words */
#define DC_OPT_ARGKEY 2005 /* Invalid argument key */
/***********************************************************************
*
* Typedefs and structures
*
***********************************************************************/
/* The p_file structure is used to read through the object file,
keeping track of the current byte value and byte position.
Procedures to manipulate it are found in pfile.c */
struct p_file {
FILE *pf;
int byte;
long count;
};
extern struct p_file p1; /* program object (IRUN) file */
/* The ib_header_data structure holds data obtained from the object
file header. */
struct ib_header_data {
int version;
int program_type;
long object_size;
long obj_header_size;
unsigned long options_word;
char * var_hdr_data[VAR_HDR_FIELDS];
unsigned int nargs;
unsigned int nvars;
unsigned int symof;
unsigned int linof;
};
extern struct ib_header_data header_data;
/* Information about each COMMON area defined in a program is held
* in a COMMON_TYPE structure. This is of variable size, since
* it holds information about each variable within the common area.
*/
typedef struct pi_common_elt_str PI_COMMON_ELEMENT;
struct pi_common_elt_str {
int dims; /* Number of dimensions */
char * rows; /* Number of rows; NULL = scalar */
char * cols; /* Number of columns; NULL = 1-dim */
};
typedef struct sma_common_elt_str SMA_COMMON_ELEMENT;
struct sma_common_elt_str {
unsigned int var_no; /* Local variable referencing this array */
unsigned int rows; /* Number of rows */
unsigned int cols; /* Number of columns; 0 = 1-dim */
};
typedef struct common_element_str COMMON_ELEMENT;
struct common_element_str {
char * name; /* Variable name */
int type; /* 1 = SMA-style array */
union {
PI_COMMON_ELEMENT pi;
SMA_COMMON_ELEMENT sma;
} data;
};
typedef struct common_str COMMON_TYPE, *COMMON_PTR;
struct common_str {
unsigned int var_no; /* Variable number in this program */
char name[10]; /* COMMON area name */
unsigned int size; /* Size (number of elements) */
COMMON_ELEMENT elt[1]; /* Data for each element */
};
extern COMMON_PTR common_list[];
/* In order to de-compile expressions, the program keeps a symbolic
* stack which parallels the run-time stack movements that occur when
* a program is executed. Each element of the stack is not a value,
* but holds information about the sub-expression that it corresponds to.
* In most cases, this is the text of the sub-expressions, plus a
* priority used to determine whether parentheses are needed.
* These are operator precedence values: higher number means a lower
* priority operator.
*/
/* Rstack entry types */
#define RS_NONE 0 /* Not complete yet */
#define RS_TEXT 1 /* Sub-expression text */
#define RS_LOCAL 2 /* Local variable reference */
#define RS_COMMON 3 /* COMMON variable reference */
#define RS_INTEGER 4 /* Integer constant */
#define RS_SUBROUTINE 5 /* Subroutine link (DSUBR) */
/* Text entry */
typedef struct rstack_text_str RSTACK_TEXT_TYPE;
struct rstack_text_str {
int priority; /* operator precedence of this entry */
char * text; /* expression text */
};
/* Local variable entry */
typedef struct rstack_local_str RSTACK_LOCAL_TYPE;
struct rstack_local_str {
unsigned int var_no; /* variable number */
};
/* COMMON variable entry */
typedef struct rstack_common_str RSTACK_COMMON_TYPE;
struct rstack_common_str {
unsigned int common_no; /* COMMON number */
unsigned int offset; /* Offset within COMMON */
};
/* Integer constant entry */
typedef struct rstack_integer_str RSTACK_INTEGER_TYPE;
struct rstack_integer_str {
long value; /* constant value */
};
/* Subroutine entry */
typedef struct rstack_subroutine_str RSTACK_SUBROUTINE_TYPE;
struct rstack_subroutine_str {
char * text; /* subroutine reference */
};
typedef struct rstack_str RSTACK_TYPE, *RSTACK_PTR;
struct rstack_str {
RSTACK_PTR previous; /* pointer to stack element below this */
int type; /* Type of entry */
int duplicate; /* Has been duplicated by DUP opcode */
union {
RSTACK_TEXT_TYPE expr;
RSTACK_LOCAL_TYPE local;
RSTACK_COMMON_TYPE common;
RSTACK_INTEGER_TYPE integer;
RSTACK_SUBROUTINE_TYPE subr;
} data;
};
extern RSTACK_PTR rstack_top; /* top of stack, i.e. newest entry */
/* As de-compilation proceeds, lines of generated output are held in
* a linked list of output_line structures. For each line, we also
* hold the offset in the object file where the code for that line
* starts. This allows us to identify and mark the target line for
* each branch opcode.
*/
typedef struct output_line_str OUTPUT_LINE_TYPE, *OUTPUT_LINE_PTR;
struct output_line_str {
OUTPUT_LINE_PTR next; /* Link to next line */
OUTPUT_LINE_PTR previous; /* Link to previous line */
union {
char * text; /* Text of line */
COMMON_PTR common; /* COMMON data area */
} line;
long offset; /* Start pos. in object code */
int level; /* Logical indentation level */
int branch; /* Used as a branch target */
int type; /* Text or other */
};
/* Most lines are held as text, but some are incomplete, e.g.
* those for COMMON areas. The 'type' field identifies which,
* taking on the values below:
*/
#define OL_EMPTY 0 /* Line not created yet */
#define OL_TEXT 1 /* Normal text line */
#define OL_COMMON 2 /* COMMON declaration */
extern OUTPUT_LINE_PTR output_first; /* First line of output */
extern OUTPUT_LINE_PTR output_last; /* Last line of output */
/* The target offsets for forward branches are held in a sorted linked
* linked list of PENDING_BRANCH structures.
*/
typedef struct pending_branch_str PENDING_BRANCH_TYPE, *PENDING_BRANCH_PTR;
struct pending_branch_str {
PENDING_BRANCH_PTR next; /* Link to next in list */
long offset; /* Offset that occurs as branch target */
};
extern PENDING_BRANCH_PTR pending_branch_first;
/* Control structures are handled by a stack of level_str structures.
* Each one contains state indicators relating to ON ERROR clauses,
* LOCKED clauses, and other clauses, as well as the offset of the
* end of the current part of the control structure.
*
* State values are as follows:
*/
#define NOT_ACTIVE 0 /* Applies all indicators */
/*
* Values for "ON ERROR" status
*/
#define ONERR_START 1 /* 'ONERR' opcode seen */
#define ONERR_IO_SEEN 2 /* I/O opcode seen, BRLNERR expected */
#define ONERR_GOING 3 /* In "ON ERROR" clause */
/*
* Values for "LOCKED" status
*/
#define LOCKED_START 1 /* 'LDIOOPT' opcode seen */
#define LOCKED_IO_SEEN 2 /* I/O opcode seen, LOCKED expected */
#define LOCKED_BRL1 3 /* First BRLFALS seen */
#define LOCKED_GOING 4 /* In "LOCKED" clause */
#define LOCKED_RECLOCK 5 /* Seen RECORDLOCK statement */
/*
* Values for other clause status
*/
#define CTL_START 1 /* Expecting "THEN" */
#define CTL_THEN_GOING 2 /* In "THEN" clause */
#define CTL_ELSE_GOING 3 /* In "ELSE" clause */
#define CTL_FOR_START 4 /* Seen "FORINIT", expecting "FORTST" */
#define CTL_FOR_GOING 5 /* In "FOR/NEXT" loop */
#define CTL_FILELOCK 6 /* Expecting fake "THEN" */
#define CTL_ELSE_EXPR 7 /* In "ELSE" part of conditional expression */
typedef struct level_str LEVEL_TYPE, *LEVEL_PTR;
struct level_str {
LEVEL_PTR previous; /* Link to level below this one */
int depth; /* Nesting depth */
int onerr; /* ON ERROR status */
int locked; /* LOCKED status */
int ctl; /* other control status */
int needelse; /* This THEN needs an ELSE */
unsigned int for_top; /* FOR-loop top-of-loop address */
unsigned int end_offset; /* End of current structure */
};
extern LEVEL_PTR level_base; /* base of level stack, i.e. 1st entry */
extern LEVEL_PTR level_top; /* top of level stack, i.e. last entry */
extern LEVEL_TYPE cur_status; /* Current situation */
/* The number of dimensions associated with each local variable
* is held in the local_dims array;
*/
extern int * local_dims;
/* For each call to a user-defined function, a separate DEFFUN
* is created. These are held in a separate linked list and
* written out at the beginning of the generated output.
*/
typedef struct deffun_line_str DEFFUN_LINE_TYPE, *DEFFUN_LINE_PTR;
struct deffun_line_str {
DEFFUN_LINE_PTR next; /* Link to next line */
DEFFUN_LINE_PTR previous; /* Link to previous line */
char * text; /* Text of line */
};
extern DEFFUN_LINE_PTR deffun_first; /* Start of DEFFUN list */
extern DEFFUN_LINE_PTR deffun_last; /* End of DEFFUN list */
/* saved_capture_variable holds the argument to !SMA.CAPTURING,
* for use by EXECUTE */
extern char * saved_capture_variable;
/* using_names indicates whether or not original names are being
* used for local variables. */
extern int using_names;
/***********************************************************************
*
* Procedure declarations
*
***********************************************************************/
/* Routines to handle the 'pfile' structure */
long get_paddr proto((struct p_file *pfile));
int get_pchar proto((struct p_file *pfile));
unsigned long get_plong proto((struct p_file *pfile));
unsigned int get_pshort proto((struct p_file *pfile));
int open_pfile proto((struct p_file *pfile, char *pfile_name));
int seek_pfile proto((struct p_file *pfile, long where));
int size_pfile proto((struct p_file *pfile, long * size_output));
/* Date/time conversion routines */
int get_date proto((char *buf, long date_value));
int get_time proto((char *buf, long time_value));
/* Template expander */
char * expand_template proto((
char * xtmplptr, /* Pointer to template */
char * xidptr, /* Pointer to message id */
char * xargptr /* Pointer to argument list */
));
/* @-variable lookup */
char * get_at_var proto((unsigned int devsys_offset));
/* Output of $OPTIONS lines */
void write_dollar_options proto((FILE * outfile, unsigned long opt_word));
/* Generated-subroutine lookup */
int gs_lookup proto((char **arg_vector, int *is_special));
/* Table of local-variable names */
int load_variable_names proto((long where));
char * get_local_var_name proto((unsigned int local_var_no));
char * get_common_var_name proto((COMMON_PTR cp, unsigned int common_offset));
void generate_unique proto((char * new_name));