io.c revision c05e22d7
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 110c05e22d7Smrg if ((ch & 0xff) == ch) { 111c05e22d7Smrg if (unget->offset == sizeof(unget->buffer)) { 112c05e22d7Smrg LispWarning("character %c lost at LispUnget()", unget->buffer[0]); 113c05e22d7Smrg memmove(unget->buffer, unget->buffer + 1, unget->offset - 1); 114c05e22d7Smrg unget->buffer[unget->offset - 1] = ch; 115c05e22d7Smrg } 116c05e22d7Smrg else 117c05e22d7Smrg unget->buffer[unget->offset++] = ch; 1185dfecf96Smrg } 1195dfecf96Smrg 1205dfecf96Smrg return (ch); 1215dfecf96Smrg} 1225dfecf96Smrg 1235dfecf96Smrgvoid 1245dfecf96SmrgLispPushInput(LispObj *stream) 1255dfecf96Smrg{ 1265dfecf96Smrg if (!STREAMP(stream) || !stream->data.stream.readable) 1275dfecf96Smrg LispDestroy("bad stream at PUSH-INPUT"); 1285dfecf96Smrg lisp__data.input_list = CONS(stream, lisp__data.input_list); 1295dfecf96Smrg SINPUT = stream; 1305dfecf96Smrg if (lisp__data.iunget + 1 == lisp__data.nunget) { 1315dfecf96Smrg LispUngetInfo **info = 1325dfecf96Smrg realloc(lisp__data.unget, 1335dfecf96Smrg sizeof(LispUngetInfo) * (lisp__data.nunget + 1)); 1345dfecf96Smrg 1355dfecf96Smrg if (!info || 1365dfecf96Smrg (info[lisp__data.nunget] = 1375dfecf96Smrg calloc(1, sizeof(LispUngetInfo))) == NULL) 1385dfecf96Smrg LispDestroy("out of memory"); 1395dfecf96Smrg lisp__data.unget = info; 1405dfecf96Smrg ++lisp__data.nunget; 1415dfecf96Smrg } 1425dfecf96Smrg ++lisp__data.iunget; 1435dfecf96Smrg memset(lisp__data.unget[lisp__data.iunget], '\0', sizeof(LispUngetInfo)); 1445dfecf96Smrg lisp__data.eof = 0; 1455dfecf96Smrg} 1465dfecf96Smrg 1475dfecf96Smrgvoid 1485dfecf96SmrgLispPopInput(LispObj *stream) 1495dfecf96Smrg{ 1505dfecf96Smrg if (!CONSP(lisp__data.input_list) || stream != CAR(lisp__data.input_list)) 1515dfecf96Smrg LispDestroy("bad stream at POP-INPUT"); 1525dfecf96Smrg lisp__data.input_list = CDR(lisp__data.input_list); 1535dfecf96Smrg SINPUT = CONSP(lisp__data.input_list) ? 1545dfecf96Smrg CAR(lisp__data.input_list) : lisp__data.input_list; 1555dfecf96Smrg --lisp__data.iunget; 1565dfecf96Smrg lisp__data.eof = 0; 1575dfecf96Smrg} 1585dfecf96Smrg 1595dfecf96Smrg/* 1605dfecf96Smrg * Low level functions 1615dfecf96Smrg */ 1625dfecf96Smrgstatic int 1635dfecf96Smrgcalculate_line(void *data, int size) 1645dfecf96Smrg{ 1655dfecf96Smrg int line = 0; 1665dfecf96Smrg char *str, *ptr; 1675dfecf96Smrg 1685dfecf96Smrg for (str = (char*)data, ptr = (char*)data + size; str < ptr; str++) 1695dfecf96Smrg if (*ptr == '\n') 1705dfecf96Smrg ++line; 1715dfecf96Smrg 1725dfecf96Smrg return (line); 1735dfecf96Smrg} 1745dfecf96Smrg 1755dfecf96Smrgstatic int 1765dfecf96Smrgcalculate_column(void *data, int size, int column) 1775dfecf96Smrg{ 1785dfecf96Smrg char *str, *ptr; 1795dfecf96Smrg 1805dfecf96Smrg /* search for newline in data */ 1815dfecf96Smrg for (str = (char*)data, ptr = (char*)data + size - 1; ptr >= str; ptr--) 1825dfecf96Smrg if (*ptr == '\n') 1835dfecf96Smrg break; 1845dfecf96Smrg 1855dfecf96Smrg /* newline found */ 1865dfecf96Smrg if (ptr >= str) 1875dfecf96Smrg return (size - (ptr - str) - 1); 1885dfecf96Smrg 1895dfecf96Smrg /* newline not found */ 1905dfecf96Smrg return (column + size); 1915dfecf96Smrg} 1925dfecf96Smrg 1935dfecf96SmrgLispFile * 1945dfecf96SmrgLispFdopen(int descriptor, int mode) 1955dfecf96Smrg{ 1965dfecf96Smrg LispFile *file = calloc(1, sizeof(LispFile)); 1975dfecf96Smrg 1985dfecf96Smrg if (file) { 1995dfecf96Smrg struct stat st; 2005dfecf96Smrg 2015dfecf96Smrg file->descriptor = descriptor; 2025dfecf96Smrg file->readable = (mode & READ_BIT) != 0; 2035dfecf96Smrg file->writable = (mode & WRITE_BIT) != 0; 2045dfecf96Smrg 2055dfecf96Smrg if (fstat(descriptor, &st) == 0) 2065dfecf96Smrg file->regular = S_ISREG(st.st_mode); 2075dfecf96Smrg else 2085dfecf96Smrg file->regular = 0; 2095dfecf96Smrg 2105dfecf96Smrg file->buffered = (mode & BUFFERED_BIT) != 0; 2115dfecf96Smrg if ((mode & UNBUFFERED_BIT) == 0) 2125dfecf96Smrg file->buffered = file->regular; 2135dfecf96Smrg 2145dfecf96Smrg if (file->buffered) { 2155dfecf96Smrg file->buffer = malloc(pagesize); 2165dfecf96Smrg if (file->buffer == NULL) 2175dfecf96Smrg file->buffered = 0; 2185dfecf96Smrg } 2195dfecf96Smrg file->line = 1; 2205dfecf96Smrg file->binary = (mode & BINARY_BIT) != 0; 2215dfecf96Smrg file->io_write = write; 2225dfecf96Smrg } 2235dfecf96Smrg 2245dfecf96Smrg return (file); 2255dfecf96Smrg} 2265dfecf96Smrg 2275dfecf96SmrgLispFile * 2285dfecf96SmrgLispFopen(char *path, int mode) 2295dfecf96Smrg{ 2305dfecf96Smrg LispFile *file; 2315dfecf96Smrg int descriptor; 2325dfecf96Smrg int flags = O_NOCTTY; 2335dfecf96Smrg 2345dfecf96Smrg /* check read/write attributes */ 2355dfecf96Smrg if ((mode & (READ_BIT | WRITE_BIT)) == (READ_BIT | WRITE_BIT)) 2365dfecf96Smrg flags |= O_RDWR; 2375dfecf96Smrg else if (mode & READ_BIT) 2385dfecf96Smrg flags |= O_RDONLY; 2395dfecf96Smrg else if (mode & WRITE_BIT) 2405dfecf96Smrg flags |= O_WRONLY; 2415dfecf96Smrg 2425dfecf96Smrg /* create if does not exist */ 2435dfecf96Smrg if (mode & WRITE_BIT) { 2445dfecf96Smrg flags |= O_CREAT; 2455dfecf96Smrg 2465dfecf96Smrg /* append if exists? */ 2475dfecf96Smrg if (mode & APPEND_BIT) 2485dfecf96Smrg flags |= O_APPEND; 2495dfecf96Smrg else 2505dfecf96Smrg flags |= O_TRUNC; 2515dfecf96Smrg } 2525dfecf96Smrg 2535dfecf96Smrg /* open file */ 2545dfecf96Smrg descriptor = open(path, flags, 0666); 2555dfecf96Smrg if (descriptor < 0) 2565dfecf96Smrg return (NULL); 2575dfecf96Smrg 2585dfecf96Smrg /* initialize LispFile structure */ 2595dfecf96Smrg file = LispFdopen(descriptor, mode); 2605dfecf96Smrg if (file == NULL) 2615dfecf96Smrg close(descriptor); 2625dfecf96Smrg 2635dfecf96Smrg return (file); 2645dfecf96Smrg} 2655dfecf96Smrg 2665dfecf96Smrgvoid 2675dfecf96SmrgLispFclose(LispFile *file) 2685dfecf96Smrg{ 2695dfecf96Smrg /* flush any pending output */ 2705dfecf96Smrg LispFflush(file); 2715dfecf96Smrg /* cleanup */ 2725dfecf96Smrg close(file->descriptor); 2735dfecf96Smrg if (file->buffer) 2745dfecf96Smrg free(file->buffer); 2755dfecf96Smrg free(file); 2765dfecf96Smrg} 2775dfecf96Smrg 2785dfecf96Smrgio_write_fn 2795dfecf96SmrgLispSetFileWrite(LispFile *file, io_write_fn new_write) 2805dfecf96Smrg{ 2815dfecf96Smrg io_write_fn old_write = file->io_write; 2825dfecf96Smrg 2835dfecf96Smrg file->io_write = new_write; 2845dfecf96Smrg 2855dfecf96Smrg return (old_write); 2865dfecf96Smrg} 2875dfecf96Smrg 2885dfecf96Smrgint 2895dfecf96SmrgLispFflush(LispFile *file) 2905dfecf96Smrg{ 2915dfecf96Smrg if (file->writable && file->length) { 2925dfecf96Smrg int length = (*file->io_write)(file->descriptor, 2935dfecf96Smrg file->buffer, file->length); 2945dfecf96Smrg 2955dfecf96Smrg if (length > 0) { 2965dfecf96Smrg if (file->length > length) 2975dfecf96Smrg memmove(file->buffer, file->buffer + length, 2985dfecf96Smrg file->length - length); 2995dfecf96Smrg file->length -= length; 3005dfecf96Smrg } 3015dfecf96Smrg return (length); 3025dfecf96Smrg } 3035dfecf96Smrg 3045dfecf96Smrg return (0); 3055dfecf96Smrg} 3065dfecf96Smrg 3075dfecf96Smrgint 3085dfecf96SmrgLispFungetc(LispFile *file, int ch) 3095dfecf96Smrg{ 3105dfecf96Smrg if (file->readable) { 3115dfecf96Smrg file->available = 1; 3125dfecf96Smrg file->unget = ch; 3135dfecf96Smrg /* this should never happen */ 3145dfecf96Smrg if (ch == '\n' && !file->binary) 3155dfecf96Smrg --file->line; 3165dfecf96Smrg } 3175dfecf96Smrg 3185dfecf96Smrg return (ch); 3195dfecf96Smrg} 3205dfecf96Smrg 3215dfecf96Smrgint 3225dfecf96SmrgLispFgetc(LispFile *file) 3235dfecf96Smrg{ 3245dfecf96Smrg int ch; 3255dfecf96Smrg 3265dfecf96Smrg if (file->readable) { 3275dfecf96Smrg unsigned char c; 3285dfecf96Smrg 3295dfecf96Smrg if (file->available) { 3305dfecf96Smrg ch = file->unget; 3315dfecf96Smrg file->available = 0; 3325dfecf96Smrg } 3335dfecf96Smrg else if (file->buffered) { 3345dfecf96Smrg if (file->writable) { 3355dfecf96Smrg LispFflush(file); 3365dfecf96Smrg if (read(file->descriptor, &c, 1) == 1) 3375dfecf96Smrg ch = c; 3385dfecf96Smrg else 3395dfecf96Smrg ch = EOF; 3405dfecf96Smrg } 3415dfecf96Smrg else { 3425dfecf96Smrg if (file->offset < file->length) 3435dfecf96Smrg ch = ((unsigned char*)file->buffer)[file->offset++]; 3445dfecf96Smrg else { 3455dfecf96Smrg int length = read(file->descriptor, 3465dfecf96Smrg file->buffer, pagesize); 3475dfecf96Smrg 3485dfecf96Smrg if (length >= 0) 3495dfecf96Smrg file->length = length; 3505dfecf96Smrg else 3515dfecf96Smrg file->length = 0; 3525dfecf96Smrg file->offset = 0; 3535dfecf96Smrg if (file->length) 3545dfecf96Smrg ch = ((unsigned char*)file->buffer)[file->offset++]; 3555dfecf96Smrg else 3565dfecf96Smrg ch = EOF; 3575dfecf96Smrg } 3585dfecf96Smrg } 3595dfecf96Smrg } 3605dfecf96Smrg else if (read(file->descriptor, &c, 1) == 1) 3615dfecf96Smrg ch = c; 3625dfecf96Smrg else 3635dfecf96Smrg ch = EOF; 3645dfecf96Smrg } 3655dfecf96Smrg else 3665dfecf96Smrg ch = EOF; 3675dfecf96Smrg 3685dfecf96Smrg if (ch == '\n' && !file->binary) 3695dfecf96Smrg ++file->line; 3705dfecf96Smrg 3715dfecf96Smrg return (ch); 3725dfecf96Smrg} 3735dfecf96Smrg 3745dfecf96Smrgint 3755dfecf96SmrgLispFputc(LispFile *file, int ch) 3765dfecf96Smrg{ 3775dfecf96Smrg if (file->writable) { 3785dfecf96Smrg unsigned char c = ch; 3795dfecf96Smrg 3805dfecf96Smrg if (file->buffered) { 3815dfecf96Smrg if (file->length + 1 >= pagesize) 3825dfecf96Smrg LispFflush(file); 3835dfecf96Smrg file->buffer[file->length++] = c; 3845dfecf96Smrg } 3855dfecf96Smrg else if ((*file->io_write)(file->descriptor, &c, 1) != 1) 3865dfecf96Smrg ch = EOF; 3875dfecf96Smrg 3885dfecf96Smrg if (!file->binary) { 3895dfecf96Smrg /* update column number */ 3905dfecf96Smrg if (ch == '\n') 3915dfecf96Smrg file->column = 0; 3925dfecf96Smrg else 3935dfecf96Smrg ++file->column; 3945dfecf96Smrg } 3955dfecf96Smrg } 3965dfecf96Smrg 3975dfecf96Smrg return (ch); 3985dfecf96Smrg} 3995dfecf96Smrg 4005dfecf96Smrgint 4015dfecf96SmrgLispSgetc(LispString *string) 4025dfecf96Smrg{ 4035dfecf96Smrg int ch; 4045dfecf96Smrg 4055dfecf96Smrg if (string->input >= string->length) 4065dfecf96Smrg return (EOF); /* EOF reading from string */ 4075dfecf96Smrg 4085dfecf96Smrg ch = ((unsigned char*)string->string)[string->input++]; 4095dfecf96Smrg if (ch == '\n' && !string->binary) 4105dfecf96Smrg ++string->line; 4115dfecf96Smrg 4125dfecf96Smrg return (ch); 4135dfecf96Smrg} 4145dfecf96Smrg 4155dfecf96Smrgint 4165dfecf96SmrgLispSputc(LispString *string, int ch) 4175dfecf96Smrg{ 4185dfecf96Smrg if (string->output + 1 >= string->space) { 4195dfecf96Smrg if (string->fixed) 4205dfecf96Smrg return (EOF); 4215dfecf96Smrg else { 4225dfecf96Smrg char *tmp = realloc(string->string, string->space + pagesize); 4235dfecf96Smrg 4245dfecf96Smrg if (tmp == NULL) 4255dfecf96Smrg return (EOF); 4265dfecf96Smrg string->string = tmp; 4275dfecf96Smrg string->space += pagesize; 4285dfecf96Smrg } 4295dfecf96Smrg } 4305dfecf96Smrg 4315dfecf96Smrg string->string[string->output++] = ch; 4325dfecf96Smrg if (string->length < string->output) 4335dfecf96Smrg string->length = string->output; 4345dfecf96Smrg 4355dfecf96Smrg /* update column number */ 4365dfecf96Smrg if (!string->binary) { 4375dfecf96Smrg if (ch == '\n') 4385dfecf96Smrg string->column = 0; 4395dfecf96Smrg else 4405dfecf96Smrg ++string->column; 4415dfecf96Smrg } 4425dfecf96Smrg 4435dfecf96Smrg return (ch); 4445dfecf96Smrg} 4455dfecf96Smrg 4465dfecf96Smrgchar * 4475dfecf96SmrgLispFgets(LispFile *file, char *string, int size) 4485dfecf96Smrg{ 4495dfecf96Smrg int ch, offset = 0; 4505dfecf96Smrg 4515dfecf96Smrg if (size < 1) 4525dfecf96Smrg return (string); 4535dfecf96Smrg 4545dfecf96Smrg for (;;) { 4555dfecf96Smrg if (offset + 1 >= size) 4565dfecf96Smrg break; 4575dfecf96Smrg if ((ch = LispFgetc(file)) == EOF) 4585dfecf96Smrg break; 4595dfecf96Smrg string[offset++] = ch; 4605dfecf96Smrg /* line number is calculated in LispFgetc */ 4615dfecf96Smrg if (ch == '\n') 4625dfecf96Smrg break; 4635dfecf96Smrg } 4645dfecf96Smrg string[offset] = '\0'; 4655dfecf96Smrg 4665dfecf96Smrg return (offset ? string : NULL); 4675dfecf96Smrg} 4685dfecf96Smrg 4695dfecf96Smrgint 4705dfecf96SmrgLispFputs(LispFile *file, char *buffer) 4715dfecf96Smrg{ 4725dfecf96Smrg return (LispFwrite(file, buffer, strlen(buffer))); 4735dfecf96Smrg} 4745dfecf96Smrg 4755dfecf96Smrgint 4765dfecf96SmrgLispSputs(LispString *string, char *buffer) 4775dfecf96Smrg{ 4785dfecf96Smrg return (LispSwrite(string, buffer, strlen(buffer))); 4795dfecf96Smrg} 4805dfecf96Smrg 4815dfecf96Smrgint 4825dfecf96SmrgLispFread(LispFile *file, void *data, int size) 4835dfecf96Smrg{ 4845dfecf96Smrg int bytes, length; 4855dfecf96Smrg char *buffer; 4865dfecf96Smrg 4875dfecf96Smrg if (!file->readable) 4885dfecf96Smrg return (EOF); 4895dfecf96Smrg 4905dfecf96Smrg if (size <= 0) 4915dfecf96Smrg return (size); 4925dfecf96Smrg 4935dfecf96Smrg length = 0; 4945dfecf96Smrg buffer = (char*)data; 4955dfecf96Smrg 4965dfecf96Smrg /* check if there is an unget character */ 4975dfecf96Smrg if (file->available) { 4985dfecf96Smrg *buffer++ = file->unget; 4995dfecf96Smrg file->available = 0; 5005dfecf96Smrg if (--size == 0) { 5015dfecf96Smrg if (file->unget == '\n' && !file->binary) 5025dfecf96Smrg ++file->line; 5035dfecf96Smrg 5045dfecf96Smrg return (1); 5055dfecf96Smrg } 5065dfecf96Smrg 5075dfecf96Smrg length = 1; 5085dfecf96Smrg } 5095dfecf96Smrg 5105dfecf96Smrg if (file->buffered) { 5115dfecf96Smrg void *base_data = (char*)data - length; 5125dfecf96Smrg 5135dfecf96Smrg if (file->writable) { 5145dfecf96Smrg LispFflush(file); 5155dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5165dfecf96Smrg if (bytes < 0) 5175dfecf96Smrg bytes = 0; 5185dfecf96Smrg if (!file->binary) 5195dfecf96Smrg file->line += calculate_line(base_data, length + bytes); 5205dfecf96Smrg 5215dfecf96Smrg return (length + bytes); 5225dfecf96Smrg } 5235dfecf96Smrg 5245dfecf96Smrg /* read anything that is in the buffer */ 5255dfecf96Smrg if (file->offset < file->length) { 5265dfecf96Smrg bytes = file->length - file->offset; 5275dfecf96Smrg if (bytes > size) 5285dfecf96Smrg bytes = size; 5295dfecf96Smrg memcpy(buffer, file->buffer + file->offset, bytes); 5305dfecf96Smrg buffer += bytes; 5315dfecf96Smrg file->offset += bytes; 5325dfecf96Smrg size -= bytes; 5335dfecf96Smrg } 5345dfecf96Smrg 5355dfecf96Smrg /* if there is still something to read */ 5365dfecf96Smrg if (size) { 5375dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5385dfecf96Smrg if (bytes < 0) 5395dfecf96Smrg bytes = 0; 5405dfecf96Smrg 5415dfecf96Smrg length += bytes; 5425dfecf96Smrg } 5435dfecf96Smrg 5445dfecf96Smrg if (!file->binary) 5455dfecf96Smrg file->line += calculate_line(base_data, length); 5465dfecf96Smrg 5475dfecf96Smrg return (length); 5485dfecf96Smrg } 5495dfecf96Smrg 5505dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5515dfecf96Smrg if (bytes < 0) 5525dfecf96Smrg bytes = 0; 5535dfecf96Smrg if (!file->binary) 5545dfecf96Smrg file->line += calculate_line(buffer - length, length + bytes); 5555dfecf96Smrg 5565dfecf96Smrg return (length + bytes); 5575dfecf96Smrg} 5585dfecf96Smrg 5595dfecf96Smrgint 5605dfecf96SmrgLispFwrite(LispFile *file, void *data, int size) 5615dfecf96Smrg{ 5625dfecf96Smrg if (!file->writable || size < 0) 5635dfecf96Smrg return (EOF); 5645dfecf96Smrg 5655dfecf96Smrg if (!file->binary) 5665dfecf96Smrg file->column = calculate_column(data, size, file->column); 5675dfecf96Smrg 5685dfecf96Smrg if (file->buffered) { 5695dfecf96Smrg int length, bytes; 5705dfecf96Smrg char *buffer = (char*)data; 5715dfecf96Smrg 5725dfecf96Smrg length = 0; 5735dfecf96Smrg if (size + file->length > pagesize) { 5745dfecf96Smrg /* fill remaining space in buffer and flush */ 5755dfecf96Smrg bytes = pagesize - file->length; 5765dfecf96Smrg memcpy(file->buffer + file->length, buffer, bytes); 5775dfecf96Smrg file->length += bytes; 5785dfecf96Smrg LispFflush(file); 5795dfecf96Smrg 5805dfecf96Smrg /* check if all data was written */ 5815dfecf96Smrg if (file->length) 5825dfecf96Smrg return (pagesize - file->length); 5835dfecf96Smrg 5845dfecf96Smrg length = bytes; 5855dfecf96Smrg buffer += bytes; 5865dfecf96Smrg size -= bytes; 5875dfecf96Smrg } 5885dfecf96Smrg 5895dfecf96Smrg while (size > pagesize) { 5905dfecf96Smrg /* write multiple of pagesize */ 5915dfecf96Smrg bytes = (*file->io_write)(file->descriptor, buffer, 5925dfecf96Smrg size - (size % pagesize)); 5935dfecf96Smrg if (bytes <= 0) 5945dfecf96Smrg return (length); 5955dfecf96Smrg 5965dfecf96Smrg length += bytes; 5975dfecf96Smrg buffer += bytes; 5985dfecf96Smrg size -= bytes; 5995dfecf96Smrg } 6005dfecf96Smrg 6015dfecf96Smrg if (size) { 6025dfecf96Smrg /* keep remaining data in buffer */ 6035dfecf96Smrg switch (size) { 6045dfecf96Smrg case 8: 6055dfecf96Smrg file->buffer[file->length++] = *buffer++; 6065dfecf96Smrg case 7: 6075dfecf96Smrg file->buffer[file->length++] = *buffer++; 6085dfecf96Smrg case 6: 6095dfecf96Smrg file->buffer[file->length++] = *buffer++; 6105dfecf96Smrg case 5: 6115dfecf96Smrg file->buffer[file->length++] = *buffer++; 6125dfecf96Smrg case 4: 6135dfecf96Smrg file->buffer[file->length++] = *buffer++; 6145dfecf96Smrg case 3: 6155dfecf96Smrg file->buffer[file->length++] = *buffer++; 6165dfecf96Smrg case 2: 6175dfecf96Smrg file->buffer[file->length++] = *buffer++; 6185dfecf96Smrg case 1: 6195dfecf96Smrg file->buffer[file->length++] = *buffer++; 6205dfecf96Smrg break; 6215dfecf96Smrg default: 6225dfecf96Smrg memcpy(file->buffer + file->length, buffer, size); 6235dfecf96Smrg file->length += size; 6245dfecf96Smrg break; 6255dfecf96Smrg } 6265dfecf96Smrg length += size; 6275dfecf96Smrg } 6285dfecf96Smrg 6295dfecf96Smrg return (length); 6305dfecf96Smrg } 6315dfecf96Smrg 6325dfecf96Smrg return ((*file->io_write)(file->descriptor, data, size)); 6335dfecf96Smrg} 6345dfecf96Smrg 6355dfecf96Smrgint 6365dfecf96SmrgLispSwrite(LispString *string, void *data, int size) 6375dfecf96Smrg{ 638f14f4646Smrg int bytes; 639f14f4646Smrg 6405dfecf96Smrg if (size < 0) 6415dfecf96Smrg return (EOF); 6425dfecf96Smrg 6435dfecf96Smrg if (string->output + size >= string->space) { 6445dfecf96Smrg if (string->fixed) { 6455dfecf96Smrg /* leave space for a ending nul character */ 646f14f4646Smrg bytes = string->space - string->output - 1; 647f14f4646Smrg 648f14f4646Smrg if (bytes < size) 649f14f4646Smrg size = bytes; 6505dfecf96Smrg 6515dfecf96Smrg if (size <= 0) 6525dfecf96Smrg return (-1); 6535dfecf96Smrg } 6545dfecf96Smrg else { 655f14f4646Smrg char *tmp; 656f14f4646Smrg 657f14f4646Smrg bytes = string->space + size; 658f14f4646Smrg bytes += pagesize - (bytes % pagesize); 659f14f4646Smrg tmp = realloc(string->string, bytes); 6605dfecf96Smrg 6615dfecf96Smrg if (tmp == NULL) 6625dfecf96Smrg return (-1); 6635dfecf96Smrg 6645dfecf96Smrg string->string = tmp; 665f14f4646Smrg string->space = bytes; 6665dfecf96Smrg } 6675dfecf96Smrg } 6685dfecf96Smrg memcpy(string->string + string->output, data, size); 6695dfecf96Smrg string->output += size; 6705dfecf96Smrg if (string->length < string->output) 6715dfecf96Smrg string->length = string->output; 6725dfecf96Smrg 6735dfecf96Smrg if (!string->binary) 6745dfecf96Smrg string->column = calculate_column(data, size, string->column); 6755dfecf96Smrg 6765dfecf96Smrg return (size); 6775dfecf96Smrg} 6785dfecf96Smrg 6795dfecf96Smrgchar * 6805dfecf96SmrgLispGetSstring(LispString *string, int *length) 6815dfecf96Smrg{ 6825dfecf96Smrg if (string->string == NULL || string->length <= 0) { 6835dfecf96Smrg *length = 0; 6845dfecf96Smrg 6855dfecf96Smrg return (""); 6865dfecf96Smrg } 6875dfecf96Smrg *length = string->length; 6885dfecf96Smrg if (string->string[string->length -1] != '\0') { 6895dfecf96Smrg if (string->length < string->space) 6905dfecf96Smrg string->string[string->length] = '\0'; 6915dfecf96Smrg else if (string->fixed && string->space) 6925dfecf96Smrg string->string[string->space - 1] = '\0'; 6935dfecf96Smrg else { 6945dfecf96Smrg char *tmp = realloc(string->string, string->space + pagesize); 6955dfecf96Smrg 6965dfecf96Smrg if (tmp == NULL) 6975dfecf96Smrg string->string[string->space - 1] = '\0'; 6985dfecf96Smrg else { 6995dfecf96Smrg string->string = tmp; 7005dfecf96Smrg string->space += pagesize; 7015dfecf96Smrg string->string[string->length] = '\0'; 7025dfecf96Smrg } 7035dfecf96Smrg } 7045dfecf96Smrg } 7055dfecf96Smrg 7065dfecf96Smrg return (string->string); 7075dfecf96Smrg} 7085dfecf96Smrg 7095dfecf96Smrgint 7105dfecf96SmrgLispRename(char *from, char *to) 7115dfecf96Smrg{ 7125dfecf96Smrg return (rename(from, to)); 7135dfecf96Smrg} 7145dfecf96Smrg 7155dfecf96Smrgint 7165dfecf96SmrgLispUnlink(char *name) 7175dfecf96Smrg{ 7185dfecf96Smrg return (unlink(name)); 7195dfecf96Smrg} 720