~ubuntu-branches/ubuntu/dapper/ncbi-tools6/dapper

« back to all changes in this revision

Viewing changes to corelib/ncbistr.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2002-04-04 22:13:09 UTC
  • Revision ID: james.westby@ubuntu.com-20020404221309-vfze028rfnlrldct
Tags: upstream-6.1.20011220a
ImportĀ upstreamĀ versionĀ 6.1.20011220a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*   ncbistr.c
 
2
* ===========================================================================
 
3
*
 
4
*                            PUBLIC DOMAIN NOTICE                          
 
5
*               National Center for Biotechnology Information
 
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 have not placed any restriction on its use or reproduction.  
 
13
*                                                                          
 
14
*  Although all reasonable efforts have been taken to ensure the accuracy  
 
15
*  and reliability of the software and data, the NLM and the U.S.          
 
16
*  Government do not and cannot warrant the performance or results that    
 
17
*  may be obtained by using this software or data. The NLM and the U.S.    
 
18
*  Government disclaim all warranties, express or implied, including       
 
19
*  warranties of performance, merchantability or fitness for any particular
 
20
*  purpose.                                                                
 
21
*                                                                          
 
22
*  Please cite the author in any work or product based on this material.   
 
23
*
 
24
* ===========================================================================
 
25
*
 
26
* File Name:  ncbistr.c
 
27
*
 
28
* Author:  Gish, Kans, Ostell, Schuler, Brylawski, Vakatov, Lavrentiev
 
29
*
 
30
* Version Creation Date:   3/4/91
 
31
*
 
32
* $Revision: 6.10 $
 
33
*
 
34
* File Description: 
 
35
*       portable string routines
 
36
*
 
37
* Modifications:  
 
38
* --------------------------------------------------------------------------
 
39
* $Log: ncbistr.c,v $
 
40
* Revision 6.10  2001/01/05 22:43:58  shavirin
 
41
* Added functions, that transfer Uint8 values to platform-independent
 
42
* objects and back.
 
43
*
 
44
* Revision 6.9  2000/12/04 23:48:02  kans
 
45
* trim spaces around string now handles trailing tabs, newlines, etc.
 
46
*
 
47
* Revision 6.8  2000/11/30 22:46:07  lavr
 
48
* Added the following functions for conversions of Int8 and Uint8
 
49
* to strings and back; test suite attached at the end of the file.
 
50
* Nlm_Int8ToString, Nlm_Uint8ToString, Nlm_StringToInt8, Nlm_StringToUint8
 
51
*
 
52
* Revision 6.7  2000/08/28 18:36:25  vakatov
 
53
* un-const casts in some functions to pass C++ compilation
 
54
*
 
55
* Revision 6.6  1999/04/15 20:24:06  vakatov
 
56
* Dont use "list" name as it can clash with the standard "list<>" template
 
57
* on some raw C++ compilers
 
58
*
 
59
* Revision 6.5  1999/03/11 16:10:00  kans
 
60
* StringHasNoText and TrimSpacesAroundString moved from vibforms
 
61
*
 
62
* Revision 6.4  1998/11/23 00:09:47  kans
 
63
* fixed bug in StringTokMT (found by Hugues)
 
64
*
 
65
* Revision 6.3  1998/10/07 19:09:00  kans
 
66
* added Nlm_StringTokMT, multithread-safe version
 
67
*
 
68
* Revision 6.2  1997/11/26 21:26:25  vakatov
 
69
* Fixed errors and warnings issued by C and C++ (GNU and Sun) compilers
 
70
*
 
71
* Revision 6.1  1997/10/29 02:44:52  vakatov
 
72
* Type castings to pass through the C++ compiler
 
73
*
 
74
* Revision 5.5  1997/07/16 19:49:18  vakatov
 
75
* Added Nlm_StringPrintable() function
 
76
*
 
77
* Revision 5.4  1997/04/11 17:57:25  brandon
 
78
* added StrIPCmp, StrNIPCmp
 
79
*
 
80
 * Revision 5.3  1997/03/04  22:01:12  vakatov
 
81
 * Added a set of functions to format(stream2text), unformat(text2stream)
 
82
 * and adjust(rule_line) text and test/demo code #TEST_TEXT_FMT for these
 
83
 *
 
84
 * Revision 5.2  1997/01/03  15:56:28  vakatov
 
85
 * Added auxiliary function Nlm_StringNCpy_0() -- that guarantees the
 
86
 * resulting string be '\0'-terminated
 
87
 *
 
88
 * Revision 5.1  1996/12/03  21:48:33  vakatov
 
89
 * Adopted for 32-bit MS-Windows DLLs
 
90
 *
 
91
 * Revision 4.12  1996/05/22  18:04:14  kans
 
92
 * changed nulls to '\0' in new string functions
 
93
 *
 
94
 * Revision 4.11  1996/05/22  14:46:19  brandon
 
95
 * Fixed SkipToString, SkipPastString to work with short strings
 
96
 *
 
97
 * Revision 4.10  1996/05/07  13:22:37  kans
 
98
 * more protection for stringsearch
 
99
 *
 
100
 * Revision 4.9  1996/05/06  15:07:58  kans
 
101
 * fixed StringISearch to set d [] based on TO_UPPER, not to crash if nonASCII
 
102
 *
 
103
 * Revision 4.8  1996/03/14  03:42:44  epstein
 
104
 * change String variables to theString to work around SGI4 problem
 
105
 *
 
106
 * Revision 4.7  1996/01/05  02:29:37  ostell
 
107
 * provided return value for TruncateStringCopy()
 
108
 *
 
109
 * Revision 4.6  1996/01/03  21:04:46  epstein
 
110
 * modify StringSubString() API and add other new functions, per Brandon
 
111
 *
 
112
 * Revision 4.5  1996/01/02  14:17:32  ostell
 
113
 * added a number of Brandons functions
 
114
 *
 
115
 * Revision 4.4  1995/12/28  15:41:56  epstein
 
116
 * added Brylawskin to revision history and author list
 
117
 *
 
118
 * Revision 4.3  1995/12/27  20:53:48  epstein
 
119
 * add Brandon's string-management functions
 
120
 *
 
121
 * Revision 4.2  1995/10/28  15:03:20  ostell
 
122
 * added casts to quiet DOS compile warnings
 
123
 *
 
124
 * Revision 4.1  1995/10/16  13:43:29  epstein
 
125
 * fix brain-dmanaged string-compare logic to handle null strings correctly
 
126
 *
 
127
 * Revision 2.12  1995/07/18  19:56:10  tatiana
 
128
 * add Nlm_LabelCopyNext()
 
129
 *
 
130
 * Revision 2.11  1995/05/30  13:19:37  kans
 
131
 * fixed StringSearch algorithm - check until i <= strLen, not just < strLen
 
132
 *
 
133
* 3/4/91   Kans        Stricter typecasting for GNU C and C++.
 
134
* 09-19-91 Schuler     Changed all types expressing sizes to size_t.
 
135
* 09-19-91 Schuler     Changed return type for compare functions to int.
 
136
* 09-19-91 Schuler     Changed all functions to _cdecl calling convention.
 
137
* 09-19-91 Schuler     Where possible, NCBI functions call the actual ANSI
 
138
*                       functions after checking for NULL pointers.
 
139
* 09-19-91 Schuler     Debug-class error posted on any NULL argument.
 
140
* 09-19-91 Schuler     StringSave() calls MemGet() instead of MemNew().
 
141
* 09-19-91 Schuler     StringSave(NULL) returns NULL.
 
142
* 10-17-91 Schuler     Removed ErrPost() calls on NULL arguments.
 
143
* 10-17-91 Schuler     Added Nlm_StringCnt(),Nlm_StringStr(),Nlm_StringTok()
 
144
* 11-18-91 Schuler     Added more ANSI-style functions
 
145
* 04-15-93 Schuler     Changed _cdecl to LIBCALL
 
146
* 05-27-93 Schuler     Added const qualifiers to match ANSI cognates
 
147
* 06-14-94 Schuler     Added StrUpper() and StrLower() functions
 
148
* 03-08-95 Kans        Added StringSearch and StringISearch
 
149
* 12-27-95 Brylawski   Added a variety of functions, including search-and-
 
150
*                      replace functions.
 
151
*
 
152
* ==========================================================================
 
153
*/
 
154
 
 
155
#include <ncbi.h>
 
156
#include <ncbiwin.h>
 
157
 
 
158
/* ClearDestString clears the destination string if the source is NULL. */
 
159
static Nlm_CharPtr NEAR Nlm_ClearDestString (Nlm_CharPtr to, size_t max)
 
160
{
 
161
  if (to != NULL && max > 0) {
 
162
    Nlm_MemSet (to, 0, max);
 
163
    *to = '\0';
 
164
  }
 
165
  return to;
 
166
}
 
167
 
 
168
NLM_EXTERN size_t LIBCALL  Nlm_StringLen (const char *str)
 
169
{
 
170
        return str ? StrLen (str) : 0;
 
171
}
 
172
 
 
173
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringCpy (char FAR *to, const char FAR *from)
 
174
{
 
175
        return (to && from) ? StrCpy (to, from) : Nlm_ClearDestString (to, 1);
 
176
}
 
177
 
 
178
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringNCpy (char FAR *to, const char FAR *from, size_t max)
 
179
{
 
180
        return (to && from) ? StrNCpy (to, from, max) : Nlm_ClearDestString (to, max);
 
181
}
 
182
 
 
183
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringNCpy_0 (char FAR *to, const char FAR *from, size_t max)
 
184
{
 
185
  if (to != NULL  &&  max > 0)
 
186
    to[0] = '\0';
 
187
 
 
188
  if (from != NULL)
 
189
    StrNCat(to, from, max - 1);
 
190
 
 
191
  return to;
 
192
}
 
193
 
 
194
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringCat (char FAR *to, const char FAR *from)
 
195
{
 
196
        return (to && from) ? StrCat (to, from) : to;
 
197
}
 
198
 
 
199
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringNCat (char FAR *to, const char FAR *from, size_t max)
 
200
{       
 
201
    return (to && from) ? StrNCat (to, from, max) : to;
 
202
}
 
203
 
 
204
NLM_EXTERN int LIBCALL  Nlm_StringCmp (const char FAR *a, const char FAR *b)
 
205
{
 
206
        return (a && b) ? StrCmp(a, b) : (a ? 1 : (b ? -1 : 0));
 
207
}
 
208
 
 
209
NLM_EXTERN int LIBCALL  Nlm_StringNCmp (const char FAR *a, const char FAR *b, size_t max)
 
210
{
 
211
        return (a && b) ? StrNCmp(a, b, max) : (a ? 1 : (b ? -1 : 0));
 
212
}
 
213
 
 
214
NLM_EXTERN int LIBCALL  Nlm_StringICmp (const char FAR *a, const char FAR *b)
 
215
{
 
216
        return (a && b) ? Nlm_StrICmp(a, b) : (a ? 1 : (b ? -1 : 0));
 
217
}
 
218
 
 
219
NLM_EXTERN int LIBCALL  Nlm_StringNICmp (const char FAR *a, const char FAR *b, size_t max)
 
220
{
 
221
        return (a && b) ? Nlm_StrNICmp(a, b, max) : (a ? 1 : (b ? -1 : 0));
 
222
}
 
223
 
 
224
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringChr (const char FAR *str, int chr)
 
225
{
 
226
        return (Nlm_CharPtr) (str ? Nlm_StrChr(str,chr) : 0);
 
227
}
 
228
 
 
229
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringRChr (const char FAR *str, int chr)
 
230
{
 
231
        return (Nlm_CharPtr) (str ? Nlm_StrRChr(str,chr) : 0);
 
232
}
 
233
 
 
234
NLM_EXTERN size_t LIBCALL  Nlm_StringSpn (const char FAR *a, const char FAR *b)
 
235
{
 
236
        return (a && b) ? Nlm_StrSpn (a, b) : 0;
 
237
}
 
238
 
 
239
NLM_EXTERN size_t LIBCALL  Nlm_StringCSpn (const char FAR *a, const char FAR *b)
 
240
{
 
241
        return (a && b) ? Nlm_StrCSpn (a, b) : 0;
 
242
}
 
243
 
 
244
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringPBrk (const char FAR *a, const char FAR *b)
 
245
{
 
246
        return (Nlm_CharPtr) ((a && b) ? Nlm_StrPBrk (a, b) : 0);
 
247
}
 
248
 
 
249
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringStr (const char FAR *str1, const char FAR *str2)
 
250
{
 
251
        return (Nlm_CharPtr) ((str1 && str2) ? Nlm_StrStr(str1,str2) : 0);
 
252
}
 
253
 
 
254
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringTok (char FAR *str1, const char FAR *str2)
 
255
{
 
256
    return str2 ? Nlm_StrTok(str1,str2) : 0;
 
257
}
 
258
 
 
259
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringTokMT (char FAR *str1, const char FAR *str2, char FAR **tmp)
 
260
{
 
261
        char ch;
 
262
        char FAR *ptr;
 
263
        char FAR *rsult = NULL;
 
264
 
 
265
        if (str2 == NULL || tmp == NULL) return NULL;
 
266
        if (str1 != NULL) {
 
267
          *tmp = str1;
 
268
    }
 
269
    ptr = *tmp;
 
270
    if (ptr == NULL) return NULL;
 
271
    ch = *ptr;
 
272
    while (ch != '\0' && strchr (str2, ch) != NULL) {
 
273
      ptr++;
 
274
      ch = *ptr;
 
275
    }
 
276
    if (ch == '\0') {
 
277
      *tmp = NULL;
 
278
      return NULL;
 
279
    }
 
280
    rsult = ptr;
 
281
    while (ch != '\0' && strchr (str2, ch) == NULL) {
 
282
      ptr++;
 
283
      ch = *ptr;
 
284
    }
 
285
    if (ch == '\0') {
 
286
      *tmp = NULL;
 
287
    } else {
 
288
      *ptr = '\0';
 
289
      ptr++;
 
290
      *tmp = ptr;
 
291
    }
 
292
    return rsult; 
 
293
}
 
294
 
 
295
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringMove (char FAR *to, const char FAR *from)
 
296
{
 
297
    return (to && from) ? Nlm_StrMove (to, from) : to;
 
298
}
 
299
 
 
300
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringSave (const char FAR *from)
 
301
{
 
302
    return from ? Nlm_StrSave (from) : 0;
 
303
}
 
304
 
 
305
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StringSaveNoNull (const char FAR *from)
 
306
{
 
307
    return (from  && *from) ? Nlm_StrSave(from) : 0;
 
308
}
 
309
 
 
310
NLM_EXTERN size_t LIBCALL  Nlm_StringCnt (const char FAR *str, const char FAR *x_list)
 
311
{
 
312
    return (str && x_list) ? Nlm_StrCnt(str,x_list) : 0;
 
313
}
 
314
 
 
315
NLM_EXTERN char * LIBCALL Nlm_StringUpper (char *string)
 
316
{
 
317
        return (string == NULL) ? 0 : StrUpper(string);
 
318
}
 
319
 
 
320
NLM_EXTERN char * LIBCALL Nlm_StringLower (char *string)
 
321
{
 
322
        return (string == NULL) ? 0 : StrLower(string);
 
323
}
 
324
 
 
325
 
 
326
 
 
327
 
 
328
 
 
329
NLM_EXTERN int LIBCALL  Nlm_StrICmp (const char FAR *a, const char FAR *b)
 
330
{
 
331
        int diff, done;
 
332
 
 
333
    if (a == b)   return 0;
 
334
 
 
335
        done = 0;
 
336
        while (! done)
 
337
        {
 
338
                diff = TO_UPPER(*a) - TO_UPPER(*b);
 
339
                if (diff)
 
340
                        return (Nlm_Int2) diff;
 
341
                if (*a == '\0')
 
342
                        done = 1;
 
343
                else
 
344
                {
 
345
                        a++; b++;
 
346
                }
 
347
        }
 
348
        return 0;
 
349
}
 
350
 
 
351
NLM_EXTERN int LIBCALL  Nlm_StrIPCmp (const char FAR *a, const char FAR *b)
 
352
{
 
353
  int diff, done;
 
354
  
 
355
  if (a == b)   return 0;
 
356
  
 
357
  while (*a && !isalnum(*a))
 
358
    a++;
 
359
  
 
360
  while (*b && !isalnum(*b))
 
361
    b++;
 
362
  
 
363
  done = 0;
 
364
  while (! done)
 
365
    {
 
366
      if (!isalnum(*a) && !isalnum(*b))
 
367
        {
 
368
          while (*a && !isalnum(*a))
 
369
            a++;
 
370
          
 
371
          while (*b && !isalnum(*b))
 
372
            b++;
 
373
        }
 
374
      
 
375
      diff = TO_UPPER(*a) - TO_UPPER(*b);
 
376
      if (diff)
 
377
        return (Nlm_Int2) diff;
 
378
      if (*a == '\0')
 
379
        done = 1;
 
380
      else
 
381
        {
 
382
          a++; b++;
 
383
        }
 
384
    }
 
385
  return 0;
 
386
}
 
387
 
 
388
NLM_EXTERN int LIBCALL  Nlm_StrNICmp (const char FAR *a, const char FAR *b, size_t max)
 
389
{
 
390
        int diff, done;
 
391
        
 
392
    if (a == b)   return 0;
 
393
 
 
394
        done = 0;
 
395
        while (! done)
 
396
        {
 
397
                diff = TO_UPPER(*a) - TO_UPPER(*b);
 
398
                if (diff)
 
399
                        return (Nlm_Int2) diff;
 
400
                if (*a == '\0')
 
401
                        done = 1;
 
402
                else
 
403
                {
 
404
                        a++; b++; max--;
 
405
                        if (! max)
 
406
                                done = 1;
 
407
                }
 
408
        }
 
409
        return 0;
 
410
}
 
411
 
 
412
NLM_EXTERN int LIBCALL  Nlm_StrNIPCmp (const char FAR *a, const char FAR *b, size_t max)
 
413
{
 
414
  int diff, done;
 
415
  
 
416
  if (a == b)   return 0;
 
417
  
 
418
  while (*a && !isalnum(*a))
 
419
    a++;
 
420
  
 
421
  while (*b && !isalnum(*b))
 
422
    b++;
 
423
  
 
424
  done = 0;
 
425
  while (! done)
 
426
    {
 
427
      if (!isalnum(*a) && !isalnum(*b))
 
428
        {
 
429
          while (*a && !isalnum(*a))
 
430
            {
 
431
              a++; max--;
 
432
              if (!max)
 
433
                {
 
434
                  done = 1;
 
435
                  break;
 
436
                }
 
437
            }
 
438
          
 
439
          while (*b && !isalnum(*b))
 
440
            b++;
 
441
        }
 
442
      
 
443
      
 
444
      diff = TO_UPPER(*a) - TO_UPPER(*b);
 
445
      if (diff)
 
446
        return (Nlm_Int2) diff;
 
447
      if (*a == '\0')
 
448
        done = 1;
 
449
      else
 
450
        {
 
451
          a++; b++; max--;
 
452
          if (! max)
 
453
            done = 1;
 
454
        }
 
455
    }
 
456
  return 0;
 
457
}
 
458
 
 
459
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StrSave (const char FAR *from)
 
460
{
 
461
        size_t len;
 
462
        Nlm_CharPtr to;
 
463
 
 
464
        len = Nlm_StringLen(from);
 
465
        if ((to = (Nlm_CharPtr) Nlm_MemGet(len +1, FALSE)) != NULL) {
 
466
        Nlm_MemCpy (to, from, len +1);
 
467
        }
 
468
        return to;
 
469
}
 
470
 
 
471
NLM_EXTERN Nlm_CharPtr LIBCALL  Nlm_StrMove (char FAR *to, const char FAR *from)
 
472
{
 
473
        while (*from != '\0')
 
474
        {
 
475
                *to = *from;
 
476
                to++; from++;
 
477
        }
 
478
        *to = '\0';
 
479
        return to;
 
480
}
 
481
 
 
482
NLM_EXTERN Nlm_Boolean LIBCALL Nlm_StringHasNoText (Nlm_CharPtr str)
 
483
 
 
484
{
 
485
  Nlm_Uchar  ch;        /* to use 8bit characters in multibyte languages */
 
486
 
 
487
  if (str != NULL) {
 
488
    ch = *str;
 
489
    while (ch != '\0') {
 
490
      if (ch > ' ') {
 
491
        return FALSE;
 
492
      }
 
493
      str++;
 
494
      ch = *str;
 
495
    }
 
496
  }
 
497
  return TRUE;
 
498
}
 
499
 
 
500
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_TrimSpacesAroundString (Nlm_CharPtr str)
 
501
 
 
502
{
 
503
  Nlm_Uchar    ch;      /* to use 8bit characters in multibyte languages */
 
504
  Nlm_CharPtr  dst;
 
505
  Nlm_CharPtr  ptr;
 
506
 
 
507
  if (str != NULL && str [0] != '\0') {
 
508
    dst = str;
 
509
    ptr = str;
 
510
    ch = *ptr;
 
511
    while (ch != '\0' && ch <= ' ') {
 
512
      ptr++;
 
513
      ch = *ptr;
 
514
    }
 
515
    while (ch != '\0') {
 
516
      *dst = ch;
 
517
      dst++;
 
518
      ptr++;
 
519
      ch = *ptr;
 
520
    }
 
521
    *dst = '\0';
 
522
    dst = NULL;
 
523
    ptr = str;
 
524
    ch = *ptr;
 
525
    while (ch != '\0') {
 
526
      if (ch > ' ') {
 
527
        dst = NULL;
 
528
      } else if (dst == NULL) {
 
529
        dst = ptr;
 
530
      }
 
531
      ptr++;
 
532
      ch = *ptr;
 
533
    }
 
534
    if (dst != NULL) {
 
535
      *dst = '\0';
 
536
    }
 
537
  }
 
538
  return str;
 
539
}
 
540
 
 
541
NLM_EXTERN size_t LIBCALL Nlm_StrCnt(const char FAR *s, const char FAR *x_list)
 
542
{
 
543
        size_t  cmap[1<<CHAR_BIT];
 
544
        Nlm_Byte        c;
 
545
        size_t  u, cnt;
 
546
        const Nlm_Byte *bs = (const Nlm_Byte*)s;
 
547
        const Nlm_Byte *blist = (const Nlm_Byte*)x_list;
 
548
 
 
549
        if (s == NULL || x_list == NULL)
 
550
                return 0;
 
551
 
 
552
        for (u = 0; u < DIM(cmap); ++u)
 
553
                cmap[u] = 0;
 
554
        while (*blist != '\0')
 
555
                ++cmap[*blist++];
 
556
 
 
557
        blist = (Nlm_BytePtr)cmap;
 
558
 
 
559
        cnt = 0;
 
560
        while ((c = *bs++) != '\0')
 
561
                cnt += blist[c];
 
562
 
 
563
        return cnt;
 
564
}
 
565
 
 
566
#ifndef COMP_MSC
 
567
NLM_EXTERN char * LIBCALL Nlm_StrUpper (char *string)
 
568
{
 
569
        register char *p = string;
 
570
        ASSERT(string != NULL);
 
571
        while (*p)
 
572
        {
 
573
                if (isalpha(*p))
 
574
                        *p = (char)toupper(*p);
 
575
                ++p;
 
576
        }
 
577
        return string;
 
578
}
 
579
#endif
 
580
 
 
581
#ifndef COMP_MSC
 
582
NLM_EXTERN char * LIBCALL Nlm_StrLower (char *string)
 
583
{
 
584
        register char *p = string;
 
585
        ASSERT(string != NULL);
 
586
        while (*p)
 
587
        {
 
588
                if (isalpha(*p))
 
589
                        *p = (char)tolower(*p);
 
590
                ++p;
 
591
        }
 
592
        return string;
 
593
}
 
594
#endif
 
595
 
 
596
 
 
597
/*  -------------------- MeshStringICmp() --------------------------------
 
598
 *  MeshStringICmp compares strings where / takes precedence to space.
 
599
 */
 
600
 
 
601
NLM_EXTERN Nlm_Int2 LIBCALL Nlm_MeshStringICmp (const char FAR *str1, const char FAR *str2)
 
602
{
 
603
        Nlm_Char  ch1, ch2;
 
604
 
 
605
        if (str1 == NULL)
 
606
        {
 
607
                if (str2 == NULL)
 
608
                        return (Nlm_Int2)0;
 
609
                else
 
610
                        return (Nlm_Int2)1;
 
611
        }
 
612
        else if (str2 == NULL)
 
613
                return (Nlm_Int2)-1;
 
614
 
 
615
        while ((*str1 >= ' ') && (*str2 >= ' ') && (TO_LOWER(*str1) == TO_LOWER(*str2)))
 
616
        {
 
617
                str1++; str2++;
 
618
        }
 
619
 
 
620
        ch1 = *str1;
 
621
        ch2 = *str2;
 
622
        if ((ch1 < ' ') && (ch2 < ' '))
 
623
                return (Nlm_Int2)0;
 
624
        else if (ch1 < ' ')
 
625
                return (Nlm_Int2)-1;
 
626
        else if (ch2 < ' ')
 
627
                return (Nlm_Int2)1;
 
628
 
 
629
        if (ch1 == '/')
 
630
          ch1 = '\31';
 
631
        if (ch2 == '/')
 
632
          ch2 = '\31';
 
633
 
 
634
        if (TO_LOWER (ch1) > TO_LOWER (ch2))
 
635
          return (Nlm_Int2)1;
 
636
        else if (TO_LOWER (ch1) < TO_LOWER (ch2))
 
637
          return (Nlm_Int2)(-1);
 
638
        else
 
639
          return (Nlm_Int2)0;
 
640
}
 
641
 
 
642
/* StringSearch and StringISearch use the Boyer-Moore algorithm, as described
 
643
   in Niklaus Wirth, Algorithms and Data Structures, Prentice- Hall, Inc.,
 
644
   Englewood Cliffs, NJ., 1986, p. 69.  The original had an error, where
 
645
   UNTIL (j < 0) OR (p[j] # s[i]) should be UNTIL (j < 0) OR (p[j] # s[k]). */
 
646
 
 
647
static Nlm_CharPtr Nlm_FindSubString (const char FAR *str, const char FAR *sub,
 
648
                                      Nlm_Boolean caseCounts)
 
649
 
 
650
{
 
651
  int      ch;
 
652
  int      d [256];
 
653
  int      i;
 
654
  int      j;
 
655
  int      k;
 
656
  size_t   strLen;
 
657
  size_t   subLen;
 
658
 
 
659
  if (sub != NULL && sub [0] != '\0' && str != NULL && str [0] != '\0') {
 
660
    strLen = Nlm_StringLen (str);
 
661
    subLen = Nlm_StringLen (sub);
 
662
    if (subLen <= strLen) {
 
663
      for (ch = 0; ch < 256; ch++) {
 
664
        d [ch] = subLen;
 
665
      }
 
666
      for (j = 0; j < (int)(subLen - 1); j++) {
 
667
        ch = (int) (caseCounts ? sub [j] : TO_UPPER (sub [j]));
 
668
        if (ch >= 0 && ch <= 255) {
 
669
          d [ch] = subLen - j - 1;
 
670
        }
 
671
     }
 
672
      i = subLen;
 
673
      do {
 
674
        j = subLen;
 
675
        k = i;
 
676
        do {
 
677
          k--;
 
678
          j--;
 
679
        } while (j >= 0 &&
 
680
                 (caseCounts ? sub [j] : TO_UPPER (sub [j])) ==
 
681
                 (caseCounts ? str [k] : TO_UPPER (str [k])));
 
682
        if (j >= 0) {
 
683
          ch = (int) (caseCounts ? str [i - 1] : TO_UPPER (str [i - 1]));
 
684
          if (ch >= 0 && ch <= 255) {
 
685
            i += d [ch];
 
686
          } else {
 
687
            i++;
 
688
          }
 
689
        }
 
690
      } while (j >= 0 && i <= (int) strLen);
 
691
      if (j < 0) {
 
692
        i -= subLen;
 
693
        return (Nlm_CharPtr) (str + i);
 
694
      }
 
695
    }
 
696
  }
 
697
  return NULL;
 
698
}
 
699
 
 
700
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_StringSearch (const char FAR *str, const char FAR *sub)
 
701
 
 
702
{
 
703
  return Nlm_FindSubString (str, sub, TRUE);
 
704
}
 
705
 
 
706
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_StringISearch (const char FAR *str, const char FAR *sub)
 
707
 
 
708
{
 
709
  return Nlm_FindSubString (str, sub, FALSE);
 
710
}
 
711
 
 
712
NLM_EXTERN Nlm_Uint1Ptr LIBCALL Uint8ToBytes(Nlm_Uint8 value)
 
713
{
 
714
    Nlm_Uint1Ptr out_bytes;
 
715
    Nlm_Int4 i, mask = 0xFF;
 
716
    
 
717
    out_bytes = MemNew(8);
 
718
    
 
719
    for(i = 0; i < 8; i++) {
 
720
        out_bytes[i] = value & mask;
 
721
        value >>= 8;
 
722
    }
 
723
    
 
724
    return out_bytes;
 
725
}
 
726
 
 
727
NLM_EXTERN Nlm_Uint8 LIBCALL BytesToUint8(Nlm_Uint1Ptr bytes)
 
728
{
 
729
    Nlm_Uint8 value;
 
730
    Nlm_Int4 i;
 
731
 
 
732
    value = 0;
 
733
    for(i = 7; i >= 0; i--) {
 
734
        value += bytes[i];
 
735
        if(i) value <<= 8;
 
736
    }
 
737
    
 
738
    return value;
 
739
}
 
740
static Nlm_Uint8 s_StringToUint8(const char *str, const char **endptr, int *sgn)
 
741
{
 
742
    int sign = 0;  /* actual sign */
 
743
    Nlm_Uint8 limdiv, limoff, result;
 
744
    const char *s, *save;
 
745
    char c;
 
746
 
 
747
    /* assume error */
 
748
    *endptr = 0;
 
749
    if (!str)
 
750
        return 0;
 
751
 
 
752
    s = str;
 
753
    while (IS_WHITESP(*s))
 
754
        s++;
 
755
    /* empty string - error */
 
756
    if (*s == '\0')
 
757
        return 0;
 
758
 
 
759
    if (*sgn == 1) {
 
760
        if (*s == '-') {
 
761
            sign = 1;
 
762
            s++;
 
763
        } else if (*s == '+') {
 
764
            s++;
 
765
        }        
 
766
    }
 
767
    save = s;
 
768
 
 
769
    limdiv = UINT8_MAX / 10;
 
770
    limoff = UINT8_MAX % 10;
 
771
    result = 0;
 
772
    
 
773
    for (c = *s; c; c = *++s) {
 
774
        if (!IS_DIGIT(c)) {
 
775
            break;
 
776
        }
 
777
        c -= '0';
 
778
        if (result > limdiv || (result == limdiv && c > limoff)) {
 
779
            /* overflow */
 
780
            return 0;
 
781
        }
 
782
        result *= 10;
 
783
        result += c;
 
784
    }
 
785
 
 
786
    /* there was no conversion - error */
 
787
    if (save == s)
 
788
        return 0;
 
789
 
 
790
    *sgn = sign;
 
791
    *endptr = s;
 
792
    return result;
 
793
}
 
794
 
 
795
 
 
796
NLM_EXTERN Nlm_Uint8 LIBCALL Nlm_StringToUint8(const char* str, const char** endptr)
 
797
{
 
798
    int sign = 0; /* no sign allowed */
 
799
    return s_StringToUint8(str, endptr, &sign);
 
800
}
 
801
 
 
802
 
 
803
NLM_EXTERN Nlm_Int8  LIBCALL Nlm_StringToInt8(const char* str, const char** endptr)
 
804
{
 
805
    int sign = 1; /* sign allowed */
 
806
    Nlm_Uint8 result = s_StringToUint8(str, endptr, &sign);
 
807
    if (*endptr) {
 
808
        /* Check for overflow */
 
809
        if (result > (sign
 
810
                      ? -((Nlm_Uint8)(INT8_MIN + 1)) + 1
 
811
                      : (Nlm_Uint8)(INT8_MAX)))
 
812
            *endptr = 0;            
 
813
    }
 
814
    if (!*endptr)
 
815
        return 0;
 
816
    return sign ? -result : result;
 
817
}
 
818
 
 
819
 
 
820
static char *s_Uint8ToString(Nlm_Uint8 value, char *str, size_t str_size)
 
821
{
 
822
    char buf[32];
 
823
    size_t i, j;
 
824
 
 
825
    if (!str || str_size < 2)
 
826
        return 0;
 
827
 
 
828
    for (i = sizeof(buf) - 1; i > 0; i--) {
 
829
        buf[i] = (char)(value % 10 + '0');
 
830
        value /= 10;
 
831
        if (!value)
 
832
            break;
 
833
    }
 
834
    if (!i || (j = sizeof(buf) - i) >= str_size)
 
835
        return 0;
 
836
    memcpy(str, buf + i, j);
 
837
    str[j] = '\0';
 
838
    return str;
 
839
}
 
840
 
 
841
 
 
842
NLM_EXTERN char* LIBCALL Nlm_Uint8ToString(Nlm_Uint8 value, char* str, size_t str_size)
 
843
{
 
844
    return s_Uint8ToString(value, str, str_size);
 
845
}
 
846
 
 
847
 
 
848
NLM_EXTERN char* LIBCALL Nlm_Int8ToString (Nlm_Int8  value, char* str, size_t str_size)
 
849
{
 
850
    Nlm_Uint8 val;
 
851
    char *save = str;
 
852
 
 
853
    if (value < 0) {
 
854
        if (!str || !str_size)
 
855
            return 0;
 
856
        *str++ = '-';
 
857
        str_size--;
 
858
        val = -(Nlm_Uint8)(value + 1) + 1;
 
859
    } else
 
860
        val = value;
 
861
 
 
862
    return s_Uint8ToString(val, str, str_size) ? save : 0;
 
863
}
 
864
 
 
865
 
 
866
/*****************************************************************************
 
867
*
 
868
*   LabelCopy (to, from, buflen)
 
869
*       Copies the string "from" into "to" for up to "buflen" chars
 
870
*       if "from" is longer than buflen, makes the last character '>'
 
871
*       always puts one '\0' to terminate the string in to
 
872
*       to MUST be one character longer than buflen to leave room for the
 
873
*               last '\0' if from = buflen.
 
874
*       returns number of characters transferred to "to"
 
875
*
 
876
*****************************************************************************/
 
877
NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopy (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen)
 
878
{
 
879
        Nlm_Int2 len;
 
880
 
 
881
        if ((to == NULL) || (from == NULL) || (buflen < 0)) return 0;
 
882
        
 
883
        if (buflen == 0)         /* this is a sign of multiple writes */
 
884
        {
 
885
                *(to-1) = '>';
 
886
                return 0;
 
887
        }
 
888
        
 
889
        len = buflen;
 
890
 
 
891
        while ((*from != '\0') && (buflen))
 
892
        {
 
893
                *to = *from;
 
894
                from++; to++; buflen--;
 
895
        }
 
896
 
 
897
        if (*from != '\0')
 
898
        {
 
899
                *(to - 1) = '>';
 
900
        }
 
901
 
 
902
        *to = '\0';      /* buffer is bufferlen+1 */
 
903
        return (Nlm_Int2)(len - buflen);
 
904
}
 
905
 
 
906
NLM_EXTERN void LIBCALL Nlm_LabelCopyNext(Nlm_CharPtr PNTR to, Nlm_CharPtr from, Nlm_Int2 PNTR buflen)
 
907
{
 
908
        Nlm_Int2 diff;
 
909
 
 
910
        diff = Nlm_LabelCopy(*to, from, *buflen);
 
911
        *buflen -= diff; *to += diff;
 
912
        
 
913
}
 
914
 
 
915
/*****************************************************************************
 
916
*
 
917
*   LabelCopyExtra (to, from, buflen, prefix, suffix)
 
918
*       Copies the string "from" into "to" for up to "buflen" chars
 
919
*       if all together are longer than buflen, makes the last character '>'
 
920
*       always puts one '\0' to terminate the string in to
 
921
*       to MUST be one character longer than buflen to leave room for the
 
922
*               last '\0' if from = buflen.
 
923
*       returns number of characters transferred to "to"
 
924
*
 
925
*       if not NULL, puts prefix before from and suffix after from
 
926
*               both contained within buflen
 
927
*  
 
928
*
 
929
*****************************************************************************/
 
930
NLM_EXTERN Nlm_Int2 LIBCALL Nlm_LabelCopyExtra (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen, Nlm_CharPtr prefix, Nlm_CharPtr suffix)
 
931
{
 
932
        Nlm_Int2 len, diff;
 
933
 
 
934
        if ((to == NULL) || (buflen < 1) || (from == NULL)) return 0;
 
935
 
 
936
        len = buflen;
 
937
        diff = Nlm_LabelCopy(to, prefix, buflen);
 
938
        buflen -= diff; to += diff;
 
939
 
 
940
        diff = Nlm_LabelCopy(to, from, buflen);
 
941
        buflen -= diff; to += diff;
 
942
 
 
943
        diff = Nlm_LabelCopy(to, suffix, buflen);
 
944
        buflen -= diff;
 
945
 
 
946
        return (Nlm_Int2)(len-buflen);
 
947
}
 
948
 
 
949
#define NEWLINE '\n'
 
950
#define SPACE ' '
 
951
 
 
952
NLM_EXTERN Nlm_CharPtr LIBCALL StrCpyPtr (char FAR *Dest, char FAR *Start, char FAR *Stop)
 
953
/* copies the string from Start (inclusive) to Stop (exclusive) to 
 
954
string Dest. Start and Stop MUST point to the same string! 
 
955
*/
 
956
{
 
957
  Nlm_CharPtr To = Dest;
 
958
  while ( *Start && ( Start < Stop ) )
 
959
    *To++ = *Start++;
 
960
  *To = NULLB;
 
961
  
 
962
  return(Dest);
 
963
}
 
964
 
 
965
NLM_EXTERN Nlm_CharPtr LIBCALL StrDupPtr(char FAR *Start,char FAR *Stop)
 
966
/* copies the string from Start (inclusive) to Stop (exclusive) to 
 
967
   a new string and returns its pointer. 
 
968
   Start and Stop MUST point to the same string! 
 
969
*/
 
970
{
 
971
  Nlm_CharPtr Dest, DestPtr;
 
972
  
 
973
  DestPtr = Dest = (Nlm_CharPtr)Nlm_MemGet((Stop - Start + 1),MGET_ERRPOST);
 
974
  
 
975
  while ( *Start && ( Start < Stop ) )
 
976
    *DestPtr++ = *Start++;
 
977
  *DestPtr = NULLB;
 
978
  return(Dest);
 
979
}
 
980
 
 
981
NLM_EXTERN Nlm_CharPtr LIBCALL SkipSpaces(char FAR *Line)
 
982
/* returns the next non-whitespace position in the line. */
 
983
{
 
984
  while( (*Line != NULLB) && isspace(*Line) )
 
985
    Line++;
 
986
  return(Line);
 
987
}
 
988
 
 
989
 
 
990
NLM_EXTERN Nlm_CharPtr LIBCALL SkipToSpace(char FAR *theString)
 
991
/* returns a pointer to the leftmost whitespace character in theString, 
 
992
   or to the trailing NULL if no whitespace is found. */
 
993
{
 
994
  while (*theString && ( ! isspace(*theString) ))
 
995
    theString++;
 
996
  return(theString);
 
997
}
 
998
 
 
999
 
 
1000
NLM_EXTERN Nlm_CharPtr LIBCALL SkipChar(char FAR *theString,char Char)
 
1001
/* returns a pointer to the next non-Char character in theString. */
 
1002
{
 
1003
  while (*theString && ( *theString == Char ) )
 
1004
    theString++;
 
1005
  return(theString);
 
1006
}
 
1007
 
 
1008
 
 
1009
NLM_EXTERN Nlm_CharPtr LIBCALL SkipToChar(char FAR *theString,char Char)
 
1010
/* returns a pointer to leftmost instance of Char in theString, or to
 
1011
   the trailing NULL if none found. */
 
1012
{
 
1013
  while (*theString && ( *theString != Char ) )
 
1014
    theString++;
 
1015
  return(theString);
 
1016
}
 
1017
 
 
1018
 
 
1019
NLM_EXTERN Nlm_CharPtr LIBCALL SkipPastChar(char FAR *theString,char Char)
 
1020
/* returns a pointer to the next character after the leftmost instance
 
1021
   of Char in theString, or to the trailing NULL if none found. */
 
1022
{
 
1023
  while (*theString && ( *theString != Char ) )
 
1024
    theString++;
 
1025
 
 
1026
  if (*theString)
 
1027
    return(theString+1);
 
1028
  else
 
1029
    return(theString);
 
1030
}
 
1031
 
 
1032
NLM_EXTERN Nlm_CharPtr LIBCALL SkipToString(char FAR *theString,char FAR *Find)
 
1033
/* returns a pointer to leftmost instance of Find in theString, or to
 
1034
   the trailing NULL if none found. */
 
1035
{
 
1036
  char *FindPtr,*theStringPtr;
 
1037
  
 
1038
  while (*theString)
 
1039
    {
 
1040
      FindPtr = Find;
 
1041
      theStringPtr = theString;
 
1042
      while (*FindPtr && ( *FindPtr == *theStringPtr))
 
1043
        {
 
1044
          FindPtr++;
 
1045
          theStringPtr++;
 
1046
        }
 
1047
      
 
1048
      if (*FindPtr == '\0')
 
1049
        return(theString);
 
1050
      else
 
1051
        theString++;
 
1052
    }
 
1053
  
 
1054
  return(theString);
 
1055
}
 
1056
 
 
1057
 
 
1058
NLM_EXTERN Nlm_CharPtr LIBCALL NoCaseSkipToString(char FAR *theString,char FAR *Find)
 
1059
/* returns a pointer to leftmost instance of Find in theString, 
 
1060
   ignoring case, or to the trailing NULL if none found. */
 
1061
{
 
1062
  char *FindPtr,*theStringPtr;
 
1063
  
 
1064
  while (*theString)
 
1065
    {
 
1066
      FindPtr = Find;
 
1067
      theStringPtr = theString;
 
1068
      while (*FindPtr && (toupper(*FindPtr) == toupper(*theStringPtr)))
 
1069
        {
 
1070
          FindPtr++;
 
1071
          theStringPtr++;
 
1072
        }
 
1073
      
 
1074
      if (*FindPtr == '\0')
 
1075
        return(theString);
 
1076
      else
 
1077
        theString++;
 
1078
    }
 
1079
  
 
1080
  return(theString);
 
1081
}
 
1082
 
 
1083
 
 
1084
NLM_EXTERN Nlm_CharPtr LIBCALL SkipPastString(char FAR *theString,char FAR *Find)
 
1085
/* returns a pointer to the next character after the leftmost
 
1086
   instance of Find in theString, or to the trailing NULL if none found. */
 
1087
{
 
1088
  Nlm_CharPtr Ptr = SkipToString(theString,Find);
 
1089
 
 
1090
  if (*Ptr == '\0')
 
1091
    return (Ptr);
 
1092
 
 
1093
  return (Ptr + Nlm_StringLen(Find));
 
1094
}
 
1095
 
 
1096
NLM_EXTERN Nlm_CharPtr LIBCALL NoCaseSkipPastString(char FAR *theString,char FAR *Find)
 
1097
/* returns a pointer to the next character after the leftmost
 
1098
   instance of Find in theString, ignoring case,
 
1099
   or to the trailing NULL if none found. */
 
1100
{
 
1101
  Nlm_CharPtr Ptr = SkipToString(theString,Find);
 
1102
 
 
1103
  if (*Ptr == '\0')
 
1104
    return (Ptr);
 
1105
 
 
1106
  return (Ptr + Nlm_StringLen(Find));
 
1107
}
 
1108
 
 
1109
NLM_EXTERN Nlm_CharPtr LIBCALL SkipSet(char FAR *theString,char FAR *CharSet)
 
1110
/* returns a pointer to the next character in theString that is
 
1111
   not in CharSet. */
 
1112
{
 
1113
  Nlm_CharPtr CharSetPtr;
 
1114
  while (*theString)
 
1115
    {
 
1116
      CharSetPtr = CharSet;
 
1117
      while ( *CharSetPtr && *theString != *CharSetPtr )
 
1118
        CharSetPtr++;
 
1119
      if ( ! *CharSetPtr )
 
1120
        return (theString);
 
1121
      theString++;
 
1122
    }
 
1123
  return(theString);
 
1124
}
 
1125
 
 
1126
NLM_EXTERN Nlm_CharPtr LIBCALL SkipToSet(char FAR *theString,char FAR *CharSet)
 
1127
/* returns a pointer to leftmost instance of any char in string
 
1128
   CharSet in theString, or to the trailing NULL if none found. */
 
1129
{
 
1130
  Nlm_CharPtr CharSetPtr;
 
1131
  while (*theString)
 
1132
    {
 
1133
      CharSetPtr = CharSet;
 
1134
      while ( *CharSetPtr && (*theString != *CharSetPtr) )
 
1135
        CharSetPtr++;
 
1136
      if ( *CharSetPtr )
 
1137
        return (theString);
 
1138
      theString++;
 
1139
    }
 
1140
  return(theString);
 
1141
}
 
1142
 
 
1143
 
 
1144
NLM_EXTERN Nlm_Boolean LIBCALL StringSub(char FAR *theString, char Find, char Replace)
 
1145
/* replaces all instances of the character Find in the given theString with
 
1146
   the character Replace. It returns TRUE if any characters were 
 
1147
   replaced, else FALSE.   */
 
1148
{
 
1149
  Nlm_Boolean Replaced = FALSE;
 
1150
  while ( *theString != NULLB )
 
1151
    {
 
1152
      if ( *theString == Find )
 
1153
        {
 
1154
          *theString = Replace;
 
1155
          Replaced = TRUE;
 
1156
        }
 
1157
      theString++;
 
1158
    }
 
1159
  return(Replaced);
 
1160
}
 
1161
 
 
1162
NLM_EXTERN Nlm_Boolean LIBCALL StringSubSet(char FAR *theString,char FAR *FindSet, char Replace)
 
1163
/* replaces all instances of any character in string FindSet found in
 
1164
   theString with the character Replace.  It returns TRUE if any
 
1165
   characters were replaced, else FALSE. */
 
1166
{
 
1167
  Nlm_CharPtr FindPtr;
 
1168
  Nlm_Boolean Replaced = FALSE;
 
1169
 
 
1170
  while ( *theString != NULLB )
 
1171
    {
 
1172
      FindPtr = FindSet;
 
1173
      while ( *FindPtr != NULLB )
 
1174
        {
 
1175
          if (*theString == *FindPtr )
 
1176
            {
 
1177
              *theString = Replace;
 
1178
              Replaced = TRUE;
 
1179
            }
 
1180
          FindPtr++;
 
1181
        }
 
1182
      theString++;
 
1183
    }
 
1184
  return(Replaced);
 
1185
}
 
1186
 
 
1187
NLM_EXTERN Nlm_Boolean LIBCALL StringSubString(char FAR *theString, char FAR *Find, char FAR *Replace, Nlm_Int4 MaxLength)
 
1188
/* replaces all non-overlapping instances of the string Find in the
 
1189
   string theString with the string Replace. The strings do not have to be the 
 
1190
   same size. The new string is truncated at MaxLength characters
 
1191
   Including the final NULL). If MaxLength is zero, the string's current
 
1192
   length is presumed to be the maximum.
 
1193
   It returns TRUE if any strings were replaced, else FALSE.
 
1194
   */
 
1195
{
 
1196
  Nlm_CharPtr FindPtr,ComparePtr,StringPtr,NewString, NewStringPtr;
 
1197
  Nlm_Int4 SpaceNeeded,Len;
 
1198
  Nlm_Boolean Replaced = FALSE;
 
1199
 
 
1200
  if (*Find == NULLB)
 
1201
    return(FALSE);
 
1202
 
 
1203
  Len = Nlm_StringLen(theString);
 
1204
  SpaceNeeded = MAX( (Nlm_Int4)((Len * Nlm_StringLen(Replace) 
 
1205
                                 * sizeof(Nlm_Char) )
 
1206
                                / Nlm_StringLen(Find) + 1),Len) + 1;
 
1207
 
 
1208
  NewStringPtr = NewString = (Nlm_CharPtr)
 
1209
    Nlm_MemGet((size_t)SpaceNeeded, MGET_ERRPOST);
 
1210
 
 
1211
  StringPtr = theString;
 
1212
  while (*StringPtr != NULLB)
 
1213
    {
 
1214
      FindPtr = Find;
 
1215
      ComparePtr = StringPtr;
 
1216
      while ( (*FindPtr != NULLB) && (*FindPtr == *ComparePtr) )
 
1217
        {
 
1218
          FindPtr++;
 
1219
          ComparePtr++;
 
1220
        }
 
1221
      
 
1222
      /* if we found the entire string, replace it. */
 
1223
      if (*FindPtr == NULLB)
 
1224
        {
 
1225
          NewStringPtr = StringMove(NewStringPtr,Replace);
 
1226
          StringPtr = ComparePtr;
 
1227
          Replaced = TRUE;
 
1228
        }
 
1229
      else
 
1230
        /* otherwise, move on to the next character. */
 
1231
        *NewStringPtr++ = *StringPtr++;
 
1232
    }
 
1233
  *NewStringPtr = NULLB;
 
1234
 
 
1235
  if (MaxLength <= 0)
 
1236
    MaxLength = strlen(theString) + 1;
 
1237
 
 
1238
  /* Truncate the string, if necessary.*/
 
1239
  if ((Nlm_Int4)strlen(NewString) >= MaxLength - 1)
 
1240
    {
 
1241
      NewString[MaxLength-1] = NULLB;
 
1242
    }
 
1243
    
 
1244
  Nlm_StringCpy(theString,NewString);
 
1245
  Nlm_MemFree(NewString);
 
1246
 
 
1247
  return(Replaced);
 
1248
}
 
1249
 
 
1250
 
 
1251
NLM_EXTERN Nlm_CharPtr LIBCALL StringEnd(char FAR *theString)
 
1252
/* This returns a pointer to the terminating null of the given theString.
 
1253
 */
 
1254
{
 
1255
  while (*theString != NULLB)
 
1256
    theString++;
 
1257
  return(theString);
 
1258
}
 
1259
 
 
1260
 
 
1261
 
 
1262
NLM_EXTERN Nlm_Int4 LIBCALL CountChar(char FAR *theString, char Char)
 
1263
/* returns the number of times a given character appears in the given
 
1264
   theString. */
 
1265
{
 
1266
  Nlm_Int4 CharCount = 0;
 
1267
 
 
1268
  while(*theString)
 
1269
    if (*theString++ == Char)
 
1270
      CharCount++;
 
1271
 
 
1272
  return(CharCount);
 
1273
}
 
1274
 
 
1275
NLM_EXTERN Nlm_Int4 LIBCALL CountStrings(char FAR *theString, char FAR *Find)
 
1276
/*  This returns the number of non-overlapping instances of Find
 
1277
    in theString. */
 
1278
{
 
1279
  Nlm_Int4 count = 0;
 
1280
  Nlm_Int4 Len = Nlm_StringLen(Find);
 
1281
  Nlm_CharPtr Ptr = theString;
 
1282
 
 
1283
  for(;;)
 
1284
    {
 
1285
      Ptr = SkipToString(Ptr,Find);
 
1286
      if (*Ptr == NULLB)
 
1287
        break;
 
1288
 
 
1289
      count++;
 
1290
      Ptr += Len;
 
1291
    }
 
1292
 
 
1293
  return count;
 
1294
}
 
1295
 
 
1296
NLM_EXTERN Nlm_Int4 LIBCALL CountSet(char FAR *theString, char FAR *Set)
 
1297
/* returns the number of times any one of a given set of characters 
 
1298
   appears in the given theString. */
 
1299
{
 
1300
  Nlm_Int4 CharCount = 0;
 
1301
  Nlm_CharPtr SetPtr;
 
1302
 
 
1303
  while(*theString)
 
1304
    {
 
1305
      SetPtr = Set;
 
1306
 
 
1307
      while(*SetPtr)
 
1308
        {
 
1309
          if (*theString == *SetPtr)
 
1310
            {
 
1311
              CharCount++;
 
1312
              break;
 
1313
            }
 
1314
          SetPtr++;
 
1315
        }
 
1316
 
 
1317
      theString++;
 
1318
    }
 
1319
 
 
1320
  return(CharCount);
 
1321
}
 
1322
 
 
1323
 
 
1324
NLM_EXTERN Nlm_CharPtr LIBCALL StripSpaces(char FAR *Line)
 
1325
/* returns a pointer to the next nonwhitespace character in the string
 
1326
and also removes trailing whitespaces. */
 
1327
{
 
1328
  Nlm_CharPtr Ptr;
 
1329
 
 
1330
  Line = SkipSpaces(Line);
 
1331
  if (*Line != NULLB)
 
1332
    {
 
1333
      Ptr = StringEnd(Line) - 1;
 
1334
      while ( (Ptr > Line) && isspace(*Ptr) )
 
1335
        Ptr--;
 
1336
      *(Ptr+1) = NULLB;
 
1337
    }
 
1338
 
 
1339
  return(Line);
 
1340
}
 
1341
 
 
1342
NLM_EXTERN void LIBCALL CleanSpaces(char FAR *Line)
 
1343
/* This in-place deletes all leading and trailing whitespace and replaces
 
1344
   all instances of one or more whitespace characters with one space,
 
1345
   or one newline if the whitespace contained a newline.
 
1346
   */
 
1347
{
 
1348
  Nlm_Boolean HasNewLine;
 
1349
  Nlm_CharPtr LinePtr = SkipSpaces(Line);
 
1350
 
 
1351
  while (*LinePtr )
 
1352
    {
 
1353
      while ( *LinePtr &&  ! isspace (*LinePtr) )
 
1354
        *Line++ = *LinePtr++;
 
1355
 
 
1356
      HasNewLine = FALSE;
 
1357
      while ( isspace(*LinePtr) )
 
1358
        {
 
1359
          if (*LinePtr == NEWLINE)
 
1360
            HasNewLine = TRUE;
 
1361
          LinePtr++;
 
1362
        }
 
1363
 
 
1364
      if (HasNewLine)
 
1365
        *Line++ = NEWLINE;
 
1366
      else
 
1367
        if (*LinePtr)
 
1368
          *Line++ = SPACE;
 
1369
    }
 
1370
  *Line = NULLB;
 
1371
}
 
1372
 
 
1373
 
 
1374
NLM_EXTERN Nlm_Int4 LIBCALL StringDiff(char FAR *This, char FAR *That)
 
1375
/* This returns the character offset where the strings differ, or -1 if
 
1376
   the strings are the same. */
 
1377
{
 
1378
  Nlm_Int4 Diff = 0;
 
1379
 
 
1380
  while (*This && (*This == *That) )
 
1381
    {
 
1382
      Diff++;
 
1383
      This++;
 
1384
      That++;
 
1385
    }
 
1386
 
 
1387
  if (*This || *That)
 
1388
    return(Diff);
 
1389
  else
 
1390
    return (-1);
 
1391
}
 
1392
 
 
1393
NLM_EXTERN Nlm_Int4 LIBCALL StringDiffNum(char FAR *This, char FAR *That, Nlm_Int4 NumChars)
 
1394
/* returns the character offset where the strings differ, examining only
 
1395
   the first NumChars Characters. returns -1 if the two substrings 
 
1396
   examined are equivalent. */
 
1397
{
 
1398
  Nlm_Int4 Diff = 0;
 
1399
 
 
1400
  while ((NumChars > 0) && *This &&  (*This == *That) )
 
1401
    {
 
1402
      This++;
 
1403
      That++;
 
1404
      NumChars--;
 
1405
      Diff++;
 
1406
    }
 
1407
 
 
1408
  if ( NumChars && (*This || *That) )
 
1409
    return(Diff);
 
1410
  else 
 
1411
    return(-1);
 
1412
}
 
1413
 
 
1414
NLM_EXTERN void LIBCALL TruncateString(char FAR *theString, Nlm_Int4 Length)
 
1415
/* truncates a string to fit into an array of Length characters, 
 
1416
   including the trailing NULL. */
 
1417
{
 
1418
  if((Nlm_Int4)strlen(theString) >= Length - 1)
 
1419
    theString [Length-1] = NULLB;
 
1420
}
 
1421
 
 
1422
NLM_EXTERN Nlm_CharPtr LIBCALL TruncateStringCopy(char FAR *theString, Nlm_Int4 Length)
 
1423
/* Returns a new string consisting of at most the first length-1 
 
1424
   characters of theString. */
 
1425
{
 
1426
  Nlm_CharPtr NewString = (Nlm_CharPtr)MemNew((size_t)Length);
 
1427
 
 
1428
  StrNCpy(NewString, theString, (size_t)(Length - 1));
 
1429
  NewString[Length-1] = NULLB;
 
1430
  return NewString;
 
1431
}
 
1432
 
 
1433
 
 
1434
NLM_EXTERN Nlm_Int4 LIBCALL BreakString(char FAR *theString, Nlm_CharPtr PNTR Words)
 
1435
/* Breaks up a string at each occurrence of one or more spaces, placing
 
1436
   each substring obtained into the array Words and returning the 
 
1437
   number of substrings obtained. 
 
1438
   */
 
1439
{
 
1440
  Nlm_CharPtr Start, Stop, *WordPtr;
 
1441
 
 
1442
  Start = SkipSpaces(theString);
 
1443
  WordPtr = Words;
 
1444
 
 
1445
  while (*Start)
 
1446
    {
 
1447
      Stop = SkipToSpace(Start);
 
1448
      StrCpyPtr(*WordPtr++,Start,Stop);
 
1449
      Start = SkipSpaces(Stop);
 
1450
    }
 
1451
 
 
1452
  return((Nlm_Int4) (WordPtr - Words) );
 
1453
}
 
1454
 
 
1455
NLM_EXTERN void LIBCALL DeleteChar(char FAR *theString,char Delete)
 
1456
/* removes all instances of the character Delete from the theString. */
 
1457
{
 
1458
  Nlm_CharPtr StringPtr = theString;
 
1459
 
 
1460
  while(*StringPtr)
 
1461
    {
 
1462
      if (*StringPtr !=  Delete)
 
1463
        *theString++ = *StringPtr++;
 
1464
      else
 
1465
        StringPtr++;
 
1466
    }
 
1467
 
 
1468
  *theString = NULLB;
 
1469
}
 
1470
 
 
1471
 
 
1472
 
 
1473
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_StringPrintable(const Nlm_Char PNTR str,
 
1474
                                                   Nlm_Boolean rn_eol)
 
1475
{
 
1476
  size_t str_len = 0;
 
1477
  const Nlm_Char PNTR s;
 
1478
  Nlm_CharPtr new_str, new_s;
 
1479
 
 
1480
  if ( !str )
 
1481
    return NULL;
 
1482
 
 
1483
  if ( rn_eol )
 
1484
    {
 
1485
      for (s = str;  *s;  s++)
 
1486
        if (*s == '\n')
 
1487
          str_len += 2;
 
1488
        else if (*s == '\t'  ||  IS_PRINT(*s))
 
1489
          str_len++;
 
1490
    }
 
1491
  else
 
1492
    {
 
1493
      for (s = str;  *s;  s++)
 
1494
        if (*s == '\n'  ||  *s == '\t'  ||  IS_PRINT(*s))
 
1495
          str_len++;
 
1496
    }
 
1497
 
 
1498
  new_str = (Nlm_CharPtr)Nlm_MemGet(str_len+1, MGET_ERRPOST);
 
1499
  if ( !new_str )
 
1500
    return NULL;
 
1501
 
 
1502
  if ( rn_eol )
 
1503
    {
 
1504
      for (s = str, new_s = new_str;  *s;  s++)
 
1505
        if (*s == '\n')
 
1506
          {
 
1507
            *new_s++ = '\r';
 
1508
            *new_s++ = '\n';
 
1509
          }
 
1510
        else if (*s == '\t'  ||  IS_PRINT(*s))
 
1511
          *new_s++ = *s;
 
1512
    }
 
1513
  else
 
1514
    {
 
1515
      for (s = str, new_s = new_str;  *s;  s++)
 
1516
        if (*s == '\n'  ||  *s == '\t'  ||  IS_PRINT(*s))
 
1517
          *new_s++ = *s;
 
1518
    }
 
1519
  *new_s = '\0';
 
1520
 
 
1521
  return new_str;
 
1522
}
 
1523
        
 
1524
  
 
1525
/*****************************************************************************
 
1526
 *  Text Formatting Functions
 
1527
 ****************************************************************************/
 
1528
 
 
1529
#define MAX_NO_DASH 2
 
1530
#define MIN_LEAD    3
 
1531
#define MIN_TAIL    1
 
1532
 
 
1533
#define SPACE ' '
 
1534
 
 
1535
/* Act like a regular memcpy but replace all space symbols to #SPACE
 
1536
 */
 
1537
static void x_memcpy(Nlm_Char FAR PNTR targ, const Nlm_Char FAR PNTR src,
 
1538
                     size_t n)
 
1539
{
 
1540
  for ( ;  n--;  src++)
 
1541
    {
 
1542
      ASSERT ( *src );
 
1543
      if ( IS_WHITESP(*src) )
 
1544
        *targ++ = SPACE;
 
1545
      else
 
1546
        *targ++ = *src;
 
1547
    }
 
1548
}
 
1549
 
 
1550
 
 
1551
/* Set of conditions when the decision on the line breaking can be
 
1552
 * made having only 2 symbols("ch0" and "ch1" -- to the left and to the
 
1553
 * right of the break, respectively)
 
1554
 */
 
1555
static int can_break(Nlm_Char ch0, Nlm_Char ch1)
 
1556
{
 
1557
  if (ch1 == '\0'  ||
 
1558
      IS_WHITESP(ch1)  ||  IS_WHITESP(ch0))
 
1559
    return 1;
 
1560
 
 
1561
  switch ( ch1 )
 
1562
    {
 
1563
    case '(':
 
1564
    case '[':
 
1565
    case '{':
 
1566
      return 1;
 
1567
    }
 
1568
 
 
1569
  switch ( ch0 )
 
1570
    {
 
1571
    case '-':
 
1572
    case '+':
 
1573
    case '=':
 
1574
    case '&':
 
1575
    case '|':
 
1576
    case ')':
 
1577
    case '}':
 
1578
    case ']':
 
1579
      if (ch1 != ch0)
 
1580
        return 1;
 
1581
      break;
 
1582
  
 
1583
    case '\\':
 
1584
    case '/':
 
1585
    case '*':
 
1586
    case ';':
 
1587
    case ':':
 
1588
    case ',':
 
1589
      return 1;
 
1590
 
 
1591
    case '?':
 
1592
    case '!':
 
1593
    case '.':
 
1594
      if (ch1 != '.'  &&  ch1 != '?'  &&  ch1 != '!')
 
1595
        return 1;
 
1596
      break;
 
1597
    }
 
1598
 
 
1599
  return 0;
 
1600
}
 
1601
 
 
1602
 
 
1603
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_text2stream(const Nlm_Char FAR PNTR str)
 
1604
{
 
1605
  int on_space = 0;
 
1606
  Nlm_CharPtr line, s;
 
1607
 
 
1608
  if ( !str )
 
1609
    return NULL;
 
1610
 
 
1611
  while (*str  &&  IS_WHITESP( *str ))
 
1612
    str++;
 
1613
  if ( !*str )
 
1614
    return NULL;
 
1615
 
 
1616
  s = line = (Nlm_CharPtr) Nlm_MemNew(Nlm_StringLen(str) + 1);
 
1617
 
 
1618
  for (  ;  *str;  str++)
 
1619
    {
 
1620
      if ( IS_WHITESP(*str) )
 
1621
        {
 
1622
          if (*str == '\n')
 
1623
            *s = '\n';
 
1624
          on_space = 1;
 
1625
        }
 
1626
      else
 
1627
        {
 
1628
          if ( on_space ) {
 
1629
            if (*s == '\n'  &&
 
1630
                s - line > 1  &&  *(s-1) == '-'  &&  IS_ALPHA(*(s-2)))
 
1631
              {
 
1632
                *s = '\0';
 
1633
                s--;  /* eat dash before end-of-line, merge the broken word */
 
1634
              }
 
1635
            else
 
1636
              *s++ = SPACE;
 
1637
 
 
1638
            *s++ = *str;
 
1639
            on_space = 0;
 
1640
          }
 
1641
          else
 
1642
            *s++ = *str;
 
1643
        }
 
1644
    }
 
1645
  *s = '\0';
 
1646
 
 
1647
  return (Nlm_CharPtr) realloc(line, Nlm_StringLen(line) + 1);
 
1648
}
 
1649
 
 
1650
 
 
1651
NLM_EXTERN size_t Nlm_stream2text(const Nlm_Char FAR PNTR str, size_t max_col,
 
1652
                                  int PNTR dash)
 
1653
{
 
1654
  const Nlm_Char FAR PNTR s;
 
1655
  const Nlm_Char FAR PNTR sb; /* the nearest breakable position */
 
1656
  size_t n_lead = 0;
 
1657
  size_t n_tail = 0;
 
1658
 
 
1659
  size_t len = Nlm_StringLen( str );
 
1660
  len = max_col < len ? max_col : len;
 
1661
 
 
1662
  *dash = 0;
 
1663
  if (len == 0  ||  can_break(str[len-1], str[len]))
 
1664
    return len;
 
1665
 
 
1666
  /* go to the beginning of the last completely fit word */
 
1667
  for (sb = &str[len-1];
 
1668
       sb != str  &&  !IS_WHITESP(*sb)  &&  !can_break(*sb, *(sb+1));
 
1669
       sb--) continue;
 
1670
  while (sb != str  &&  IS_WHITESP(*sb))
 
1671
    sb--;
 
1672
 
 
1673
  if (sb == str)
 
1674
    { /* the first word is longer than "max_col" */
 
1675
      if (len > MAX_NO_DASH  &&  IS_ALPHA(str[len-1])  &&  IS_ALPHA(str[len]))
 
1676
        *dash = 1;  /* recommend use dash in the place of last symbol */
 
1677
 
 
1678
      return len;
 
1679
    }
 
1680
 
 
1681
  /* decide of whether and how to break the last alphabet word */
 
1682
 
 
1683
  /*  count the lead and the tail of the last non-fit word */
 
1684
  for (s = &str[len];  *s != '\0'  &&  IS_ALPHA(*s);  s++, n_tail++) continue;
 
1685
  for (s = &str[len-1];  IS_ALPHA(*s);  s--, n_lead++) continue;
 
1686
  ASSERT ( s > str );
 
1687
 
 
1688
  /* try to "move" symbols from lead in the sake of tail */
 
1689
  while (n_lead > MIN_LEAD  &&  n_tail < MIN_TAIL)  {
 
1690
    n_lead--;
 
1691
    n_tail++;
 
1692
  }
 
1693
 
 
1694
  if (n_lead < MIN_LEAD  ||  n_tail < MIN_TAIL)
 
1695
    { /* no luck this time -- move the whole non-fit word to the next line */
 
1696
      return (sb - str + 1);
 
1697
    }
 
1698
  else
 
1699
    {
 
1700
      *dash = 1;
 
1701
      return (s - str + n_lead + 1);
 
1702
    }
 
1703
}
 
1704
 
 
1705
 
 
1706
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_rule_line(const Nlm_Char FAR PNTR str,
 
1707
                                             size_t len,
 
1708
                                             enumRuleLine method)
 
1709
{
 
1710
  size_t str_len;
 
1711
  size_t n_space;
 
1712
 
 
1713
  /* allocate and initialize the resulting string */
 
1714
  Nlm_CharPtr s = (Nlm_CharPtr) Nlm_MemNew(len + 1);
 
1715
  Nlm_MemSet(s, SPACE, len);
 
1716
  s[len] = '\0';
 
1717
 
 
1718
  /* skip leading and trailing spaces */
 
1719
  while ( IS_WHITESP(*str) )
 
1720
    str++;
 
1721
  if ( !*str )
 
1722
    return s;
 
1723
  for (str_len = Nlm_StringLen( str );  IS_WHITESP(str[str_len-1]); str_len--) continue;
 
1724
 
 
1725
 
 
1726
  /* truncate the original string if doesn't fit */
 
1727
  if (len <= str_len) {
 
1728
    x_memcpy(s, str, len);
 
1729
    return s;
 
1730
  }
 
1731
 
 
1732
  n_space = len - str_len;
 
1733
  switch ( method )
 
1734
    {
 
1735
    case RL_Left:
 
1736
      {
 
1737
        x_memcpy(s, str, str_len);
 
1738
        break;
 
1739
      }
 
1740
    case RL_Right:
 
1741
      {
 
1742
        x_memcpy(s + n_space, str, str_len);
 
1743
        break;
 
1744
      }
 
1745
    case RL_Spread:
 
1746
      {
 
1747
        size_t n_gap = 0;
 
1748
 
 
1749
        int prev_space = 0;
 
1750
        const Nlm_Char FAR PNTR _str = str;
 
1751
        size_t i = str_len;
 
1752
        for ( ;  i--;  _str++)
 
1753
          {
 
1754
            ASSERT ( *_str );
 
1755
            if ( IS_WHITESP(*_str) )
 
1756
              {
 
1757
                if ( !prev_space ) {
 
1758
                  n_gap++;
 
1759
                  prev_space = 1;
 
1760
                }
 
1761
                n_space++;
 
1762
              }
 
1763
            else
 
1764
              prev_space = 0;
 
1765
          }
 
1766
        ASSERT ( !prev_space );
 
1767
 
 
1768
        if ( n_gap )
 
1769
          {
 
1770
            size_t n_div = n_space / n_gap;
 
1771
            size_t n_mod = n_space % n_gap;
 
1772
 
 
1773
            Nlm_CharPtr _s = s;
 
1774
            for (_str = str;  *_str; )
 
1775
              {
 
1776
                if ( !IS_WHITESP( *_str ) )
 
1777
                  *_s++ = *_str++;
 
1778
                else if ( n_space )
 
1779
                  {
 
1780
                    size_t n_add = n_div;
 
1781
                    if (n_mod > 0) {
 
1782
                      n_add++;
 
1783
                      n_mod--;
 
1784
                    }
 
1785
                    n_space -= n_add;
 
1786
                    while ( n_add-- )
 
1787
                      *_s++ = SPACE;
 
1788
 
 
1789
                    for (_str++;  IS_WHITESP(*_str);  _str++) continue;
 
1790
                  }
 
1791
                else
 
1792
                  break;
 
1793
              }
 
1794
            ASSERT ( _s == s + len );
 
1795
            break;
 
1796
          }  /* else -- use RL_Center */
 
1797
      }
 
1798
 
 
1799
    case RL_Center:
 
1800
      {
 
1801
        x_memcpy(s + n_space/2, str, str_len);
 
1802
        break;
 
1803
      }
 
1804
 
 
1805
    default:
 
1806
      ASSERT ( 0 );
 
1807
      Nlm_MemFree( s );
 
1808
      return 0;
 
1809
    }
 
1810
 
 
1811
  return s;
 
1812
}
 
1813
 
 
1814
 
 
1815
#ifdef TEST_TEXT_FMT
 
1816
Nlm_Int2 Nlm_Main( void )
 
1817
{
 
1818
#define MAX_COL 24
 
1819
  Nlm_Int4     argc = Nlm_GetArgc();
 
1820
  Nlm_CharPtr *argv = Nlm_GetArgv();
 
1821
 
 
1822
  Nlm_Char x_str[MAX_COL * 1024];
 
1823
  FILE *fp = NULL;
 
1824
  int n_read;
 
1825
 
 
1826
  FILE *logfile = Nlm_FileOpen("stdout", "w");
 
1827
  ASSERT ( logfile );
 
1828
 
 
1829
  if (argc < 2)  {
 
1830
    fprintf(logfile, "Usage: %s <file_name>\n", argv[0]);
 
1831
    return 1;
 
1832
  }
 
1833
 
 
1834
  fp = Nlm_FileOpen(argv[1], "rb");
 
1835
  if ( !fp ) {
 
1836
    fprintf(logfile, "Cannot open file: \"%s\"\n", argv[1]);
 
1837
    return 2;
 
1838
  }
 
1839
 
 
1840
  n_read = FileRead(x_str, 1, sizeof(x_str) - 1, fp);
 
1841
  if (n_read < 2 * MAX_COL) {  
 
1842
    fprintf(logfile, "Too few bytes read from \"%s\": %d\n", argv[1], n_read);
 
1843
    return 3;
 
1844
  }
 
1845
 
 
1846
  ASSERT ( n_read < sizeof(x_str) );
 
1847
  x_str[n_read] = '\0';
 
1848
 
 
1849
  {{
 
1850
    size_t max_col = MAX_COL - 1;
 
1851
    int    inc     = 1;
 
1852
    enumRuleLine rule_method = RL_Center;
 
1853
 
 
1854
    Nlm_CharPtr str = text2stream( x_str );
 
1855
    Nlm_CharPtr text_str = str;
 
1856
    if ( !str ) {  
 
1857
      fprintf(logfile, "No non-space symbols in \"%s\"\n", argv[1]);
 
1858
      return 4;
 
1859
    }
 
1860
    
 
1861
    while (*str != '\0')
 
1862
      {
 
1863
        Nlm_Char s[MAX_COL + 1];
 
1864
        int dash = -12345;
 
1865
        size_t n_print;
 
1866
 
 
1867
        while (*str  &&  IS_WHITESP(*str))
 
1868
          str++;
 
1869
 
 
1870
        n_print = stream2text(str, max_col, &dash);
 
1871
        ASSERT ( (max_col > 0  &&  str  &&  *str)  ==  (n_print > 0) );
 
1872
        ASSERT ( n_print <= max_col );
 
1873
        ASSERT ( dash != -12345 );
 
1874
 
 
1875
        Nlm_MemCpy(s, str, n_print);
 
1876
        s[n_print] = '\0';
 
1877
        ASSERT ( dash == 0  ||  n_print > 1 );
 
1878
        if ( dash )
 
1879
          s[--n_print] = '-';
 
1880
 
 
1881
        {{
 
1882
          Nlm_CharPtr ruled_str = rule_line(s,
 
1883
                                            (rule_method == RL_Right ||
 
1884
                                             rule_method == RL_Center ) ?
 
1885
                                            MAX_COL : max_col,
 
1886
                                            rule_method);
 
1887
          fprintf(logfile, "|%s|\n", ruled_str);
 
1888
          Nlm_MemFree( ruled_str );
 
1889
        }}
 
1890
        
 
1891
        str += n_print;
 
1892
 
 
1893
        if (max_col == 0  ||  max_col == MAX_COL)
 
1894
          inc = -inc;
 
1895
        max_col += inc;
 
1896
 
 
1897
        if (max_col == 0)
 
1898
          if (rule_method == RL_Spread)
 
1899
            rule_method = RL_Left;
 
1900
          else
 
1901
            rule_method++;
 
1902
      }
 
1903
 
 
1904
    Nlm_MemFree( text_str );
 
1905
  }}
 
1906
 
 
1907
  Nlm_FileClose( logfile );
 
1908
  Nlm_FileClose( fp );
 
1909
  return 0;
 
1910
}
 
1911
#endif  /* TEST_TEXT_FMT */
 
1912
 
 
1913
 
 
1914
#ifdef TEST_INT8_CONVERSION
 
1915
Nlm_Int2 Nlm_Main( void )
 
1916
{
 
1917
    char buffer[100];
 
1918
    char *s;
 
1919
    const char *p;
 
1920
    Nlm_Int8 i;
 
1921
    Nlm_Uint8 j;
 
1922
 
 
1923
    s = Nlm_Int8ToString(0, buffer, sizeof(buffer));
 
1924
    assert(s != 0);
 
1925
    printf("0 = %s\n", s);
 
1926
    s = Nlm_Int8ToString(1, buffer, sizeof(buffer));
 
1927
    assert(s != 0);
 
1928
    printf("1 = %s\n", s);
 
1929
    s = Nlm_Int8ToString(1222222, buffer, sizeof(buffer));
 
1930
    assert(s != 0);
 
1931
    printf("1222222 = %s\n", s);
 
1932
    s = Nlm_Int8ToString(-15, buffer, sizeof(buffer));
 
1933
    assert(s != 0);
 
1934
    printf("-15 = %s\n", s);
 
1935
    s = Nlm_Int8ToString(-15555555, buffer, sizeof(buffer));
 
1936
    assert(s != 0);
 
1937
    printf("-15555555 = %s\n", s);
 
1938
    s = Nlm_Int8ToString(INT8_MAX, buffer, sizeof(buffer));
 
1939
    assert(s != 0);
 
1940
    printf("INT8_MAX = %s\n", s);
 
1941
    s = Nlm_Int8ToString(INT8_MIN, buffer, sizeof(buffer));
 
1942
    assert(s != 0);
 
1943
    printf("INT8_MIN = %s\n", s);
 
1944
    s = Nlm_Int8ToString(UINT8_MAX, buffer, sizeof(buffer));
 
1945
    assert(s != 0);
 
1946
    printf("UINT8_MAX = %s\n", s);
 
1947
    s = Nlm_Uint8ToString(UINT8_MAX, buffer, sizeof(buffer));
 
1948
    assert(s != 0);
 
1949
    printf("UINT8_MAX = %s\n", s);
 
1950
 
 
1951
    strcpy(buffer, "9223372036854775807");
 
1952
    i = Nlm_StringToInt8(buffer, &p);
 
1953
    assert(p == buffer + strlen(buffer));
 
1954
    s = Nlm_Int8ToString(i, buffer + strlen(buffer) + 1,
 
1955
                         sizeof(buffer) - strlen(buffer) - 1);
 
1956
    assert(s != 0);
 
1957
    assert(strcmp(buffer, s) == 0);
 
1958
    printf("INT8_MAX input Ok\n");
 
1959
    i++;
 
1960
    s = Nlm_Int8ToString(i, buffer, sizeof(buffer));
 
1961
    assert(s != 0);
 
1962
    printf("INT8_MAX+1 = %s\n", s);
 
1963
 
 
1964
    strcpy(buffer, "-9223372036854775808");
 
1965
    i = Nlm_StringToInt8(buffer, &p);
 
1966
    assert(p == buffer + strlen(buffer));
 
1967
    s = Nlm_Int8ToString(i, buffer + strlen(buffer) + 1,
 
1968
                         sizeof(buffer) - strlen(buffer) - 1);
 
1969
    assert(s != 0);
 
1970
    assert(strcmp(buffer, s) == 0);
 
1971
    printf("INT8_MIN input Ok\n");
 
1972
    i--;
 
1973
    s = Nlm_Int8ToString(i, buffer, sizeof(buffer));
 
1974
    assert(s != 0);
 
1975
    printf("INT8_MIN-1 = %s\n", s);
 
1976
 
 
1977
    strcpy(buffer, "18446744073709551615");
 
1978
    j = Nlm_StringToUint8(buffer, &p);
 
1979
    assert(p == buffer + strlen(buffer));
 
1980
    s = Nlm_Uint8ToString(j, buffer + strlen(buffer) + 1,
 
1981
                          sizeof(buffer) - strlen(buffer) - 1);
 
1982
    assert(s != 0);
 
1983
    assert(strcmp(buffer, s) == 0);
 
1984
    printf("UINT8_MAX input Ok\n");
 
1985
    j++;
 
1986
    s = Nlm_Uint8ToString(j, buffer, sizeof(buffer));
 
1987
    assert(s != 0);
 
1988
    printf("UINT8_MAX+1 = %s\n", s);
 
1989
 
 
1990
    strcpy(buffer, "1234567890abcdef0123546");
 
1991
    i = Nlm_StringToInt8(buffer, &p);
 
1992
    assert(p != 0);
 
1993
    s = Nlm_Int8ToString(i, buffer + strlen(buffer) + 1,
 
1994
                         sizeof(buffer) - strlen(buffer) - 1);
 
1995
    assert(s != 0);
 
1996
    printf("Out of %s only %.*s was accepted as input for Int8 %s\n",
 
1997
           buffer, (int)(p - buffer), buffer, s);
 
1998
 
 
1999
    strcpy(buffer, "-987654321234567890abcdef0123546");
 
2000
    i = Nlm_StringToInt8(buffer, &p);
 
2001
    assert(p != 0);
 
2002
    s = Nlm_Int8ToString(i, buffer + strlen(buffer) + 1,
 
2003
                         sizeof(buffer) - strlen(buffer) - 1);
 
2004
    assert(s != 0);
 
2005
    printf("Out of %s only %.*s was accepted as input for Int8 %s\n",
 
2006
           buffer, (int)(p - buffer), buffer, s);
 
2007
 
 
2008
    strcpy(buffer, "987654321234567890abcdef0123546");
 
2009
    j = Nlm_StringToUint8(buffer, &p);
 
2010
    assert(p != 0);
 
2011
    s = Nlm_Uint8ToString(j, buffer + strlen(buffer) + 1,
 
2012
                          sizeof(buffer) - strlen(buffer) - 1);
 
2013
    assert(s != 0);
 
2014
    printf("Out of %s only %.*s was accepted as input for Uint8 %s\n",
 
2015
           buffer, (int)(p - buffer), buffer, s);
 
2016
 
 
2017
    strcpy(buffer, "-987654321234567890abcdef0123546");
 
2018
    j = Nlm_StringToUint8(buffer, &p);
 
2019
    assert(p == 0);
 
2020
    printf("Conversion of %s (negative) to Uint8 caused error\n", buffer);
 
2021
 
 
2022
    strcpy(buffer, "9223372036854775808");
 
2023
    i = Nlm_StringToInt8(buffer, &p);
 
2024
    assert(p == 0);
 
2025
    printf("Conversion of %s (INT8_MAX + 1) to Int8 caused error\n", buffer);
 
2026
 
 
2027
    strcpy(buffer, "-9223372036854775809");
 
2028
    i = Nlm_StringToInt8(buffer, &p);
 
2029
    assert(p == 0);
 
2030
    printf("Conversion of %s (INT8_MIN - 1) to Int8 caused error\n", buffer);
 
2031
 
 
2032
    strcpy(buffer, "18446744073709551616");
 
2033
    j = Nlm_StringToUint8(buffer, &p);
 
2034
    assert(p == 0);
 
2035
    printf("Conversion of %s (UINT8_MAX + 1) to Uint8 caused error\n", buffer);
 
2036
 
 
2037
    printf("All tests succeeded\n");
 
2038
 
 
2039
    return 0;
 
2040
}
 
2041
#endif /* TEST_INT8_CONVERSION */