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 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 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