1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/* Copyright (C) 2013 Kevin W. Hamlen
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* The latest version of this program can be obtained from
* http://songs.sourceforge.net.
*/
#if HAVE_CONFIG_H
# include "config.h"
#else
# include "vsconfig.h"
#endif
#include "chars.h"
#include "songidx.h"
#include "fileio.h"
#if HAVE_STRING_H
# include <string.h>
#endif
/* fileopen(<fstate>,<filename>)
* Open <filename> for reading, storing the file handle in <fstate>. Return
* 1 on success or 0 on failure.
*/
int
fileopen(fs,fnam)
FSTATE *fs;
const char *fnam;
{
if (strcmp(fnam,"-"))
{
fs->f = fopen(fnam, "r");
if (!fs->f)
{
fprintf(stderr, "songidx: Unable to open %s for reading.\n", fnam);
return 0;
}
}
else
{
fs->f = stdin;
fnam = "stdin";
}
fs->filename = (char *) calloc(strlen(fnam)+1, sizeof(char));
if (!fs->filename)
{
fprintf(stderr, "songidx: Out of memory!\n");
fclose(fs->f);
return 0;
}
strcpy(fs->filename, fnam);
fs->lineno = 0;
return 1;
}
/* fileclose(<fstate>)
* Close file handle <fstate>.
*/
void
fileclose(fs)
FSTATE *fs;
{
if (fs->f != stdin) fclose(fs->f);
free(fs->filename);
fs->f = NULL;
fs->filename = NULL;
fs->lineno = 0;
}
/* filereadln(<fstate>,<buffer>,<eof flag>)
* Read a line of output into <buffer>, which should be at least MAXLINELEN
* wide-characters in size. If the line is too long to fit into the buffer,
* close the file and report an error. Eliminate the trailing \n from the
* returned line. Return 1 on success or end-of-line, or 0 on failure. If
* end-of-line, set <eof flag> to 1. */
int
filereadln(fs,buf,eof)
FSTATE *fs;
WCHAR *buf;
int *eof;
{
size_t n;
++fs->lineno;
if (!ws_fgets(buf, MAXLINELEN, fs->f))
{
if (!ferror(fs->f))
{
*eof=1;
return 1;
}
fprintf(stderr, "songidx:%s:%d: read error\n", fs->filename, fs->lineno);
fileclose(fs);
return 0;
}
n = ws_strlen(buf);
if ((n==0) || ((buf[n-1] != wc_newline) && (buf[n-1] != wc_cr)))
{
fprintf(stderr, "songidx:%s:%d: line too long\n", fs->filename, fs->lineno);
fileclose(fs);
return 0;
}
buf[n-1] = wc_null;
if ((n>=2) && ((buf[n-2] == wc_newline) || (buf[n-2] == wc_cr)))
buf[n-2] = wc_null;
return 1;
}
|