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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
/*
* Aiksaurus - An English-language thesaurus library
* Copyright (C) 2001-2002 by Jared Davis
*
* 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., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/
/*
NOTE: this really is C code. It only has the .cpp file extension
because I don't know how to get automake to work correctly with
a mixed C++ and C program.
*/
#include "AiksaurusC.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char* dupeString(const char* str);
static void noMemory();
static void checkError();
static void noSynonyms();
static void printSynonyms();
static void handleArguments(int argc, char** argv);
int main(int argc, char** argv)
{
int found;
/* Check that our arguments are correct. */
handleArguments(argc, argv);
/* Create thesaurus object. (might cause an error...) */
if (!Aiksaurus_init())
{
noMemory();
}
checkError();
/* Search thesaurus for the word. */
found = Aiksaurus_find(argv[1]);
checkError();
if (found)
{
/* synonyms were found. print off the synonyms. */
printSynonyms();
}
else
{
/* no synonyms found, print off nearby words. */
noSynonyms();
}
printf("\n");
return 0;
}
/*
* dupeString()
* create a copy of a string. this copy must be destroyed
* by the caller with free().
*/
static char* dupeString(const char* str)
{
char* ret = (char*) malloc ( strlen(str) * sizeof(char) + 1 );
if (!ret)
noMemory();
strcpy(ret, str);
return ret;
}
/*
* noMemory()
* we set this as our new handler so that if we run out of
* memory, we can just print an error message and die.
*/
static void noMemory()
{
printf("Error: Virtual memory exhausted.\n");
exit(1);
}
/*
* checkError()
* checks to see if there was an error with the thesaurus,
* prints the message and terminates the program if there is.
*/
static void checkError()
{
if (Aiksaurus_error()[0])
{
printf("%s\n", Aiksaurus_error());
exit(1);
}
}
/*
* noSynonyms()
* called if there are no known synonyms. prints out nearby
* words.
*/
static void noSynonyms()
{
const char* r;
checkError();
printf("*** No synonyms known. ***\n");
printf("Alphabetically similar known words are: \n");
for(r = Aiksaurus_similar(); r[0]; r = Aiksaurus_similar())
{
checkError();
printf("\t%s\n", r);
}
}
/*
* printSynonyms()
* called if there are known synonyms. prints out all the
* meanings that the thesaurus knows.
*/
static void printSynonyms()
{
const char* r;
int prev_meaning = -1;
int meaning;
for(r = Aiksaurus_next(&meaning); r[0]; r = Aiksaurus_next(&meaning))
{
/* next() might cause an error, ensure that it didn't. */
checkError();
/* see if we have a new meaning. */
if (meaning != prev_meaning)
{
/* we do have a new meaning. figure out what the titles are. */
char* option1 = dupeString(r);
char* option2 = dupeString( Aiksaurus_next(&meaning) );
char* title;
int i;
/* we called next() again, so check the error again. */
checkError();
/* choose which title to output. we want option1 unless it's
the same as our current word, */
title = strcmp(option1, Aiksaurus_word()) ? (option1) : (option2);
/* now we know what title we want to output. normally we want
to add a line of space between each meaning, but we don't
want to do this if this is the very first meaning. So, we
can see if prev_meaning is -1 and respond accordingly. */
if (prev_meaning != -1)
{
printf("\n\n");
}
/* update what our previous meaning was. */
prev_meaning = meaning;
/* Let's go ahead and actually print our title now.
All this just prints "=== <title> ===================" */
printf("=== %s ", title);
for(i = strlen(title); i < 25; ++i) { printf("="); }
printf("\n");
r = Aiksaurus_next(&meaning);
checkError();
if (!r[0])
break;
}
else
{
/* this is a continuation of the previous meaning.
print a comma to separate this word from the last. */
printf(", ");
}
/* Output the actual synonym. */
printf("%s", r);
}
/* This just looks a bit better. */
printf("\n");
}
/*
* handleArguments()
* checks for --version or --help flags, and ensures
* that the user searched for a word.
*/
static void handleArguments(int argc, char** argv)
{
/* the message to print if we get --version or -v. */
const char* version =
"Aiksaurus, Version " VERSION "\n"
"Copyright (C) 2001-2002 by Jared Davis\n\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License\n"
"as published by the Free Software Foundation; either version 2\n"
"of the License, or (at your option) any later version.\n\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA \n"
"02111-1307, USA.\n\n";
/* the message to print out if we get --help or -h */
const char* help =
"Aiksaurus is an English-language thesaurus library. This \n"
"is a simple command-line interface to it.\n\n"
" -v, --version Output version information and quit.\n"
" -h, --help Output this help message and quit.\n\n"
"For more help, visit\n"
" http://www.aiksaurus.com/\n\n";
int i;
for(i = 1;i < argc;++i)
{
char* arg = argv[i];
/* see if we got --version. */
if ( !strcmp(arg, "--version") || !strcmp(arg, "-v") )
{
printf("%s", version);
exit(0);
}
/* see if we got --help */
else if ( !strcmp(arg, "--help") || !strcmp(arg, "-h") )
{
printf("Usage: %s [word]\n\n", argv[0]);
printf("%s", help);
exit(0);
}
}
/* make sure we have exactly two arguments. */
if (argc != 2)
{
printf("Usage: %s [word]\n", argv[0]);
printf("%s", help);
exit(1);
}
}
|