tinycobol/lib/cobmove.c

408 lines
14 KiB
C

/*
* Copyright (C) 1999 - 2003, Rildo Pragana, Jim Noeth,
* Andrew Cameron, David Essex.
* Copyright (C) 1993, 1991 Rildo Pragana.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1,
* or (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING.LIB. If
* not, write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*/
/*
*
* COBOL Compiler Run Time Library -- Move Module
*
*/
#include "htcoblib.h"
/* #define DEBUG_RTS 0 */
/* #define DEBUG_MOVE_RTS 1 */
#define COBMV_9_ 0
#define COBMV_B_ 6
#define COBMV_C_ 12
#define COBMV_E_ 30
#define COBMV_F_ 18
#define COBMV_X_ 24
#define COBMV__9 0
#define COBMV__B 1
#define COBMV__C 2
#define COBMV__E 3
#define COBMV__F 4
#define COBMV__X 5
#define COBMV_MAX 255
#ifdef DEBUG_MOVE_RTS
char *StrMovRtn[] = {
"tcob_move_9_9", "tcob_move_9_b", "tcob_move_9_c",
"tcob_move_9_e", "tcob_move_9_f", "tcob_move_9_x",
"tcob_move_b_9", "tcob_move_b_b", "tcob_move_b_c",
"tcob_move_b_e", "tcob_move_b_f", "tcob_move_b_x",
"tcob_move_c_9", "tcob_move_c_b", "tcob_move_c_c",
"tcob_move_c_e", "tcob_move_c_f", "tcob_move_c_x",
"tcob_move_f_9", "tcob_move_f_b", "tcob_move_f_c",
"tcob_move_f_e", "tcob_move_f_f", "tcob_move_f_x",
"tcob_move_x_9", "tcob_move_x_b", "tcob_move_x_c",
"tcob_move_x_e", "tcob_move_x_f", "tcob_move_x_x",
"tcob_move_e_9", "tcob_move_e_b", "tcob_move_e_c",
"tcob_move_e_e", "tcob_move_e_f", "tcob_move_e_x"
};
#endif
/*--------------------------------------------------------------------------*\
| |
| void tcob_move( struct fld_desc *FieldDescSrc, |
| char *caSrcBuffer, |
| struct fld_desc *FieldDescDest, |
| char *caDestBuffer) |
| |
| Copy the contents of the field described by FieldDescSrc (data is |
| pointed to by caSrcBuffer) to the field described by FieldDescDest |
| (data will be stored in memory pointed to by caDescBuffer). |
| |
| This routine will appropriately convert data (or format it) as it |
| potentially moves from one data type to another. Truncation and |
| padding will also be done in this routine if field sizes differ. |
| Data types that this routine will handle are: |
| |
| Type Source Type Destination Type Defined As |
| '9' Numeric Display Numeric Display DTYPE_DISPLAY |
| 'D' Accept Display Accept Display DTYPE_ACCEP_DISPLAY |
| 'C' Numeric Packed Decimal Numeric Packed Decimal DTYPE_PACKED |
| 'A' Alpha Alpha DTYPE_ALPHA |
| 'X' AlphaNumeric AlphaNumeric DTYPE_ALPHANUMERIC |
| 'E' AlphaNumeric Numeric Edited DTYPE_EDITED |
| 'G' AlphaNumeric AlphaNumeric DTYPE_GROUP |
| 'B' Numeric Bin Int Numeric Bin Int DTYPE_BININT |
| 'U' Floating Point Floating Point DTYPE_FLOAT |
| |
| The main entry point is tcob_move, which looks at the data types of |
| the source and destinations, then calls a specific routine to handle |
| those specific data types. The routines are listed below, their name |
| is composed of tcob_move_?_?, where the first question mark is the |
| source data type, and the second question mark is the destination |
| data type. Certain data types are grouped together, such as ALPHA, |
| ALPHANUMERIC, GROUP and EDITED (when it is the source). This reduces |
| the number of routines needed to handle the various data types (the |
| list below is without the prefix tcob_move, i.e. _x_x means: |
| tcob_move_x_x). |
| |
| _x_x _9_x _b_x _f_x _c_x |
| _x_9 _9_9 _b_9 _f_9 _c_9 |
| _x_c _9_c _b_b _f_b _c_b |
| _x_e _9_b _b_c _f_c _c_c |
| _x_f _9_e _b_e _f_e _c_e |
| _x_b _9_f _b_f _f_f _c_f |
| |
\*-------------------------------------------------------------------------*/
void tcob_move( struct fld_desc *pfldDesc1, char *caData1,
struct fld_desc *pfldDesc2, char *caData2 ) {
int i;
extern void (*pMovRtn[])(struct fld_desc *, char *,
struct fld_desc *, char *);
switch(pfldDesc1->type) {
case DTYPE_DISPLAY:
i = COBMV_9_;
break;
case DTYPE_ALPHA:
i = COBMV_X_;
break;
case DTYPE_BININT:
i = COBMV_B_;
break;
case DTYPE_PACKED:
i = COBMV_C_;
break;
case DTYPE_ACCEPT_DISPLAY:
i = COBMV_X_;
break;
case DTYPE_EDITED:
// i = COBMV_X_;
i = COBMV_E_;
break;
case DTYPE_GROUP:
i = COBMV_X_;
break;
case DTYPE_FLOAT:
i = COBMV_F_;
break;
case DTYPE_ALPHANUMERIC:
case DTYPE_ALPHANUMERICL:
i = COBMV_X_;
break;
default:
runtime_error(RTERR_INVALID_PIC, pfldDesc1, (void *)caData1);
return;
}
switch(pfldDesc2->type) {
case DTYPE_DISPLAY:
i += COBMV__9;
break;
case DTYPE_ALPHA:
i += COBMV__X;
break;
case DTYPE_BININT:
i += COBMV__B;
break;
case DTYPE_PACKED:
i += COBMV__C;
break;
case DTYPE_ACCEPT_DISPLAY:
i += COBMV__X;
break;
case DTYPE_EDITED:
i += COBMV__E;
break;
case DTYPE_GROUP:
i += COBMV__X;
break;
case DTYPE_FLOAT:
i += COBMV__F;
break;
case DTYPE_ALPHANUMERIC:
case DTYPE_ALPHANUMERICL:
i += COBMV__X;
break;
default:
runtime_error(RTERR_INVALID_PIC, pfldDesc2, (void *)caData2);
return;
}
/* Override for non-elementary moves */
if ((pfldDesc1->type == DTYPE_GROUP)
|| (pfldDesc2->type == DTYPE_GROUP)) {
i = COBMV_X_ + COBMV__X;
}
#ifdef DEBUG_MOVE_RTS
// fprintf(stderr, "Debug: tcob_move type = %d\n", i);
fprintf(stderr, "Debug: tcob_move type = %d, %s\n", i, StrMovRtn[i]);
#endif
pMovRtn[i](pfldDesc1, caData1, pfldDesc2, caData2);
}
/*------------------------------------------------------------------------*\
| |
| runtime_error |
| |
\*------------------------------------------------------------------------*/
void runtime_error(int iErrorNum, struct fld_desc *pField, void *pData) {
unsigned int i, j;
extern int _iRtErrorNbr[];
extern char *_szRtErrorDesc[];
for(i = 0; _iRtErrorNbr[i] != -1; ++i)
if(iErrorNum == _iRtErrorNbr[i])
break;
fprintf(stderr, "\n\nRun Time Error - ");
if(_iRtErrorNbr[i] != -1)
fprintf(stderr, "%s\n", _szRtErrorDesc[i]);
else
fprintf(stderr, "Unknown Error\n");
if(pField) {
fprintf(stderr, "Field Description: ");
fprintf(stderr, "len = %ld, type = %c, dec/pscale = %d/%d, all = %d, just_r = %d, signs = %d/%d\n",
pField->len, pField->type, (char)pField->decimals,
(char)pField->pscale, pField->all, pField->just_r,
pField->separate_sign, pField->leading_sign);
}
if(!pData) {
fprintf(stderr, "No data pointer provided\n");
return;
}
fprintf(stderr, "Data Dump, Address = %08lX", (unsigned long)pData);
for(j=0; j<tcob_fldLength(pField); j+=24) {
fprintf(stderr, "\n%04d: ", (unsigned)j);
for(i = 0; i < 24; ++i) {
if((i + j) == tcob_fldLength(pField))
break;
fprintf(stderr, "%02X ", ((unsigned char *)pData)[j+i]);
}
fprintf(stderr, "\n ");
for(i = 0; i < 24; ++i) {
if((i + j) == pField->len)
if((i + j) == tcob_fldLength(pField))
break;
if((((unsigned char *)pData)[i] >= ' ')
&& (((unsigned char *)pData)[i] < 0x7f))
fprintf(stderr, " %c ", ((unsigned char *)pData)[j+i]);
else
fprintf(stderr, " ");
}
}
fprintf(stderr, "\n\n");
}
int _iRtErrorNbr[] = {
RTERR_INVALID_DATA,
RTERR_INVALID_PIC,
-1
};
char *_szRtErrorDesc[] = {
"Invalid Data Content",
"Invalid Picture Structure",
(char *)0
};
/*------------------------------------------------------------------------*\
| |
| _DUMP_ |
| |
\*------------------------------------------------------------------------*/
void _DUMP_(unsigned char *caData, char *szCount, char *caOut) {
unsigned int i, k;
unsigned char c;
k = 0;
for(i = 0; i < 4; ++i) {
if(szCount[i] == '\0')
break;
k = (k * 10) + (szCount[i] - '0');
}
for(i = 0; i < k; ++i) {
c = (caData[i] >> 4) + '0';
if (c > '9') c += 7;
caOut[i * 2] = c;
c = (caData[i] & 0xf) + '0';
if (c > '9') c += 7;
caOut[(i * 2) + 1] = c;
}
}
/*------------------------------------------------------------------------*\
| |
| _FLDDUMP_ |
| |
\*------------------------------------------------------------------------*/
void _FLDDUMP_(struct fld_desc *pField, char *pData, char *szDesc) {
unsigned int i, j;
if(szDesc)
fprintf(stderr, "\n_FLDDUMP_\n%s: ", szDesc);
if(pField) {
fprintf(stderr, "len=%ld, type=%c, dec/pscale=%d/%d, ",
pField->len, pField->type, (char)pField->decimals, (char)pField->pscale);
fprintf(stderr, "all=%d, jr/bz=%d/%d, signs (l/s)= %d/%d\n",
pField->all, pField->just_r, pField->blank, pField->leading_sign, pField->separate_sign);
}
if (pField->type != DTYPE_GROUP && pField->type != DTYPE_ALPHANUMERICL) {
fprintf(stderr, "picture:");
for(i=0; tcob_picElemVal(pField->pic,i); i++) {
fprintf(stderr, "%c(%d)", tcob_picElemVal(pField->pic,i),
tcob_picElemLen(pField->pic,i));
}
fprintf(stderr, "\n");
}
if(!pData) {
fprintf(stderr, "No data pointer provided\n");
return;
}
fprintf(stderr, "Data Dump, Address = %08lX", (unsigned long)pData);
for(j=0; j<tcob_fldLength(pField); j+=24) {
fprintf(stderr, "\n%04d: ", (unsigned)j);
for(i = 0; i < 24; ++i) {
if((i + j) == tcob_fldLength(pField))
break;
fprintf(stderr, "%02X ", ((unsigned char *)pData)[j+i]);
}
fprintf(stderr, "\n ");
for(i = 0; i < 24; ++i) {
if((i + j) == tcob_fldLength(pField))
break;
if((((unsigned char *)pData)[i] >= ' ')
&& (((unsigned char *)pData)[i] < 0x7f))
fprintf(stderr, " %c ", ((unsigned char *)pData)[j+i]);
else
fprintf(stderr, " ");
}
}
fprintf(stderr, "\n\n");
}
/*------------------------------------------------------------------------*\
| |
| initIntValues |
| Initialize the values in the _iIntValues_ array. |
| |
\*------------------------------------------------------------------------*/
void initIntValues () {
unsigned int i;
extern long long _iIntValues_[MAX_INTEGERS];
_iIntValues_[MAX_INTEGERS - 1] = (long long)1;
for(i = MAX_INTEGERS -1; i > 0; --i)
_iIntValues_[i - 1] = _iIntValues_[i] * (long long)10;
}
/*------------------------------------------------------------------------*\
| |
| Static Storage Definitions |
| |
\*------------------------------------------------------------------------*/
int bDecimalComma = 0;
char cCurrencySymbol = '$';
long long _iIntValues_[MAX_INTEGERS] = {
(long long)-1, (long long)-1, (long long)-1,
(long long)-1, (long long)-1, (long long)-1,
(long long)-1, (long long)-1, (long long)-1,
(long long)-1, (long long)-1, (long long)-1,
(long long)-1, (long long)-1, (long long)-1,
(long long)-1, (long long)-1, (long long)-1
};
void (*pMovRtn[])(struct fld_desc *, char *,
struct fld_desc *, char *) = {
tcob_move_9_9, tcob_move_9_b, tcob_move_9_c,
tcob_move_9_e, tcob_move_9_f, tcob_move_9_x,
tcob_move_b_9, tcob_move_b_b, tcob_move_b_c,
tcob_move_b_e, tcob_move_b_f, tcob_move_b_x,
tcob_move_c_9, tcob_move_c_b, tcob_move_c_c,
tcob_move_c_e, tcob_move_c_f, tcob_move_c_x,
tcob_move_f_9, tcob_move_f_b, tcob_move_f_c,
tcob_move_f_e, tcob_move_f_f, tcob_move_f_x,
tcob_move_x_9, tcob_move_x_b, tcob_move_x_c,
tcob_move_x_e, tcob_move_x_f, tcob_move_x_x,
tcob_move_e_9, tcob_move_e_b, tcob_move_e_c,
tcob_move_e_e, tcob_move_e_f, tcob_move_e_x
};
#ifdef DEBUG_MOVE_RTS
int _iMoveLevel_ = 0;
#endif