|
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 - 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); }