home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
stg_v4.lzh
/
edt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-11
|
14KB
|
732 lines
/*
* 89/??/?? StG original concept and specs for DB9 format
* 90/09/?? StG coding began
* 91/05/27 StG updated to new naming conventions, fixed bugs
* 91/07/28 StG cleanup
*
* _Dsp(psFld,pcDat) - display field
* _Edt(psFld,pcDat) - edit field
*
* psFld - field structure to control edit/display
* pcDat - pointer to data to edit (offset
*
* psFld->acFld_Mask - mask for display/edit of data
* '_' - char from data (# of these is data len)
* - all other chars are displayed as is
* psFld->acFld_Opt - option codes (defined in db9.h)
*
* psFld->oFld_Pos - offset from dat
* psFld->oFld_Len - number of bytes
*
* returns:
* 0 - ESC, changes aborted
* otherwise key pressed is returned
*
*/
#define ERR (-1)
#include "db9.h"
#include "key.h"
extern int errno;
#define EDTMAX 256
int _edtcsr=-1; /* cursor position in data */
int _edtchg=0; /* field changed flag */
int _dspflg=0;
char _edtchr[128]; /* accepted chars */
char _edtbuf[EDTMAX];
char _dspbuf[EDTMAX];
char *_pcBS=0;
char *_pcSPC=0;
char *malloc();
void
_InitBSPC()
{
_pcBS=malloc(EDTMAX+1);
if (!_pcBS)
exit(errno);
_pcSPC=malloc(EDTMAX+1);
if (!_pcSPC)
exit(errno);
MSET(_pcBS,8,EDTMAX);
*(_pcBS+EDTMAX)=0;
MSET(_pcSPC,32,EDTMAX);
*(_pcSPC+EDTMAX)=0;
}
/* display data at ptr, leave cursor at byte csr */
_DispDriver(pcData,iToCursor)
char *pcData;
int iToCursor;
{
static char acDispBuf[EDTMAX];
static int iCursor;
char *pcDispBuf;
int iTemp;
/* preset backspace and space pattern buffers */
if (!_pcBS) _InitBSPC();
/* if called with 0 pcData, reset buffer for new data */
if (!pcData)
{
MSET(acDispBuf,0,EDTMAX);
iCursor=0;
return(0);
}
pcDispBuf=acDispBuf;
dspagn:
/* find first char that doesn't match */
while (*pcDispBuf && *pcDispBuf==*pcData)
{
pcDispBuf++;
pcData++;
}
/* if strings match, must both be null */
if (*pcDispBuf==*pcData) goto dspdun;
/* move cursor to first difference (pcDispBuf) */
iTemp=(pcDispBuf-acDispBuf)-iCursor;
if (iTemp<0) write(1,_pcBS,-iTemp);
if (iTemp>0) write(1,acDispBuf+iCursor,iTemp);
iCursor+=iTemp;
/* count number of bytes being changed */
iTemp=0;
while (*pcData && *pcDispBuf!=*pcData)
{
*pcDispBuf++=*pcData++;
iTemp++;
}
if (!*pcData) *pcDispBuf=0;
/* and write them out */
if (iTemp)
{
write(1,pcDispBuf-iTemp,iTemp);
iCursor+=iTemp;
/* go through loop again to find any more */
goto dspagn;
}
/* end of supplied string, clear rest of display */
if (*pcData) exit(1);
iTemp=0;
while (*pcDispBuf)
{
*pcDispBuf++=0;
iTemp++;
}
write(1,_pcSPC,iTemp);
write(1,_pcBS,iTemp);
dspdun:
/* move cursor to iToCursor */
iTemp=iToCursor-iCursor;
if (iTemp<0) write(1,_pcBS,-iTemp);
if (iTemp>0) write(1,acDispBuf+iCursor,iTemp);
iCursor=iToCursor;
return(0);
}
#define AcceptChars(fm,to,ok) {int x=fm;while (x<=to) _edtchr[x++]=ok;}
_Dsp(psFld,pcDat)
struct sFld_Block *psFld;
char *pcDat;
{
_DispDriver(0,0);
_dspflg=1;
_edtcsr=-1;
return(_Edt(psFld,pcDat));
}
_Edt(psFld,pcDat)
struct sFld_Block *psFld;
char *pcDat;
{
char cKey,*pcTemp1,*pcTemp2,*pcTemp3;
int iTemp1,iTemp2;
O oTemp;
L lTemp;
char cEdtNoNull; /* null field okay */
char cEdtCaps; /* 0=normal, 1=Caps, 2=CAPS */
char cEdtRight; /* right justify */
int _edtoff=0; /* display offset from _dspbuf */
int _edtpos,_dspoff,_edtlen,_dspcsr;
int _dsplen; /* display length */
/* if no ptrs reset */
if (!psFld || !pcDat)
{
_edtcsr=-1; /* StG 92/12/04 */
_edtoff=0;
_DispDriver(0,0);
#ifdef _UNIX
_Eko(0);
#endif
return(0);
}
#ifdef _UNIX
_Eko(1);
#endif
pcDat+=psFld->oFld_Pos;
if (psFld->oFld_Len>EDTMAX)
{
errno=DE_EDTLEN;
return(ERR);
}
cKey=0;
/* count number of _'s */
_dsplen=0;
pcTemp1=psFld->acFld_Mask;
while (*pcTemp1)
if (*pcTemp1++=='_')
_dsplen++;
/* clear table and flags */
AcceptChars(0,127,0);
cEdtNoNull=cEdtCaps=cEdtRight=0;
pcTemp1=psFld->acFld_Opts;
if (!*pcTemp1) switch(psFld->cFld_Type)
{
case FT_SINT : pcTemp1="rn-"; break;
case FT_UINT : pcTemp1="rn"; break;
case FT_HEX : pcTemp1="rxu"; break;
case FT_DATE : pcTemp1="rn"; break;
case FT_INET : pcTemp1="n"; break;
case FT_ASCII:
default: pcTemp1="*"; break;
}
while (*pcTemp1) switch(*pcTemp1++)
{
case FO_ALL : AcceptChars(32,126,1); break;
case FO_ALPHA: AcceptChars('A','Z',1); AcceptChars('a','z',1); break;
case FO_SPACE: _edtchr[' ']=1; break;
case FO_HEX : AcceptChars('A','F',1);
case FO_NUM : AcceptChars('0','9',1); break;
case FO_DOT : _edtchr['.']=1; break;
case FO_DASH : _edtchr['-']=1; break;
case FO_PUNCT: /* *-a-b-n */ break;
case FO_EXCLM: AcceptChars('!','!',1); break;
case FO_ACCPT:
while (*pcTemp1 && *pcTemp1!='!') _edtchr[*pcTemp1++]=1;
case FO_EXCPT:
while (*pcTemp1) _edtchr[*pcTemp1++]=1;
break;
case FO_UPPER: cEdtCaps=2; break;
case FO_CAP1 : cEdtCaps=1; break;
case FO_NULL : cEdtNoNull=1; break;
case FO_RIGHT: cEdtRight=1; break;
default: pcTemp1="";
}
/* if (!_dspflg && _edtcsr<0) _edtcsr=0; */
edtagn:
/* based on storage type, copy dat to edtbuf */
switch (psFld->cFld_Type)
{
case FT_DATE:
iTemp1=psFld->oFld_Len;
pcTemp1=pcDat;
pcTemp2=_edtbuf;
while (iTemp1--)
{
iTemp2=*pcTemp1/10;
if (iTemp2>9)
{
*pcTemp2++='*';
*pcTemp2++='*';
}
else
{
*pcTemp2++='0'+iTemp2;
*pcTemp2++='0'+(*pcTemp1%10);
}
pcTemp1++;
}
*pcTemp2=0;
_edtlen=pcTemp2-_edtbuf;
break;
case FT_INET: /* internet address format */
iTemp1=psFld->oFld_Len;
pcTemp1=pcDat;
pcTemp2=_edtbuf;
while (iTemp1--)
{
iTemp2=(*pcTemp1&255)/100;
*pcTemp2++='0'+iTemp2;
*pcTemp2++='0'+((*pcTemp1&255)-iTemp2*100)/10;
*pcTemp2++='0'+((*pcTemp1&255)%10);
pcTemp1++;
}
*pcTemp2=0;
_edtlen=pcTemp2-_edtbuf;
break;
case FT_HEX:
iTemp1=psFld->oFld_Len;
pcTemp1=pcDat;
pcTemp2=_edtbuf;
while (iTemp1--)
{
iTemp2=((*pcTemp1)>>4)&15;
if (iTemp2>9) iTemp2+=7;
*pcTemp2++='0'+iTemp2;
iTemp2=(*pcTemp1++)&15;
if (iTemp2>9) iTemp2+=7;
*pcTemp2++='0'+iTemp2;
}
*pcTemp2=0;
_edtlen=pcTemp2-_edtbuf;
/* while (*_edtbuf=='0' && *(_edtbuf+1)) MCPY(_edtbuf,_edtbuf+1,psFld->oFld_Len); */
break;
case FT_SINT:
iTemp1=psFld->oFld_Len;
if (iTemp1>4) iTemp1=4;
pcTemp1=pcDat;
#ifdef __MSDOS__
pcTemp1+=iTemp1;
#endif
lTemp=0;
while (iTemp1--)
{
lTemp<<=8;
lTemp&=~255;
#ifndef __MSDOS__
lTemp|=(*pcTemp1++)&255;
#else
lTemp|=(*--pcTemp1)&255;
#endif
}
switch (psFld->oFld_Len)
{
case 1: if (lTemp&0x000080) lTemp=(lTemp&0x00007F)-0x000080; break;
case 2: if (lTemp&0x008000) lTemp=(lTemp&0x007FFF)-0x008000; break;
case 3: if (lTemp&0x800000) lTemp=(lTemp&0x7FFFFF)-0x800000; break;
}
oTemp=abs(lTemp);
if (oTemp<10)
_edtlen=1;
else if (oTemp<100)
_edtlen=2;
else if (oTemp<1000)
_edtlen=3;
else if (oTemp<10000)
_edtlen=4;
else if (oTemp<100000)
_edtlen=5;
else if (oTemp<1000000)
_edtlen=6;
else if (oTemp<10000000)
_edtlen=7;
else if (oTemp<100000000)
_edtlen=8;
else if (oTemp<1000000000)
_edtlen=9;
else
_edtlen=10;
if (lTemp<0)
_edtlen++;
if (_edtlen>_dsplen)
_edtlen=_dsplen;
pcTemp1=_edtbuf;
pcTemp1+=_edtlen;
*pcTemp1=0;
iTemp2=_edtlen;
while (iTemp2--)
{
*--pcTemp1='0'+(oTemp%10);
oTemp/=10;
}
if (lTemp<0)
*pcTemp1='-';
break;
case FT_UINT:
iTemp1=psFld->oFld_Len;
if (iTemp1>4) iTemp1=4;
_edtlen=10;
if (iTemp1==1) _edtlen=3;
if (iTemp1==2) _edtlen=5;
if (iTemp1==3) _edtlen=8;
if (_edtlen>_dsplen)
_edtlen=_dsplen;
pcTemp1=pcDat;
#ifdef __MSDOS__
pcTemp1+=iTemp1;
#endif
oTemp=0;
while (iTemp1--)
{
oTemp<<=8;
oTemp&=~255;
#ifndef __MSDOS__
oTemp|=(*pcTemp1++)&255;
#else
oTemp|=(*--pcTemp1)&255;
#endif
}
pcTemp1=_edtbuf;
pcTemp1+=_edtlen;
*pcTemp1=0;
iTemp2=_edtlen;
while (iTemp2--)
{
*--pcTemp1='0'+(oTemp%10);
oTemp/=10;
}
while (_edtbuf[0]=='0' && _edtbuf[1])
MCPY(_edtbuf,_edtbuf+1,_edtlen--);
break;
default: /* assume FT_ASCII */
/* _edtlen=psFld->oFld_Len; */
MCPY(_edtbuf,pcDat,psFld->oFld_Len);
*(_edtbuf+psFld->oFld_Len)=0;
_edtlen=strlen(_edtbuf);
}
if (_edtlen>_dsplen)
_edtlen=_dsplen;
_edtchg=0;
goto disnxt;
bell:
write(1,"\7",1);
goto edtnxt;
disnxt:
if (cEdtRight)
{
if (!_dspflg && _edtcsr<0)
_edtcsr=_edtlen;
_dspoff=_dsplen-_edtlen;
}
else
{
if (!_dspflg && _edtcsr<0)
{
if (psFld->cFld_Type==FT_ASCII)
_edtcsr=_edtlen;
else
_edtcsr=0;
}
_dspoff=0;
}
/* copy edtbuf to dspbuf via msk */
_edtpos=_dspcsr=0;
pcTemp1=_edtbuf;
pcTemp2=psFld->acFld_Mask;
pcTemp3=_dspbuf;
while (*pcTemp2)
{
/* if mask is not _, copy it to display */
if (*pcTemp2!='_')
{
*pcTemp3++=*pcTemp2++;
continue;
}
/* remember display position of cursor in edit buffer */
if (_edtcsr==_edtpos-_dspoff)
_dspcsr=(pcTemp3-_dspbuf);
/* if (!*pcTemp1)*/
if (_edtpos<_dspoff || _edtpos>=_edtlen+_dspoff)
*pcTemp3++=(_dspflg?' ':'_');
else
{
if (*pcTemp1>126 || !_edtchr[*pcTemp1])
{
*pcTemp3++='~';
pcTemp1++;
}
else
*pcTemp3++=*pcTemp1++;
}
_edtpos++;
pcTemp2++;
if (_edtcsr==_edtpos-_dspoff)
_dspcsr=(pcTemp3-_dspbuf);
}
*pcTemp1=0;
*pcTemp3=0;
/* if (_edtlen!=_edtpos)
exit(1,writeln(2,"_Edt() bug: edtlen!=edtpos\n",80);
*/
if (_dspflg)
_dspcsr=0;
if (_edtcsr>_edtlen)
{
_edtcsr=_edtlen;
goto disnxt;
}
if (psFld->bFld_DispMax)
{
while (_dspcsr>_edtoff+psFld->bFld_DispMax)
_edtoff+=psFld->bFld_DispMax>>1;
while (_dspcsr<_edtoff)
_edtoff-=psFld->bFld_DispMax>>1;
if (_edtoff<0)
_edtoff=0;
*(_dspbuf+_edtoff+psFld->bFld_DispMax)=0;
}
_DispDriver(_dspbuf+_edtoff,_dspcsr-_edtoff);
if (_dspflg)
{
_dspflg=0;
return(cKey);
}
edtnxt:
pcTemp1=_edtbuf+_edtcsr;
cKey=_Key(1);
if (cKey>=32 && cKey<=126)
{
if (_edtcsr==_dsplen)
goto bell;
if (cEdtCaps==2)
cKey=toupper(cKey);
if (!_edtchr[cKey])
goto bell;
MINS(pcTemp1+1,pcTemp1,_dsplen-_edtcsr-1);
if (_edtlen<_dsplen)
_edtlen++;
*pcTemp1=cKey;
_edtcsr++;
_edtchg=1;
goto disnxt;
}
switch (cKey)
{
case KY_HOME:
_edtcsr=0;
goto disnxt;
case KY_LEFT:
if (!_edtcsr) goto bell;
_edtcsr--;
goto disnxt;
case KY_INS:
if (!_edtchr[' ']) goto bell;
MINS(pcTemp1+1,pcTemp1,_dsplen-_edtcsr-1);
if (_edtlen<_dsplen)
_edtlen++;
*pcTemp1=' ';
_edtchg=1;
goto disnxt;
case KY_DEL:
if (!_edtlen) goto bell;
/* if (!*pcTemp1 || _edtlen==_edtcsr) goto bell; */
MCPY(pcTemp1,pcTemp1+1,_dsplen-_edtcsr-1);
_edtbuf[--_edtlen]=0;
/* pcTemp1[_edtlen-_edtcsr-1]=0; */
_edtchg=1;
goto disnxt;
case KY_END:
if (_edtcsr==_edtlen) goto bell;
_edtcsr=_edtlen;
goto disnxt;
case KY_RIGHT:
if (_edtcsr==_edtlen) goto bell;
_edtcsr++;
goto disnxt;
case KY_BKSPC:
if (!_edtcsr) goto bell;
_edtcsr--;
pcTemp1--;
MCPY(pcTemp1,pcTemp1+1,_dsplen-_edtcsr-1);
_edtbuf[--_edtlen]=0;
/* pcTemp1[_edtlen-_edtcsr]=0; */
_edtchg=1;
goto disnxt;
case KY_KILL:
if (_edtlen==_edtcsr) goto bell;
_edtlen=_edtcsr;
_edtbuf[_edtlen]=0;
_edtchg=1;
goto disnxt;
}
/* if esc and data changed, restart */
if (cKey==27 && _edtchg) goto edtagn;
/* copy data back to dat */
switch(psFld->cFld_Type)
{
case FT_DATE:
pcTemp1=_edtbuf;
pcTemp2=pcDat;
iTemp1=_edtlen>>1;
while (iTemp1--)
{
if (*pcTemp1<'0' || *pcTemp1>'9' || *(pcTemp1+1)<'0' || *(pcTemp1+1)>'9')
{
*pcTemp2++=-1;
pcTemp1+=2;
continue;
}
iTemp2=(*pcTemp1++)-'0';
iTemp2*=10;
iTemp2+=(*pcTemp1++)-'0';
*pcTemp2++=iTemp2;
}
break;
case FT_INET:
pcTemp1=_edtbuf;
pcTemp2=pcDat;
iTemp1=_edtlen/3;
while (iTemp1--)
{
iTemp2=(*pcTemp1++)-'0';
iTemp2*=10;
iTemp2+=(*pcTemp1++)-'0';
iTemp2*=10;
iTemp2+=(*pcTemp1++)-'0';
*pcTemp2++=iTemp2;
}
break;
case FT_HEX:
pcTemp1=_edtbuf;
while (*pcTemp1) pcTemp1++;
pcTemp2=pcDat;
iTemp1=_edtlen>>1;
if (iTemp1>psFld->oFld_Len) iTemp1=psFld->oFld_Len;
while (iTemp1--) *pcTemp2++=0;
iTemp1=_edtlen>>1;
if (iTemp1>psFld->oFld_Len) iTemp1=psFld->oFld_Len;
while (iTemp1--)
{
pcTemp2--;
if (!*--pcTemp1) break;
iTemp2=*pcTemp1-'0';
if (iTemp2>9) iTemp2-=7;
*pcTemp2|=iTemp2&15;
if (!*--pcTemp1) break;
iTemp2=*pcTemp1-'0';
if (iTemp2>9) iTemp2-=7;
*pcTemp2|=(iTemp2&15)<<4;
}
break;
case FT_SINT:
pcTemp1=_edtbuf;
lTemp=0;
if (*pcTemp1=='-')
pcTemp1++;
while (*pcTemp1)
{
lTemp*=10;
lTemp+=(*pcTemp1++)-'0';
}
iTemp1=psFld->oFld_Len;
if (iTemp1>4) iTemp1=4;
if (*_edtbuf=='-')
lTemp=~lTemp+1;
pcTemp1=pcDat;
#ifndef __MSDOS__
pcTemp1+=iTemp1;
#endif
while (iTemp1--)
{
#ifdef __MSDOS__
*pcTemp1++=lTemp&255;
#else
*--pcTemp1=lTemp&255;
#endif
lTemp>>=8;
}
break;
case FT_UINT:
pcTemp1=_edtbuf;
oTemp=0;
while (*pcTemp1)
{
oTemp*=10;
oTemp+=(*pcTemp1++)-'0';
}
iTemp1=psFld->oFld_Len;
if (iTemp1>4) iTemp1=4;
pcTemp1=pcDat;
#ifndef __MSDOS__
pcTemp1+=iTemp1;
#endif
while (iTemp1--)
{
#ifdef __MSDOS__
*pcTemp1++=oTemp&255;
#else
*--pcTemp1=oTemp&255;
#endif
oTemp>>=8;
}
break;
default: /* assume FT_ASCII */
MSET(_edtbuf+_edtlen,0,psFld->oFld_Len-_edtlen);
MCPY(pcDat,_edtbuf,psFld->oFld_Len);
}
_dspflg=1; /* cause _Edt() to return(cKey) after redisplay */
goto disnxt;
}