|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: A T
Length: 8524 (0x214c)
Types: TextFile
Names: »AppendSource.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/Toolkit/DECToolkit/src/AppendSource.c«
/*
* $Source: /u1/X/DECToolkit/src/RCS/AppendSource.c,v $
* $Header: AppendSource.c,v 1.1 86/12/17 08:59:58 swick Exp $
*/
#ifndef lint
static char *rcsid_AppendSource_c = "$Header: AppendSource.c,v 1.1 86/12/17 08:59:58 swick Exp $";
#endif lint
#ifndef lint
static char *sccsid = "@(#)AppendSource.c 1.5 12/11/86";
#endif lint
/*
* COPYRIGHT 1986
* DIGITAL EQUIPMENT CORPORATION
* MAYNARD, MASSACHUSETTS
* ALL RIGHTS RESERVED.
*
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
* SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
* DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
* ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
*
* IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
* APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
* SET FORTH ABOVE.
*
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting documentation,
* and that the name of Digital Equipment Corporation not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*/
/* File: AppendSource.c */
#include <X/Xlib.h>
#include <stdio.h>
#include "Toolkit.h"
#include "TextDisplay.h" /** included in all text subwindow files **/
/** private TAppendSource definitions **/
typedef struct _TAppendSourceData {
FILE *file;
TTextPosition position, /*** read position for file ***/
length; /*** length of file ***/
char *buffer; /*** piece of file in memory ***/
int charsInBuffer; /*** number of bytes used in memory ***/
} TAppendSourceData, *TAppendSourcePtr;
#define bufSize 1000
#define Increment(data, position, direction)\
{\
if (direction == left) {\
if (position > 0) \
position -= 1;\
}\
else {\
if (position < data->length)\
position += 1;\
}\
}
static char Look(data, position, direction)
TAppendSourcePtr data;
TTextPosition position;
enum ScanDirection direction;
{
TTextPosition pos;
if (direction == left) {
if (position == 0)
return('\n');
else {
FillBuffer(data, position - 1);
return(data->buffer[position - data->position - 1]);
}
}
else {
if (position == data->length)
return('\n');
else {
FillBuffer(data, position);
return(data->buffer[position - data->position]);
}
}
}
/***
*** this routine will read source into "text", starting at "pos", for
*** "maxRead" characters or end.
***/
int AppendReadText (src, pos, text, maxRead)
TTextSource *src;
TTextPosition pos; /** starting position ***/
TTextBlock *text; /** RETURNED: text read in ***/
int maxRead; /** max number of bytes to read **/
{
TTextPosition nextPos, count;
TAppendSourcePtr data;
data = (TAppendSourcePtr) src->data;
FillBuffer(data, pos);
text->ptr = data->buffer + (pos - data->position);
count = data->charsInBuffer - (pos - data->position);
text->length = (maxRead > count) ? count : maxRead;
return pos + text->length;
}
/***
*** this routine reads text starting at "pos" into memory.
***/
static int FillBuffer (data, pos)
TAppendSourcePtr data;
TTextPosition pos;
{
TTextPosition readPos;
if ((pos < data->position ||
pos >= data->position + data->charsInBuffer - 100) &&
data->charsInBuffer != data->length) {
if (pos < (bufSize / 2))
readPos = 0;
else
if (pos >= data->length - bufSize)
readPos = data->length - bufSize;
else
if (pos >= data->position + data->charsInBuffer - 100)
readPos = pos - (bufSize / 2);
else
readPos = pos;
fseek(data->file, readPos, 0);
data->charsInBuffer = fread(data->buffer, sizeof(char), bufSize,
data->file);
data->position = readPos;
}
}
/***
*** this routine will append text to the end of the file and to the end]
*** of the buffer currently in memory.
***/
static int AppendReplaceText (src, startPos, endPos, text)
TTextSource *src;
TTextPosition startPos, endPos;
TTextBlock *text;
{
char temp_str[bufSize], buf_format[25];
TAppendSourcePtr data;
data = (TAppendSourcePtr) src->data;
/*** write the new text to the end of the file ***/
if (text->length > 0) {
fseek(data->file, data->length, 0);
fwrite(text->ptr, sizeof(char), text->length, data->file);
} else
/*** if the delete key was hit, blank out last char in the file ***/
if (text->length < 0) {
fseek(data->file, data->length-1, 0);
fwrite(" ", sizeof(char), 1, data->file);
}
fseek(data->file, 0, 2); /** need this for anyone else trying to seek
to end of file. - mary **/
/*** put the new text into the buffer in memory ***/
data->length += text->length;
if (data->charsInBuffer + text->length <= bufSize) {
if (text->length > 0) {
strncpy(temp_str, data->buffer, data->charsInBuffer);
sprintf(buf_format, "%%.%ds%%.%ds",
data->charsInBuffer, text->length);
sprintf(data->buffer, buf_format, temp_str, text->ptr);
}
data->charsInBuffer += text->length;
} else
FillBuffer(data, data->length - text->length);
return (text->length);
}
/***
*** returns the length of the file.
***/
static TTextPosition AppendGetLastPos (src)
TTextSource *src;
{
return (((TAppendSourceData *)(src->data))->length);
}
/***
*** lets you modify the source length.
***/
static int AppendSetLastPos (src, lastPos)
TTextSource *src;
TTextPosition lastPos;
{
((TAppendSourceData *)(src->data))->length = lastPos;
}
/***
*** what time of text insertion is allowed for this source.
***/
static enum InsertionType AppendEditType()
{
return(append);
}
/***
*** This routine will start at
*** the "pos" position of the source and scan in the appropriate
*** direction until it finds something of the right sType. It returns
*** the new position. If upon reading it hits the end of the buffer
*** in memory, it will refill the buffer.
***/
static TTextPosition AppendScan (src, pos, sType, dir, word_break_symbols)
TTextSource *src;
TTextPosition pos; /*** starting position ***/
enum SelectionType sType; /*** char, word, eoln **/
enum ScanDirection dir; /*** left or right ***/
char *word_break_symbols;
{
TAppendSourcePtr data;
TTextPosition position;
int whiteSpace;
char c;
data = (TAppendSourcePtr) src->data;
position = pos;
switch (sType) {
case charSelection:
Increment(data, position, dir);
break;
case wordSelection:
whiteSpace = 0;
while (position > 0 && position < data->length) {
FillBuffer(data, position);
c = Look(data, position, dir);
whiteSpace = (c == ' ') || (c == '\t') || (c == '\n');
if (whiteSpace)
break;
else
if (index(word_break_symbols, c) != 0)
break;
Increment(data, position, dir);
}
break;
case lineSelection:
position = pos;
while (position > 0 && position < data->length) {
FillBuffer(data, position);
if (Look(data, position, dir) == '\n')
break;
Increment(data, position, dir);
}
break;
case allSelection:
if (dir == left)
position = 0;
else
position = data->length;
}
return(position);
}
/********************* Public routines ******************************/
int *TCreateAppendSource (name)
char *name;
{
TTextSource *src;
TAppendSourcePtr data;
src = (TTextSource *) Tmalloc(sizeof(TTextSource));
src->read = AppendReadText;
src->replace = AppendReplaceText;
src->getLastPos = AppendGetLastPos;
src->setLastPos = AppendSetLastPos;
src->getEditType = AppendEditType;
src->scan = AppendScan;
src->data = (int *) (Tmalloc(sizeof(TAppendSourceData)));
data = (TAppendSourcePtr) src->data;
if ((data->file = fopen(name, "w+")) == 0)
fprintf(stderr, "XToolkit: error opening appendable source file \n");
fseek (data->file, 0, 2);
data->length = ftell (data->file);
data->buffer = (char *) Tmalloc(bufSize);
data->position = 0;
data->charsInBuffer = 0;
src->data = (int *) (data);
return(int *) src;
}
void TDestroyAppendSource (src)
TTextSource *src;
{
free(src->data);
free(src);
}