~ubuntu-branches/ubuntu/jaunty/ncbi-tools6/jaunty

« back to all changes in this revision

Viewing changes to demo/raw2delt.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2008-07-14 19:43:15 UTC
  • mfrom: (2.1.12 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080714194315-ed44u9ek7txva2rz
Tags: 6.1.20080302-3
tools/readdb.c: enable madvise()-based code on all glibc (hence all
Debian) systems, not just Linux.  (Closes: #490437.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*   raw2delt.c
 
2
* ===========================================================================
 
3
*
 
4
*                            PUBLIC DOMAIN NOTICE
 
5
*            National Center for Biotechnology Information (NCBI)
 
6
*
 
7
*  This software/database is a "United States Government Work" under the
 
8
*  terms of the United States Copyright Act.  It was written as part of
 
9
*  the author's official duties as a United States Government employee and
 
10
*  thus cannot be copyrighted.  This software/database is freely available
 
11
*  to the public for use. The National Library of Medicine and the U.S.
 
12
*  Government do not place any restriction on its use or reproduction.
 
13
*  We would, however, appreciate having the NCBI and the author cited in
 
14
*  any work or product based on this material
 
15
*
 
16
*  Although all reasonable efforts have been taken to ensure the accuracy
 
17
*  and reliability of the software and data, the NLM and the U.S.
 
18
*  Government do not and cannot warrant the performance or results that
 
19
*  may be obtained by using this software or data. The NLM and the U.S.
 
20
*  Government disclaim all warranties, express or implied, including
 
21
*  warranties of performance, merchantability or fitness for any particular
 
22
*  purpose.
 
23
*
 
24
* ===========================================================================
 
25
*
 
26
* File Name:  raw2delt.c
 
27
*
 
28
* Author:  Colleen Bollin
 
29
*
 
30
* Version Creation Date:   4/12/07
 
31
*
 
32
* $Revision: 1.2 $
 
33
*
 
34
* File Description: 
 
35
*
 
36
* Modifications:  
 
37
* --------------------------------------------------------------------------
 
38
* Date     Name        Description of modification
 
39
* -------  ----------  -----------------------------------------------------
 
40
*
 
41
*
 
42
* ==========================================================================
 
43
*/
 
44
 
 
45
#include <ncbi.h>
 
46
#include <objall.h>
 
47
#include <objsset.h>
 
48
#include <objsub.h>
 
49
#include <objfdef.h>
 
50
#include <sequtil.h>
 
51
#include <gather.h>
 
52
#include <sqnutils.h>
 
53
#include <explore.h>
 
54
#include <seqport.h>
 
55
 
 
56
#define RAW2DELT_APP_VER "1.0"
 
57
 
 
58
CharPtr RAW2DELT_APPLICATION = RAW2DELT_APP_VER;
 
59
 
 
60
typedef struct outputstream {
 
61
  CharPtr  results_dir;
 
62
  CharPtr  base;
 
63
  CharPtr  suffix;
 
64
  CharPtr  outfile;
 
65
  CharPtr  outsuffix;
 
66
  AsnIoPtr aip;
 
67
  Boolean  is_binary;
 
68
} OutputStreamData, PNTR OutputStreamPtr;
 
69
 
 
70
typedef struct inputstream {
 
71
  CharPtr directory;
 
72
  CharPtr base;
 
73
  CharPtr suffix;
 
74
  Boolean is_binary;
 
75
  Boolean is_seqentry;
 
76
} InputStreamData, PNTR InputStreamPtr;
 
77
 
 
78
typedef struct asnstream {
 
79
  AsnModulePtr amp;
 
80
  AsnTypePtr   atp_se;
 
81
  AsnTypePtr   atp_bss;
 
82
  AsnTypePtr   atp_bss_se;
 
83
} AsnStreamData, PNTR AsnStreamPtr;
 
84
 
 
85
static FILE* OpenOneFile (
 
86
  CharPtr directory,
 
87
  CharPtr base,
 
88
  CharPtr suffix
 
89
)
 
90
 
 
91
{
 
92
  Char  file [FILENAME_MAX], path [PATH_MAX];
 
93
 
 
94
  if (base == NULL) {
 
95
    base = "";
 
96
  }
 
97
  if (suffix == NULL) {
 
98
    suffix = "";
 
99
  }
 
100
 
 
101
  StringNCpy_0 (path, directory, sizeof (path));
 
102
  sprintf (file, "%s%s", base, suffix);
 
103
  FileBuildPath (path, NULL, file);
 
104
 
 
105
  return FileOpen (path, "r");
 
106
}
 
107
 
 
108
static AsnIoPtr AsnIoFromInputStream (
 
109
  InputStreamPtr isp
 
110
)
 
111
 
 
112
{
 
113
  AsnIoPtr aip;
 
114
  Char     file [FILENAME_MAX], path [PATH_MAX];
 
115
  CharPtr  read_flag;
 
116
 
 
117
  if (isp == NULL) return NULL;
 
118
 
 
119
  if (isp->is_binary) {
 
120
    read_flag = "rb";
 
121
  } else {
 
122
    read_flag = "r";
 
123
  }
 
124
 
 
125
  if (isp->base == NULL) {
 
126
    aip = AsnIoOpen ("stdin", read_flag);
 
127
  } else {
 
128
    StringNCpy_0 (path, isp->directory, sizeof (path));
 
129
    sprintf (file, "%s%s", isp->base, isp->suffix);
 
130
    FileBuildPath (path, NULL, file);
 
131
    aip = AsnIoOpen (path, read_flag);
 
132
  }
 
133
  return aip;
 
134
}
 
135
 
 
136
 
 
137
static AsnIoPtr AsnIoFromOutputStream (OutputStreamPtr osp)
 
138
{
 
139
  AsnIoPtr   aip;
 
140
  Char       file [FILENAME_MAX], path [PATH_MAX];
 
141
  CharPtr    write_flag;
 
142
 
 
143
  if (osp == NULL) return NULL;
 
144
  if (osp->aip == NULL) {
 
145
    write_flag = osp->is_binary ? "wb" : "w";
 
146
    if (StringDoesHaveText (osp->outfile)) {
 
147
      StringNCpy_0 (path, osp->outfile, sizeof (path));
 
148
    } else {
 
149
      if (osp->base == NULL) {
 
150
        aip = AsnIoOpen ("stdout", write_flag);
 
151
      } else {
 
152
        if (osp->outsuffix == NULL) {
 
153
          osp->outsuffix = "";
 
154
        }
 
155
        StringNCpy_0 (path, osp->results_dir, sizeof (path));
 
156
        sprintf (file, "%s%s%s", osp->base, osp->suffix, osp->outsuffix);
 
157
        FileBuildPath (path, NULL, file);
 
158
        aip = AsnIoOpen (path, write_flag);
 
159
        if (aip == NULL) {
 
160
          Message (MSG_POSTERR, "Unable to write to %s.", path);
 
161
        }
 
162
      }
 
163
    }
 
164
  } else {
 
165
    aip = osp->aip;
 
166
  }
 
167
  return aip;
 
168
}
 
169
 
 
170
static void WriteOneFile (
 
171
  OutputStreamPtr osp,
 
172
  SeqEntryPtr sep
 
173
)
 
174
 
 
175
{
 
176
  AsnIoPtr   aip;
 
177
 
 
178
  aip = AsnIoFromOutputStream (osp);
 
179
  if (aip != NULL) {
 
180
    SeqEntryAsnWrite (sep, aip, NULL);
 
181
    AsnIoFlush (aip);
 
182
  }
 
183
  if (aip != osp->aip) {
 
184
    AsnIoClose (aip);
 
185
  }
 
186
}
 
187
 
 
188
 
 
189
static void CollectBioseqsForConversion (BioseqPtr bsp, Pointer userdata)
 
190
{
 
191
  ValNodePtr PNTR list;
 
192
  
 
193
  if (bsp == NULL || bsp->repr != Seq_repr_raw || ISA_aa (bsp->mol)) return;
 
194
  if (userdata == NULL)
 
195
  {
 
196
    return;
 
197
  }
 
198
  list = (ValNodePtr PNTR) userdata;
 
199
  
 
200
  ValNodeAddPointer (list, 0, bsp);
 
201
}
 
202
 
 
203
 
 
204
static void ProcessSeqEntry (SeqEntryPtr sep, Int4Ptr gap_sizes)
 
205
{
 
206
  ValNodePtr     bsp_list = NULL, vnp;
 
207
  BioseqPtr      bsp;
 
208
 
 
209
  if (sep == NULL || gap_sizes == NULL) return;
 
210
 
 
211
  VisitBioseqsInSep (sep, &bsp_list, CollectBioseqsForConversion);
 
212
 
 
213
  for (vnp = bsp_list; vnp != NULL; vnp = vnp->next) {
 
214
    bsp = (BioseqPtr) vnp->data.ptrvalue;
 
215
    ConvertNsToGaps (bsp, gap_sizes);
 
216
  }
 
217
  bsp_list = ValNodeFree (bsp_list);
 
218
}
 
219
 
 
220
static Uint2 ProcessOneAsn (
 
221
  FILE* fp,
 
222
  CharPtr path,
 
223
  Int4Ptr gap_sizes
 
224
)
 
225
 
 
226
{
 
227
  Pointer        dataptr;
 
228
  Uint2          datatype, entityID = 0;
 
229
  SeqEntryPtr    sep;
 
230
 
 
231
  if (fp == NULL || gap_sizes == NULL) return 0;
 
232
 
 
233
  dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, &entityID, TRUE, FALSE, TRUE, FALSE);
 
234
  if (dataptr == NULL) {
 
235
    Message (MSG_POSTERR, "Unable to read data from %s.", path);
 
236
    return 0;
 
237
  }
 
238
 
 
239
  sep = GetTopSeqEntryForEntityID (entityID);
 
240
  ProcessSeqEntry (sep, gap_sizes);
 
241
 
 
242
  return entityID;
 
243
}
 
244
 
 
245
/* return -1 if failure, 0 if success */
 
246
static Int4 ProcessOneRecord (
 
247
  CharPtr directory,
 
248
  OutputStreamPtr osp,
 
249
  Int4Ptr   gap_sizes
 
250
)
 
251
 
 
252
{
 
253
  Uint2              entityID;
 
254
  FILE               *fp;
 
255
  SeqEntryPtr        sep;
 
256
 
 
257
  if (osp == NULL || gap_sizes == NULL) return -1;
 
258
  fp = OpenOneFile (directory, osp->base, osp->suffix);
 
259
  if (fp == NULL) return -1;
 
260
 
 
261
  entityID = ProcessOneAsn (fp, osp->base == NULL ? "input stream" : osp->base, gap_sizes);
 
262
  
 
263
  FileClose (fp);
 
264
 
 
265
  if (entityID == 0) return -1;
 
266
 
 
267
  /* finish processing */
 
268
 
 
269
  sep = GetTopSeqEntryForEntityID (entityID);
 
270
  if (sep != NULL) {
 
271
    WriteOneFile (osp, sep);
 
272
  }
 
273
 
 
274
  ObjMgrFreeByEntityID (entityID);
 
275
  return 0;
 
276
}
 
277
 
 
278
static Int4 ProcessStream (InputStreamPtr isp, OutputStreamPtr osp, AsnStreamPtr asp, Int4Ptr gap_sizes)
 
279
{
 
280
  AsnTypePtr   atp, atp_srch;
 
281
  AsnIoPtr asn_in, asn_out;
 
282
  Int4         rval = 0;
 
283
  SeqEntryPtr  sep;
 
284
  Uint2        entityID;
 
285
  DataVal av;
 
286
  
 
287
  if (isp == NULL || osp == NULL || asp == NULL || gap_sizes == NULL) return 1;
 
288
 
 
289
  asn_in = AsnIoFromInputStream (isp);
 
290
  asn_out = AsnIoFromOutputStream (osp);
 
291
 
 
292
  if (isp->is_seqentry) {
 
293
    atp = asp->atp_se;
 
294
    atp_srch = asp->atp_se;
 
295
  }
 
296
  else {
 
297
    atp = asp->atp_bss;
 
298
    atp_srch = asp->atp_bss_se;
 
299
  }
 
300
 
 
301
  while ((atp = AsnReadId(asn_in, asp->amp, atp)) != NULL && rval == 0) {
 
302
    if (atp != atp_srch) {
 
303
      AsnReadVal(asn_in, atp, &av);
 
304
      AsnWrite(asn_out, atp, &av);
 
305
      AsnKillValue(atp, &av);
 
306
      continue;
 
307
    }
 
308
    if ((sep = SeqEntryAsnRead(asn_in, atp)) == NULL) {
 
309
      Message (MSG_POSTERR, "SeqEntryAsnRead failure");
 
310
      rval = 1;
 
311
    } else  {
 
312
      entityID = ObjMgrRegister (OBJ_SEQENTRY, sep);
 
313
      ProcessSeqEntry (sep, gap_sizes);
 
314
 
 
315
      if (! SeqEntryAsnWrite(sep, asn_out, atp)) {
 
316
       Message (MSG_POSTERR, "SeqEntryAsnWrite failure");
 
317
       rval = 1;
 
318
      }
 
319
      AsnIoFlush(asn_out);
 
320
      ObjMgrFreeByEntityID (entityID);
 
321
    }
 
322
  }                             /* Endwhile, AsnReadId */
 
323
 
 
324
  AsnIoClose(asn_in);
 
325
  if (asn_out != osp->aip) {
 
326
    AsnIoClose(asn_out);
 
327
  }
 
328
  
 
329
  return rval;
 
330
}
 
331
 
 
332
/* return -1 on failure, 0 on success */
 
333
static Int4 FileRecurse (
 
334
  CharPtr         directory,
 
335
  InputStreamPtr  isp,
 
336
  OutputStreamPtr osp,
 
337
  AsnStreamPtr    asp,
 
338
  Int4Ptr         gap_sizes
 
339
)
 
340
 
 
341
{
 
342
  Char        path [PATH_MAX];
 
343
  CharPtr     ptr;
 
344
  CharPtr     str;
 
345
  ValNodePtr  head, vnp;
 
346
  CharPtr     orig_dir, orig_base;
 
347
  Int4        rval = 0;
 
348
 
 
349
  /* get list of all files in source directory */
 
350
 
 
351
  head = DirCatalog (directory);
 
352
 
 
353
  for (vnp = head; vnp != NULL; vnp = vnp->next) {
 
354
    if (vnp->choice == 0) {
 
355
      str = (CharPtr) vnp->data.ptrvalue;
 
356
      if (StringDoesHaveText (str)) {
 
357
 
 
358
        /* does filename have desired substring? */
 
359
 
 
360
        ptr = StringStr (str, osp->suffix);
 
361
 
 
362
        if (ptr != NULL) {
 
363
 
 
364
          /* make sure detected suffix is really at end of filename */
 
365
 
 
366
          if (StringCmp (ptr, osp->suffix) == 0) {
 
367
            *ptr = '\0';
 
368
 
 
369
            /* process file that has desired suffix (usually .fsa) */
 
370
            osp->base = str;
 
371
            orig_dir = isp->directory;
 
372
            isp->directory = directory;
 
373
            orig_base = isp->base;
 
374
            isp->base = str;
 
375
            if (isp->is_binary) {
 
376
              rval |= ProcessStream (isp, osp, asp, gap_sizes);
 
377
            } else {
 
378
              rval |= ProcessOneRecord (directory, osp, gap_sizes);
 
379
            }
 
380
            isp->directory = orig_dir;
 
381
            isp->base = orig_base;
 
382
            osp->base = NULL;
 
383
          }
 
384
        }
 
385
      }
 
386
    } else if (vnp->choice == 1) {
 
387
 
 
388
      /* recurse into subdirectory */
 
389
 
 
390
      StringNCpy_0 (path, directory, sizeof (path));
 
391
      str = (CharPtr) vnp->data.ptrvalue;
 
392
      FileBuildPath (path, str, NULL);
 
393
      rval |= FileRecurse (path, isp, osp, asp, gap_sizes);
 
394
    }
 
395
  }
 
396
 
 
397
  /* clean up file list */
 
398
 
 
399
  ValNodeFreeData (head);
 
400
  return rval;
 
401
}
 
402
 
 
403
static Boolean SetUpAsnStreamData (AsnStreamPtr asp)
 
404
 
 
405
{
 
406
  if (asp == NULL) return FALSE;
 
407
 
 
408
  if (! SeqSetAsnLoad()) {
 
409
    Message (MSG_POSTERR, "Unable to load SeqSet parse tree");
 
410
    return FALSE;
 
411
  }
 
412
  asp->amp = AsnAllModPtr();
 
413
  if (asp->amp == NULL) {
 
414
    Message (MSG_POSTERR, "Unable to obtain ASN.1 module pointer");
 
415
    return FALSE;
 
416
  }
 
417
 
 
418
  /* Get pointers to ASN.1 types that must be dealt with in asn_in */
 
419
 
 
420
  if ( (asp->atp_bss = AsnFind("Bioseq-set")) == NULL) {
 
421
    Message (MSG_POSTERR, "could not find type Bioseq-set");
 
422
    return FALSE;
 
423
  }
 
424
  if ( (asp->atp_bss_se = AsnFind("Bioseq-set.seq-set.E")) == NULL) {
 
425
    Message (MSG_POSTERR, "AsnFind failure: Bioseq-set.seq-set.E");
 
426
    return FALSE;
 
427
  }
 
428
  if ( (asp->atp_se = AsnFind("Seq-entry")) == NULL) {
 
429
    Message (MSG_POSTERR, "AsnFind failure: Seq-entry");
 
430
    return FALSE;
 
431
  }
 
432
  return TRUE;
 
433
}
 
434
 
 
435
/* Args structure contains command-line arguments */
 
436
 
 
437
#define p_argInputPath         0
 
438
#define r_argOutputPath        1
 
439
#define i_argInputFile         2
 
440
#define o_argOutputFile        3
 
441
#define x_argSuffix            4
 
442
#define s_argOutSuffix         5
 
443
#define b_argInputBinary       6
 
444
#define e_argInputSeqEntry     7
 
445
#define d_argOutputBinary      8
 
446
#define u_argEqUnknownGap      9
 
447
#define U_argGTEqUnknownGap   10
 
448
#define k_argEqUnknownGap     11
 
449
#define K_argGtEqUnknownGap   12
 
450
 
 
451
 
 
452
Args myargs [] = {
 
453
  {"Path to Files", NULL, NULL, NULL,
 
454
    TRUE, 'p', ARG_STRING, 0.0, 0, NULL},
 
455
  {"Path for Results", NULL, NULL, NULL,
 
456
    TRUE, 'r', ARG_STRING, 0.0, 0, NULL},
 
457
  {"Single Input File", NULL, NULL, NULL,
 
458
    TRUE, 'i', ARG_FILE_IN, 0.0, 0, NULL},
 
459
  {"Single Output File", NULL, NULL, NULL,
 
460
    TRUE, 'o', ARG_FILE_OUT, 0.0, 0, NULL},
 
461
  {"Suffix", ".sqn", NULL, NULL,
 
462
    TRUE, 'x', ARG_STRING, 0.0, 0, NULL},
 
463
  {"Suffix for converted files", "", NULL, NULL,
 
464
    TRUE, 's', ARG_STRING, 0.0, 0, NULL},
 
465
  {"Input is binary", "F", NULL, NULL,
 
466
    TRUE, 'b', ARG_BOOLEAN, 0.0, 0, NULL},
 
467
  {"Input is Seq-entry", "F", NULL, NULL,
 
468
    TRUE, 'e', ARG_BOOLEAN, 0.0, 0, NULL},
 
469
  {"Output is binary", "F", NULL, NULL,
 
470
    TRUE, 'b', ARG_BOOLEAN, 0.0, 0, NULL},
 
471
  {"Exact size to convert to unknown length gap", "-1", NULL, NULL,
 
472
    TRUE, 'u', ARG_INT, 0.0, 0, NULL},
 
473
  {"Size greater than/equal to to convert to unknown length gap", "-1", NULL, NULL,
 
474
    TRUE, 'U', ARG_INT, 0.0, 0, NULL},
 
475
  {"Exact size to convert to known length gap", "-1", NULL, NULL,
 
476
    TRUE, 'k', ARG_INT, 0.0, 0, NULL},
 
477
  {"Size greater than/equal to to convert to known length gap", "-1", NULL, NULL,
 
478
    TRUE, 'K', ARG_INT, 0.0, 0, NULL},
 
479
};
 
480
 
 
481
Int2 Main(void)
 
482
{
 
483
  Char             app [64];
 
484
  CharPtr          directory;
 
485
  CharPtr          ptr;
 
486
  Char             sfx [32];
 
487
  OutputStreamData osd;
 
488
  InputStreamData  isd;
 
489
  AsnStreamData    asd;
 
490
  Int4             gap_sizes[2];
 
491
  Int4             rval = 0;
 
492
  Int4             u_eq = 0, u_gteq = -1, k_eq = 0, k_gteq = -1;
 
493
 
 
494
  /* standard setup */
 
495
 
 
496
  ErrSetFatalLevel (SEV_MAX);
 
497
  ErrClearOptFlags (EO_SHOW_USERSTR);
 
498
  UseLocalAsnloadDataAndErrMsg ();
 
499
  ErrPathReset ();
 
500
 
 
501
  /* finish resolving internal connections in ASN.1 parse tables */
 
502
 
 
503
  if (! AllObjLoad ()) {
 
504
    Message (MSG_FATAL, "AllObjLoad failed");
 
505
    return 1;
 
506
  }
 
507
  if (! SubmitAsnLoad ()) {
 
508
    Message (MSG_FATAL, "SubmitAsnLoad failed");
 
509
    return 1;
 
510
  }
 
511
  if (! FeatDefSetLoad ()) {
 
512
    Message (MSG_FATAL, "FeatDefSetLoad failed");
 
513
    return 1;
 
514
  }
 
515
  if (! SeqCodeSetLoad ()) {
 
516
    Message (MSG_FATAL, "SeqCodeSetLoad failed");
 
517
    return 1;
 
518
  }
 
519
  if (! GeneticCodeTableLoad ()) {
 
520
    Message (MSG_FATAL, "GeneticCodeTableLoad failed");
 
521
    return 1;
 
522
  }
 
523
 
 
524
  SetUpAsnStreamData (&asd);
 
525
 
 
526
  /* initialize OuputStreamData */
 
527
  MemSet (&osd, 0, sizeof (osd));
 
528
 
 
529
  /* initialize InputStreamData */
 
530
  MemSet (&isd, 0, sizeof (isd));
 
531
 
 
532
  /* initialize gap_sizes */
 
533
  gap_sizes[0] = 0;
 
534
  gap_sizes[1] = 0;
 
535
 
 
536
  /* process command line arguments */
 
537
 
 
538
  sprintf (app, "raw2delt %s", RAW2DELT_APPLICATION);
 
539
  if (! GetArgs (app, sizeof (myargs) / sizeof (Args), myargs)) {
 
540
    return 0;
 
541
  }
 
542
 
 
543
  u_eq = (Int4) myargs [u_argEqUnknownGap].intvalue;
 
544
  u_gteq = (Int4) myargs [U_argGTEqUnknownGap].intvalue;
 
545
  k_eq = (Int4) myargs [k_argEqUnknownGap].intvalue;
 
546
  k_gteq = (Int4) myargs [K_argGtEqUnknownGap].intvalue;
 
547
 
 
548
  if (u_eq < 1 && u_gteq < 1 && k_eq < 1 && k_gteq < 1) {
 
549
    Message (MSG_FATAL, "Must specify values for at least one of -u, -U, -k, -K");
 
550
    return 1;
 
551
  } else if (u_eq > -1 && u_gteq > -1) {
 
552
    Message (MSG_FATAL, "May only specify value for -u or -U, not both");
 
553
    return 1;
 
554
  } else if (k_eq > -1 && k_gteq > -1) {
 
555
    Message (MSG_FATAL, "May only specify value for -k or -K, not both");
 
556
    return 1;
 
557
  }
 
558
    
 
559
  if (u_eq > 0) {
 
560
    gap_sizes[0] = u_eq;
 
561
  } else if (u_gteq > 0) {
 
562
    gap_sizes[0] = 0 - u_gteq;
 
563
  }
 
564
 
 
565
  if (k_eq > 0) {
 
566
    gap_sizes[1] = k_eq;
 
567
  } else if (k_gteq > 0) {
 
568
    gap_sizes[1] = 0 - k_gteq;
 
569
  }
 
570
 
 
571
  if (gap_sizes[0] == gap_sizes[1]) {
 
572
    Message (MSG_FATAL, "Cannot specify the same size for known and unknown length gaps");
 
573
    return 1;
 
574
  }
 
575
 
 
576
  directory = (CharPtr) myargs [p_argInputPath].strvalue;
 
577
  osd.results_dir = (CharPtr) myargs [r_argOutputPath].strvalue;
 
578
  if (StringHasNoText (osd.results_dir)) {
 
579
    osd.results_dir = NULL;
 
580
  }
 
581
  osd.suffix = (CharPtr) myargs [x_argSuffix].strvalue;
 
582
  osd.outsuffix = (CharPtr) myargs [s_argOutSuffix].strvalue;
 
583
  osd.base = (CharPtr) myargs [i_argInputFile].strvalue;
 
584
  osd.outfile = (CharPtr) myargs [o_argOutputFile].strvalue;
 
585
  if (StringHasNoText (osd.outfile)) {
 
586
    osd.outfile = NULL;
 
587
  }
 
588
  osd.is_binary = (Boolean) myargs [d_argOutputBinary].intvalue;
 
589
 
 
590
  if (osd.base == "stdin") {
 
591
    osd.base = NULL;
 
592
  }
 
593
 
 
594
  /* if we don't have an output directory or an output file, and the user hasn't provided an
 
595
   * output suffix, add a default.
 
596
   */
 
597
  if (osd.results_dir == NULL && osd.outfile == NULL && StringHasNoText (osd.outsuffix)) {
 
598
    osd.outsuffix = ".delta";
 
599
  } 
 
600
 
 
601
  isd.is_binary = (Boolean) myargs [b_argInputBinary].intvalue;
 
602
  isd.is_seqentry = (Boolean) myargs [e_argInputSeqEntry].intvalue;
 
603
  isd.directory = directory;
 
604
  isd.base = osd.base;
 
605
  isd.suffix = osd.suffix;
 
606
 
 
607
  if (StringDoesHaveText (osd.outfile)) {
 
608
    osd.aip = AsnIoOpen (osd.outfile, "w");
 
609
    if (osd.aip == NULL) {
 
610
      Message (MSG_FATAL, "Unable to open output file");
 
611
      return 1;
 
612
    }
 
613
  } else {
 
614
    if (StringHasNoText (osd.results_dir)) {
 
615
      osd.results_dir = directory;
 
616
    }
 
617
    /* if we're putting the results in a separate directory, strip the directory name from the output base */
 
618
    if (!StringHasNoText (osd.results_dir) && !StringHasNoText (osd.base)) {
 
619
#ifdef OS_MSWIN
 
620
      ptr = StringRChr (osd.base, '\\');
 
621
#else
 
622
      ptr = StringRChr (osd.base, '/');
 
623
#endif;
 
624
      if (ptr != NULL) {
 
625
        osd.base = ptr + 1;
 
626
      }
 
627
    }
 
628
  }
 
629
 
 
630
 
 
631
  if (StringHasNoText(directory) && StringHasNoText(osd.base)) {
 
632
    rval = ProcessStream (&isd, &osd, &asd, gap_sizes);
 
633
  } else if (StringDoesHaveText (osd.base)) {
 
634
    ptr = StringRChr (osd.base, '.');
 
635
    sfx[0] = '\0';
 
636
    if (ptr != NULL) {
 
637
      StringNCpy_0 (sfx, ptr, sizeof (sfx));
 
638
      *ptr = '\0';
 
639
    }
 
640
    osd.suffix = sfx;
 
641
    isd.suffix = sfx;
 
642
    if (isd.is_binary) {
 
643
      rval = ProcessStream (&isd, &osd, &asd, gap_sizes);
 
644
    } else {
 
645
      rval = ProcessOneRecord (directory, &osd, gap_sizes);
 
646
    }
 
647
  } else {
 
648
 
 
649
    rval = FileRecurse (directory, &isd, &osd, &asd, gap_sizes);
 
650
  }
 
651
 
 
652
  if (osd.aip != NULL) {
 
653
    AsnIoFlush (osd.aip);
 
654
    AsnIoClose (osd.aip);
 
655
  }
 
656
  return rval;
 
657
}