1 /*
2 * sasearch.c for libdivsufsort
3 * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following
12 * conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #if HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30 #include <stdio.h>
31 #if HAVE_STRING_H
32 # include <string.h>
33 #endif
34 #if HAVE_STDLIB_H
35 # include <stdlib.h>
36 #endif
37 #if HAVE_MEMORY_H
38 # include <memory.h>
39 #endif
40 #if HAVE_STDDEF_H
41 # include <stddef.h>
42 #endif
43 #if HAVE_STRINGS_H
44 # include <strings.h>
45 #endif
46 #if HAVE_SYS_TYPES_H
47 # include <sys/types.h>
48 #endif
49 #if HAVE_IO_H && HAVE_FCNTL_H
50 # include <io.h>
51 # include <fcntl.h>
52 #endif
53 #include <divsufsort.h>
54 #include "lfs.h"
55
56
57 static
58 void
print_help(const char * progname,int status)59 print_help(const char *progname, int status) {
60 fprintf(stderr,
61 "sasearch, a simple SA-based full-text search tool, version %s\n",
62 divsufsort_version());
63 fprintf(stderr, "usage: %s PATTERN FILE SAFILE\n\n", progname);
64 exit(status);
65 }
66
67 int
main(int argc,const char * argv[])68 main(int argc, const char *argv[]) {
69 FILE *fp;
70 const char *P;
71 sauchar_t *T;
72 saidx_t *SA;
73 LFS_OFF_T n;
74 size_t Psize;
75 saidx_t i, size, left;
76
77 if((argc == 1) ||
78 (strcmp(argv[1], "-h") == 0) ||
79 (strcmp(argv[1], "--help") == 0)) { print_help(argv[0], EXIT_SUCCESS); }
80 if(argc != 4) { print_help(argv[0], EXIT_FAILURE); }
81
82 P = argv[1];
83 Psize = strlen(P);
84
85 /* Open a file for reading. */
86 #if HAVE_FOPEN_S
87 if(fopen_s(&fp, argv[2], "rb") != 0) {
88 #else
89 if((fp = LFS_FOPEN(argv[2], "rb")) == NULL) {
90 #endif
91 fprintf(stderr, "%s: Cannot open file `%s': ", argv[0], argv[2]);
92 perror(NULL);
93 exit(EXIT_FAILURE);
94 }
95
96 /* Get the file size. */
97 if(LFS_FSEEK(fp, 0, SEEK_END) == 0) {
98 n = LFS_FTELL(fp);
99 rewind(fp);
100 if(n < 0) {
101 fprintf(stderr, "%s: Cannot ftell `%s': ", argv[0], argv[2]);
102 perror(NULL);
103 exit(EXIT_FAILURE);
104 }
105 } else {
106 fprintf(stderr, "%s: Cannot fseek `%s': ", argv[0], argv[2]);
107 perror(NULL);
108 exit(EXIT_FAILURE);
109 }
110
111 /* Allocate 5n bytes of memory. */
112 T = (sauchar_t *)malloc((size_t)n * sizeof(sauchar_t));
113 SA = (saidx_t *)malloc((size_t)n * sizeof(saidx_t));
114 if((T == NULL) || (SA == NULL)) {
115 fprintf(stderr, "%s: Cannot allocate memory.\n", argv[0]);
116 exit(EXIT_FAILURE);
117 }
118
119 /* Read n bytes of data. */
120 if(fread(T, sizeof(sauchar_t), (size_t)n, fp) != (size_t)n) {
121 fprintf(stderr, "%s: %s `%s': ",
122 argv[0],
123 (ferror(fp) || !feof(fp)) ? "Cannot read from" : "Unexpected EOF in",
124 argv[2]);
125 perror(NULL);
126 exit(EXIT_FAILURE);
127 }
128 fclose(fp);
129
130 /* Open the SA file for reading. */
131 #if HAVE_FOPEN_S
132 if(fopen_s(&fp, argv[3], "rb") != 0) {
133 #else
134 if((fp = LFS_FOPEN(argv[3], "rb")) == NULL) {
135 #endif
136 fprintf(stderr, "%s: Cannot open file `%s': ", argv[0], argv[3]);
137 perror(NULL);
138 exit(EXIT_FAILURE);
139 }
140
141 /* Read n * sizeof(saidx_t) bytes of data. */
142 if(fread(SA, sizeof(saidx_t), (size_t)n, fp) != (size_t)n) {
143 fprintf(stderr, "%s: %s `%s': ",
144 argv[0],
145 (ferror(fp) || !feof(fp)) ? "Cannot read from" : "Unexpected EOF in",
146 argv[3]);
147 perror(NULL);
148 exit(EXIT_FAILURE);
149 }
150 fclose(fp);
151
152 /* Search and print */
153 size = sa_search(T, (saidx_t)n,
154 (const sauchar_t *)P, (saidx_t)Psize,
155 SA, (saidx_t)n, &left);
156 for(i = 0; i < size; ++i) {
157 fprintf(stdout, "%" PRIdSAIDX_T "\n", SA[left + i]);
158 }
159
160 /* Deallocate memory. */
161 free(SA);
162 free(T);
163
164 return 0;
165 }
166