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