~ubuntu-branches/debian/jessie/eso-midas/jessie

« back to all changes in this revision

Viewing changes to libsrc/tbl/str1.c

  • Committer: Package Import Robot
  • Author(s): Ole Streicher
  • Date: 2014-04-22 14:44:58 UTC
  • Revision ID: package-import@ubuntu.com-20140422144458-okiwi1assxkkiz39
Tags: upstream-13.09pl1.2+dfsg
ImportĀ upstreamĀ versionĀ 13.09pl1.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
  Copyright (C) 1995-2009 European Southern Observatory (ESO)
 
3
 
 
4
  This program is free software; you can redistribute it and/or 
 
5
  modify it under the terms of the GNU General Public License as 
 
6
  published by the Free Software Foundation; either version 2 of 
 
7
  the License, or (at your option) any later version.
 
8
 
 
9
  This program is distributed in the hope that it will be useful,
 
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
  GNU General Public License for more details.
 
13
 
 
14
  You should have received a copy of the GNU General Public 
 
15
  License along with this program; if not, write to the Free 
 
16
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
 
17
  MA 02139, USA.
 
18
 
 
19
  Correspondence concerning ESO-MIDAS should be addressed as follows:
 
20
        Internet e-mail: midas@eso.org
 
21
        Postal address: European Southern Observatory
 
22
                        Data Management Division 
 
23
                        Karl-Schwarzschild-Strasse 2
 
24
                        D 85748 Garching bei Muenchen 
 
25
                        GERMANY
 
26
===========================================================================*/
 
27
 
 
28
/*+++++++++  
 
29
.MODULE    str1.c
 
30
.AUTHOR    Francois Ochsenbein [ESO]
 
31
.LANGUAGE  C
 
32
.CATEGORY  Basic string manipulation
 
33
 
 
34
.COMMENTS
 
35
\begin{TeX}
 
36
        Function names start with {\bf str} for case-sensitive functions,
 
37
        with {\bf stu} for case-insensitive functions.
 
38
        Declarations and corresponding macro definitions are in the header 
 
39
        STR.H.
 
40
The general features of all these functions are:
 
41
\begin{itemize}
 
42
\item The first argument is always a pointer to the string to scan or modify;
 
43
\item All functions in this module return an integer, which is
 
44
        \begin{itemize}
 
45
        \item either the length
 
46
        \item or an index, with values 0 to (length-1) for success,
 
47
                length for failure (mismatch). 
 
48
                It is then easy to test the found byte, as in the
 
49
                following example:
 
50
\begin{verbatim}
 
51
        char  s[80];
 
52
        if (s[strloc(s,'.')])   
 
53
                printf("s contains a dot!");
 
54
\end{verbatim}
 
55
        \item   or the result of a comparison
 
56
        \end{itemize}
 
57
\item   The function name is followed by an underscore `\_' when a table is 
 
58
        required as the last parameter. The usage of 256-byte tables for 
 
59
        span / scan / translate operations allow higher speed.
 
60
\end{itemize}
 
61
\end{TeX}
 
62
 
 
63
.VERSION   1.0  25-Nov-1985: Creation 
 
64
 
 
65
.VERSION   2.0  26-Jan-1988: Prepared for Midas, on top of osc routines.
 
66
.VERSION   2.1  28-Mar-1989: Removed bug in stritem (if 2nd string is of length 0)
 
67
.VERSION   2.2  12-May-1989: Added strncopy.
 
68
.VERSION   2.3  16-Jun-1989: Check for null addresses
 
69
.VERSION   2.4  31-Jan-1990: Removed strid (now in str2). Cosmetic modifications
 
70
                        Added strloc1, strscan1
 
71
.VERSION   2.5  30-Mar-1990: Added strred (replace macro),
 
72
.VERSION   2.6  11-Sep-1990: Added strins (Insert)
 
73
 
 
74
 090406         last modif
 
75
----------------------------------------------------------------------------*/
 
76
 
 
77
#include <macrogen.h>
 
78
#include <atype.h>
 
79
#include <string.h>
 
80
#include <sys/types.h>
 
81
 
 
82
#include <osdefos.h>
 
83
#include <proto_os.h>  
 
84
 
 
85
#define BITS_PER_CHAR   8
 
86
#define SIZE            (1<<BITS_PER_CHAR)
 
87
 
 
88
static unsigned char ttable[SIZE];
 
89
static char argstr[2] = "x";            /* for stuloc / stuskip */
 
90
static int (*f)();
 
91
 
 
92
static unsigned char *cpt(table, tabl0)
 
93
/*+++++++
 
94
.PURPOSE Copy table, inserting tabl0
 
95
.RETURNS Address of Copy
 
96
.REMARKS Copy because main_ascii is read-only ... can't just modify first byte
 
97
---------*/
 
98
        unsigned char *table;   /* IN: Table to copy    */
 
99
        unsigned char  tabl0;   /* IN: Value of tabl[0] */
 
100
{
 
101
    oscopy((char *)ttable, (char *)table, SIZE);
 
102
    ttable[0] = tabl0;
 
103
    
 
104
    return(ttable);
 
105
}
 
106
 
 
107
/*===========================================================================
 
108
 *                      Copy strings
 
109
 *===========================================================================*/
 
110
int strcopy(dest, source)
 
111
/*+++++++
 
112
.PURPOSE Copy strings, taking care of possible overlays.
 
113
.RETURNS Length of destination.
 
114
---------*/
 
115
        char *dest;     /* OUT: destination string      */
 
116
        char *source;   /* IN: source string    */
 
117
{
 
118
        register int len;
 
119
 
 
120
  if (source)
 
121
        len = strlen(source),   oscopy(dest, source, len+1);
 
122
  else  *dest = '\0', len = 0;
 
123
 
 
124
  return(len);
 
125
}
 
126
 
 
127
int strncopy(dest, maxsize, source)
 
128
/*+++++++
 
129
.PURPOSE Copy strings, taking care of possible overlays, but with max size.
 
130
        (forbid any overfill)
 
131
.RETURNS Length of destination.
 
132
---------*/
 
133
        char *dest;     /* OUT: destination string      */
 
134
        int   maxsize;  /* IN: Size of destination buffer (1+max.length) */
 
135
        char *source;   /* IN: source string    */
 
136
{
 
137
        register char *p;
 
138
        register int  len;
 
139
 
 
140
  p = dest;
 
141
  
 
142
  if (maxsize)
 
143
  {
 
144
        if (source)
 
145
        {       
 
146
                len = strlen(source) + 1;
 
147
                if (len > maxsize)      len = maxsize;
 
148
                len--;
 
149
                p += oscopy(p, source, len);
 
150
        }
 
151
        *p = '\0';
 
152
  }
 
153
 
 
154
  return(p-dest);
 
155
}
 
156
 
 
157
 
 
158
int strfill(dest, len, filler)
 
159
/*+++++++
 
160
.PURPOSE Fill a string with specified char, and terminates with EOS.
 
161
.RETURNS Length of destination.
 
162
---------*/
 
163
        char *dest;     /* OUT: destination string      */
 
164
        int   len;      /* IN: Size of destination buffer */
 
165
        int   filler;   /* IN: Character to be used for filling */
 
166
{
 
167
  *(dest+oscfill(dest,len,filler)) = '\0';
 
168
  return(len);
 
169
}
 
170
 
 
171
/*===========================================================================
 
172
 *                      Locate / Skip a char
 
173
 *===========================================================================*/
 
174
int strloc(str, c)
 
175
/*+++++++
 
176
.PURPOSE Locate the first occurence of character `c'
 
177
.RETURNS Index of `c' in str; length of str if `c' not found.
 
178
---------*/
 
179
        char *str;      /* IN: string to scan   */
 
180
        char c;         /* IN: char to locate   */
 
181
{
 
182
        register char *p;
 
183
 
 
184
  for (p=str; *p; p++)
 
185
        if (*p == c)    break;
 
186
  return(p-str);
 
187
}
 
188
 
 
189
int strloc1(str, c)
 
190
/*+++++++
 
191
.PURPOSE Locate the first occurence of character `c' --- but only if `c'
 
192
        is not escaped by a backslash
 
193
.RETURNS Index of `c' in str; length of str if `c' not found.
 
194
---------*/
 
195
        char *str;      /* IN: string to scan   */
 
196
        char c;         /* IN: char to locate   */
 
197
{
 
198
        register char *p;
 
199
 
 
200
  for (p=str; *p; p++)
 
201
  {
 
202
        if (*p == '\\') { p++; continue; }
 
203
        if (*p == c)    break;  
 
204
  }
 
205
  return(p-str);
 
206
}
 
207
 
 
208
int strbloc(str, c)
 
209
/*+++++++
 
210
.PURPOSE Locate the last occurence of character `c'
 
211
.RETURNS Index of `c' in str; -1 if `c' not found.
 
212
---------*/
 
213
        char *str;      /* IN: string to scan   */
 
214
        char c;         /* IN: char to locate   */
 
215
{
 
216
  return(oscbloc(str,strlen(str),c));
 
217
}       
 
218
 
 
219
/*===========================================================================*/
 
220
int strskip(str, c)
 
221
/*+++++++
 
222
.PURPOSE Locate the first character that differs from `c'
 
223
.RETURNS Index of `c' in str; length of str if str is made only of `c's
 
224
---------*/
 
225
        char *str;      /* IN: string to scan   */
 
226
        char c;         /* IN: char to locate   */
 
227
{
 
228
        register char *p;
 
229
 
 
230
  for (p=str; *p; p++)
 
231
        if (*p != c)    break;
 
232
  return(p-str);
 
233
}
 
234
        
 
235
int strbskip(str, c)
 
236
/*+++++++
 
237
.PURPOSE Locate the last character that differs from `c'
 
238
.RETURNS Index of `c' in str; -1 if str is made only of `c's
 
239
---------*/
 
240
        char *str;      /* IN: string to scan   */
 
241
        char c;         /* IN: char to locate   */
 
242
{
 
243
  return(oscbskip(str, strlen(str), c));
 
244
}
 
245
 
 
246
/*===========================================================================*/
 
247
int stuset(table, list)
 
248
/*+++++++
 
249
.PURPOSE Prepare table for scan / span operations: value of 1 for characters
 
250
        in list, value 0 for other characters. Both upper and lower case
 
251
        are inserted in table.
 
252
.RETURNS Length of list
 
253
---------*/
 
254
        unsigned char *table;   /* OUT: Table with flagged characters   */
 
255
        char *list;     /* IN: list of characters to flag       */
 
256
{
 
257
        register char *p;
 
258
 
 
259
  oscfill((char *)table, SIZE, 0);
 
260
  for (p=list; *p; p++) 
 
261
  {     *(table + *(unsigned char *)p) = 1; 
 
262
        *(table + (unsigned)tocase(*p)) = 1;
 
263
  }
 
264
  
 
265
  return(p-list);
 
266
}
 
267
 
 
268
/*===========================================================================*/
 
269
int stuspans (str, list)
 
270
/*+++++++
 
271
.PURPOSE Match as many as possible chars specified in list, case insensitive.
 
272
.RETURNS Index of first character which is not in list;
 
273
        length of str if all characters are in list.
 
274
.REMARK  To span e.g. alphabetic chars, use macro strspan(str, _ALPHA_) 
 
275
---------*/
 
276
        char *str;      /* IN: address of string to span        */
 
277
        char *list;     /* IN: list of matching characters      */
 
278
{
 
279
  stuset(ttable, list);
 
280
  return(oscspan((unsigned char *)str, (int) strlen(str), 1, ttable));
 
281
}
 
282
        
 
283
/*===========================================================================
 
284
 *                      Scan / Span strings
 
285
 *===========================================================================*/
 
286
 
 
287
int strset(table, list)
 
288
/*+++++++
 
289
.PURPOSE Prepare table for scan / span operations: value of 1 for characters
 
290
        in list, value 0 for other characters.
 
291
.RETURNS Length of list
 
292
---------*/
 
293
        unsigned char *table;   /* OUT: Table [256] with flagged characters */
 
294
        char *list;             /* IN: list of characters to flag       */
 
295
{
 
296
        register char *p;
 
297
 
 
298
  oscfill((char *)table, SIZE, 0);
 
299
  for (p=list; *p; p++)         *(table + *(unsigned char *)p) = 1;
 
300
  
 
301
  return(p-list);
 
302
}
 
303
 
 
304
/*===========================================================================*/
 
305
int strspan_ (str, mask, table)
 
306
/*+++++++
 
307
.PURPOSE Match as many as possible of flagged (non-zero in table) chars.
 
308
.RETURNS Index of first character which is not flagged; 
 
309
        length of str if all characters are flagged.
 
310
.REMARKS Table can be created with strset.
 
311
        If table[0] is not null, the result may be wrong.
 
312
---------*/
 
313
        char *str;      /* IN: address of string to span        */
 
314
        unsigned char mask;     /* IN: attribute mask           */
 
315
        unsigned char *table;   /* IN: attribute table          */
 
316
{
 
317
  if (table[0] & mask)  table = cpt(table, 0);  /* EOS MUST end */
 
318
  return(oscspan((unsigned char *)str, strlen(str), mask, table));
 
319
}
 
320
 
 
321
int strbspan_ (str, mask, table)
 
322
/*+++++++
 
323
.PURPOSE Match as many as possible of flagged chars, 
 
324
        starting from end (backwards matching)
 
325
.RETURNS Index of first character which is not flagged (RIHT to LEFT);  -1 
 
326
        if all characters are flagged.
 
327
.REMARKS Table can be created with strset
 
328
---------*/
 
329
        char *str;      /* IN: address of string to span        */
 
330
        unsigned char mask;     /* IN: attribute mask           */
 
331
        unsigned char *table;   /* IN: attribute table          */
 
332
{
 
333
  return(oscbspan((unsigned char *)str, strlen(str), mask, table));
 
334
}
 
335
 
 
336
/*===========================================================================*/
 
337
int strspans (str, list)
 
338
/*+++++++
 
339
.PURPOSE Match as many as possible chars specified in list.
 
340
.RETURNS Index of first character which is not in list;
 
341
        length of str if all characters are in list.
 
342
---------*/
 
343
        char *str;      /* IN: address of string to span        */
 
344
        char *list;     /* IN: list of matching characters      */
 
345
{
 
346
  strset(ttable, list);         /* ttable[0] is zero    */
 
347
  return(oscspan((unsigned char *)str, strlen(str), 1, ttable));
 
348
}
 
349
 
 
350
/*===========================================================================*/
 
351
int strbspans (str, list)
 
352
/*+++++++
 
353
.PURPOSE Match as many as possible chars specified in list, 
 
354
                looking from the end of the string.
 
355
.RETURNS Index of last character which is not in list; -1 if 
 
356
        all characters are in list.
 
357
---------*/
 
358
        char *str;      /* IN: address of string to span        */
 
359
        char *list;     /* IN: list of matching characters      */
 
360
{
 
361
  strset(ttable, list);
 
362
  return(oscbspan((unsigned char *)str, strlen(str), 1, ttable));
 
363
}
 
364
 
 
365
/*===========================================================================*/
 
366
int stubspans (str, list)
 
367
/*+++++++
 
368
.PURPOSE Match as many as possible chars specified in list, case insensitive,
 
369
                looking from the end of the string.
 
370
.RETURNS Index of last character which is not in list; -1 if 
 
371
                all characters are in list.
 
372
---------*/
 
373
        char *str;      /* IN: address of string to span        */
 
374
        char *list;     /* IN: list of matching characters      */
 
375
{
 
376
  stuset(ttable, list);
 
377
  return(oscbspan((unsigned char *)str, strlen(str), 1, ttable));
 
378
}
 
379
 
 
380
 
 
381
/*===========================================================================*/
 
382
int stuskip(str, c)
 
383
/*+++++++
 
384
.PURPOSE Locate the first character that differs from `c', case insensitive.
 
385
.RETURNS Index of `c' in str; length of str if str is made only of `c's
 
386
---------*/
 
387
        char *str;      /* IN: string to scan   */
 
388
        char c;         /* IN: char to locate   */
 
389
{
 
390
  argstr[0] = c;
 
391
  return(stuspans(str, argstr));
 
392
}
 
393
        
 
394
int stubskip(str, c)
 
395
/*+++++++
 
396
.PURPOSE Locate the last character that differs from `c', case insensitive.
 
397
.RETURNS Index of `c' in str; -1 if str is made only of `c's
 
398
---------*/
 
399
        char *str;      /* IN: string to scan   */
 
400
        char c;         /* IN: char to locate   */
 
401
{
 
402
  argstr[0] = c;
 
403
  return(stubspans(str, argstr));
 
404
}
 
405
 
 
406
/*===========================================================================*/
 
407
int strscan_ (str, mask, table)
 
408
/*+++++++
 
409
.PURPOSE Look for first flagged (non-zero in table) char.
 
410
.RETURNS Index of first flagged character; length of str if none was found.
 
411
.REMARKS Table can be created with strset
 
412
---------*/
 
413
        char *str;      /* IN: address of string to span        */
 
414
        unsigned char mask;     /* IN: attribute mask           */
 
415
        unsigned char *table;   /* IN: attribute table          */
 
416
{
 
417
  if_not(table[0] & mask)       
 
418
        table = cpt(table, mask);       /* EOS MUST end */
 
419
  
 
420
  return(oscscan((unsigned char *)str, strlen(str), mask, table));
 
421
}
 
422
 
 
423
int strbscan_ (str, mask, table)
 
424
/*+++++++
 
425
.PURPOSE Look for last flagged (non-zero in table) char.
 
426
.RETURNS Index of last flagged character, -1 if none was found.
 
427
.REMARKS Table can be created with strset
 
428
---------*/
 
429
        char *str;      /* IN: address of string to span        */
 
430
        unsigned char mask;     /* IN: attribute mask           */
 
431
        unsigned char *table;   /* IN: attribute table          */
 
432
{
 
433
  return(oscbscan((unsigned char *)str, strlen(str), mask, table));
 
434
}
 
435
 
 
436
/*===========================================================================*/
 
437
int strscans (str, list)
 
438
/*+++++++
 
439
.PURPOSE Look for first char specified in list.
 
440
.RETURNS Index of first character in str which is in list;
 
441
        length of str if none was found.
 
442
.REMARK  To scan e.g. alphabetic chars, use macro strscan(str, _ALPHA_) 
 
443
---------*/
 
444
        char *str;      /* IN: address of string to span        */
 
445
        char *list;     /* IN: list of matching characters      */
 
446
{
 
447
  strset(ttable, list); ttable[0] = 1;
 
448
  return(oscscan((unsigned char *)str, strlen(str), 1, ttable));
 
449
}
 
450
 
 
451
int strscan1 (str, list)
 
452
/*+++++++
 
453
.PURPOSE Look for first char specified in list, only if not escaped
 
454
        by a backslash
 
455
.RETURNS Index of first character in str which is in list;
 
456
        length of str if none was found.
 
457
---------*/
 
458
        char *str;      /* IN: address of string to span        */
 
459
        char *list;     /* IN: list of matching characters      */
 
460
{
 
461
        char    *p;
 
462
 
 
463
  strset(ttable, list); ttable[0] = 1;  ttable['\\'] = 1;
 
464
 
 
465
  for (p = str; *p; )
 
466
  {     p += oscscan((unsigned char *)p, strlen(p), 1, ttable);
 
467
        if (*p != '\\') break;
 
468
        p += 2;
 
469
  }
 
470
  return(p - str);
 
471
}
 
472
 
 
473
/*===========================================================================*/
 
474
int stuscans (str, list)
 
475
/*+++++++
 
476
.PURPOSE Look for first flagged (non-zero in table) char, case insensitive
 
477
.RETURNS Index of first character in str which is in list;
 
478
        length of str if none was found.
 
479
---------*/
 
480
        char *str;      /* IN: address of string to scan        */
 
481
        char *list;     /* IN: list of matching characters      */
 
482
{
 
483
  stuset(ttable, list); ttable[0] = 1;
 
484
  return(oscscan((unsigned char *)str, strlen(str), 1, ttable));
 
485
}
 
486
 
 
487
/*===========================================================================*/
 
488
int strbscans (str, list)
 
489
/*+++++++
 
490
.PURPOSE Retrieve last char specified in list.
 
491
.RETURNS Index of last char in str which is in list, -1 if none was found.
 
492
---------*/
 
493
        char *str;      /* IN: address of string to span        */
 
494
        char *list;     /* IN: list of matching characters      */
 
495
{
 
496
  strset(ttable, list);
 
497
  return(oscbscan((unsigned char *)str, strlen(str), 1, ttable));
 
498
}
 
499
 
 
500
/*===========================================================================*/
 
501
int stubscans (str, list)
 
502
/*+++++++
 
503
.PURPOSE Retrieve last char specified in list, case insensitive.
 
504
.RETURNS Index of last char in str which is in list, -1 if none was found.
 
505
---------*/
 
506
        char *str;      /* IN: address of string to scan        */
 
507
        char *list;     /* IN: list of matching characters      */
 
508
{
 
509
  stuset(ttable, list);
 
510
  return(oscbscan((unsigned char *)str, strlen(str), 1, ttable));
 
511
}
 
512
 
 
513
/*===========================================================================
 
514
 *                      String Comparisons
 
515
 *===========================================================================*/
 
516
 
 
517
int strcomp(s1,s2)
 
518
/*++++++++++++++++++++++++
 
519
.PURPOSE Compare (or compute difference of) two strings.
 
520
.RETURNS A positive value if s1 > s2, zero if strings are identical,
 
521
        a negative value if s1 < s2.
 
522
-----------*/
 
523
     char *s1;  /* IN: address of first string  */
 
524
     char *s2;  /* IN: address of 2nd string    */
 
525
{
 
526
        register char *p, *q;
 
527
 
 
528
  for (p=s1, q=s2; *p == *q; p++, q++)
 
529
        if (!(*p))      break;
 
530
  
 
531
  return(*p - *q);
 
532
}
 
533
 
 
534
/*===========================================================================*/
 
535
int stucomp(s1,s2)
 
536
/*++++++++++++++++++++++++
 
537
.PURPOSE Compare (or compute difference of) two strings, case insensitive.
 
538
.RETURNS A positive value if s1 > s2, zero if strings are identical,
 
539
        a negative value if s1 < s2.
 
540
-----------*/
 
541
     char *s1;  /* IN: address of first string  */
 
542
     char *s2;  /* IN: address of 2nd string    */
 
543
{
 
544
        char    *p, *q;
 
545
        char    cp, cq;
 
546
 
 
547
  for (p=s1, q=s2; ; p++, q++)
 
548
  {     cp = toupper(*p), cq = toupper(*q);
 
549
        if (cp != cq)   break;
 
550
        if (!cp)        break;
 
551
  }
 
552
  
 
553
  return(cp - cq);
 
554
}
 
555
 
 
556
/*===========================================================================*/
 
557
int strmatch(s1,s2)
 
558
/*++++++++++++++++++++++++
 
559
.PURPOSE Look for longest matching string.
 
560
.RETURNS The number of characters common to s1 and s2. If strings are identical,
 
561
        the common length of both strings.
 
562
-----------*/
 
563
     char *s1;  /* IN: address of first string  */
 
564
     char *s2;  /* IN: address of 2nd string    */
 
565
{
 
566
        register char *p, *q;
 
567
 
 
568
  for (p=s1, q=s2; *p == *q; p++, q++)
 
569
        if (!(*p))      break;
 
570
  
 
571
  return(p - s1);
 
572
}
 
573
 
 
574
/*===========================================================================*/
 
575
int stumatch(s1,s2)
 
576
/*++++++++++++++++++++++++
 
577
.PURPOSE Look for longest matching string, case insensitive.
 
578
.RETURNS The number of characters common to s1 and s2. If strings are identical,
 
579
        the common length of both strings.
 
580
-----------*/
 
581
     char *s1;  /* IN: address of first string  */
 
582
     char *s2;  /* IN: address of 2nd string    */
 
583
{
 
584
        char    *p, *q;
 
585
        char    cp, cq;
 
586
 
 
587
  for (p=s1, q=s2; ; p++, q++)
 
588
  {     cp = toupper(*p), cq = toupper(*q);
 
589
        if (cp != cq)   break;
 
590
        if (!cp)        break;
 
591
  }
 
592
  
 
593
  return(p - s1);
 
594
}
 
595
 
 
596
/*===========================================================================*/
 
597
int strindex( s1, s2)
 
598
/*++++++++++++++++++++++++
 
599
.PURPOSE Locates a substring within a string
 
600
.RETURNS Index within first string of second string;
 
601
          length of the first string for mismatch.
 
602
.METHOD  Use a scan on first char, then compare.
 
603
-----------*/
 
604
     char *s1;  /* IN: address of first string (source) */
 
605
     char *s2;  /* IN: address of 2nd string  (object to find)  */
 
606
{   
 
607
        register char *s;
 
608
 
 
609
     s = strstr(s1,s2);
 
610
     if (s == NULL) return(strlen(s1));
 
611
     else           return(s-s1);
 
612
     
 
613
}
 
614
 
 
615
/*===========================================================================*/
 
616
int stuindex( s1, s2)
 
617
/*++++++++++++++++++++++++
 
618
.PURPOSE Locates a substring within a string, case insensitive
 
619
.RETURNS Index within first string of second string;
 
620
          length of the first string for mismatch.
 
621
.METHOD  Use a scan on first char, then compare.
 
622
-----------*/
 
623
     char *s1;  /* IN: address of first string (source) */
 
624
     char *s2;  /* IN: address of 2nd string  (object to find)  */
 
625
{   
 
626
        register char *p1;
 
627
        register int l2;
 
628
 
 
629
  p1 = s1;
 
630
  if ((l2 = strlen(s2)) == 0)   goto FIN;
 
631
  oscfill((char *)ttable, sizeof(ttable), 0);   
 
632
  ttable[0] = 1; 
 
633
  ttable[(int) *s2] = 1; 
 
634
  ttable[(unsigned)tocase(*s2)] = 1;
 
635
 
 
636
  for (; *p1; p1++)
 
637
  {     p1 += oscscan((unsigned char *)p1, strlen(p1), 1, ttable);
 
638
        if (!(*p1))                     break;
 
639
        if (osccomp(p1, s2, l2) == 0)   break;
 
640
  }
 
641
 
 
642
  FIN: return(p1-s1);
 
643
}
 
644
 
 
645
/*===========================================================================*/
 
646
static int _item( s1, s2, sep)
 
647
/*++++++++++++++++++++++++
 
648
.PURPOSE Locates a substring within a string, which must be followed / preceded
 
649
        by separator(s) characters
 
650
.RETURNS Index within first string of second string. The index
 
651
          is the length of the first string for mismatch.
 
652
.METHOD  Use strindex, then check preceding / following char.
 
653
-----------*/
 
654
     char *s1;  /* IN: address of first string (source) */
 
655
     char *s2;  /* IN: address of 2nd string  (object to find)  */
 
656
     char *sep; /* IN: list of separators       */
 
657
{   
 
658
        register char   *p, *p1;
 
659
        register int    i;
 
660
 
 
661
  i = strlen(s2);
 
662
  if (i == 0)   i = 1;
 
663
  
 
664
  for (p = p1 = s1; ; p1 += i)
 
665
  {     p1 += (*f)(p1, s2);             /* Index of s2 in p1    */
 
666
        if_not(*p1)     break;          /* Not Found...         */
 
667
        if (p1 > s1)                    /* Check preceding char */
 
668
        {       p = p1-1;
 
669
                if_not(sep[strloc(sep, *p)])
 
670
                        continue;
 
671
        }
 
672
        p = p1 + i;                     /* Check following char */
 
673
        if_not(*p)      break;          /* Located at end : OK  */
 
674
        if (sep[strloc(sep, *p)])       /* Separator found      */
 
675
                        break;
 
676
  }
 
677
 
 
678
  return(p1-s1);
 
679
}
 
680
 
 
681
/*===========================================================================*/
 
682
int stritem( s1, s2, sep)
 
683
/*++++++++++++++++++++++++
 
684
.PURPOSE Locates a substring within a string, which must be followed / preceded
 
685
        by separator(s) characters
 
686
.RETURNS Index within first string of second string;
 
687
          length of the first string for mismatch.
 
688
.METHOD  Use strindex, then check preceding / following char.
 
689
-----------*/
 
690
     char       *s1;    /* IN: address of first string (source) */
 
691
     char       *s2;    /* IN: address of 2nd string  (object to find)  */
 
692
     char       *sep;   /* IN: list of separators       */
 
693
{   
 
694
        int strindex();
 
695
  
 
696
  f = strindex;
 
697
  
 
698
  return(_item(s1,s2,sep));
 
699
}
 
700
 
 
701
/*===========================================================================*/
 
702
int stuitem( s1, s2, sep)
 
703
/*++++++++++++++++++++++++
 
704
.PURPOSE Locates a substring within a string, which must be followed / preceded
 
705
        by separator(s) characters, case insensitive.
 
706
.RETURNS Index within first string of second string;
 
707
          length of the first string for mismatch.
 
708
.METHOD  Use stuindex, then check preceding / following char.
 
709
-----------*/
 
710
     char *s1;  /* IN: address of first string (source) */
 
711
     char *s2;  /* IN: address of 2nd string  (object to find)  */
 
712
     char *sep; /* IN: list of separators       */
 
713
{   
 
714
        int stuindex();
 
715
  
 
716
  f = stuindex;
 
717
  
 
718
  return(_item(s1,s2,sep));
 
719
}
 
720
 
 
721
/*===========================================================================
 
722
 *                      String Conversions
 
723
 *===========================================================================*/
 
724
 
 
725
int strsetr (table, s1, s2)
 
726
/*+++++++
 
727
.PURPOSE  Create a table for character translations.
 
728
.RETURNS  Length of s1.
 
729
.REMARKS  Characters in s1 without counterpart in s2 (i.e. s1 is longer
 
730
        than s2) are replaced by a tilde (~).
 
731
---------*/
 
732
     unsigned char *table;      /* OUT: translation table[256]  */
 
733
     char *s1;          /* IN: list characters to translate     */
 
734
     char *s2;          /* IN: list of translated characters    */
 
735
{
 
736
        register char *p, *q;
 
737
        register int i;
 
738
 
 
739
  for (i=0; i<SIZE; i++)        *(table + i) = i;       /* Fill table   */
 
740
  for (p=s1, q=s2; *p; )
 
741
        *(table + *(p++)) = (*q ? *(q++) : '~');
 
742
 
 
743
  return(p-s1);
 
744
}
 
745
 
 
746
/*===========================================================================*/
 
747
int strtr_ (dest, source, table)
 
748
/*+++++++
 
749
.PURPOSE  Translate source into destination, according to translation table.
 
750
.RETURNS  Length of source / destination
 
751
.REMARKS  The translation table may be created by strsetr.
 
752
---------*/
 
753
     char *dest;        /* OUT: the translated string           */
 
754
     char *source;      /* IN:  the string to translate         */
 
755
     unsigned char *table; /* IN: translation table             */
 
756
{
 
757
  return(osctr((unsigned char *)dest ,(unsigned char *)source, strlen(source)+1, table));
 
758
}
 
759
 
 
760
/*===========================================================================*/
 
761
int strtrs (dest, source, s1, s2)
 
762
/*+++++++
 
763
.PURPOSE  Translate source into destination, transforming characters in s1
 
764
        into the corresponding character in s2.
 
765
.RETURNS  Length of source / dest.
 
766
.REMARKS  Characters in s1 without counterpart in s2 (i.e. s1 is longer
 
767
        than s2) are replaced by a tilde (~).
 
768
        The strings may overlap.
 
769
---------*/
 
770
     char *dest;        /* OUT: the translated string           */
 
771
     char *source;      /* IN:  the string to translate         */
 
772
     char *s1;          /* IN: list characters to translate     */
 
773
     char *s2;          /* IN: list of translated characters    */
 
774
{
 
775
        register int len;
 
776
 
 
777
  strsetr(ttable, s1, s2);
 
778
  len = strlen(source);
 
779
  osctr((unsigned char *)dest, (unsigned char *)source, len+1, ttable);
 
780
  return(len);
 
781
}
 
782
 
 
783
/*===========================================================================
 
784
 *                      Change Cases
 
785
 *===========================================================================*/
 
786
int strlower ( str )
 
787
/*+++++++++
 
788
.PURPOSE  Converts (in place) a string to lower case
 
789
.RETURNS  Length of string
 
790
--------*/
 
791
     char *str; /* MOD: starting address        */
 
792
{
 
793
        register char *p;
 
794
 
 
795
  for (p = str; *p; p++)
 
796
        *p = tolower(*p); 
 
797
 
 
798
  return(p-str);
 
799
}
 
800
 
 
801
/*===========================================================================*/
 
802
int strupper ( str )
 
803
/*+++++++++
 
804
.PURPOSE  Converts (in place) a string to upper case
 
805
.RETURNS  Length of string
 
806
--------*/
 
807
     char *str; /* MOD: starting address        */
 
808
{
 
809
        register char *p;
 
810
 
 
811
  for (p = str; *p; p++)
 
812
        *p = toupper(*p); 
 
813
 
 
814
  return(p-str);
 
815
}
 
816
 
 
817
/*===========================================================================*/
 
818
int strcase ( str )
 
819
/*+++++++++
 
820
.PURPOSE  Changes (in place) the case of a string, i.e. uppercase to lowercase
 
821
        and vice-versa.
 
822
.RETURNS  Length of string
 
823
--------*/
 
824
     char *str; /* MOD: starting address        */
 
825
{
 
826
        register char *p;
 
827
 
 
828
  for (p = str; *p; p++)
 
829
        *p = tocase(*p); 
 
830
 
 
831
  return(p-str);
 
832
}
 
833
 
 
834
/*===========================================================================
 
835
 *                      Reduce a string
 
836
 *===========================================================================*/
 
837
 
 
838
int strdel_ (str, mask, table)
 
839
/*+++++++
 
840
.PURPOSE  Delete all chars flagged in table
 
841
.RETURNS  New Length of string
 
842
.REMARKS  The string is EOS-terminated.
 
843
---------*/
 
844
     char *str; /* MOD: string to modify                */
 
845
     unsigned char mask;        /* IN: Mask to use (ANDed with table)   */
 
846
     unsigned char *table;      /* IN: table of flags                   */
 
847
{
 
848
        register char *p, *q;
 
849
 
 
850
  for ( p=str, q=p; *p; p++)
 
851
        if (!(ischar_(*p, mask, table)))        *(q++) = *p;
 
852
 
 
853
  *q = EOS;
 
854
 
 
855
  return(q-str);
 
856
}
 
857
 
 
858
/*===========================================================================*/
 
859
int strred_ (str, mask, table)
 
860
/*+++++++++++
 
861
.PURPOSE Reduces (in place) a string with suppression of redundant flagged
 
862
        characters (e.g. spaces).
 
863
        Leading and trailing spaces are also removed.
 
864
.RETURNS Length of modified (shorter) string.
 
865
-----------*/
 
866
     char *str; /* MOD: string to modify                */
 
867
     unsigned char mask;        /* IN: Mask to use (ANDed with table)   */
 
868
     unsigned char *table;      /* IN: table of flags                   */
 
869
{
 
870
        register char *p, *q;
 
871
        char this_char, prec_char;
 
872
 
 
873
  this_char = prec_char = mask; /* for a suppression of leading spaces */
 
874
 
 
875
  for (p=str, q=p; *p; prec_char = this_char, p++)
 
876
  {     this_char = ischar_(*p, mask, table);
 
877
        if (prec_char && this_char) continue;
 
878
        *(q++) = *p;
 
879
  }
 
880
                                     /* suppress last char if = fill */
 
881
  if(prec_char && (q != str))   q--; 
 
882
  *q = EOS;
 
883
 
 
884
  return(q-str);
 
885
}
 
886
 
 
887
/*===========================================================================*/
 
888
int strred (str)
 
889
/*+++++++++++
 
890
.PURPOSE Reduces (in place) a string with suppression of redundant spaces.
 
891
        Leading and trailing spaces are also removed.
 
892
.RETURNS Length of modified (shorter) string.
 
893
-----------*/
 
894
     char *str;                 /* MOD: string to modify                */
 
895
{
 
896
        register char *p, *q;
 
897
        char this_char, prec_char;
 
898
 
 
899
  this_char = prec_char = ' ';  /* for a suppression of leading spaces */
 
900
 
 
901
  for (p=str, q=p; *p; prec_char = this_char, p++)
 
902
  {     this_char = (isspace(*p) ? ' ' : *p);
 
903
        if ((prec_char == ' ') && (this_char == ' ')) continue;
 
904
        *(q++) = *p;
 
905
  }
 
906
                                     /* suppress last char if = fill */
 
907
  if((prec_char == ' ') && (q != str))  q--; 
 
908
  *q = EOS;
 
909
 
 
910
  return(q-str);
 
911
}
 
912
 
 
913
/*===========================================================================*/
 
914
int strred1 ( str , escape )
 
915
/*+++++++++
 
916
.PURPOSE Reduces (in place) a string with suppression of `escape' char's,
 
917
        e.g. if escape is \  replace \\ by \, \% by %, etc.
 
918
.RETURNS Length of reduced string.
 
919
.REMARKS First and last `escape' are also removed. This function can be
 
920
        used e.g. to extract a string within quotes.
 
921
----------*/
 
922
     char *str;         /* MOD: String to modify        */
 
923
     char escape;       /* IN: escape char to be removed        */
 
924
{
 
925
        register char *p, *q;
 
926
 
 
927
  for (p = str, q=p; *p; )
 
928
  {     if (*p == escape)    if (*(++p) == EOS) break;
 
929
        *(q++) = *(p++);
 
930
  }
 
931
  *q = EOS;
 
932
 
 
933
  return(q-str);
 
934
}
 
935
 
 
936
 
 
937
/*===========================================================================
 
938
 *                      Other string utilities
 
939
 *===========================================================================*/
 
940
int strline_ ( str, lmax, mask, table)
 
941
/*+++++++++++++++
 
942
.PURPOSE Look for the longest match of a line in a string without 
 
943
        cutting words; a word is made of chars surrounded by sep_char(s).
 
944
.RETURNS Returns the length of the best match.
 
945
.REMARKS The rightestmost space is ignored.
 
946
----------------*/
 
947
     char *str;                 /* MOD: string to scan                  */
 
948
     int lmax;                  /* IN: max length of a line             */
 
949
     unsigned char mask;        /* IN: Mask to use (ANDed with table)   */
 
950
     unsigned char *table;      /* IN: table of flags                   */
 
951
{
 
952
        register int len;
 
953
        register char *p;
 
954
 
 
955
  if_not(table[0] & mask)       
 
956
        table = cpt(table, mask);       /* EOS MUST end */
 
957
 
 
958
  for (p = str; *p; )
 
959
  {     len = oscscan((unsigned char *)p, lmax, mask, table);
 
960
        if (((p-str)+len) > lmax)       break;
 
961
        p += len;
 
962
        p += oscspan((unsigned char *)p, lmax, mask, table);    /* Don't span EOS! */
 
963
  }
 
964
                                /* If no space was found, set to lmax   */
 
965
  if ((*p) && (p == str))       p = str + lmax;
 
966
 
 
967
  return(p-str);
 
968
}
 
969
 
 
970
/*===========================================================================*/
 
971
int stuloc(str, c)
 
972
/*+++++++
 
973
.PURPOSE Locate the first occurence of character `c', case insensitive.
 
974
.RETURNS Index of `c' or `C' in str; length of str if `c' not found.
 
975
---------*/
 
976
        char *str;      /* IN: string to scan   */
 
977
        char c;         /* IN: char to locate   */
 
978
{
 
979
  argstr[0] = c;
 
980
  return(stuscans(str, argstr));
 
981
}
 
982
 
 
983
 
 
984
int stubloc(str, c)
 
985
/*+++++++
 
986
.PURPOSE Locate the last occurence of character `c', case insensitive.
 
987
.RETURNS Index of `c' or `C' in str; -1 if `c' not found.
 
988
---------*/
 
989
        char *str;      /* IN: string to scan   */
 
990
        char c;         /* IN: char to locate   */
 
991
{
 
992
  argstr[0] = c;
 
993
  return(stubscans(str, argstr));
 
994
}
 
995