home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
SOURCE
/
CSSRC
/
FNDOUBLE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-31
|
8KB
|
307 lines
/*
fndouble.c 10/14/86
% double_funcs
Regular Double funcs.
The field variable should be a double *.
C-scape 3.2
Copyright (c) 1986, 1987, 1988 by Oakland Group, Inc.
ALL RIGHTS RESERVED.
Revision History:
-----------------
10/01/87 jmd added casting
4/06/88 jmd added call to sed_DoSpecial
5/12/88 jmd added calls to sed_GetScratchPad()
9/17/88 jmd added std_ funcs
10/09/88 jmd added SED_ABORT support
10/14/88 jdc added var_size element to field_funcs_struct
12/16/88 jmd added validation
6/01/89 gam added ocountry stuff
6/07/89 jmd added test for mouse code (later removed)
10/02/89 gam fixed some of the ocountry stuff
11/04/89 jdc changed toupper & tolower to otoupper & otolower
1/31/90 jmd don't reset baton on MOU_CLICK
2/21/90 pmcm fixed toggle mode/baton problem (but not my initials)
2/22/90 pmcm clear entire field on space keypress
2/22/90 pmcm/mla added BACKSPACE/DEL case for EXPONENT mode
2/22/90 pcmm/mla fixed EXPONENT digit entry to act like calculator
3/14/90 jmd moved formatting before validation
3/28/90 jmd ansi-fied
4/26/90 mla made negative toggle EXPONENT mode sensitive
6/15/90 mla added RIGHT and LEFT cases
6/15/90 mla fixed clear field case
10/31/90 ted added a cast to avoid int/char compiler warning.
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "cscape.h"
#include "fnfunc.h" /* for field functions */
#include "strdecl.h" /* for C-scape string functions */
#include "scancode.h"
OSTATIC int mantissa_pos(char *record);
/* operating modes (stored in sed baton) */
#define MANTISSA 1 /* SED_FIRST is also treated as MANTISSA */
#define EXPONENT 2
OGLOBAL field_funcs_struct double_funcs = {
double_fenter,
double_fexit,
double_fkey,
double_senter,
double_sexit,
sizeof(double)
};
void double_fenter(sed_type sed)
{
/* handle border prompt */
std_fenter(sed);
sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
}
boolean double_fexit(sed_type sed)
{
double val;
if (sed_GetBaton(sed) != SED_ABORT) {
/* format the field's record */
std_format(sed);
sscanf(sed_GetCurrRecord(sed), "%le", &val);
/* call standard numeric validation routine (fnstdval.c) */
if (!std_NumValid(sed, (double) val)) {
return(FALSE);
}
}
return(std_fexit(sed));
}
void double_fkey(sed_type sed)
{
int scancode, key, mode, expos;
char c, *exp_sign_sp, *s;
scancode = kb_Read();
if (sed_DoSpecial(sed, scancode))
return;
if (special_key(sed, scancode))
return;
if (inter_field(sed, scancode))
return;
if (inter_page(sed, scancode))
return;
mode = (sed_GetBaton(sed) == SED_FIRST) ? MANTISSA : sed_GetBaton(sed);
if (mode == EXPONENT) {
sed_GoEnd(sed);
}
else {
sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
}
key = ascii(scancode);
switch(scancode) {
case DEL:
case BACKSPACE:
if (mode == MANTISSA) {
sed_PullLeft(sed);
if (digit_count(sed_GetCurrRecord(sed)) == 0) {
sed_Overwrite(sed, '0');
}
}
else {
expos = mantissa_pos(sed_GetCurrRecord(sed)) + 3;
sed_GotoChar(sed, expos);
c = '0';
while (sed_GetRecordPos(sed) <= sed_GetCurrRecordLen(sed) - 1) {
c = sed_Overwrite(sed, c);
if (!sed_IncChar(sed)) {
break;
}
}
}
break;
case RIGHT:
if (mode == MANTISSA) {
/* change to exponent mode */
mode = EXPONENT;
sed_SetBaton(sed, EXPONENT);
sed_GoEnd(sed);
}
break;
case LEFT:
if (mode == EXPONENT) {
/* change to mantissa mode */
mode = MANTISSA;
sed_SetBaton(sed, MANTISSA);
sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
}
break;
default:
if (isdigit(key) || key == '.' || key == ' ') {
if (sed_GetBaton(sed) == SED_FIRST || key == ' ') {
/* Clear entire field if space key is pressed */
/* Clear entire field if first key pressed is a digit */
sprintf((s = sed_GetScratchPad(sed)), "%.le", 0.0);
/* now clear the field up to the 'e'. */
while (otoupper(*s) != 'E') {
*(s++) = ' ';
}
strright(sed_GetScratchPad(sed), sed_GetCurrRecordLen(sed));
sed_SetCurrRecord(sed, sed_GetScratchPad(sed));
sed_UpdateCurrField(sed);
sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
}
if (key == ' ') {
/* screen space key from further processing */
break;
}
if (mode == EXPONENT) {
/* Edit exponent */
expos = mantissa_pos(sed_GetCurrRecord(sed)) + 3;
c = (char) key;
while (sed_GetRecordPos(sed) >= expos) {
if (sed_GetChar(sed, expos) == '0') {
c = sed_Overwrite(sed, c);
}
sed_DecChar(sed);
}
sed_GoEnd(sed);
}
else {
/* Edit mantissa */
if (sed_GetChar(sed, 1) == ' ' || sed_GetChar(sed, 1) == '-'){
if (sed_GetCurrChar(sed) == '0' &&
digit_count(sed_GetCurrRecord(sed)) == 1) {
sed_Overwrite(sed, key);
}
else {
sed_PushLeft(sed, key);
}
}
}
}
/* toggle minus sign if appropriate */
else if (key == '-') {
strcpy(sed_GetScratchPad(sed), sed_GetCurrRecord(sed));
if (mode == EXPONENT) {
exp_sign_sp = sed_GetScratchPad(sed) + mantissa_pos(sed_GetScratchPad(sed)) + 2;
if (*exp_sign_sp == '-') {
*exp_sign_sp = '+';
}
else {
*exp_sign_sp = '-';
}
sed_SetCurrRecord(sed, sed_GetScratchPad(sed));
}
else { /* mode == MANTISSA */
sed_SetCurrRecord(sed, strminus(sed_GetScratchPad(sed)));
}
sed_UpdateCurrField(sed);
}
/* if no decimal point yet, add one */
else if (key == ocountry.dec_char &&
(sed_GetChar(sed, 1) == ' '|| sed_GetChar(sed, 1) == '-')) {
if (strchr(sed_GetCurrRecord(sed), ocountry.dec_char) == NULL) {
/* no decimal point */
sed_PushLeft(sed, ocountry.dec_char);
}
}
/* toggle EXP mode */
else if (otoupper(key) == 'E') {
if (mode == EXPONENT) {
mode = MANTISSA;
sed_SetBaton(sed, MANTISSA);
sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
}
else {
mode = EXPONENT;
sed_SetBaton(sed, EXPONENT);
sed_GoEnd(sed);
}
}
break;
}
/* reset baton */
if (scancode != MOU_CLICK) {
sed_SetBaton(sed, mode);
}
}
static int mantissa_pos(char *record)
/*
returns the record position of the mantissa
i.e., the position before the 'e'.
*/
{
char *p;
int pos;
for (p = record, pos= 0; p[pos] != '\0' && p[pos] != 'e' && p[pos] != 'E'; pos++) {
;
}
return((pos > 0) ? (pos - 1) : 0);
}
void double_senter(sed_type sed, int fieldno)
/*
Convert native type to string for record.
*/
{
sprintf(sed_GetScratchPad(sed), "%.le", *((double *) sed_GetVar(sed, fieldno)));
/* My change to change the decimal default from printf to
the ocountry decimal character. */
strtrans(sed_GetScratchPad(sed), '.', ocountry.dec_char);
strright(sed_GetScratchPad(sed), sed_GetRecordLen(sed, fieldno));
sed_SetRecord(sed, sed_GetScratchPad(sed), fieldno);
std_senter(sed, fieldno);
}
void double_sexit(sed_type sed, int fieldno)
/*
Converts record back to native type.
*/
{
if (sed_GetBaton(sed) != SED_ABORT) {
strcpy(sed_GetScratchPad(sed), sed_GetRecord(sed, fieldno));
strnocomma(sed_GetScratchPad(sed));
strtrans(sed_GetScratchPad(sed), ocountry.dec_char, '.');
sscanf(sed_GetRecord(sed, fieldno), "%le", (double *) sed_GetVar(sed, fieldno));
}
}