DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ D T ┃
Length: 11977 (0x2ec9) Types: TextFile Names: »DiskSrc.c«
└─⟦5f3412b64⟧ Bits:30000745 8mm tape, Rational 1000, ENVIRONMENT 12_6_5 TOOLS └─ ⟦91c658230⟧ »DATA« └─⟦5d656759a⟧ └─⟦8fb0c967c⟧ └─⟦d10a02448⟧ Bits:30000409 8mm tape, Rational 1000, ENVIRONMENT, D_12_7_3 └─ ⟦fc9b38f02⟧ »DATA« └─⟦8e9e227a9⟧ └─⟦8fb0c967c⟧ └─ ⟦this⟧ »X11/DiskSrc.c«
#ifndef lint static char Xrcsid[] = "$XConsortium: DiskSrc.c,v 1.20 88/10/18 12:29:54 swick Exp $"; #endif lint /*********************************************************** Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. All Rights Reserved 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 names of Digital or MIT not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ /* File: DiskSource.c */ /* Documentation for source specfic routine semantics may be found in the * TextPrivate.h file. */ #include <stdio.h> #ifdef VMS #else #include <sys/param.h> #endif #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> #include <X11/Xatom.h> #include <X11/Xmu.h> #include <X11/TextP.h> #define TMPSIZ 32 /* bytes to allocate for tmpnam */ extern char *tmpnam(); /** private DiskSource definitions **/ typedef struct _DiskSourceData { /* resources */ char *fileName; /* private data */ Boolean is_tempfile; FILE *file; XtTextPosition position, /* file position of first char in buffer */ length; /* length of file */ char *buffer; /* piece of file in memory */ int charsInBuffer; /* number of bytes used in memory */ } DiskSourceData, *DiskSourcePtr; #define bufSize 1000 #define Increment(data, position, direction)\ {\ if (direction == XtsdLeft) {\ if (position > 0) \ position -= 1;\ }\ else {\ if (position < data->length)\ position += 1;\ }\ } static XtResource diskResources[] = { {XtNfile, XtCFile, XtRString, sizeof (char *), XtOffset(DiskSourcePtr, fileName), XtRString, NULL}, }; static XtResource sourceResources[] = { {XtNeditType, XtCEditType, XtREditMode, sizeof(int), XtOffset(XtTextSource, edit_mode), XtRString, "read"}, }; static char Look(data, position, direction) DiskSourcePtr data; XtTextPosition position; XtTextScanDirection direction; { if (direction == XtsdLeft) { 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]); } } } static XtTextPosition DiskReadText (src, pos, text, length) XtTextSource src; XtTextPosition pos; /** starting position */ XtTextBlock *text; /** RETURNED: text read in */ int length; /** max number of bytes to read **/ { XtTextPosition count; DiskSourcePtr data; data = (DiskSourcePtr) src->data; FillBuffer(data, pos); text->firstPos = pos; text->ptr = data->buffer + (pos - data->position); count = data->charsInBuffer - (pos - data->position); text->length = (length > count) ? count : length; return pos + text->length; } /* * this routine reads text starting at "pos" into memory. * Contains heuristic for keeping the read position centered in the buffer. */ static int FillBuffer (data, pos) DiskSourcePtr data; XtTextPosition pos; { long 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; (void) fseek(data->file, readPos, 0); data->charsInBuffer = fread(data->buffer, sizeof(char), bufSize, data->file); data->position = readPos; } } /* * This is a dummy routine for read only disk sources. */ /*ARGSUSED*/ /* keep lint happy */ static int DummyReplaceText (src, startPos, endPos, text) XtTextSource src; XtTextPosition startPos, endPos; XtTextBlock *text; { return(EditError); } /* * This routine will only append to the end of a source. If incorrect * starting and ending positions are given, an error will be returned. */ static int DiskAppendText (src, startPos, endPos, text) XtTextSource src; XtTextPosition startPos, endPos; XtTextBlock *text; { long topPosition = 0; char *tmpPtr; DiskSourcePtr data; data = (DiskSourcePtr) src->data; if (startPos != endPos || endPos != data->length) return (PositionError); /* write the new text to the end of the file */ if (text->length > 0) { (void) fseek(data->file, data->length, 0); (void) 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) { (void) fseek(data->file, data->length-1, 0); (void) fwrite(" ", sizeof(char), 1, data->file); } /* need this in case the application trys to seek to end of file. */ (void) fseek(data->file, topPosition, 2); /* put the new text into the buffer in memory */ data->length += text->length; if (data->charsInBuffer + text->length <= bufSize) { /**** NOTE: need to check if text won't fit in the buffer ***/ if (text->length > 0) { tmpPtr = data->buffer + data->charsInBuffer; bcopy(text->ptr, tmpPtr, text->length); } data->charsInBuffer += text->length; } else FillBuffer(data, data->length - text->length); return (EditDone); } static int DiskSetLastPos (src, lastPos) XtTextSource src; XtTextPosition lastPos; { ((DiskSourceData *)(src->data))->length = lastPos; } /* * 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 XtTextPosition DiskScan (src, pos, sType, dir, count, include) XtTextSource src; XtTextPosition pos; XtTextScanType sType; XtTextScanDirection dir; int count; Boolean include; { DiskSourcePtr data; XtTextPosition position; int i, whiteSpace; char c; data = (DiskSourcePtr) src->data; position = pos; switch (sType) { case XtstPositions: if (!include && count > 0) count -= 1; for (i = 0; i < count; i++) { Increment(data, position, dir); } break; case XtstWhiteSpace: for (i = 0; i < count; i++) { 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; Increment(data, position, dir); } if (i + 1 != count) Increment(data, position, dir); } if (include) Increment(data, position, dir); break; case XtstEOL: for (i = 0; i < count; i++) { while (position >= 0 && position <= data->length) { if (Look(data, position, dir) == '\n') break; Increment(data, position, dir); } if (i + 1 != count) Increment(data, position, dir); } if (include) { /* later!!!check for last char in file # eol */ Increment(data, position, dir); } break; case XtstAll: if (dir == XtsdLeft) position = 0; else position = data->length; } return(position); } static Boolean ConvertSelection(d, src, selection, target, type, value, length, format) Display* d; XtTextSource src; Atom *selection, *target, *type; caddr_t *value; unsigned long *length; int *format; { DiskSourcePtr data = (DiskSourcePtr)src->data; if (*selection != XA_PRIMARY) return False; if (*target == XA_TARGETS(d)) { *value = XtMalloc(sizeof(Atom)); *(Atom*)*value = XA_FILENAME(d); *type = XA_ATOM; *length = 1; *format = 32; return True; } else if (*target == XA_FILENAME(d)) { #ifdef unix if (*data->fileName != '/') { char fullname[MAXPATHLEN+2]; /* +2 for getcwd */ char *p = data->fileName; int len; #ifdef SYSV extern char *getcwd(); #define get_current_directory(buf,len) getcwd (buf, len) #else extern char *getwd(); #define get_current_directory(buf,len) getwd (buf) #endif if (get_current_directory (fullname, sizeof fullname) == NULL) fullname[0] = '\0'; while (*p == '.') { if (*++p == '/') { p++; continue; } if (*p == '.' && *++p == '/') { char *d = rindex(fullname, '/'); if (d != NULL) *d = '\0'; p++; continue; } else break; } if (fullname[len=strlen(fullname)] != '/') fullname[len++] = '/'; strcpy(&fullname[len], p); *value = XtNewString(fullname); } else #endif /*unix*/ *value = XtNewString(data->fileName); *type = XA_STRING; *length = strlen(*value); *format = 8; return True; } /* else */ return False; } /******* Public routines **********/ XtTextSource XtDiskSourceCreate(parent, args, num_args) Widget parent; ArgList args; Cardinal num_args; { XtTextSource src; DiskSourcePtr data; long topPosition = 0; src = XtNew(XtTextSourceRec); XtGetSubresources (parent, (caddr_t)src, XtNtextSource, XtCTextSource, sourceResources, XtNumber(sourceResources), args, num_args); src->Read = DiskReadText; src->SetLastPos = DiskSetLastPos; src->Scan = DiskScan; src->SetSelection = NULL; src->ConvertSelection = ConvertSelection; data = XtNew(DiskSourceData); src->data = (caddr_t)data; XtGetSubresources (parent, (caddr_t)data, XtNtextSource, XtCTextSource, diskResources, XtNumber(diskResources), args, num_args); if (data->fileName == NULL) { data->fileName = tmpnam (XtMalloc((unsigned)TMPSIZ)); data->is_tempfile = TRUE; } else data->is_tempfile = FALSE; switch (src->edit_mode) { case XttextRead: if ((data->file = fopen(data->fileName, "r")) == 0) XtError("Cannot open source file in XtDiskSourceCreate"); src->Replace = DummyReplaceText; break; case XttextAppend: if ((data->file = fopen(data->fileName, "r+")) == 0) XtError("Cannot open source file in XtDiskSourceCreate"); src->Replace = DiskAppendText; break; default: if ((data->file = fopen(data->fileName, "r")) == 0) XtError("Cannot open source file in XtDiskSourceCreate"); src->Replace = DummyReplaceText; } (void) fseek(data->file, topPosition, 2); data->length = ftell (data->file); data->buffer = (char *) XtMalloc((unsigned)bufSize); data->position = 0; data->charsInBuffer = 0; return src; } void XtDiskSourceDestroy (src) XtTextSource src; { DiskSourcePtr data; data = (DiskSourcePtr) src->data; XtFree((char *) data->buffer); if (data->is_tempfile) { #ifdef VMS delete(data->fileName); #else unlink(data->fileName); #endif XtFree((char *) data->fileName); } XtFree((char *) src->data); XtFree((char *) src); }