io.c revision f14f4646
15dfecf96Smrg/* 25dfecf96Smrg * Copyright (c) 2002 by The XFree86 Project, Inc. 35dfecf96Smrg * 45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a 55dfecf96Smrg * copy of this software and associated documentation files (the "Software"), 65dfecf96Smrg * to deal in the Software without restriction, including without limitation 75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the 95dfecf96Smrg * Software is furnished to do so, subject to the following conditions: 105dfecf96Smrg * 115dfecf96Smrg * The above copyright notice and this permission notice shall be included in 125dfecf96Smrg * all copies or substantial portions of the Software. 135dfecf96Smrg * 145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 205dfecf96Smrg * SOFTWARE. 215dfecf96Smrg * 225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall 235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other 245dfecf96Smrg * dealings in this Software without prior written authorization from the 255dfecf96Smrg * XFree86 Project. 265dfecf96Smrg * 275dfecf96Smrg * Author: Paulo César Pereira de Andrade 285dfecf96Smrg */ 295dfecf96Smrg 305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/io.c,v 1.16tsi Exp $ */ 315dfecf96Smrg 325dfecf96Smrg#include "lisp/io.h" 335dfecf96Smrg#include <errno.h> 345dfecf96Smrg#include <fcntl.h> 355dfecf96Smrg#include <stdarg.h> 365dfecf96Smrg#include <sys/types.h> 375dfecf96Smrg#include <sys/stat.h> 385dfecf96Smrg 395dfecf96Smrg/* Match the FILE_XXX flags */ 405dfecf96Smrg#define READ_BIT 0x01 415dfecf96Smrg#define WRITE_BIT 0x02 425dfecf96Smrg#define APPEND_BIT 0x04 435dfecf96Smrg#define BUFFERED_BIT 0x08 445dfecf96Smrg#define UNBUFFERED_BIT 0x10 455dfecf96Smrg#define BINARY_BIT 0x20 465dfecf96Smrg 475dfecf96Smrg/* 485dfecf96Smrg * Prototypes 495dfecf96Smrg */ 505dfecf96Smrgstatic int calculate_line(void*, int); 515dfecf96Smrgstatic int calculate_column(void*, int, int); 525dfecf96Smrg 535dfecf96Smrg/* 545dfecf96Smrg * Initialization 555dfecf96Smrg */ 565dfecf96Smrgextern int pagesize; 575dfecf96Smrg 585dfecf96Smrg/* 595dfecf96Smrg * Implementation 605dfecf96Smrg */ 615dfecf96Smrgint 625dfecf96SmrgLispGet(void) 635dfecf96Smrg{ 645dfecf96Smrg int ch = EOF; 655dfecf96Smrg LispUngetInfo *unget = lisp__data.unget[lisp__data.iunget]; 665dfecf96Smrg 675dfecf96Smrg if (unget->offset) 685dfecf96Smrg ch = ((unsigned char*)unget->buffer)[--unget->offset]; 695dfecf96Smrg else if (SINPUT->data.stream.readable) { 705dfecf96Smrg LispFile *file = NULL; 715dfecf96Smrg 725dfecf96Smrg switch (SINPUT->data.stream.type) { 735dfecf96Smrg case LispStreamStandard: 745dfecf96Smrg case LispStreamFile: 755dfecf96Smrg file = FSTREAMP(SINPUT); 765dfecf96Smrg break; 775dfecf96Smrg case LispStreamPipe: 785dfecf96Smrg file = IPSTREAMP(SINPUT); 795dfecf96Smrg break; 805dfecf96Smrg case LispStreamString: 815dfecf96Smrg ch = LispSgetc(SSTREAMP(SINPUT)); 825dfecf96Smrg break; 835dfecf96Smrg default: 845dfecf96Smrg ch = EOF; 855dfecf96Smrg break; 865dfecf96Smrg } 875dfecf96Smrg if (file != NULL) { 885dfecf96Smrg if (file->nonblock) { 895dfecf96Smrg if (fcntl(file->descriptor, F_SETFL, 0) < 0) 905dfecf96Smrg LispDestroy("fcntl: %s", strerror(errno)); 915dfecf96Smrg file->nonblock = 0; 925dfecf96Smrg } 935dfecf96Smrg ch = LispFgetc(file); 945dfecf96Smrg } 955dfecf96Smrg } 965dfecf96Smrg else 975dfecf96Smrg LispDestroy("cannot read from *STANDARD-INPUT*"); 985dfecf96Smrg 995dfecf96Smrg if (ch == EOF) 1005dfecf96Smrg lisp__data.eof = 1; 1015dfecf96Smrg 1025dfecf96Smrg return (ch); 1035dfecf96Smrg} 1045dfecf96Smrg 1055dfecf96Smrgint 1065dfecf96SmrgLispUnget(int ch) 1075dfecf96Smrg{ 1085dfecf96Smrg LispUngetInfo *unget = lisp__data.unget[lisp__data.iunget]; 1095dfecf96Smrg 1105dfecf96Smrg if (unget->offset == sizeof(unget->buffer)) { 1115dfecf96Smrg LispWarning("character %c lost at LispUnget()", unget->buffer[0]); 1125dfecf96Smrg memmove(unget->buffer, unget->buffer + 1, unget->offset - 1); 1135dfecf96Smrg unget->buffer[unget->offset - 1] = ch; 1145dfecf96Smrg } 1155dfecf96Smrg else 1165dfecf96Smrg unget->buffer[unget->offset++] = ch; 1175dfecf96Smrg 1185dfecf96Smrg return (ch); 1195dfecf96Smrg} 1205dfecf96Smrg 1215dfecf96Smrgvoid 1225dfecf96SmrgLispPushInput(LispObj *stream) 1235dfecf96Smrg{ 1245dfecf96Smrg if (!STREAMP(stream) || !stream->data.stream.readable) 1255dfecf96Smrg LispDestroy("bad stream at PUSH-INPUT"); 1265dfecf96Smrg lisp__data.input_list = CONS(stream, lisp__data.input_list); 1275dfecf96Smrg SINPUT = stream; 1285dfecf96Smrg if (lisp__data.iunget + 1 == lisp__data.nunget) { 1295dfecf96Smrg LispUngetInfo **info = 1305dfecf96Smrg realloc(lisp__data.unget, 1315dfecf96Smrg sizeof(LispUngetInfo) * (lisp__data.nunget + 1)); 1325dfecf96Smrg 1335dfecf96Smrg if (!info || 1345dfecf96Smrg (info[lisp__data.nunget] = 1355dfecf96Smrg calloc(1, sizeof(LispUngetInfo))) == NULL) 1365dfecf96Smrg LispDestroy("out of memory"); 1375dfecf96Smrg lisp__data.unget = info; 1385dfecf96Smrg ++lisp__data.nunget; 1395dfecf96Smrg } 1405dfecf96Smrg ++lisp__data.iunget; 1415dfecf96Smrg memset(lisp__data.unget[lisp__data.iunget], '\0', sizeof(LispUngetInfo)); 1425dfecf96Smrg lisp__data.eof = 0; 1435dfecf96Smrg} 1445dfecf96Smrg 1455dfecf96Smrgvoid 1465dfecf96SmrgLispPopInput(LispObj *stream) 1475dfecf96Smrg{ 1485dfecf96Smrg if (!CONSP(lisp__data.input_list) || stream != CAR(lisp__data.input_list)) 1495dfecf96Smrg LispDestroy("bad stream at POP-INPUT"); 1505dfecf96Smrg lisp__data.input_list = CDR(lisp__data.input_list); 1515dfecf96Smrg SINPUT = CONSP(lisp__data.input_list) ? 1525dfecf96Smrg CAR(lisp__data.input_list) : lisp__data.input_list; 1535dfecf96Smrg --lisp__data.iunget; 1545dfecf96Smrg lisp__data.eof = 0; 1555dfecf96Smrg} 1565dfecf96Smrg 1575dfecf96Smrg/* 1585dfecf96Smrg * Low level functions 1595dfecf96Smrg */ 1605dfecf96Smrgstatic int 1615dfecf96Smrgcalculate_line(void *data, int size) 1625dfecf96Smrg{ 1635dfecf96Smrg int line = 0; 1645dfecf96Smrg char *str, *ptr; 1655dfecf96Smrg 1665dfecf96Smrg for (str = (char*)data, ptr = (char*)data + size; str < ptr; str++) 1675dfecf96Smrg if (*ptr == '\n') 1685dfecf96Smrg ++line; 1695dfecf96Smrg 1705dfecf96Smrg return (line); 1715dfecf96Smrg} 1725dfecf96Smrg 1735dfecf96Smrgstatic int 1745dfecf96Smrgcalculate_column(void *data, int size, int column) 1755dfecf96Smrg{ 1765dfecf96Smrg char *str, *ptr; 1775dfecf96Smrg 1785dfecf96Smrg /* search for newline in data */ 1795dfecf96Smrg for (str = (char*)data, ptr = (char*)data + size - 1; ptr >= str; ptr--) 1805dfecf96Smrg if (*ptr == '\n') 1815dfecf96Smrg break; 1825dfecf96Smrg 1835dfecf96Smrg /* newline found */ 1845dfecf96Smrg if (ptr >= str) 1855dfecf96Smrg return (size - (ptr - str) - 1); 1865dfecf96Smrg 1875dfecf96Smrg /* newline not found */ 1885dfecf96Smrg return (column + size); 1895dfecf96Smrg} 1905dfecf96Smrg 1915dfecf96SmrgLispFile * 1925dfecf96SmrgLispFdopen(int descriptor, int mode) 1935dfecf96Smrg{ 1945dfecf96Smrg LispFile *file = calloc(1, sizeof(LispFile)); 1955dfecf96Smrg 1965dfecf96Smrg if (file) { 1975dfecf96Smrg struct stat st; 1985dfecf96Smrg 1995dfecf96Smrg file->descriptor = descriptor; 2005dfecf96Smrg file->readable = (mode & READ_BIT) != 0; 2015dfecf96Smrg file->writable = (mode & WRITE_BIT) != 0; 2025dfecf96Smrg 2035dfecf96Smrg if (fstat(descriptor, &st) == 0) 2045dfecf96Smrg file->regular = S_ISREG(st.st_mode); 2055dfecf96Smrg else 2065dfecf96Smrg file->regular = 0; 2075dfecf96Smrg 2085dfecf96Smrg file->buffered = (mode & BUFFERED_BIT) != 0; 2095dfecf96Smrg if ((mode & UNBUFFERED_BIT) == 0) 2105dfecf96Smrg file->buffered = file->regular; 2115dfecf96Smrg 2125dfecf96Smrg if (file->buffered) { 2135dfecf96Smrg file->buffer = malloc(pagesize); 2145dfecf96Smrg if (file->buffer == NULL) 2155dfecf96Smrg file->buffered = 0; 2165dfecf96Smrg } 2175dfecf96Smrg file->line = 1; 2185dfecf96Smrg file->binary = (mode & BINARY_BIT) != 0; 2195dfecf96Smrg file->io_write = write; 2205dfecf96Smrg } 2215dfecf96Smrg 2225dfecf96Smrg return (file); 2235dfecf96Smrg} 2245dfecf96Smrg 2255dfecf96SmrgLispFile * 2265dfecf96SmrgLispFopen(char *path, int mode) 2275dfecf96Smrg{ 2285dfecf96Smrg LispFile *file; 2295dfecf96Smrg int descriptor; 2305dfecf96Smrg int flags = O_NOCTTY; 2315dfecf96Smrg 2325dfecf96Smrg /* check read/write attributes */ 2335dfecf96Smrg if ((mode & (READ_BIT | WRITE_BIT)) == (READ_BIT | WRITE_BIT)) 2345dfecf96Smrg flags |= O_RDWR; 2355dfecf96Smrg else if (mode & READ_BIT) 2365dfecf96Smrg flags |= O_RDONLY; 2375dfecf96Smrg else if (mode & WRITE_BIT) 2385dfecf96Smrg flags |= O_WRONLY; 2395dfecf96Smrg 2405dfecf96Smrg /* create if does not exist */ 2415dfecf96Smrg if (mode & WRITE_BIT) { 2425dfecf96Smrg flags |= O_CREAT; 2435dfecf96Smrg 2445dfecf96Smrg /* append if exists? */ 2455dfecf96Smrg if (mode & APPEND_BIT) 2465dfecf96Smrg flags |= O_APPEND; 2475dfecf96Smrg else 2485dfecf96Smrg flags |= O_TRUNC; 2495dfecf96Smrg } 2505dfecf96Smrg 2515dfecf96Smrg /* open file */ 2525dfecf96Smrg descriptor = open(path, flags, 0666); 2535dfecf96Smrg if (descriptor < 0) 2545dfecf96Smrg return (NULL); 2555dfecf96Smrg 2565dfecf96Smrg /* initialize LispFile structure */ 2575dfecf96Smrg file = LispFdopen(descriptor, mode); 2585dfecf96Smrg if (file == NULL) 2595dfecf96Smrg close(descriptor); 2605dfecf96Smrg 2615dfecf96Smrg return (file); 2625dfecf96Smrg} 2635dfecf96Smrg 2645dfecf96Smrgvoid 2655dfecf96SmrgLispFclose(LispFile *file) 2665dfecf96Smrg{ 2675dfecf96Smrg /* flush any pending output */ 2685dfecf96Smrg LispFflush(file); 2695dfecf96Smrg /* cleanup */ 2705dfecf96Smrg close(file->descriptor); 2715dfecf96Smrg if (file->buffer) 2725dfecf96Smrg free(file->buffer); 2735dfecf96Smrg free(file); 2745dfecf96Smrg} 2755dfecf96Smrg 2765dfecf96Smrgio_write_fn 2775dfecf96SmrgLispSetFileWrite(LispFile *file, io_write_fn new_write) 2785dfecf96Smrg{ 2795dfecf96Smrg io_write_fn old_write = file->io_write; 2805dfecf96Smrg 2815dfecf96Smrg file->io_write = new_write; 2825dfecf96Smrg 2835dfecf96Smrg return (old_write); 2845dfecf96Smrg} 2855dfecf96Smrg 2865dfecf96Smrgint 2875dfecf96SmrgLispFflush(LispFile *file) 2885dfecf96Smrg{ 2895dfecf96Smrg if (file->writable && file->length) { 2905dfecf96Smrg int length = (*file->io_write)(file->descriptor, 2915dfecf96Smrg file->buffer, file->length); 2925dfecf96Smrg 2935dfecf96Smrg if (length > 0) { 2945dfecf96Smrg if (file->length > length) 2955dfecf96Smrg memmove(file->buffer, file->buffer + length, 2965dfecf96Smrg file->length - length); 2975dfecf96Smrg file->length -= length; 2985dfecf96Smrg } 2995dfecf96Smrg return (length); 3005dfecf96Smrg } 3015dfecf96Smrg 3025dfecf96Smrg return (0); 3035dfecf96Smrg} 3045dfecf96Smrg 3055dfecf96Smrgint 3065dfecf96SmrgLispFungetc(LispFile *file, int ch) 3075dfecf96Smrg{ 3085dfecf96Smrg if (file->readable) { 3095dfecf96Smrg file->available = 1; 3105dfecf96Smrg file->unget = ch; 3115dfecf96Smrg /* this should never happen */ 3125dfecf96Smrg if (ch == '\n' && !file->binary) 3135dfecf96Smrg --file->line; 3145dfecf96Smrg } 3155dfecf96Smrg 3165dfecf96Smrg return (ch); 3175dfecf96Smrg} 3185dfecf96Smrg 3195dfecf96Smrgint 3205dfecf96SmrgLispFgetc(LispFile *file) 3215dfecf96Smrg{ 3225dfecf96Smrg int ch; 3235dfecf96Smrg 3245dfecf96Smrg if (file->readable) { 3255dfecf96Smrg unsigned char c; 3265dfecf96Smrg 3275dfecf96Smrg if (file->available) { 3285dfecf96Smrg ch = file->unget; 3295dfecf96Smrg file->available = 0; 3305dfecf96Smrg } 3315dfecf96Smrg else if (file->buffered) { 3325dfecf96Smrg if (file->writable) { 3335dfecf96Smrg LispFflush(file); 3345dfecf96Smrg if (read(file->descriptor, &c, 1) == 1) 3355dfecf96Smrg ch = c; 3365dfecf96Smrg else 3375dfecf96Smrg ch = EOF; 3385dfecf96Smrg } 3395dfecf96Smrg else { 3405dfecf96Smrg if (file->offset < file->length) 3415dfecf96Smrg ch = ((unsigned char*)file->buffer)[file->offset++]; 3425dfecf96Smrg else { 3435dfecf96Smrg int length = read(file->descriptor, 3445dfecf96Smrg file->buffer, pagesize); 3455dfecf96Smrg 3465dfecf96Smrg if (length >= 0) 3475dfecf96Smrg file->length = length; 3485dfecf96Smrg else 3495dfecf96Smrg file->length = 0; 3505dfecf96Smrg file->offset = 0; 3515dfecf96Smrg if (file->length) 3525dfecf96Smrg ch = ((unsigned char*)file->buffer)[file->offset++]; 3535dfecf96Smrg else 3545dfecf96Smrg ch = EOF; 3555dfecf96Smrg } 3565dfecf96Smrg } 3575dfecf96Smrg } 3585dfecf96Smrg else if (read(file->descriptor, &c, 1) == 1) 3595dfecf96Smrg ch = c; 3605dfecf96Smrg else 3615dfecf96Smrg ch = EOF; 3625dfecf96Smrg } 3635dfecf96Smrg else 3645dfecf96Smrg ch = EOF; 3655dfecf96Smrg 3665dfecf96Smrg if (ch == '\n' && !file->binary) 3675dfecf96Smrg ++file->line; 3685dfecf96Smrg 3695dfecf96Smrg return (ch); 3705dfecf96Smrg} 3715dfecf96Smrg 3725dfecf96Smrgint 3735dfecf96SmrgLispFputc(LispFile *file, int ch) 3745dfecf96Smrg{ 3755dfecf96Smrg if (file->writable) { 3765dfecf96Smrg unsigned char c = ch; 3775dfecf96Smrg 3785dfecf96Smrg if (file->buffered) { 3795dfecf96Smrg if (file->length + 1 >= pagesize) 3805dfecf96Smrg LispFflush(file); 3815dfecf96Smrg file->buffer[file->length++] = c; 3825dfecf96Smrg } 3835dfecf96Smrg else if ((*file->io_write)(file->descriptor, &c, 1) != 1) 3845dfecf96Smrg ch = EOF; 3855dfecf96Smrg 3865dfecf96Smrg if (!file->binary) { 3875dfecf96Smrg /* update column number */ 3885dfecf96Smrg if (ch == '\n') 3895dfecf96Smrg file->column = 0; 3905dfecf96Smrg else 3915dfecf96Smrg ++file->column; 3925dfecf96Smrg } 3935dfecf96Smrg } 3945dfecf96Smrg 3955dfecf96Smrg return (ch); 3965dfecf96Smrg} 3975dfecf96Smrg 3985dfecf96Smrgint 3995dfecf96SmrgLispSgetc(LispString *string) 4005dfecf96Smrg{ 4015dfecf96Smrg int ch; 4025dfecf96Smrg 4035dfecf96Smrg if (string->input >= string->length) 4045dfecf96Smrg return (EOF); /* EOF reading from string */ 4055dfecf96Smrg 4065dfecf96Smrg ch = ((unsigned char*)string->string)[string->input++]; 4075dfecf96Smrg if (ch == '\n' && !string->binary) 4085dfecf96Smrg ++string->line; 4095dfecf96Smrg 4105dfecf96Smrg return (ch); 4115dfecf96Smrg} 4125dfecf96Smrg 4135dfecf96Smrgint 4145dfecf96SmrgLispSputc(LispString *string, int ch) 4155dfecf96Smrg{ 4165dfecf96Smrg if (string->output + 1 >= string->space) { 4175dfecf96Smrg if (string->fixed) 4185dfecf96Smrg return (EOF); 4195dfecf96Smrg else { 4205dfecf96Smrg char *tmp = realloc(string->string, string->space + pagesize); 4215dfecf96Smrg 4225dfecf96Smrg if (tmp == NULL) 4235dfecf96Smrg return (EOF); 4245dfecf96Smrg string->string = tmp; 4255dfecf96Smrg string->space += pagesize; 4265dfecf96Smrg } 4275dfecf96Smrg } 4285dfecf96Smrg 4295dfecf96Smrg string->string[string->output++] = ch; 4305dfecf96Smrg if (string->length < string->output) 4315dfecf96Smrg string->length = string->output; 4325dfecf96Smrg 4335dfecf96Smrg /* update column number */ 4345dfecf96Smrg if (!string->binary) { 4355dfecf96Smrg if (ch == '\n') 4365dfecf96Smrg string->column = 0; 4375dfecf96Smrg else 4385dfecf96Smrg ++string->column; 4395dfecf96Smrg } 4405dfecf96Smrg 4415dfecf96Smrg return (ch); 4425dfecf96Smrg} 4435dfecf96Smrg 4445dfecf96Smrgchar * 4455dfecf96SmrgLispFgets(LispFile *file, char *string, int size) 4465dfecf96Smrg{ 4475dfecf96Smrg int ch, offset = 0; 4485dfecf96Smrg 4495dfecf96Smrg if (size < 1) 4505dfecf96Smrg return (string); 4515dfecf96Smrg 4525dfecf96Smrg for (;;) { 4535dfecf96Smrg if (offset + 1 >= size) 4545dfecf96Smrg break; 4555dfecf96Smrg if ((ch = LispFgetc(file)) == EOF) 4565dfecf96Smrg break; 4575dfecf96Smrg string[offset++] = ch; 4585dfecf96Smrg /* line number is calculated in LispFgetc */ 4595dfecf96Smrg if (ch == '\n') 4605dfecf96Smrg break; 4615dfecf96Smrg } 4625dfecf96Smrg string[offset] = '\0'; 4635dfecf96Smrg 4645dfecf96Smrg return (offset ? string : NULL); 4655dfecf96Smrg} 4665dfecf96Smrg 4675dfecf96Smrgint 4685dfecf96SmrgLispFputs(LispFile *file, char *buffer) 4695dfecf96Smrg{ 4705dfecf96Smrg return (LispFwrite(file, buffer, strlen(buffer))); 4715dfecf96Smrg} 4725dfecf96Smrg 4735dfecf96Smrgint 4745dfecf96SmrgLispSputs(LispString *string, char *buffer) 4755dfecf96Smrg{ 4765dfecf96Smrg return (LispSwrite(string, buffer, strlen(buffer))); 4775dfecf96Smrg} 4785dfecf96Smrg 4795dfecf96Smrgint 4805dfecf96SmrgLispFread(LispFile *file, void *data, int size) 4815dfecf96Smrg{ 4825dfecf96Smrg int bytes, length; 4835dfecf96Smrg char *buffer; 4845dfecf96Smrg 4855dfecf96Smrg if (!file->readable) 4865dfecf96Smrg return (EOF); 4875dfecf96Smrg 4885dfecf96Smrg if (size <= 0) 4895dfecf96Smrg return (size); 4905dfecf96Smrg 4915dfecf96Smrg length = 0; 4925dfecf96Smrg buffer = (char*)data; 4935dfecf96Smrg 4945dfecf96Smrg /* check if there is an unget character */ 4955dfecf96Smrg if (file->available) { 4965dfecf96Smrg *buffer++ = file->unget; 4975dfecf96Smrg file->available = 0; 4985dfecf96Smrg if (--size == 0) { 4995dfecf96Smrg if (file->unget == '\n' && !file->binary) 5005dfecf96Smrg ++file->line; 5015dfecf96Smrg 5025dfecf96Smrg return (1); 5035dfecf96Smrg } 5045dfecf96Smrg 5055dfecf96Smrg length = 1; 5065dfecf96Smrg } 5075dfecf96Smrg 5085dfecf96Smrg if (file->buffered) { 5095dfecf96Smrg void *base_data = (char*)data - length; 5105dfecf96Smrg 5115dfecf96Smrg if (file->writable) { 5125dfecf96Smrg LispFflush(file); 5135dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5145dfecf96Smrg if (bytes < 0) 5155dfecf96Smrg bytes = 0; 5165dfecf96Smrg if (!file->binary) 5175dfecf96Smrg file->line += calculate_line(base_data, length + bytes); 5185dfecf96Smrg 5195dfecf96Smrg return (length + bytes); 5205dfecf96Smrg } 5215dfecf96Smrg 5225dfecf96Smrg /* read anything that is in the buffer */ 5235dfecf96Smrg if (file->offset < file->length) { 5245dfecf96Smrg bytes = file->length - file->offset; 5255dfecf96Smrg if (bytes > size) 5265dfecf96Smrg bytes = size; 5275dfecf96Smrg memcpy(buffer, file->buffer + file->offset, bytes); 5285dfecf96Smrg buffer += bytes; 5295dfecf96Smrg file->offset += bytes; 5305dfecf96Smrg size -= bytes; 5315dfecf96Smrg } 5325dfecf96Smrg 5335dfecf96Smrg /* if there is still something to read */ 5345dfecf96Smrg if (size) { 5355dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5365dfecf96Smrg if (bytes < 0) 5375dfecf96Smrg bytes = 0; 5385dfecf96Smrg 5395dfecf96Smrg length += bytes; 5405dfecf96Smrg } 5415dfecf96Smrg 5425dfecf96Smrg if (!file->binary) 5435dfecf96Smrg file->line += calculate_line(base_data, length); 5445dfecf96Smrg 5455dfecf96Smrg return (length); 5465dfecf96Smrg } 5475dfecf96Smrg 5485dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5495dfecf96Smrg if (bytes < 0) 5505dfecf96Smrg bytes = 0; 5515dfecf96Smrg if (!file->binary) 5525dfecf96Smrg file->line += calculate_line(buffer - length, length + bytes); 5535dfecf96Smrg 5545dfecf96Smrg return (length + bytes); 5555dfecf96Smrg} 5565dfecf96Smrg 5575dfecf96Smrgint 5585dfecf96SmrgLispFwrite(LispFile *file, void *data, int size) 5595dfecf96Smrg{ 5605dfecf96Smrg if (!file->writable || size < 0) 5615dfecf96Smrg return (EOF); 5625dfecf96Smrg 5635dfecf96Smrg if (!file->binary) 5645dfecf96Smrg file->column = calculate_column(data, size, file->column); 5655dfecf96Smrg 5665dfecf96Smrg if (file->buffered) { 5675dfecf96Smrg int length, bytes; 5685dfecf96Smrg char *buffer = (char*)data; 5695dfecf96Smrg 5705dfecf96Smrg length = 0; 5715dfecf96Smrg if (size + file->length > pagesize) { 5725dfecf96Smrg /* fill remaining space in buffer and flush */ 5735dfecf96Smrg bytes = pagesize - file->length; 5745dfecf96Smrg memcpy(file->buffer + file->length, buffer, bytes); 5755dfecf96Smrg file->length += bytes; 5765dfecf96Smrg LispFflush(file); 5775dfecf96Smrg 5785dfecf96Smrg /* check if all data was written */ 5795dfecf96Smrg if (file->length) 5805dfecf96Smrg return (pagesize - file->length); 5815dfecf96Smrg 5825dfecf96Smrg length = bytes; 5835dfecf96Smrg buffer += bytes; 5845dfecf96Smrg size -= bytes; 5855dfecf96Smrg } 5865dfecf96Smrg 5875dfecf96Smrg while (size > pagesize) { 5885dfecf96Smrg /* write multiple of pagesize */ 5895dfecf96Smrg bytes = (*file->io_write)(file->descriptor, buffer, 5905dfecf96Smrg size - (size % pagesize)); 5915dfecf96Smrg if (bytes <= 0) 5925dfecf96Smrg return (length); 5935dfecf96Smrg 5945dfecf96Smrg length += bytes; 5955dfecf96Smrg buffer += bytes; 5965dfecf96Smrg size -= bytes; 5975dfecf96Smrg } 5985dfecf96Smrg 5995dfecf96Smrg if (size) { 6005dfecf96Smrg /* keep remaining data in buffer */ 6015dfecf96Smrg switch (size) { 6025dfecf96Smrg case 8: 6035dfecf96Smrg file->buffer[file->length++] = *buffer++; 6045dfecf96Smrg case 7: 6055dfecf96Smrg file->buffer[file->length++] = *buffer++; 6065dfecf96Smrg case 6: 6075dfecf96Smrg file->buffer[file->length++] = *buffer++; 6085dfecf96Smrg case 5: 6095dfecf96Smrg file->buffer[file->length++] = *buffer++; 6105dfecf96Smrg case 4: 6115dfecf96Smrg file->buffer[file->length++] = *buffer++; 6125dfecf96Smrg case 3: 6135dfecf96Smrg file->buffer[file->length++] = *buffer++; 6145dfecf96Smrg case 2: 6155dfecf96Smrg file->buffer[file->length++] = *buffer++; 6165dfecf96Smrg case 1: 6175dfecf96Smrg file->buffer[file->length++] = *buffer++; 6185dfecf96Smrg break; 6195dfecf96Smrg default: 6205dfecf96Smrg memcpy(file->buffer + file->length, buffer, size); 6215dfecf96Smrg file->length += size; 6225dfecf96Smrg break; 6235dfecf96Smrg } 6245dfecf96Smrg length += size; 6255dfecf96Smrg } 6265dfecf96Smrg 6275dfecf96Smrg return (length); 6285dfecf96Smrg } 6295dfecf96Smrg 6305dfecf96Smrg return ((*file->io_write)(file->descriptor, data, size)); 6315dfecf96Smrg} 6325dfecf96Smrg 6335dfecf96Smrgint 6345dfecf96SmrgLispSwrite(LispString *string, void *data, int size) 6355dfecf96Smrg{ 636f14f4646Smrg int bytes; 637f14f4646Smrg 6385dfecf96Smrg if (size < 0) 6395dfecf96Smrg return (EOF); 6405dfecf96Smrg 6415dfecf96Smrg if (string->output + size >= string->space) { 6425dfecf96Smrg if (string->fixed) { 6435dfecf96Smrg /* leave space for a ending nul character */ 644f14f4646Smrg bytes = string->space - string->output - 1; 645f14f4646Smrg 646f14f4646Smrg if (bytes < size) 647f14f4646Smrg size = bytes; 6485dfecf96Smrg 6495dfecf96Smrg if (size <= 0) 6505dfecf96Smrg return (-1); 6515dfecf96Smrg } 6525dfecf96Smrg else { 653f14f4646Smrg char *tmp; 654f14f4646Smrg 655f14f4646Smrg bytes = string->space + size; 656f14f4646Smrg bytes += pagesize - (bytes % pagesize); 657f14f4646Smrg tmp = realloc(string->string, bytes); 6585dfecf96Smrg 6595dfecf96Smrg if (tmp == NULL) 6605dfecf96Smrg return (-1); 6615dfecf96Smrg 6625dfecf96Smrg string->string = tmp; 663f14f4646Smrg string->space = bytes; 6645dfecf96Smrg } 6655dfecf96Smrg } 6665dfecf96Smrg memcpy(string->string + string->output, data, size); 6675dfecf96Smrg string->output += size; 6685dfecf96Smrg if (string->length < string->output) 6695dfecf96Smrg string->length = string->output; 6705dfecf96Smrg 6715dfecf96Smrg if (!string->binary) 6725dfecf96Smrg string->column = calculate_column(data, size, string->column); 6735dfecf96Smrg 6745dfecf96Smrg return (size); 6755dfecf96Smrg} 6765dfecf96Smrg 6775dfecf96Smrgchar * 6785dfecf96SmrgLispGetSstring(LispString *string, int *length) 6795dfecf96Smrg{ 6805dfecf96Smrg if (string->string == NULL || string->length <= 0) { 6815dfecf96Smrg *length = 0; 6825dfecf96Smrg 6835dfecf96Smrg return (""); 6845dfecf96Smrg } 6855dfecf96Smrg *length = string->length; 6865dfecf96Smrg if (string->string[string->length -1] != '\0') { 6875dfecf96Smrg if (string->length < string->space) 6885dfecf96Smrg string->string[string->length] = '\0'; 6895dfecf96Smrg else if (string->fixed && string->space) 6905dfecf96Smrg string->string[string->space - 1] = '\0'; 6915dfecf96Smrg else { 6925dfecf96Smrg char *tmp = realloc(string->string, string->space + pagesize); 6935dfecf96Smrg 6945dfecf96Smrg if (tmp == NULL) 6955dfecf96Smrg string->string[string->space - 1] = '\0'; 6965dfecf96Smrg else { 6975dfecf96Smrg string->string = tmp; 6985dfecf96Smrg string->space += pagesize; 6995dfecf96Smrg string->string[string->length] = '\0'; 7005dfecf96Smrg } 7015dfecf96Smrg } 7025dfecf96Smrg } 7035dfecf96Smrg 7045dfecf96Smrg return (string->string); 7055dfecf96Smrg} 7065dfecf96Smrg 7075dfecf96Smrgint 7085dfecf96SmrgLispRename(char *from, char *to) 7095dfecf96Smrg{ 7105dfecf96Smrg return (rename(from, to)); 7115dfecf96Smrg} 7125dfecf96Smrg 7135dfecf96Smrgint 7145dfecf96SmrgLispUnlink(char *name) 7155dfecf96Smrg{ 7165dfecf96Smrg return (unlink(name)); 7175dfecf96Smrg} 718