File: loadfile.c

package info (click to toggle)
lookup 1.08b-5
  • links: PTS
  • area: contrib
  • in suites: woody
  • size: 1,108 kB
  • ctags: 1,305
  • sloc: ansic: 12,634; makefile: 236; perl: 174; sh: 53
file content (138 lines) | stat: -rw-r--r-- 3,691 bytes parent folder | download | duplicates (9)
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Jeffrey Friedl
 * Omron Corporation			ʳ
 * Nagaokakyoshi, Japan			617Ĺ
 *
 * jfriedl@nff.ncl.omron.co.jp
 *
 * This work is placed under the terms of the GNU General Purpose License
 * (the "GNU Copyleft").
 *
 * October 1993
 *
 * Routine to load a file and to load, create, and/or write an accompanying
 * index. WRT loadfile, a "file" is a rather high-level object that has
 * an index and other substructures associated with it.
 *
 * On a lower level is "readfile" which deals with filesystem files
 * as singular entities.
 */

#include "config.h"
#include "assert.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "xmalloc.h"	/* for xmalloc () */
#include "strsave.h"	/* for strsave() */
#include "system.h"
#ifndef strlen
# if defined(_HAVE_STRINGS_H_) /* might be defined in system.h */
#   include <strings.h>
# else
#   include <string.h>
#   define index strchr
#   define rindex strrchr
# endif
#endif
#include "loadfile.h"
#include "output.h"

/*
 * Given the name of a text file, return the name of its associated index
 * file (or what it would be called were it to exist). The returned string
 * should eventually be free'd by the user.
 */
char *indexfile_name(const char *datafile_name)
{
    char *indexname = xmalloc((unsigned)(strlen((void*)datafile_name)+
					 strlen(LOADFILE_INDEX_EXTENTION)+2));
    strcpy(indexname, datafile_name);
    strcat(indexname, LOADFILE_INDEX_EXTENTION);
    return indexname;
}

/*
 * If LOADFILE_READINDEX is set, the index is read from "FILENAME.jdx".
 * Otherwise, it is created internally.
 *
 * If LOADFILE_WRITEINDEX is set, the index is written to "FILENAME.jdx".
 *
 * It's stupid to have both LOADFILE_READINDEX and LOADFILE_WRITEINDEX set.
 */
struct fileinfo *
loadfile(const char *filename, unsigned percent, unsigned flags)
{
    struct fileinfo *info = xmalloc(sizeof(struct fileinfo));
    long int filesize;
    struct stat statbuf;

    /* stat for various uses */
    if (stat(filename, &statbuf) < 0) {
	warn("[can't stat \"%s\": %n]\n", filename);
	return 0;
    }

    if (statbuf.st_size == 0)
	warn("[warning: file \"%s\" is empty]\n", filename);

    /* open file */
    info->v = OpenVertFile(filename);

    /* note the short filename */
    info->short_filename = (const char *)rindex((void*)info->v->filename, '/');
    if (info->short_filename == 0)
	info->short_filename = info->v->filename;
    else
	info->short_filename++; /* skip over "/" */

    if (flags & (LOADFILE_READINDEX|LOADFILE_READifPRESENT))
    {
	char *name = indexfile_name(filename);
	int just_try = flags & LOADFILE_READifPRESENT;
	if (flags & LOADFILE_NO_MEM_INDEX)
	    info->index = read_index_file(name, just_try, flags);
	else
	    info->index = mem_read_index_file(name);

	if (info->index == 0)
	{
	    if (flags & LOADFILE_READifPRESENT)
	    {
		free(name);
		goto build_index;
	    }
	    warn("[error: couldn't read \"%s\": %n]\n", name);
	    free(name);
	    free(info);
	    return 0;
	}
	info->indexfile = name;
	if (info->index->st__mtime != statbuf.st_mtime) {
	    warn("<WARNING, [%s] has been updated since index was written>\n",
		filename);
	}
    } else {
	struct index *i;
      build_index:
	i = create_index(info->v, percent, flags);
	i->st__mtime = statbuf.st_mtime;
	i->FileP = NULL; /* no file -- it's in memory */
	info->index = i;
    }

    if (flags & LOADFILE_WRITEINDEX)
    {
	char *name = indexfile_name(filename);
	if (write_index_file(name, info->index) != 0)
	{
	    warn("[error: couldn't write \"%s\": %n]\n", name);
	    free(name);
	}
	else
	{
	    warn("[wrote index file \"%s\"]\n", name);
	    info->indexfile = name;
	}
    }
    return info;
}