1 #if	!defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: fileio.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
3 #endif
4 
5 /*
6  * ========================================================================
7  * Copyright 2006 University of Washington
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * ========================================================================
16  *
17  * Program:	file reading routines
18  *
19  */
20 
21 /*
22  * The routines in this file read and write ASCII files from the disk. All of
23  * the knowledge about files are here. A better message writing scheme should
24  * be used.
25  */
26 #include	"headers.h"
27 #include	"../pith/charconv/filesys.h"
28 
29 
30 #if	defined(bsd) || defined(lnx)
31 extern int errno;
32 #endif
33 
34 
35 
36 FIOINFO	g_pico_fio;
37 
38 /*
39  * Open a file for reading.
40  */
41 int
ffropen(char * fn)42 ffropen(char *fn)
43 {
44     int status;
45 
46     if ((status = fexist(g_pico_fio.name = fn, "r", (off_t *)NULL)) == FIOSUC){
47 	g_pico_fio.flags = FIOINFO_READ;
48 	if((g_pico_fio.fp = our_fopen(g_pico_fio.name, "r")) == NULL)
49 	  status = FIOFNF;
50     }
51 
52     return (status);
53 }
54 
55 
56 /*
57  * Write a line to the already opened file. The "buf" points to the buffer,
58  * and the "nbuf" is its length, less the free newline. Return the status.
59  * Check only at the newline.
60  */
61 int
ffputline(CELL buf[],int nbuf)62 ffputline(CELL buf[], int nbuf)
63 {
64     register int    i;
65     EML eml;
66 
67     for(i = 0; i < nbuf; ++i)
68        if(write_a_wide_char((UCS) buf[i].c, g_pico_fio.fp) == EOF)
69 	 break;
70 
71    if(i == nbuf)
72      write_a_wide_char((UCS) '\n', g_pico_fio.fp);
73 
74     if(ferror(g_pico_fio.fp)){
75 	eml.s = errstr(errno);
76         emlwwrite(_("Write error: %s"), &eml);
77 	sleep(5);
78         return FIOERR;
79     }
80 
81     return FIOSUC;
82 }
83 
84 
85 /*
86  * Read a line from a file, and store the bytes in the supplied buffer. The
87  * "nbuf" is the length of the buffer. Complain about long lines and lines
88  * at the end of the file that don't have a newline present. Check for I/O
89  * errors too. Return status.
90  *
91  * Translate the line from the user's locale charset to UCS-4.
92  */
93 int
ffgetline(UCS buf[],size_t nbuf,size_t * charsreturned,int msg)94 ffgetline(UCS buf[], size_t nbuf, size_t *charsreturned, int msg)
95 {
96     size_t i;
97     UCS    ucs;
98     static int displayed = 0;
99 
100     if(charsreturned)
101       *charsreturned = 0;
102 
103     i = 0;
104 
105     while((ucs = read_a_wide_char(g_pico_fio.fp, input_cs)) != CCONV_EOF && ucs != '\n'){
106 	/*
107 	 * Don't blat the CR should the newline be CRLF and we're
108 	 * running on a unix system.  NOTE: this takes care of itself
109 	 * under DOS since the non-binary open turns newlines into '\n'.
110 	 */
111 	if(ucs == '\r'){
112 	    if((ucs = read_a_wide_char(g_pico_fio.fp, input_cs)) == CCONV_EOF || ucs == '\n')
113 	      break;
114 
115 	    if(i < nbuf-2)		/* Bare CR. Insert it and go on... */
116 	      buf[i++] = '\r';		/* else, we're up a creek */
117 	}
118 
119         if(i >= nbuf-2){
120 	    buf[nbuf - 2] = ucs;	/* store last char read */
121 	    buf[nbuf - 1] = '\0';	/* and terminate it */
122 	    if(charsreturned)
123 	      *charsreturned = nbuf - 1;
124 
125 	    if(msg && displayed == 0){
126 	      emlwrite("File has long line", NULL);
127 	      displayed = 1;
128 	    }
129 
130 	    return FIOLNG;
131         }
132 
133         buf[i++] = ucs;
134     }
135 
136     if(ucs == CCONV_EOF){
137         if(ferror(g_pico_fio.fp)){
138             emlwrite("File read error", NULL);
139 	    if(charsreturned)
140 	      *charsreturned = i;
141 
142 	    return FIOERR;
143         }
144 
145         if(i != 0)
146 	  emlwrite("File doesn't end with newline.  Adding one.", NULL);
147 	else{
148 	    if(charsreturned)
149 	      *charsreturned = i;
150 	    return FIOEOF;
151 	}
152     }
153 
154     buf[i] = '\0';
155 
156     if(charsreturned)
157       *charsreturned = i;
158 
159     return FIOSUC;
160 }
161