Showing posts with label Turbo C. Show all posts
Showing posts with label Turbo C. Show all posts

string.h Definitions for memory and string functions

/* string.h

Definitions for memory and string functions.

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif

void *_Cdecl memccpy (void *dest, const void *src, int c, size_t n);
void *_Cdecl memchr (const void *s, int c, size_t n);
int _Cdecl memcmp (const void *s1, const void *s2, size_t n);
void *_Cdecl memcpy (void *dest, const void *src, size_t n);
int _Cdecl memicmp (const void *s1, const void *s2, size_t n);
void *_Cdecl memmove (void *dest, const void *src, size_t n);
void *_Cdecl memset (void *s, int c, size_t n);
void _Cdecl movedata(unsigned srcseg, unsigned srcoff, unsigned dstseg,
unsigned dstoff, size_t n);
char *_Cdecl stpcpy (char *dest, const char *src);
char *_Cdecl strcat (char *dest, const char *src);
char *_Cdecl strchr (const char *s, int c);
int _Cdecl strcmp (const char *s1, const char *s2);
char *_Cdecl strcpy (char *dest, const char *src);
size_t _Cdecl strcspn (const char *s1, const char *s2);
char *_Cdecl strdup (const char *s);
char *_Cdecl strerror(int errnum);
int _Cdecl stricmp (const char *s1, const char *s2);
size_t _Cdecl strlen (const char *s);
char *_Cdecl strlwr (char *s);
char *_Cdecl strncat (char *dest, const char *src, size_t maxlen);
int _Cdecl strncmp (const char *s1, const char *s2, size_t maxlen);
char *_Cdecl strncpy (char *dest, const char *src, size_t maxlen);
int _Cdecl strnicmp(const char *s1, const char *s2, size_t maxlen);
char *_Cdecl strnset (char *s, int ch, size_t n);
char *_Cdecl strpbrk (const char *s1, const char *s2);
char *_Cdecl strrchr (const char *s, int c);
char *_Cdecl strrev (char *s);
char *_Cdecl strset (char *s, int ch);
size_t _Cdecl strspn (const char *s1, const char *s2);
char *_Cdecl strstr (const char *s1, const char *s2);
char *_Cdecl strtok (char *s1, const char *s2);
char *_Cdecl strupr (char *s);

/* compatibility with other compilers */

#define strcmpi(s1,s2) stricmp(s1,s2)
#define strncmpi(s1,s2,n) strnicmp(s1,s2,n)

#if !__STDC__
char *_Cdecl _strerror (const char *s);
#endif


stdlib.h Definitions for common types, variables, and functions

/*      stdlib.h

        Definitions for common types, variables, and functions.

        Copyright (c) Borland International 1987,1988
        All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl  cdecl
#endif

#if     !defined(__STDLIB)
#define __STDLIB

#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif

#ifndef _DIV_T
#define _DIV_T
typedef struct {
        int     quot;
        int     rem;
} div_t;
#endif

#ifndef _LDIV_T
#define _LDIV_T
typedef struct {
        long    quot;
        long    rem;
} ldiv_t;
#endif

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

/* Maximum value returned by "rand" function
*/
#define RAND_MAX 0x7FFF

typedef void _Cdecl (* atexit_t)(void);

void    _Cdecl abort  (void);
int     _Cdecl abs    (int x);
int     _Cdecl atexit (atexit_t func);
double  _Cdecl atof   (const char *s);
int     _Cdecl atoi   (const char *s);
long    _Cdecl atol   (const char *s);
void   *_Cdecl bsearch(const void *key, const void *base,
                       size_t nelem, size_t width,
                       int _Cdecl (*fcmp)(/* const void *, const void * */));
void   *_Cdecl calloc (size_t nitems, size_t size);
div_t   _Cdecl div    (int numer, int denom);
void    _Cdecl exit   (int status);
void    _Cdecl free   (void *block);
char   *_Cdecl getenv (const char *name);
long    _Cdecl labs   (long x);
ldiv_t  _Cdecl ldiv   (long numer, long denom);
void   *_Cdecl malloc (size_t size);
void    _Cdecl qsort  (void *base, size_t nelem, size_t width,
                       int _Cdecl (*fcmp)(/* const void *, const void * */));
int     _Cdecl rand   (void);
void   *_Cdecl realloc(void *block, size_t size);
void    _Cdecl srand  (unsigned seed);
double  _Cdecl strtod (const char *s, char **endptr);
long    _Cdecl strtol (const char *s, char **endptr, int radix);
unsigned long _Cdecl strtoul (const char *s, char **endptr, int radix);
int     _Cdecl system (const char *command);

#if !__STDC__

#ifndef NULL
#if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#define NULL    0
#else
#define NULL    0L
#endif
#endif

/* Variables */
extern  int             _Cdecl _doserrno;
extern  char          **_Cdecl environ;
extern  int             _Cdecl errno;
extern  int             _Cdecl _fmode;
extern  unsigned char   _Cdecl _osmajor;
extern  unsigned char   _Cdecl _osminor;
extern  unsigned        _Cdecl _psp;
extern  char           *_Cdecl sys_errlist[];
extern  int             _Cdecl sys_nerr;
extern  unsigned int    _Cdecl _version;

int     _Cdecl __abs__(int x);          /* This is an in-line function */
#define abs(x)          __abs__(x)
#define atoi(s)         ((int) atol (s))

#define max(a,b)        (((a) > (b)) ? (a) : (b))
#define min(a,b)        (((a) < (b)) ? (a) : (b))

#define random(num)     (rand() % (num))
#define randomize()     srand((unsigned)time(NULL))

char   *_Cdecl ecvt     (double value, int ndig, int *dec, int *sign);
void    _Cdecl _exit    (int status);
char   *_Cdecl fcvt     (double value, int ndig, int *dec, int *sign);
char   *_Cdecl gcvt     (double value, int ndec, char *buf);
char   *_Cdecl itoa     (int value, char *string, int radix);
void   *_Cdecl lfind    (const void *key, const void *base,
                         size_t *num, size_t width,
                         int _Cdecl (*fcmp)(/* const void *, const void * */));

unsigned long _Cdecl _lrotl(unsigned long val, int count);
unsigned long _Cdecl _lrotr(unsigned long val, int count);

void   *_Cdecl lsearch  (const void *key, void *base,
                         size_t *num, size_t width,
                         int _Cdecl (*fcmp)(/* const void *, const void * */));
char   *_Cdecl ltoa     (long value, char *string, int radix);
int     _Cdecl putenv   (const char *name);

unsigned _Cdecl _rotl   (unsigned value, int count);
unsigned _Cdecl _rotr   (unsigned value, int count);

void    _Cdecl swab     (char *from, char *to, int nbytes);
char   *_Cdecl ultoa    (unsigned long value, char *string, int radix);
#endif

#endif


stdio.h Definitions for stream input/output

/*      stdio.h

        Definitions for stream input/output.

        Copyright (c) Borland International 1987,1988
        All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl  cdecl
#endif

#if     !defined(__STDIO_DEF_)
#define __STDIO_DEF_

#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif
#ifndef NULL
#   if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#   define      NULL    0
#   else
#   define      NULL    0L
#   endif
#endif

#if     !defined(__STDARG)
#include        <stdarg.h>
#endif

/* Definition of the file position type
*/
typedef long    fpos_t;

/* Definition of the control structure for streams
*/
typedef struct  {
        short           level;          /* fill/empty level of buffer */
        unsigned        flags;          /* File status flags    */
        char            fd;             /* File descriptor      */
        unsigned char   hold;           /* Ungetc char if no buffer */
        short           bsize;          /* Buffer size          */
        unsigned char   *buffer;        /* Data transfer buffer */
        unsigned char   *curp;          /* Current active pointer */
        unsigned        istemp;         /* Temporary file indicator */
        short           token;          /* Used for validity checking */
}       FILE;                           /* This is the FILE object */

/* Bufferisation type to be used as 3rd argument for "setvbuf" function
*/
#define _IOFBF  0
#define _IOLBF  1
#define _IONBF  2

/*      "flags" bits definitions
*/
#define _F_RDWR 0x0003                  /* Read/write flag      */
#define _F_READ 0x0001                  /* Read only file       */
#define _F_WRIT 0x0002                  /* Write only file      */
#define _F_BUF  0x0004                  /* Malloc'ed Buffer data */
#define _F_LBUF 0x0008                  /* line-buffered file   */
#define _F_ERR  0x0010                  /* Error indicator      */
#define _F_EOF  0x0020                  /* EOF indicator        */
#define _F_BIN  0x0040                  /* Binary file indicator */
#define _F_IN   0x0080                  /* Data is incoming     */
#define _F_OUT  0x0100                  /* Data is outgoing     */
#define _F_TERM 0x0200                  /* File is a terminal   */

/* End-of-file constant definition
*/
#define EOF     (-1)                    /* End of file indicator */

/* Number of files that can be open simultaneously
*/
#define OPEN_MAX 20                     /* Total of 20 open files */
#define SYS_OPEN 20

/* Default buffer size use by "setbuf" function
*/
#define BUFSIZ  512                     /* Buffer size for stdio */

/* Size of an arry large enough to hold a temporary file name string
*/
#define L_ctermid       5               /* CON: plus null byte */
#define L_tmpnam        13              /* tmpnam buffer size */

/* Constants to be used as 3rd argument for "fseek" function
*/
#define SEEK_CUR        1
#define SEEK_END        2
#define SEEK_SET        0

/* Number of unique file names that shall be generated by "tmpnam" function
*/
#define TMP_MAX         0xFFFF

/* Standard I/O predefined streams
*/
extern  FILE    _Cdecl _streams[];

#define stdin   (&_streams[0])
#define stdout  (&_streams[1])
#define stderr  (&_streams[2])
#define stdaux  (&_streams[3])
#define stdprn  (&_streams[4])

void     _Cdecl clearerr (FILE *stream);
int      _Cdecl fclose   (FILE *stream);
int      _Cdecl fflush   (FILE *stream);
int      _Cdecl fgetc    (FILE *stream);
int      _Cdecl fgetpos  (FILE *stream, fpos_t *pos);
char    *_Cdecl fgets    (char *s, int n, FILE *stream);
FILE    *_Cdecl fopen    (const char *path, const char *mode);
int      _Cdecl fprintf  (FILE *stream, const char *format, ...);
int      _Cdecl fputc    (int c, FILE *stream);
int      _Cdecl fputs    (const char *s, FILE *stream);
size_t   _Cdecl fread    (void *ptr, size_t size, size_t n, FILE *stream);
FILE    *_Cdecl freopen  (const char *path, const char *mode,
                          FILE *stream);
int      _Cdecl fscanf   (FILE *stream, const char *format, ...);
int      _Cdecl fseek    (FILE *stream, long offset, int whence);
int      _Cdecl fsetpos  (FILE *stream, const fpos_t *pos);
long     _Cdecl ftell    (FILE *stream);
size_t   _Cdecl fwrite   (const void *ptr, size_t size, size_t n,
                          FILE *stream);
char    *_Cdecl gets     (char *s);
void     _Cdecl perror   (const char *s);
int      _Cdecl printf   (const char *format, ...);
int      _Cdecl puts     (const char *s);
int      _Cdecl rename   (const char *oldname, const char *newname);
void     _Cdecl rewind   (FILE *stream);
int      _Cdecl scanf    (const char *format, ...);
void     _Cdecl setbuf   (FILE *stream, char *buf);
int      _Cdecl setvbuf  (FILE *stream, char *buf, int type, size_t size);
int      _Cdecl sprintf  (char *buffer, const char *format, ...);
int      _Cdecl sscanf   (const char *buffer, const char *format, ...);
char    *_Cdecl strerror (int errnum);
FILE    *_Cdecl tmpfile  (void);
char    *_Cdecl tmpnam   (char *s);
int      _Cdecl ungetc   (int c, FILE *stream);
int      _Cdecl vfprintf (FILE *stream, const char *format, va_list arglist);
int      _Cdecl vfscanf  (FILE *stream, const char *format, va_list arglist);
int      _Cdecl vprintf  (const char *format, va_list arglist);
int      _Cdecl vscanf   (const char *format, va_list arglist);
int      _Cdecl vsprintf (char *buffer, const char *format, va_list arglist);
int      _Cdecl vsscanf  (const char *buffer, const char *format, va_list arglist);

#if !__STDC__
int      _Cdecl fcloseall(void);
FILE    *_Cdecl fdopen   (int handle, char *type);
int      _Cdecl fgetchar (void);
int      _Cdecl flushall (void);
int      _Cdecl fputchar (int c);
int      _Cdecl getw     (FILE *stream);
int      _Cdecl putw     (int w, FILE *stream);
char    *_Cdecl _strerror(const char *s);
int      _Cdecl unlink   (const char *path);

#endif

int      _Cdecl _fgetc   (FILE *stream);             /* used by getc() macro */
int      _Cdecl _fputc   (char c, FILE *stream);     /* used by putc() macro */

/*      The following macros provide for common functions */

#define ferror(f)       ((f)->flags & _F_ERR)
#define feof(f)         ((f)->flags & _F_EOF)
#define fileno(f)       ((f)->fd)
#define remove(path)    unlink(path)

#define getc(f) \
  ((--((f)->level) >= 0) ? (unsigned char)(++(f)->curp)[-1] : \
_fgetc (f))
#define putc(c,f) \
  ((++((f)->level) < 0) ? (unsigned char)((++(f)->curp)[-1]=(c)) : \
_fputc ((c),f))

#define getchar()  getc(stdin)
#define putchar(c) putc((c), stdout)

#define ungetc(c,f)     ungetc((c),f)   /* traditionally a macro */

#endif



stddef.h Definitions for common types, NULL, and errno

/* stddef.h

Definitions for common types, NULL, and errno.

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

#ifndef _STDDEF
#define _STDDEF
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
typedef long ptrdiff_t;
#else
typedef int ptrdiff_t;
#endif
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif

#ifndef NULL
#if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#define NULL 0
#else
#define NULL 0L
#endif
#endif

extern int _Cdecl errno;

#endif


stdarg.h Definitions for accessing parameters in functions that accept a variable number of arguments

/* stdarg.h

Definitions for accessing parameters in functions that accept
a variable number of arguments.

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

#if !defined(__STDARG)
#define __STDARG

typedef void *va_list;

#define va_start(ap, parmN) (ap = ...)
#define va_arg(ap, type) (*((type *)(ap))++)
#define va_end(ap)
#define _va_ptr (...)
#endif


stat.h Definitions used for file status functions

/* stat.h

Definitions used for file status functions

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

#ifndef _STAT_H
#define _STAT_H 1

#define S_IFMT 0xF000 /* file type mask */
#define S_IFDIR 0x4000 /* directory */
#define S_IFIFO 0x1000 /* FIFO special */
#define S_IFCHR 0x2000 /* character special */
#define S_IFBLK 0x3000 /* block special */
#define S_IFREG 0x8000 /* or just 0x0000, regular */
#define S_IREAD 0x0100 /* owner may read */
#define S_IWRITE 0x0080 /* owner may write */
#define S_IEXEC 0x0040 /* owner may execute <directory search> */

struct stat
{
short st_dev;
short st_ino;
short st_mode;
short st_nlink;
int   st_uid;
int   st_gid;
short st_rdev;
long  st_size;
long  st_atime;
long  st_mtime;
long  st_ctime;
};

int  _Cdecl fstat (int handle, struct stat *statbuf);
int  _Cdecl stat  (char *path, struct stat *statbuf);

#endif /* _STAT_H */


signal.h Definitions for ANSI defined signaling capability

/*      signal.h
 
        Definitions for ANSI defined signaling capability

        Copyright (c) Borland International 1988
        All Rights Reserved.
*/

#ifndef __SIGNAL_H
#define __SIGNAL_H


#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

typedef int sig_atomic_t; /* Atomic entity type (ANSI) */

#define SIG_DFL ((void (* _Cdecl)(int))0) /* Default action */
#define SIG_IGN ((void (* _Cdecl)(int))1) /* Ignore action */

#ifdef __OS2__
#define SIG_SGE ((void (* _Cdecl)(int))3) /* Signal gets error */
#define SIG_ACK ((void (* _Cdecl)(int))4) /* Signal acknowlege */
#endif

#define SIG_ERR ((void (* _Cdecl)(int))-1) /* Error return */

#define SIGABRT 22
#define SIGFPE 8 /* Floating point trap */
#define SIGILL 4 /* Illegal instruction */
#define SIGINT 2
#define SIGSEGV 11 /* Memory access violation */
#define SIGTERM 15

#ifdef __OS2__
#define SIGBREAK 21 /* OS/2 Ctrl-Brk signal */
#define SIGUSR1 16 /* OS/2 process flag A */
#define SIGUSR2 17 /* OS/2 process flag B */
#define SIGUSR3 20 /* OS/2 process flag C */
#endif

int _Cdecl raise(int sig);
void (* _Cdecl signal(int sig, void (*func)(/* int */))) (int);

#endif


share.h File sharing mode for use with sopen

/* share.h

File sharing mode for use with sopen.
See DOS function 3Dh for definition.

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

#define SH_COMPAT 0x0000
#define SH_DENYRW 0x0010
#define SH_DENYWR 0x0020
#define SH_DENYRD 0x0030
#define SH_DENYNONE 0x0040

#define SH_DENYNO SH_DENYNONE /* MS documentation uses both */


setjmp.h Defines typedef and functions for setjmp/longjmp.

/* setjmp.h

Defines typedef and functions for setjmp/longjmp.

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

#ifndef _SETJMP
#define _SETJMP
typedef struct {
unsigned j_sp;
unsigned j_ss;
unsigned j_flag;
unsigned j_cs;
unsigned j_ip;
unsigned j_bp;
unsigned j_di;
unsigned j_es;
unsigned j_si;
unsigned j_ds;
} jmp_buf[1];

void _Cdecl longjmp(jmp_buf jmpb, int retval);
int _Cdecl setjmp(jmp_buf jmpb);
#endif



process.h Symbols and structures for process management

/* process.h

Symbols and structures for process management.

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

/*  Modes available as first argument to the spawnxx functions. */

#define P_WAIT  0 /* child runs separately, parent waits until exit */
#define P_NOWAIT  1 /* both concurrent -- not implemented */
#define P_OVERLAY 2 /* child replaces parent, parent no longer exists */


/*  MSDOS does not have any abstract identifier for a process, but the
    process Program Segment Prefix location provides a similar token.
*/

#ifndef _psp
extern unsigned _Cdecl _psp; /* provided unconditionally in dos.h */
#endif

#define  getpid()   (_psp)

void _Cdecl abort(void);
int _Cdecl execl(char *path, char *arg0, ...);
int _Cdecl execle(char *path, char *arg0, ...);
int _Cdecl execlp(char *path, char *arg0, ...);
int _Cdecl execlpe(char *path, char *arg0, ...);
int _Cdecl execv(char *path, char *argv[]);
int _Cdecl execve(char *path, char *argv[], char **env);
int _Cdecl execvp(char *path, char *argv[]);
int _Cdecl execvpe(char *path, char *argv[], char **env);
void _Cdecl exit(int status);
void _Cdecl _exit(int status);
int _Cdecl spawnl(int mode, char *path, char *arg0, ...);
int _Cdecl spawnle(int mode, char *path, char *arg0, ...);
int _Cdecl spawnlp(int mode, char *path, char *arg0, ...);
int _Cdecl spawnlpe(int mode, char *path, char *arg0, ...);
int _Cdecl spawnv(int mode, char *path, char *argv[]);
int _Cdecl spawnve(int mode, char *path, char *argv[], char **env);
int _Cdecl spawnvp(int mode, char *path, char *argv[]);
int _Cdecl spawnvpe(int mode, char *path, char *argv[], char **env);
int _Cdecl system(const char *command);

mem.h Memory manipulation functions

/* mem.h

Memory manipulation functions

Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif

#ifndef _STDDEF
#define _STDDEF
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
typedef long ptrdiff_t;
#else
typedef int ptrdiff_t;
#endif
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif
#endif

#ifndef NULL
#if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#define NULL 0
#else
#define NULL 0L
#endif
#endif

void *_Cdecl  memccpy(void *dest, const void *src, int c, size_t n);
void *_Cdecl  memchr (const void *s, int c, size_t n);
int _Cdecl  memcmp (const void *s1, const void *s2, size_t n);
void *_Cdecl  memcpy (void *dest, const void *src, size_t n);
int _Cdecl  memicmp (const void *s1, const void *s2, size_t n);
void *_Cdecl  memmove (void *dest, const void *src, size_t n);
void *_Cdecl  memset (void *s, int c, size_t n);
void _Cdecl  movedata (unsigned srcseg, unsigned srcoff, unsigned dstseg,
unsigned dstoff, size_t n);
void _Cdecl  movmem (void *src, void *dest, unsigned length);
void _Cdecl  setmem (void *dest, unsigned length, char value);

MCOMMAND Programming in C

/* Turbo C - (C) Copyright 1987, 1988 by Borland International */

#include <string.h>
#include <mem.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <conio.h>
#include "mcalc.h"

char *name = MSGNAME;

void moverowup(void)
/* Moves up 1 row */
{
 displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
 if (currow > toprow)
  currow--;
 else if (toprow != 0)
 {
  scroll(DOWN, 1, LEFTMARGIN + 1, 3, 80, SCREENROWS + 2, WHITE);
  displayrow(--toprow, NOUPDATE);
  currow--;
  setbottomrow();
 }
} /* moverowup */

void moverowdown(void)
/* Moves down one row */
{
 displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
 if (currow < bottomrow)
  currow++;
 else if (bottomrow < (MAXROWS - 1))
 {
  scroll(UP, 1, LEFTMARGIN + 1, 3, 80, SCREENROWS + 2, WHITE);
  toprow++;
  currow++;
  setbottomrow();
  displayrow(bottomrow, NOUPDATE);
 }
} /* moverowdown */

void movecolleft(void)
/* Moves left one column */
{
 int col, oldleftcol;
 unsigned char oldcolstart[SCREENCOLS];

 oldleftcol = leftcol;
 movmem(colstart, oldcolstart, sizeof(colstart));
 displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
 if (curcol > leftcol)
  curcol--;
 else if (leftcol != 0)
 {
  curcol--;
  leftcol--;
  setrightcol();
  setleftcol();
  if (oldleftcol <= rightcol)
   scroll(RIGHT, colstart[oldleftcol - leftcol] - LEFTMARGIN, LEFTMARGIN + 1,
          3, 80, SCREENROWS + 2, WHITE);
  clearlastcol();
  for (col = leftcol; col <= oldleftcol - 1; col++)
   displaycol(col, NOUPDATE);
 }
} /* movecolleft */

void movecolright(void)
/* Moves right one column */
{
 int col, oldleftcol, oldrightcol;
 unsigned char oldcolstart[SCREENCOLS];

 movmem(colstart, oldcolstart, sizeof(colstart));
 oldleftcol = leftcol;
 oldrightcol = rightcol;
 displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
 if (curcol < rightcol)
  curcol++;
 else if (rightcol < (MAXCOLS - 1))
 {
  curcol++;
  rightcol++;
  setleftcol();
  setrightcol();
  if (oldrightcol >= leftcol)
   scroll(LEFT, oldcolstart[leftcol - oldleftcol] - LEFTMARGIN,
          LEFTMARGIN + 1, 3, 80, SCREENROWS + 2, WHITE);
  clearlastcol();
  for (col = oldrightcol + 1; col <= rightcol; col++)
   displaycol(col, NOUPDATE);
 }
} /* movecolright */

void recalc(void)
/* Recalculates all of the numbers in the speadsheet */
{
 int col, row, dummy;

 for (col = 0; col <= lastcol; col++)
 {
  for (row = 0; row <= lastrow; row++)
  {
   if ((cell[col][row] != NULL) && (cell[col][row]->attrib == FORMULA))
    cell[col][row]->v.f.fvalue = parse(cell[col][row]->v.f.formula, &dummy);
  }
 }
 displayscreen(UPDATE);
} /* recalc */

void changeautocalc(int newmode)
/* Changes and prints the current AutoCalc value on the screen */
{
 char s[15];

 if (!autocalc && newmode)
  recalc();
 autocalc = newmode;
 if (autocalc)
  strcpy(s, MSGAUTOCALC);
 else
  s[0] = 0;
 writef(73, 1, MSGAUTOCALCCOLOR, strlen(MSGAUTOCALC), s);
} /* autocalc */

void changeformdisplay(int newmode)
/* Changes and prints the current formula display value on the screen */
{
 char s[15];

 formdisplay = newmode;
 if (formdisplay)
  strcpy(s, MSGFORMDISPLAY);
 else
  s[0] = 0;
 writef(65, 1, MSGFORMDISPLAYCOLOR, strlen(MSGFORMDISPLAY), s);
} /* autocalc */

void editcell(CELLPTR ecell)
/* Edits a selected cell */
{
 char s[MAXINPUT + 1];

 if (ecell == NULL)
  return;
 switch(ecell->attrib)
 {
  case TEXT :
   strcpy(s, ecell->v.text);
   break;
  case VALUE :
   if (ecell->v.value == HUGE_VAL)
    strcpy(s, "0");
   else
    sprintf(s, "%.*f", MAXPLACES, ecell->v.value);
   break;
  case FORMULA :
   strcpy(s, ecell->v.f.formula);
   break;
 } /* switch */
 if (!editstring(s, "", MAXINPUT) || (s[0] == 0))
  return;
 act(s);
 changed = TRUE;
} /* editcell */

void clearsheet(void)
/* Clears the current spreadsheet */
{
 int col, row;

 for (row = 0; row <= lastrow; row++)
 {
  for (col = 0; col <= lastcol; col++)
   deletecell(col, row, NOUPDATE);
 }
 initvars();
 setrightcol();
 setbottomrow();
 displayscreen(NOUPDATE);
 printfreemem();
 changed = FALSE;
} /* clearsheet */

struct CELLREC rec;

void loadsheet(char *filename)
/* Loads a new spreadsheet */
{
 int size, allocated, reallastcol = 0, reallastrow = 0, file;
 char check[81];

 if (filename[0] == 0)
 {
  writeprompt(MSGFILENAME);
  if (!editstring(filename, "", MAXINPUT))
   return;
 }
 if (access(filename, 0))
 {
  errormsg(MSGNOEXIST);
  return;
 }
 if ((file = open(filename, O_RDWR | O_BINARY)) == -1)
 {
  errormsg(MSGNOOPEN);
  return;
 }
 read(file, check, strlen(name) + 1);
 if (strcmp(check, name) != 0)
 {
  errormsg(MSGNOMICROCALC);
  close(file);
  return;
 }
 writef(1, 25, PROMPTCOLOR, 79, MSGLOADING);
 gotoxy(strlen(MSGLOADING) + 1, 25);
 clearsheet();
 read(file, (char *)&size, 1);
 read(file, (char *)&lastcol, 2);
 read(file, (char *)&lastrow, 2);
 read(file, (char *)&size, 2);
 read(file, colwidth, sizeof(colwidth));
 do
 {
  if (read(file, (char *)&curcol, 2) <= 0)
   break;
  read(file, (char *)&currow, 2);
  read(file, &format[curcol][currow], 1);
  read(file, (char *)&size, 2);
  read(file, (char *)&rec, size);
  switch (rec.attrib)
  {
   case TEXT :
    if ((allocated = alloctext(curcol, currow, rec.v.text)) == TRUE)
     setoflags(curcol, currow, NOUPDATE);
    break;
   case VALUE :
    allocated = allocvalue(curcol, currow, rec.v.value);
    break;
   case FORMULA :
    allocated = allocformula(curcol, currow, rec.v.f.formula, rec.v.f.fvalue);
    break;
  } /* switch */
  if (!allocated)
  {
   errormsg(MSGFILELOMEM);
   lastrow = reallastrow;
   lastcol = reallastcol;
   format[curcol][currow] = DEFAULTFORMAT;
   break;
  }
  else
  {
   if (curcol > reallastcol)
    reallastcol = curcol;
   if (currow > reallastrow)
    reallastrow = currow;
  }
 }
 while (TRUE);
 writef(1, 25, WHITE, strlen(MSGLOADING), "");
 gotoxy(1, 25);
 printfreemem();
 close(file);
 curcol = currow = 0;
 setrightcol();
 displayscreen(NOUPDATE);
 changed = FALSE;
} /* loadsheet */

void savesheet(void)
/* Saves the current spreadsheet */
{
 char filename[MAXINPUT+1], eof = 26;
 int size, col, row, overwrite, file;
 CELLPTR cellptr;

 filename[0] = 0;
 writeprompt(MSGFILENAME);
 if (!editstring(filename, "", MAXINPUT))
  return;
 if (!access(filename, 0))
 {
  if (!getyesno(&overwrite, MSGOVERWRITE) || (overwrite == 'N'))
   return;
 }
 if ((file = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
  S_IREAD | S_IWRITE)) == -1)
 {
  errormsg(MSGNOOPEN);
  return;
 }
 writef(1, 25, PROMPTCOLOR, 79, MSGSAVING);
 gotoxy(strlen(MSGSAVING) + 1, 25);
 write(file, name, strlen(name) + 1);
 write(file, &eof, 1);
 write(file, (char *)&lastcol, 2);
 write(file, (char *)&lastrow, 2);
 size = MAXCOLS;
 write(file, (char *)&size, 2);
 write(file, colwidth, sizeof(colwidth));
 for (row = 0; row <= lastrow; row++)
 {
  for (col = lastcol; col >= 0; col--)
  {
   if (cell[col][row] != NULL)
   {
    cellptr = cell[col][row];
    switch(cellptr->attrib)
    {
     case TEXT :
      size = strlen(cellptr->v.text) + 2;
      break;
     case VALUE :
      size = sizeof(double) + 1;
      break;
     case FORMULA :
      size = strlen(cellptr->v.f.formula) + 2 + sizeof(double);
      break;
    } /* switch */
    write(file, (char *)&col, 2);
    write(file, (char *)&row, 2);
    write(file, (char *)&format[col][row], 1);
    write(file, (char *)&size, 2);
    write(file, (char *)cellptr, size);
   }
  }
 }
 close(file);
 writef(1, 25, WHITE, strlen(MSGSAVING), "");
 gotoxy(1, 25);
 changed = FALSE;
} /* savesheet */

int pagerows(int row, int toppage, int border)
/* Returns the number of rows to print */
{
 int rows;

 rows = toppage ? 66 - TOPMARGIN : 66;
 if (border)
  rows--;
 if (row + rows - 1 > lastrow)
  return(lastrow - row + 1);
 else
  return(rows);
} /* pagerows */

int pagecols(int col, int border, int columns)
/* Returns the number of columns to print starting at col */
{
 int len = ((col == 0) && (border)) ? columns - LEFTMARGIN : columns;
 int firstcol = col;

 while ((len > 0) && (col <= lastcol))
  len -= colwidth[col++];
 if (len < 0)
  col--;
 return(col - firstcol);
} /* pagecols */

void printsheet(void)
/* Prints a copy of the spreadsheet to a file or to the printer */
{
 char filename[MAXINPUT + 1], s[133], colstr[MAXCOLWIDTH + 1];
 FILE *file;
 int columns, counter1, counter2, counter3, col = 0, row, border, toppage,
  lcol, lrow, dummy, printed, oldlastcol;

 filename[0] = 0;
 writeprompt(MSGPRINT);
 if (!editstring(filename, "", MAXINPUT))
  return;
 if (filename[0] == 0)
  strcpy(filename, "PRN");
 if ((file = fopen(filename, "wt")) == NULL)
 {
  errormsg(MSGNOOPEN);
  return;
 }
 oldlastcol = lastcol;
 for (counter1 = 0; counter1 <= lastrow; counter1++)
 {
  for (counter2 = lastcol; counter2 < MAXCOLS; counter2++)
  {
   if (format[counter2][counter1] >= OVERWRITE)
    lastcol = counter2;
  }
 }
 if (!getyesno(&columns, MSGCOLUMNS))
  return;
 columns = (columns == 'Y') ? 131 : 79;
 if (!getyesno(&border, MSGBORDER))
  return;
 border = (border == 'Y');
 while (col <= lastcol)
 {
  row = 0;
  toppage = TRUE;
  lcol = pagecols(col, border, columns) + col;
  while (row <= lastrow)
  {
   lrow = pagerows(row, toppage, border) + row;
   printed = 0;
   if (toppage)
   {
    for (counter1 = 0; counter1 < TOPMARGIN; counter1++)
    {
     fprintf(file, "\n");
     printed++;
    }
   }
   for (counter1 = row; counter1 < lrow; counter1++)
   {
    if ((border) && (counter1 == row) && (toppage))
    {
     if ((col == 0) && (border))
      sprintf(s, "%*s", LEFTMARGIN, "");
     else
      s[0] = 0;
     for (counter3 = col; counter3 < lcol; counter3++)
     {
      centercolstring(counter3, colstr);
      strcat(s, colstr);
     }
     fprintf(file, "%s\n", s);
     printed++;
    }
    if ((col == 0) && (border))
     sprintf(s, "%-*d", LEFTMARGIN, counter1 + 1);
    else
     s[0] = 0;
    for (counter2 = col; counter2 < lcol; counter2++)
     strcat(s, cellstring(counter2, counter1, &dummy, FORMAT));
    fprintf(file, "%s\n", s);
    printed++;
   }
   row = lrow;
   toppage = FALSE;
   if (printed < 66)
    fprintf(file, "%c", FORMFEED);
  }
  col = lcol;
 }
 fclose(file);
 lastcol = oldlastcol;
} /* printsheet */

void setcolwidth(int col)
/* Sets the new column width for a selected column */
{
 int width, row;

 writeprompt(MSGCOLWIDTH);
 if (!getint(&width, MINCOLWIDTH, MAXCOLWIDTH))
  return;
 colwidth[col] = width;
 setrightcol();
 if (rightcol < col)
 {
  rightcol = col;
  setleftcol();
  setrightcol();
 }
 for (row = 0; row <= lastrow; row++)
 {
  if ((cell[col][row] != NULL) && (cell[col][row]->attrib == TEXT))
   clearoflags(col + 1, row, NOUPDATE);
  else
   clearoflags(col, row, NOUPDATE);
  updateoflags(col, row, NOUPDATE);
 }
 displayscreen(NOUPDATE);
 changed = TRUE;
} /* setcolwidth */

void gotocell()
/* Moves to a selected cell */
{
 writeprompt(MSGGOTO);
 if (!getcell(&curcol, &currow))
  return;
 leftcol = curcol;
 toprow = currow;
 setbottomrow();
 setrightcol();
 setleftcol();
 displayscreen(NOUPDATE);
} /* gotocell */

void formatcells(void)
/* Prompts the user for a selected format and range of cells */
{
 int col, row, col1, col2, row1, row2, temp, newformat = 0;

 writeprompt(MSGCELL1);
 if (!getcell(&col1, &row1))
  return;
 writeprompt(MSGCELL2);
 if (!getcell(&col2, &row2))
  return;
 if ((col1 != col2) && (row1 != row2))
  errormsg(MSGDIFFCOLROW);
 else
 {
  if (col1 > col2)
   swap(&col1, &col2);
  if (row1 > row2)
   swap(&row1, &row2);
  if (!getyesno(&temp, MSGRIGHTJUST))
   return;
  newformat += (temp == 'Y') * RJUSTIFY;
  if (!getyesno(&temp, MSGDOLLAR))
   return;
  newformat += (temp == 'Y') * DOLLAR;
  if (!getyesno(&temp, MSGCOMMAS))
   return;
  newformat += (temp == 'Y') * COMMAS;
  if (newformat & DOLLAR)
   newformat += 2;
  else
  {
   writeprompt(MSGPLACES);
   if (!getint(&temp, 0, MAXPLACES))
    return;
   newformat += temp;
  }
  for (col = col1; col <= col2; col++)
  {
   for (row = row1; row <= row2; row++)
   {
    format[col][row] = (format[col][row] & OVERWRITE) | newformat;
    if ((col >= leftcol) && (col <= rightcol) &&
     (row >= toprow) && (row <= bottomrow))
     displaycell(col, row, NOHIGHLIGHT, NOUPDATE);
   }
  }
 }
 changed = TRUE;
} /* formatcells */

void deletecol(int col)
/* Deletes a column */
{
 int counter, row;

 for (counter = 0; counter <= lastrow; counter++)
  deletecell(col, counter, NOUPDATE);
 printfreemem();
 if (col != MAXCOLS - 1)
 {
  movmem(&cell[col + 1][0], &cell[col][0], MAXROWS * sizeof(CELLPTR) *
   (MAXCOLS - col - 1));
  movmem(&format[col + 1][0], &format[col][0], MAXROWS * (MAXCOLS - col - 1));
  movmem(&colwidth[col + 1], &colwidth[col], MAXCOLS - col - 1);
 }
 setmem(&cell[MAXCOLS - 1][0], MAXROWS * sizeof(CELLPTR), 0);
 setmem(&format[MAXCOLS - 1][0], MAXROWS, DEFAULTFORMAT);
 colwidth[MAXCOLS - 1] = DEFAULTWIDTH;
 if ((lastcol >= col) && (lastcol > 0))
  lastcol--;
 setrightcol();
 if (curcol > rightcol)
 {
  rightcol++;
  setleftcol();
 }
 clearlastcol();
 for (counter = 0; counter <= lastcol; counter++)
 {
  for (row = 0; row <= lastrow; row++)
  {
   if ((cell[counter][row] != NULL) &&
    (cell[counter][row]->attrib == FORMULA))
    fixformula(counter, row, COLDEL, col);
   updateoflags(col, row, NOUPDATE);
  }
 }
 while (col <= rightcol)
  displaycol(col++, NOUPDATE);
 changed = TRUE;
 recalc();
} /* deletecol */

void insertcol(int col)
/* Inserts a column */
{
 int counter, row;

 if (lastcol == MAXCOLS - 1)
 {
  for (counter = 0; counter <= lastrow; counter++)
   deletecell(lastcol, counter, NOUPDATE);
  printfreemem();
 }
 if (col != MAXCOLS - 1)
 {
  movmem(&cell[col][0], &cell[col + 1][0], MAXROWS * sizeof(CELLPTR) *
   (MAXCOLS - col - 1));
  movmem(&format[col][0], &format[col + 1][0], MAXROWS * (MAXCOLS - col - 1));
  movmem(&colwidth[col], &colwidth[col + 1], MAXCOLS - col - 1);
 }
 setmem(&cell[col][0], MAXROWS * sizeof(CELLPTR), 0);
 setmem(&format[col][0], MAXROWS, DEFAULTFORMAT);
 colwidth[col] = DEFAULTWIDTH;
 lastcol = MAXCOLS - 1;
 setlastcol();
 setrightcol();
 if (curcol > rightcol)
 {
  rightcol++;
  setleftcol();
 }
 for (counter = 0; counter <= lastcol; counter++)
 {
  for (row = 0; row <= lastrow; row++)
  {
   if ((cell[counter][row] != NULL) &&
    (cell[counter][row]->attrib == FORMULA))
    fixformula(counter, row, COLADD, col);
   updateoflags(col, row, NOUPDATE);
  }
 }
 while (col <= rightcol)
  displaycol(col++, NOUPDATE);
 changed = TRUE;
 recalc();
} /* insertcol */

void deleterow(int row)
/* Deletes a row */
{
 int counter, rowc;

 for (counter = 0; counter <= lastcol; counter++)
  deletecell(counter, row, NOUPDATE);
 printfreemem();
 if (row != MAXROWS - 1)
 {
  for (counter = 0; counter < MAXCOLS; counter++)
  {
   movmem(&cell[counter][row + 1], &cell[counter][row],
    sizeof(CELLPTR) * (MAXROWS - row - 1));
   movmem(&format[counter][row + 1], &format[counter][row], MAXROWS - row - 1);
  }
 }
 else
 {
  for (counter = 0; counter <= lastcol; counter++)
  {
   cell[counter][MAXROWS - 1] = NULL;
   format[counter][MAXROWS - 1] = DEFAULTFORMAT;
  }
 }
 if ((lastrow >= row) && (lastrow > 0))
  lastrow--;
 for (counter = 0; counter <= lastcol; counter++)
 {
  for (rowc = 0; rowc <= lastrow; rowc++)
  {
   if ((cell[counter][rowc] != NULL) &&
    (cell[counter][rowc]->attrib == FORMULA))
    fixformula(counter, rowc, ROWDEL, row);
  }
 }
 while (row <= bottomrow)
  displayrow(row++, NOUPDATE);
 changed = TRUE;
 recalc();
} /* deleterow */

void insertrow(int row)
/* Inserts a row */
{
 int counter, rowc;

 if (lastrow == MAXROWS - 1)
 {
  for (counter = 0; counter <= lastcol; counter++)
   deletecell(counter, lastrow, NOUPDATE);
  printfreemem();
 }
 if (row != MAXROWS - 1)
 {
  for (counter = 0; counter < MAXCOLS; counter++)
  {
   movmem(&cell[counter][row], &cell[counter][row + 1],
    sizeof(CELLPTR) * (MAXROWS - row - 1));
   movmem(&format[counter][row], &format[counter][row + 1], MAXROWS - row - 1);
  }
 }
 for (counter = 0; counter < MAXCOLS; counter++)
 {
  cell[counter][row] = NULL;
  format[counter][row] = DEFAULTFORMAT;
 }
 lastrow = MAXROWS - 1;
 setlastrow();
 for (counter = 0; counter <= lastcol; counter++)
 {
  for (rowc = 0; rowc <= lastrow; rowc++)
  {
   if ((cell[counter][rowc] != NULL) &&
    (cell[counter][rowc]->attrib == FORMULA))
    fixformula(counter, rowc, ROWADD, row);
  }
 }
 while (row <= bottomrow)
  displayrow(row++, NOUPDATE);
 changed = TRUE;
 recalc();
} /* insertrow */

void smenu(void)
/* Executes the commands in the spreadsheet menu */
{
 char filename[MAXINPUT + 1];

 filename[0] = 0;
 switch(getcommand(SMENU, SCOMMAND))
 {
  case 0 :
   checkforsave();
   loadsheet(filename);
   break;
  case 1 :
   savesheet();
   break;
  case 2 :
   printsheet();
   break;
  case 3 :
   checkforsave();
   clearsheet();
   break;
 } /* switch */
} /* smenu */

void cmenu(void)
/* Executes the commands in the column menu */
{
 switch(getcommand(CMENU, CCOMMAND))
 {
  case 0 :
   insertcol(curcol);
   break;
  case 1 :
   deletecol(curcol);
   break;
  case 2 :
   setcolwidth(curcol);
   break;
 } /* switch */
} /* cmenu */

void rmenu(void)
/* Executes the commands in the row menu */
{
 switch(getcommand(RMENU, RCOMMAND))
 {
  case 0 :
   insertrow(currow);
   break;
  case 1 :
   deleterow(currow);
   break;
 } /* switch */
} /* rmenu */

void umenu(void)
/* Executes the commands in the utility menu */
{
 switch(getcommand(UMENU, UCOMMAND))
 {
  case 0 :
   recalc();
   break;
  case 1 :
   changeformdisplay(!formdisplay);
   displayscreen(UPDATE);
   break;
 } /* switch */
} /* umenu */

void mainmenu(void)
/* Executes the commands in the main menu */
{
 switch(getcommand(MENU, COMMAND))
 {
  case 0 :
   smenu();
   break;
  case 1 :
   formatcells();
   break;
  case 2 :
   deletecell(curcol, currow, UPDATE);
   printfreemem();
   if (autocalc)
    recalc();
   break;
  case 3 :
   gotocell();
   break;
  case 4 :
   cmenu();
   break;
  case 5 :
   rmenu();
   break;
  case 6 :
   editcell(curcell);
   break;
  case 7 :
   umenu();
   break;
  case 8 :
   changeautocalc(!autocalc);
   break;
  case 9 :
   checkforsave();
   stop = TRUE;
   break;
 } /* switch */
} /* mainmenu */

MCINPUT Programming in C

/* Turbo C - (C) Copyright 1987,1988 by Borland International */

#include <string.h>
#include <mem.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <bios.h>
#include <conio.h>
#include <string.h>
#include "mcalc.h"

int getkey(void)
/* Uses the BIOS to read the next keyboard character */
{
 int key, lo, hi;

 key = bioskey(0);
 lo = key & 0X00FF;
 hi = (key & 0XFF00) >> 8;
 return((lo == 0) ? hi + 256 : lo);
} /* getkey */

int editstring(char *s, char *legal, int maxlength)
/* Allows the user to edit a string with only certain characters allowed -
   Returns TRUE if ESC was not pressed, FALSE is ESC was pressed.
*/
{
 int c, len = strlen(s), pos = len, insert = TRUE;

 changecursor(insert);
 do
 {
  writef(1, 25, WHITE, 79, "%s", s);
  gotoxy(pos + 1, 25);
  switch(c = getkey())
  {
   case HOMEKEY :
    pos = 0;
    break;
   case ENDKEY :
    pos = len;
    break;
   case INSKEY :
    insert = !insert;
    changecursor(insert);
    break;
   case LEFTKEY :
    if (pos > 0)
     pos--;
    break;
   case RIGHTKEY :
    if (pos < len)
     pos++;
    break;
   case BS :
    if (pos > 0)
    {
     movmem(&s[pos], &s[pos - 1], len - pos + 1);
     pos--;
     len--;
    }
    break;
   case DELKEY :
    if (pos < len)
    {
     movmem(&s[pos + 1], &s[pos], len - pos);
     len--;
    }
    break;
   case CR :
    break;
   case UPKEY :
    c = CR;
    break;
   case DOWNKEY :
    c = CR;
    break;
   case ESC :
    len = 0;
    break;
   default :
    if (((legal[0] == 0) || (strchr(legal, c) != NULL)) &&
        ((c >= ' ') && (c <= '~')) &&
        (len < maxlength))
    {
     if (insert)
     {
      memmove(&s[pos + 1], &s[pos], len - pos + 1);
      len++;
     }
     else if (pos >= len)
      len++;
     s[pos++] = c;
    }
    break;
  } /* switch */
  s[len] = 0;
 }
 while ((c != CR) && (c != ESC));
 clearinput();
 changecursor(FALSE);
 setcursor(nocursor);
 return(c != ESC);
} /* editstring */

void getinput(int c)
/* Reads and acts on an input string from the keyboard that started with c. */
{
 char s[MAXINPUT + 1];

 s[0] = c;
 s[1] = 0;
 if (!editstring(s, "", MAXINPUT) || (s[0] == 0))
  return;
 act(s);
 changed = TRUE;
} /* getinput */

int getint(int *number, int low, int high)
/* Reads in a positive integer from low to high */
{
 int i, good = FALSE;
 char s[5], message[81];

 s[0] = 0;
 sprintf(message, MSGBADNUMBER, low, high);
 do
 {
  if (!editstring(s, "1234567890", 4))
   return(FALSE);
  i = atoi(s);
  if ((good = ((i >= low) && (i <= high))) == 0)
   errormsg(message);
 }
 while (!good);
 *number = i;
 return(TRUE);
} /* getint */

int getcell(int *col, int *row)
/* Reads in a cell name that was typed in - Returns FALSE if ESC was pressed */
{
 int first = TRUE, good = FALSE, len, numlen = rowwidth(MAXROWS),
     oldcol = *col, oldrow = *row;
 char data[10], *input, *start, numstring[6];

 data[0] = 0;
 do
 {
  if (!first)
   errormsg(MSGBADCELL);
  first = FALSE;
  input = data;
  if (!editstring(data, "", numlen + 2))
  {
   *col = oldcol;
   *row = oldrow;
   return(FALSE);
  }
  *col = toupper(*(input++)) - 'A';
  if (isalpha(*input))
  {
   *col *= 26;
   *col += toupper(*(input++)) - 'A' + 26;
  }
  if (*col >= MAXCOLS)
   continue;
  start = input;
  for (len = 0; len < numlen; len++)
  {
   if (!isdigit(*(input++)))
   {
    input--;
    break;
   }
  }
  if (len == 0)
   continue;
  strncpy(numstring, start, len);
  numstring[len] = 0;
  *row = atoi(numstring) - 1;
  if ((*row >= MAXROWS) || (*row == -1) || (*input != 0))
   continue;
  good = TRUE;
 }
 while (!good);
 return(TRUE);
} /* getcell */

int getyesno(int *yesno, char *prompt)
/* Prints a prompt and gets a yes or no answer - returns TRUE if ESC was
   pressed, FALSE if not.
*/
{
 writeprompt(prompt);
 setcursor(shortcursor);
 do
 {
  *yesno = toupper(getkey());
  if (*yesno == ESC)
  {
   setcursor(nocursor);
   return(FALSE);
  }
 }
 while (strchr("YN", *yesno) == NULL);
 setcursor(nocursor);
 return(TRUE);
} /* getyesno */

MCDISPLY Programming in C

/* Turbo C - (C) Copyright 1987,1988 by Borland International */

#include <dos.h>
#include <stdio.h>
#include <string.h>
#include <mem.h>
#include <conio.h>
#include "mcalc.h"

static unsigned char colortable[256];

void setcolor(int color)
/* Sets the current color using the color table */
{
  textattr(colortable[color]);
} /* setcolor */

void writef(int col, int row, int color, int width, va_list arg_list, ...)
/* Prints a string in video memory at a selected location in a color */
{
 va_list arg_ptr;
 char *format;
 char output[81];
 int len;

 va_start(arg_ptr, arg_list);
 format = arg_list;
 vsprintf(output, format, arg_ptr);
 output[width] = 0;
 if ((len = strlen(output)) < width)
  setmem(&output[len], width - len, ' ');
 setcolor(color);
 gotoxy(col, row);
 cprintf(output);
} /* writef */

void scroll(int direction, int lines, int x1, int y1, int x2, int y2,
            int attrib)
/* Scrolls an area of the screen */
{
  if (lines == 0)
    window(x1, y1, x2, y2);
  else switch(direction)
  {
    case UP :
      movetext(x1, y1 + lines, x2, y2, x1, y1);
      window(x1, y2 - lines + 1, x2, y2);
      break;
    case DOWN :
      movetext(x1, y1, x2, y2 - lines, x1, y1 + lines);
      window(x1, y1, x2, y1 + lines - 1);
      break;
    case LEFT :
      movetext(x1 + lines, y1, x2, y2, x1, y1);
      window(x2 - lines + 1, y1, x2, y2);
      break;
    case RIGHT :
      movetext(x1, y1, x2 - lines, y2, x1 + lines, y1);
      window(x1, y1, x1 + lines - 1, y2);
      break;
  } /* switch */
  setcolor(attrib);
  clrscr();
  window(1, 1, 80, 25);
} /* scroll */

void setcursor(unsigned int shape)
/* Sets the shape of the cursor */
{
 union REGS reg;

 reg.h.ah = 1;
 reg.x.cx = shape;
 int86(0X10, &reg, &reg);
} /* setcursor */

unsigned int getcursor(void)
/* Returns the shape of the current cursor */
{
 union REGS reg;

 reg.h.ah = 3;
 reg.h.bh = 0;
 int86(0X10, &reg, &reg);
 return(reg.x.cx);
} /* getcursor */

void changecursor(insmode)
/* Changes the cursor shape based on the current insert mode */
{
 if (insmode)
  setcursor(tallcursor);
 else
  setcursor(shortcursor);
} /* changecursor */

void printcol(void)
/* Prints the column headings */
{
 int col;
 char colstr[MAXCOLWIDTH + 1];

 scroll(UP, 0, 1, 2, 80, 2, HEADERCOLOR);
 for (col = leftcol; col <= rightcol; col++)
 {
  centercolstring(col, colstr);
  writef(colstart[col - leftcol] + 1, 2, HEADERCOLOR, colwidth[col], colstr);
 }
} /* printcol */

void clearlastcol()
/* Clears any data left in the last column */
{
 int col;

 if ((col = colstart[rightcol - leftcol] + colwidth[rightcol]) < 80)
  scroll(UP, 0, col + 1, 3, 80, SCREENROWS + 2, WHITE);
} /* clearlastcol */

void printrow(void)
/* Prints the row headings */
{
 int row;

 for (row = 0; row < SCREENROWS; row++)
  writef(1, row + 3, HEADERCOLOR, LEFTMARGIN, "%-d", row + toprow + 1);
} /* printrow */

void displaycell(int col, int row, int highlighting, int updating)
/* Displays the contents of a cell */
{
 int color;
 char *s;

 if ((updating) &&
     ((cell[col][row] == NULL) || (cell[col][row]->attrib != FORMULA)))
  return;
 s = cellstring(col, row, &color, FORMAT);
 if (highlighting)
 {
  if (color == ERRORCOLOR)
   color = HIGHLIGHTERRORCOLOR;
  else
   color = HIGHLIGHTCOLOR;
 }
 writef(colstart[col - leftcol] + 1, row - toprow + 3, color, colwidth[col],
        "%s", s);
} /* displaycell */

void displaycol(int col, int updating)
/* Displays a column on the screen */
{
 int row;

 for (row = toprow; row <= bottomrow; row++)
  displaycell(col, row, NOHIGHLIGHT, updating);
} /* displaycol */

void displayrow(int row, int updating)
/* Displays a row on the screen */
{
 int col;

 for (col = leftcol; col <= rightcol; col++)
  displaycell(col, row, NOHIGHLIGHT, updating);
} /* displayrow */

void displayscreen(int updating)
/* Displays the current screen of the spreadsheet */
{
 int row;

 for (row = toprow; row <= bottomrow; row++)
  displayrow(row, updating);
 clearlastcol();
} /* displayscreen */

void clearinput(void)
/* Clears the input line */
{
 scroll(UP, 0, 1, 25, 80, 25, WHITE);
 gotoxy(1, 25);
} /* clearinput */

void showcelltype(void)
/* Prints the type of cell and what is in it */
{
 char colstr[3], *s;
 int color;

 formdisplay = !formdisplay;
 s = cellstring(curcol, currow, &color, NOFORMAT);
 colstring(curcol, colstr);
 if (curcell == NULL)
  writef(1, 23, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1, MSGEMPTY);
 else switch(curcell->attrib)
 {
  case TEXT :
   writef(1, 23, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1,
          MSGTEXT);
   break;
  case VALUE :
   writef(1, 23, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1,
          MSGVALUE);
   break;
  case FORMULA :
   writef(1, 23, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1,
          MSGFORMULA);
   break;
 } /* switch */
 writef(1, 24, CELLCONTENTSCOLOR, 80, "%s", s);
 formdisplay = !formdisplay;
} /* showcelltype */

void redrawscreen(void)
/* Displays the entire screen */
{
 setrightcol();
 setbottomrow();
 writef(1, 1, MSGMEMORYCOLOR, strlen(MSGMEMORY), MSGMEMORY);
 writef(29, 1, PROMPTCOLOR, strlen(MSGCOMMAND), MSGCOMMAND);
 changeautocalc(autocalc);
 changeformdisplay(formdisplay);
 printfreemem();
 displayscreen(NOUPDATE);
} /* redrawscreen */

void initcursor(void)
/* Initializes the different cursor types */
{
 struct text_info ti;

 gettextinfo(&ti);
 oldcursor = getcursor();
 if (ti.currmode == MONO)
 {
  shortcursor = 0x0A0C;
  tallcursor = 0x090C;
 }
 else
 {
  shortcursor = 0x0607;
  tallcursor = 0x0507;
 }
} /* initcursor */

void initcolortable(void)
/* Sets up the color table */
{
  int color, fg, bg, fcolor, bcolor;
  struct text_info ti;

  gettextinfo(&ti);
  if (ti.currmode == C80)
  {
    for (color = 0; color <= 255; color++)
      colortable[color] = color;
  }
  else
  {
    for (fg = BLACK; fg <= WHITE; fg++)
    {
      if (fg == BLACK)
        fcolor = BLACK;
      else if (fg <= LIGHTGRAY)
        fcolor = LIGHTGRAY;
      else
        fcolor = WHITE;
      for (bg = BLACK; bg <= LIGHTGRAY; bg++)
      {
        if (bg == BLACK)
          bcolor = BLACK;
        else
  {
          if (fcolor == WHITE)
            fcolor = BLACK;
          bcolor = LIGHTGRAY;
        }
        colortable[fg + (bg << 4)] = fcolor + (bcolor << 4);
      }
    }
    for (fg = 128; fg <= 255; fg++)
      colortable[fg] = colortable[fg - 128] | 0x80;
  }
} /* initcolortable */

MCALC Turbo C Programming

/* Turbo C - (C) Copyright 1987,1988 by Borland International */

#define MAIN

#include <string.h>
#include <alloc.h>
#include <stdarg.h>
#include <dos.h>
#include <conio.h>
#include "mcalc.h"

CELLPTR cell[MAXCOLS][MAXROWS], curcell;
unsigned char format[MAXCOLS][MAXROWS];
unsigned char colwidth[MAXCOLS];
unsigned char colstart[SCREENCOLS];
int leftcol, rightcol, toprow, bottomrow, curcol, currow, lastcol, lastrow;
char changed = FALSE;
char formdisplay = FALSE;
char autocalc = TRUE;
char stop = FALSE;
char colortable[128];
char colorcard;
char snow;
char far *displayptr;
long memleft;
unsigned int oldcursor, shortcursor, tallcursor, nocursor = 0x2000;

void run()
/* The main program loop */
{
 int input;

 do
 {
  displaycell(curcol, currow, HIGHLIGHT, NOUPDATE);
  curcell = cell[curcol][currow];
  showcelltype();
  input = getkey();
  switch(input)
  {
   case '/' :
    mainmenu();
    break;
   case F1 :
    recalc();
    break;
   case F2 :
    editcell(curcell);
    break;
   case DELKEY :
    deletecell(curcol, currow, UPDATE);
    printfreemem();
    if (autocalc)
     recalc();
    break;
   case PGUPKEY :
    toprow -= 20;
    currow -= 20;
    if (currow < 0)
     currow = toprow = 0;
    else if (toprow < 0)
    {
     currow -= toprow;
     toprow = 0;
    }
    setbottomrow();
    displayscreen(NOUPDATE);
    break;
   case PGDNKEY :
    toprow += 20;
    currow += 20;
    if ((currow >= MAXROWS) && (toprow >= MAXROWS))
    {
     currow = MAXROWS - 1;
     toprow = MAXROWS - 20;
    }
    else if (toprow > (MAXROWS - 20))
    {
     currow -= (toprow + 20 - MAXROWS);
     toprow = MAXROWS - 20;
    }
    setbottomrow();
    displayscreen(NOUPDATE);
    break;
   case CTRLLEFTKEY :
    displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
    if (leftcol == 0)
     curcol = 0;
    else
    {
     curcol = rightcol = leftcol - 1;
     setleftcol();
     setrightcol();
     displayscreen(NOUPDATE);
    }
    break;
   case CTRLRIGHTKEY :
    displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
    if (rightcol == MAXCOLS - 1)
     curcol = rightcol;
    else
    {
     curcol = leftcol = rightcol + 1;
     setrightcol();
     setleftcol();
     displayscreen(NOUPDATE);
    }
    break;
   case HOMEKEY :
    currow = curcol = leftcol = toprow = 0;
    setrightcol();
    setbottomrow();
    displayscreen(NOUPDATE);
    break;
   case ENDKEY :
    rightcol = curcol = lastcol;
    currow = bottomrow = lastrow;
    settoprow();
    setleftcol();
    setrightcol();
    displayscreen(NOUPDATE);
    break;
   case UPKEY :
    moverowup();
    break;
   case DOWNKEY :
    moverowdown();
    break;
   case LEFTKEY :
    movecolleft();
    break;
   case RIGHTKEY :
    movecolright();
    break;
   default :
    if ((input >= ' ') && (input <= '~'))
     getinput(input);
    break;
  } /* switch */
 }
 while (!stop);
} /* run */

void main(int argc, char *argv[])
{
 window(1, 1, 80, 25);
 initcursor();
 initcolortable();
 setcursor(nocursor);
 setcolor(WHITE);
 clrscr();
 writef((80 - strlen(MSGHEADER)) >> 1, 11, MSGHEADERCOLOR, strlen(MSGHEADER),
        MSGHEADER);
 writef((80 - strlen(MSGKEYPRESS)) >> 1, 13, PROMPTCOLOR,
        strlen(MSGKEYPRESS), MSGKEYPRESS);
 gotoxy(80, 25);
 getkey();
 setcolor(WHITE);
 clrscr();
 initvars();
 memleft = memsize;
 redrawscreen();
 if (argc > 1)
  loadsheet(argv[1]);
 clearinput();
 run();
 setcolor(LIGHTGRAY);
 clrscr();
 setcursor(oldcursor);
}

matherr - user-modifiable math error handler

/*------------------------------------------------------------------------
 * filename - matherr.c
 *
 * function(s)
 *        matherr - user-modifiable math error handler
 *-----------------------------------------------------------------------*/

/*[]---------------------------------------------------[]*/
/*| |*/
/*| Turbo C Run Time Library - Version 2.0 |*/
/*| |*/
/*| |*/
/*| Copyright (c) 1988 by Borland International |*/
/*| All Rights Reserved. |*/
/*| |*/
/*[]---------------------------------------------------[]*/


#include <math.h>

#ifdef UNIX_matherr
#include <stdio.h>
#include <process.h>

char *whyS [] =
{
    "argument domain error",
    "argument singularity ",
    "overflow range error ",
    "underflow range error",
    "total loss of significance",
    "partial loss of significance"
};

/*------------------------------------------------------------------------*

Name matherr - user-modifiable math error handler

Usage #include <math.h>
int matherr(struct exception *e);

Prototype in math.h

Description When  exceptions are  detected in  the math  library then a
call is made  to  _matherr()  with all the available
information.

That function does very little, except to map the exception
"why"  into either  ERANGE or  EDOMAIN in  errno. Its  main
purpose is  to act as  a focal point  for changes in  error
handling.

For example,  if you were  writing a spreadsheet  you might
replace  this function with one which pops up an error
window explaining something like:

"log (-2.0) caused domain error, in cell J7"

and then longjmp() to a  reset state in the spreadsheet and
await the next command from the user.

The default version  of Turbo C's matherr routine masks
underflow and precision errors; others errors are considered
fatal.  It serves as a hook that you can replace when
writing your own math error handling routine.

The rationale for masking underflow and precision errors
is that these are not errors according to the ANSI C spec.
Consequently, you will get
exp(-1000) = 0
sin(1e100) = NAN
without any error or warning, even though there is a total
loss of precision in both cases.  You can trap these errors
by modifying matherr.

The possible errors are
DOMAIN, SING, OVERFLOW, UNDERFLOW, TLOSS, PLOSS
and listed in <math.h>.  As explained above, UNDERFLOW and
TLOSS are masked by the default matherr.  PLOSS is not
supported by TC and is not generated by any library functions.
The remaining errors, DOMAIN, SING, and OVERFLOW, are fatal
with the default matherr.

You  can  modify  matherr  to  be  a  custom error handling
routine (such as one that catches and resolves certain type
of  errors); the  modified matherr  should return  0 if  it
failed to resolve  the error, or non-zero if  the error was
resolved. When matherr returns non-zero, no  error message
is printed, and errno is not changed.

The  important thing  is  that  we  don't  know what error
handling you want, but you are assured that all errors will
arrive at  matherr() with all  the information you  need to
design a custom format.

We  do not  ship as  standard the  function named matherr()
which may be  familiar to UNIX users, since  the ANSI x3j11
draft specifies  an incompatible style. This  version is as
close as we could get  without breaking the ANSI rules. You
can, however, convert this version to the UNIX style if you
prefer. The necessary code is included but switched off.

Return value The default return  value for matherr is simply  0.
matherr can also modify  e->retval, which propagates through
_matherr back to the original caller.

When matherr returns 0, (indicating that it was not able to
resolve the error) _matherr sets  errno and prints an error
message.

When matherr returns non-zero, (indicating that it was able
to resolve the error) errno is not set and no messages are
printed.

*-------------------------------------------------------------------------*/
int matherr (struct exception *e)
{
    fprintf (stderr,
"%s (%8g,%8g): %s\n", e->name, e->arg1, e->arg2, whyS [e->type - 1]);

    exit (1);
}
#else

int matherr(struct exception *e)
{
if (e->type == UNDERFLOW)
{
/* flush underflow to 0 */
e->retval = 0;
return 1;
}
if (e->type == TLOSS)
{
/* total loss of precision, but ignore the problem */
return 1;
}
/* all other errors are fatal */
return 0;
}


#endif