1 /******************************************************************************
2 *
3 * addvs.cpp - Utility to create/modify a VerseKey module by adding a single
4 * entry
5 *
6 * $Id: addvs.cpp 3063 2014-03-04 13:04:11Z chrislit $
7 *
8 * Copyright 2000-2013 CrossWire Bible Society (http://www.crosswire.org)
9 * CrossWire Bible Society
10 * P. O. Box 2528
11 * Tempe, AZ 85280-2528
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation version 2.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 */
23
24 #ifdef _MSC_VER
25 #pragma warning( disable: 4251 )
26 #endif
27
28 #include <ctype.h>
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 #include <stdlib.h>
33
34 #ifndef __GNUC__
35 #include <io.h>
36 #else
37 #include <unistd.h>
38 #endif
39
40 #include <swmgr.h>
41 #include <versekey.h>
42 #include <rawtext.h>
43 #include <iostream>
44
45 #ifndef NO_SWORD_NAMESPACE
46 using sword::SWMgr;
47 using sword::RawText;
48 using sword::SWKey;
49 using sword::VerseKey;
50 using sword::ListKey;
51 using sword::SWModule;
52 #endif
53
main(int argc,char ** argv)54 int main(int argc, char **argv) {
55
56 const char * helptext = "addvs 1.1 Bible & Commentary module creation tool for the SWORD Project\nUse -a to add a new verse from standard input or a file, -d to delete a verse,\n-l to link two verses, -c to create a new module.\n usage:\n %s -a </path/to/module> <verse> [</path/to/file/with/verse>]\n %s -d </path/to/module> <key>\n %s -l </path/to/module> <first verse (already assigned)> <second verse>\n %s -c </path/to/module>\n";
57 long entrysize;
58
59 if (argc < 3) {
60 fprintf(stderr, helptext, argv[0], argv[0], argv[0], argv[0]);
61 exit(-1);
62 }
63 if (!strcmp(argv[1], "-a") && (argc == 4 || argc == 5)) {
64
65 // Do some initialization stuff
66 char buffer[65536]; //this is the max size of any entry
67 RawText * mod = new RawText(argv[2]); // open our datapath with our RawText driver.
68 VerseKey *vkey = new VerseKey;
69 vkey->setIntros(true);
70 vkey->setAutoNormalize(false);
71 vkey->setPersist(true); // the magical setting
72 *vkey = argv[3];
73 // Set our VerseKey
74 mod->setKey(*vkey);
75 if (!vkey->getChapter()) {
76 // bad hack >>
77 // 0:0 is Book intro
78 // (chapter):0 is Chapter intro
79 //
80 // 0:2 is Module intro
81 // 0:1 is Testament intro
82 int backstep = vkey->getVerse();
83 vkey->setVerse(0);
84 *mod -= backstep;
85 // << bad hack
86
87 FILE *infile;
88 // case: add from text file
89 //Open our data file and read its contents into the buffer
90 if (argc == 5) infile = fopen(argv[4], "r");
91 // case: add from stdin
92 else infile = stdin;
93
94 entrysize = fread(buffer, sizeof(char), sizeof(buffer), infile);
95
96 mod->setEntry(buffer, entrysize); // save text to module at current position
97 }
98 else {
99 ListKey listkey = vkey->parseVerseList(argv[3], "Gen1:1", true);
100 int i;
101 bool havefirst = false;
102 VerseKey firstverse;
103 for (i = 0; i < listkey.getCount(); i++) {
104 VerseKey *element = SWDYNAMIC_CAST(VerseKey, listkey.getElement(i));
105 if (element) {
106 mod->setKey(element->getLowerBound());
107 VerseKey finalkey = element->getUpperBound();
108 std::cout << mod->getKeyText() << "-" << (const char*)finalkey << std::endl;
109 if (!havefirst) {
110 havefirst = true;
111 firstverse = *mod->getKey();
112 FILE *infile;
113 // case: add from text file
114 //Open our data file and read its contents into the buffer
115 if (argc == 5) infile = fopen(argv[4], "r");
116 // case: add from stdin
117 else infile = stdin;
118
119 entrysize = fread(buffer, sizeof(char), sizeof(buffer), infile);
120
121 mod->setEntry(buffer, entrysize); // save text to module at current position
122 std::cout << "f" << (const char*)firstverse << std::endl;
123 (*mod)++;
124 }
125 while (*mod->getKey() <= finalkey) {
126 std::cout << mod->getKeyText() << std::endl;
127 *(SWModule*)mod << &firstverse;
128 (*mod)++;
129 }
130 }
131 else {
132 if (havefirst) {
133 mod->setKey(*listkey.getElement(i));
134 *(SWModule*)mod << &firstverse;
135 std::cout << mod->getKeyText() << std::endl;
136 }
137 else {
138 mod->setKey(*listkey.getElement(i));
139 havefirst = true;
140 firstverse = *mod->getKey();
141 FILE *infile;
142 // case: add from text file
143 //Open our data file and read its contents into the buffer
144 if (argc == 5) infile = fopen(argv[4], "r");
145 // case: add from stdin
146 else infile = stdin;
147
148 entrysize = fread(buffer, sizeof(char), sizeof(buffer), infile);
149
150 mod->setEntry(buffer, entrysize); // save text to module at current position
151 std::cout << "f" << (const char*)firstverse << std::endl;
152 }
153 }
154 }
155 }
156 delete vkey;
157 }
158 // Link 2 verses
159 else if (!strcmp(argv[1], "-l") && argc == 5) {
160 // Do some initialization stuff
161 RawText *mod = new RawText(argv[2]); // open our datapath with our RawText driver.
162
163 mod->setKey(argv[4]); // set key from argument
164 SWKey tmpkey = (SWKey) argv[3];
165 *(SWModule*)mod << &(tmpkey);
166 delete mod;
167 }
168
169 else if (!strcmp(argv[1], "-d") && argc == 4) {
170 RawText mod(argv[2]); // open our datapath with our RawText driver.
171 VerseKey *vkey = new VerseKey;
172 vkey->setIntros(true);
173 vkey->setAutoNormalize(false);
174 vkey->setPersist(true); // the magical setting
175
176 // Set our VerseKey
177 mod.setKey(*vkey);
178 *vkey = argv[3];
179
180 if (!vkey->getChapter())
181 {
182 // bad hack >>
183 // 0:0 is Book intro
184 // (chapter):0 is Chapter intro
185 //
186 // 0:2 is Module intro
187 // 0:1 is Testament intro
188 int backstep = vkey->getVerse();
189 vkey->setVerse(0);
190 mod -= backstep;
191 // << bad hack
192 }
193
194 mod.deleteEntry();
195 delete vkey;
196 }
197
198 // Make a new module
199 else if (!strcmp(argv[1], "-c") && argc == 3) {
200 // Try to initialize a default set of datafiles and indicies at our
201 // datapath location passed to us from the user.
202 if (RawText::createModule(argv[2])) {
203 fprintf(stderr, "error: %s: couldn't create module at path: %s \n", argv[0], argv[2]);
204 exit(-2);
205 }
206 }
207
208 // Bad arguments, print usage
209 else {
210 fprintf(stderr, helptext, argv[0], argv[0], argv[0], argv[0]);
211 exit(-1);
212 }
213 }
214