123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- /******************************************************************************
- *
- * project name: TI-68k Developer Utilities
- * file name: ttsplit.c
- * initial date: 23/08/2000
- * authors: thomas.nussbaumer@gmx.net
- * description: splits a file into two or more files
- *
- ******************************************************************************/
- /*
- This file is part of TI-68k Developer Utilities.
- This file is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- As a special exception, UNMODIFIED copies of ttsplit may also be
- redistributed or sold without source code, for any purpose. (The Lesser
- General Public License restrictions do apply in other respects; for example,
- they cover modification of the program.) This exception notice must be
- removed on modified copies of this file.
- 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
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- // if EMBEDDED_USE is defined, than we use this sourcefile from within another
- // sourcefile
- #ifndef EMBEDDED_USE
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "tt.h" // generic defines
- #include "ttversion.h" // TI-68k Developer Utilities version info
- #include "revtools.h"
- #ifdef FILE_REVISION
- #undef FILE_REVISION
- #endif
- #define FILE_REVISION "1.7"
- //=============================================================================
- // outputs usage information of this tool
- //=============================================================================
- void PrintUsage() {
- fprintf(USAGE_OUT, "Usage: ttsplit [flags] <-t | -b> <offsetfile> <infile>\n"\
- " -t ... treat offsets as linenumbers (starting at 1)\n"\
- " -b ... treat offsets as byteoffsets (starting at 0)\n"\
- " -s <string> ... use inline split tag instead of offset file\n"\
- " -v ... output additionally messages\n\n"\
- "offsets are read from file offsetfile, which must contain offsets only\n"\
- "in ascending numbers (maximum: 999 offsets). each offset is treated as\n"\
- "the start of a new file. the first offset is the start of the second (!!!)\n"\
- "file and so on.\n"\
- "The outputfile names are generated from the inputfilename using\n"\
- "the following pattern:\n"\
- "<inputname>p<nr>.<inputextension>\n"\
- "nr ranges from 000 to 999\n\n");
- }
- #endif
- //=============================================================================
- // split text input file using a inline tag on a single line
- //=============================================================================
- unsigned int SplitWithTag(char* inputname,char* splittag,int verbose) {
- char* dot_position = strchr(inputname,'.');
- char extension[300];
- char prefix[300];
- unsigned long dpl;
- size_t len;
- FILE* fp;
- FILE* ofp = 0;
- unsigned int i;
- unsigned int generated_files = 0;
- long pos = 0;
- char ofname[1000];
- char buffer[10000];
- buffer[9999] = 0;
- if (!(fp = fopen(inputname,"r"))) {
- fprintf(stderr,"ERROR: cannot open inputfile %s\n",inputname);
- return 0;
- }
- if (!dot_position) {
- extension[0] = 0;
- strcpy(prefix,inputname);
- }
- else {
- dpl = dot_position - inputname;
- if (!dpl) prefix[0] = 0;
- else {
- strncpy(prefix,inputname,dpl);
- prefix[dpl] = 0;
- }
- len = strlen(inputname);
- if (len - dpl == 0) {
- extension[0] = 0;
- }
- else {
- strncpy(extension,&inputname[dpl],len - dpl);
- extension[len - dpl] = 0;
- }
- }
- if (verbose) {
- fprintf(stderr,"using prefix = [%s]\n",prefix);
- fprintf(stderr,"using extension = [%s]\n",extension);
- }
- pos = 1;
- i = 0;
- sprintf(ofname,"%sp%03d%s",prefix,i,extension);
- if (!(ofp = fopen(ofname,"w"))) {
- fprintf(stderr,"ERROR: cannot open outputfile %s\n",ofname);
- return generated_files;
- }
- do {
- if (fgets(buffer,9999,fp) == 0) {
- fclose(fp);
- fclose(ofp);
- return ++generated_files;
- }
- // check if line contains splittag
- if (strstr(buffer,splittag)) {
- fclose(ofp);
- generated_files++;
- sprintf(ofname,"%sp%03d%s",prefix,i+1,extension);
- if (!(ofp = fopen(ofname,"w"))) {
- fprintf(stderr,"ERROR: cannot open outputfile %s\n",ofname);
- return generated_files;
- }
- i++;
- continue;
- }
- if (fputs(buffer,ofp) == EOF) {
- fprintf(stderr,"ERROR: cannot write more lines to file %s\n",ofname);
- fclose(fp);
- fclose(ofp);
- return generated_files;
- }
- }
- while(1);
- return 0;
- }
- //=============================================================================
- // extract a part in binary mode
- //=============================================================================
- int ExtractBinary(FILE* ifp,char* outname,unsigned long start,unsigned long length)
- {
- FILE* ofp;
- int input;
- fprintf(stderr,"extracting to %s from start=%lu (length=%lu)\n",outname,start,length);
- if (!(ofp = fopen(outname,"wb"))) {
- fprintf(stderr,"ERROR: cannot open output filename %s\n",outname);
- return 0;
- }
- if (fseek(ifp,start,SEEK_SET)) {
- fprintf(stderr,"ERROR: cannot seek to binary offset %lu\n",start);
- fclose(ofp);
- return 0;
- }
- while (length--) {
- input = fgetc(ifp);
- if (input == EOF) {
- fprintf(stderr,"ERROR: cannot read more data from inputfile\n");
- fclose(ofp);
- return 0;
- }
- if (fputc(input,ofp) == EOF) {
- fprintf(stderr,"ERROR: cannot read write data to outputfile\n");
- fclose(ofp);
- return 0;
- }
- }
- fclose(ofp);
- return 1;
- }
- //=============================================================================
- // split the input file
- //=============================================================================
- unsigned int Split2Parts(char* inputname,int use_textmode,
- long* offsets, unsigned int offset_count)
- {
- char* dot_position = strchr(inputname,'.');
- char extension[300];
- char prefix[300];
- unsigned long dpl;
- size_t len;
- FILE* fp;
- FILE* ofp = 0;
- unsigned int i;
- unsigned int generated_files = 0;
- long pos = 0;
- char ofname[1000];
- char buffer[10000];
- buffer[9999] = 0;
- if (use_textmode) {
- fp = fopen(inputname,"r");
- }
- else {
- fp = fopen(inputname,"rb");
- }
- if (!fp) {
- fprintf(stderr,"ERROR: cannot open inputfile %s\n",inputname);
- return 0;
- }
- if (!dot_position) {
- extension[0] = 0;
- strcpy(prefix,inputname);
- }
- else {
- dpl = dot_position - inputname;
- if (!dpl) prefix[0] = 0;
- else {
- strncpy(prefix,inputname,dpl);
- prefix[dpl] = 0;
- }
- len = strlen(inputname);
- if (len - dpl == 0) {
- extension[0] = 0;
- }
- else {
- strncpy(extension,&inputname[dpl],len - dpl);
- extension[len - dpl] = 0;
- }
- }
- fprintf(stderr,"using prefix = [%s]\n",prefix);
- fprintf(stderr,"using extension = [%s]\n",extension);
- if (!use_textmode) {
- sprintf(ofname,"%sp000%s",prefix,extension);
- if (!ExtractBinary(fp,ofname,0,offsets[0])) {
- return generated_files;
- }
- generated_files++;
- for (i=0;i<offset_count-1;i++) {
- sprintf(ofname,"%sp%03d%s",prefix,i+1,extension);
- if (!ExtractBinary(fp,ofname,offsets[i],offsets[i+1]-offsets[i])) {
- return generated_files;
- }
- generated_files++;
- }
- fseek(fp,0,SEEK_END);
- pos = ftell(fp);
- sprintf(ofname,"%sp%03d%s",prefix,i+1,extension);
- if (!ExtractBinary(fp,ofname,offsets[offset_count-1],pos - offsets[offset_count-1])) {
- return generated_files;
- }
- generated_files++;
- return generated_files;
- }
- // here comes the textmode extraction ...
- pos = 1;
- i = 0;
- sprintf(ofname,"%sp%03d%s",prefix,i,extension);
- if (!(ofp = fopen(ofname,"w"))) {
- fprintf(stderr,"ERROR: cannot open outputfile %s\n",ofname);
- return generated_files;
- }
- do {
- if ( pos > 1
- && i < offset_count
- && pos == offsets[i]
- ) {
- fclose(ofp);
- generated_files++;
- sprintf(ofname,"%sp%03d%s",prefix,i+1,extension);
- if (!(ofp = fopen(ofname,"w"))) {
- fprintf(stderr,"ERROR: cannot open outputfile %s\n",ofname);
- return generated_files;
- }
- i++;
- }
- if (fgets(buffer,9999,fp) == 0) {
- fclose(fp);
- fclose(ofp);
- return ++generated_files;
- }
- pos++;
- if (fputs(buffer,ofp) == EOF) {
- fprintf(stderr,"ERROR: cannot write more lines to file %s\n",ofname);
- fclose(fp);
- fclose(ofp);
- return generated_files;
- }
- }
- while(1);
- return 0;
- }
- //=============================================================================
- // parse offsets from file
- //=============================================================================
- unsigned int ReadOffsets(char* filename,long* offsets) {
- FILE* fp = fopen(filename,"r");
- unsigned int count = 0;
- int read;
- if (!fp) {
- fprintf(stderr,"ERROR: cannot open offsetfile %s\n",filename);
- return 0;
- }
- do {
- read = fscanf(fp,"%ld",&offsets[count]);
- if (!read) {
- fclose(fp);
- fprintf(stderr,"ERROR: parsing offset[%u] from %s failed\n",count,filename);
- return 0;
- }
- if (read == EOF) {
- fclose(fp);
- return count;
- }
- // From 1.30-: offsets[count] < offsets[count] (???)
- if (count > 0 && offsets[count] < offsets[count - 1]) {
- fprintf(stderr,"ERROR: offsets are not ascending\n");
- fclose(fp);
- return 0;
- }
- if (offsets[count] == 0) {
- fprintf(stderr,"ERROR: offset 0 is invalid\n");
- fclose(fp);
- return 0;
- }
- count++;
- if (count==999) {
- fclose(fp);
- fprintf(stderr,"WARNING: read 1000 offsets. Dropping the rest.\n");
- return count;
- }
- }
- while (1);
- return 0;
- }
- //=============================================================================
- // nomen omen est
- //=============================================================================
- #ifndef EMBEDDED_USE
- int main(int argc, char* argv[]) {
- #else
- int TTSplit(int argc, char* argv[]) {
- #endif
- long offsets[1000]; // 1.40: from unsigned long.
- unsigned int offset_count;
- int i;
- unsigned int retval;
- int textmode = -1;
- int verbose = 0;
- char* splittag = 0;
- char* offsetname = 0;
- char* infilename = 0;
- #ifndef EMBEDDED_USE
- PRINT_ID("TTSplit");
- #endif
- for (i=1; i<argc; i++) {
- if (!strcmp(argv[i], "-b")) textmode = 0;
- else if (!strcmp(argv[i], "-t")) textmode = 1;
- else if (!strcmp(argv[i], "-v")) verbose = 1;
- else if (!strcmp(argv[i], "-s")) {
- if (i == argc - 1) {
- #ifndef EMBEDDED_USE
- PrintUsage();
- #endif
- return 1;
- }
- i++;
- splittag = argv[i];
- }
- else {
- if (!splittag && !offsetname) offsetname = argv[i];
- else if (!infilename) infilename = argv[i];
- }
- }
- if (!infilename || (!splittag && !offsetname) || textmode == -1) {
- #ifndef EMBEDDED_USE
- PrintUsage();
- #endif
- return 1;
- }
- if (!splittag) {
- if (!(offset_count = ReadOffsets(offsetname,offsets))) return 1;
- if (textmode && offsets[0] <= 1) {
- fprintf(stderr,"ERROR: offset with value 0 or 1 is not allowed for textmode\n");
- return 1;
- }
- retval = Split2Parts(infilename,textmode,offsets,offset_count);
- }
- else {
- retval = SplitWithTag(infilename,splittag,verbose);
- if (!retval) {
- fprintf(stderr,"ERROR: splitting inputfile %s failed\n",infilename);
- return 1;
- }
- if (verbose) fprintf(stderr,"successfully generated %u files\n",retval);
- return 0;
- }
- if (retval == offset_count+1) {
- fprintf(stderr,"generated ONLY %u out of %u files\n",retval,offset_count+1);
- }
- else {
- if (verbose) fprintf(stderr,"successfully generated %u out of %u files\n",retval,retval);
- }
- return (retval == offset_count+1) ? 0 : 1;
- }
- //#############################################################################
- //###################### NO MORE FAKES BEYOND THIS LINE #######################
- //#############################################################################
- //
- //=============================================================================
- // Revision History
- //=============================================================================
- //
- // Revision 1.7 2009/01/25 Lionel Debroux
- // Changes by Romain Liévin and/or me for 64-bit compatibility.
- // Adapt to new version display (revtools.h).
- //
- // Revision 1.6 2002/03/04 14:32:42 tnussb
- // now tool can be used as embedded version from within other tools
- // by defining EMBEDDED_VERSION before including the sourcefile
- //
- // Revision 1.5 2002/02/07 09:49:38 tnussb
- // all local includes changed, because header files are now located in pctools folder
- //
- // Revision 1.4 2000/11/28 00:07:32 Thomas Nussbaumer
- // using now USAGE_OUT stream for usage info
- //
- // Revision 1.3 2000/08/28 18:10:18 Thomas Nussbaumer
- // nasty bug (uninitialized variable) fixed which causes program to return
- // != 0 in good cases, too
- //
- // Revision 1.2 2000/08/26 19:00:36 Thomas Nussbaumer
- // inline split tag mode added to make ebook generation easier
- //
- // Revision 1.1 2000/08/23 20:18:10 Thomas Nussbaumer
- // initial version (quite a hack)
- //
- //
- //
|