1 |
|
|
/* $OpenBSD: misc.c,v 1.71 2015/11/14 13:09:14 millert Exp $ */ |
2 |
|
|
|
3 |
|
|
/* Copyright 1988,1990,1993,1994 by Paul Vixie |
4 |
|
|
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") |
5 |
|
|
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc. |
6 |
|
|
* |
7 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
8 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
9 |
|
|
* copyright notice and this permission notice appear in all copies. |
10 |
|
|
* |
11 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES |
12 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR |
14 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
17 |
|
|
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 |
|
|
*/ |
19 |
|
|
|
20 |
|
|
#include <sys/types.h> |
21 |
|
|
#include <sys/wait.h> |
22 |
|
|
|
23 |
|
|
#include <bitstring.h> /* for structs.h */ |
24 |
|
|
#include <stdio.h> |
25 |
|
|
#include <stdlib.h> |
26 |
|
|
#include <string.h> |
27 |
|
|
#include <time.h> /* for structs.h */ |
28 |
|
|
|
29 |
|
|
#include "macros.h" |
30 |
|
|
#include "structs.h" |
31 |
|
|
#include "funcs.h" |
32 |
|
|
#include "globals.h" |
33 |
|
|
|
34 |
|
|
int LineNumber; |
35 |
|
|
|
36 |
|
|
/* get_char(file) : like getc() but increment LineNumber on newlines |
37 |
|
|
*/ |
38 |
|
|
int |
39 |
|
|
get_char(FILE *file) |
40 |
|
|
{ |
41 |
|
|
int ch; |
42 |
|
|
|
43 |
|
|
ch = getc(file); |
44 |
|
|
if (ch == '\n') |
45 |
|
|
Set_LineNum(LineNumber + 1) |
46 |
|
|
return (ch); |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
/* unget_char(ch, file) : like ungetc but do LineNumber processing |
50 |
|
|
*/ |
51 |
|
|
void |
52 |
|
|
unget_char(int ch, FILE *file) |
53 |
|
|
{ |
54 |
|
|
ungetc(ch, file); |
55 |
|
|
if (ch == '\n') |
56 |
|
|
Set_LineNum(LineNumber - 1) |
57 |
|
|
} |
58 |
|
|
|
59 |
|
|
/* get_string(str, max, file, termstr) : like fgets() but |
60 |
|
|
* (1) has terminator string which should include \n |
61 |
|
|
* (2) will always leave room for the null |
62 |
|
|
* (3) uses get_char() so LineNumber will be accurate |
63 |
|
|
* (4) returns EOF or terminating character, whichever |
64 |
|
|
*/ |
65 |
|
|
int |
66 |
|
|
get_string(char *string, int size, FILE *file, char *terms) |
67 |
|
|
{ |
68 |
|
|
int ch; |
69 |
|
|
|
70 |
|
|
while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) { |
71 |
|
|
if (size > 1) { |
72 |
|
|
*string++ = ch; |
73 |
|
|
size--; |
74 |
|
|
} |
75 |
|
|
} |
76 |
|
|
|
77 |
|
|
if (size > 0) |
78 |
|
|
*string = '\0'; |
79 |
|
|
|
80 |
|
|
return (ch); |
81 |
|
|
} |
82 |
|
|
|
83 |
|
|
/* skip_comments(file) : read past comment (if any) |
84 |
|
|
*/ |
85 |
|
|
void |
86 |
|
|
skip_comments(FILE *file) |
87 |
|
|
{ |
88 |
|
|
int ch; |
89 |
|
|
|
90 |
|
|
while (EOF != (ch = get_char(file))) { |
91 |
|
|
/* ch is now the first character of a line. |
92 |
|
|
*/ |
93 |
|
|
|
94 |
|
|
while (ch == ' ' || ch == '\t') |
95 |
|
|
ch = get_char(file); |
96 |
|
|
|
97 |
|
|
if (ch == EOF) |
98 |
|
|
break; |
99 |
|
|
|
100 |
|
|
/* ch is now the first non-blank character of a line. |
101 |
|
|
*/ |
102 |
|
|
|
103 |
|
|
if (ch != '\n' && ch != '#') |
104 |
|
|
break; |
105 |
|
|
|
106 |
|
|
/* ch must be a newline or comment as first non-blank |
107 |
|
|
* character on a line. |
108 |
|
|
*/ |
109 |
|
|
|
110 |
|
|
while (ch != '\n' && ch != EOF) |
111 |
|
|
ch = get_char(file); |
112 |
|
|
|
113 |
|
|
/* ch is now the newline of a line which we're going to |
114 |
|
|
* ignore. |
115 |
|
|
*/ |
116 |
|
|
} |
117 |
|
|
if (ch != EOF) |
118 |
|
|
unget_char(ch, file); |
119 |
|
|
} |
120 |
|
|
|
121 |
|
|
/* char *first_word(char *s, char *t) |
122 |
|
|
* return pointer to first word |
123 |
|
|
* parameters: |
124 |
|
|
* s - string we want the first word of |
125 |
|
|
* t - terminators, implicitly including \0 |
126 |
|
|
* warnings: |
127 |
|
|
* (1) this routine is fairly slow |
128 |
|
|
* (2) it returns a pointer to static storage |
129 |
|
|
*/ |
130 |
|
|
char * |
131 |
|
|
first_word(char *s, char *t) |
132 |
|
|
{ |
133 |
|
|
static char retbuf[2][MAX_TEMPSTR + 1]; /* sure wish C had GC */ |
134 |
|
|
static int retsel = 0; |
135 |
|
|
char *rb, *rp; |
136 |
|
|
|
137 |
|
|
/* select a return buffer */ |
138 |
|
|
retsel = 1-retsel; |
139 |
|
|
rb = &retbuf[retsel][0]; |
140 |
|
|
rp = rb; |
141 |
|
|
|
142 |
|
|
/* skip any leading terminators */ |
143 |
|
|
while (*s && (NULL != strchr(t, *s))) { |
144 |
|
|
s++; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
/* copy until next terminator or full buffer */ |
148 |
|
|
while (*s && (NULL == strchr(t, *s)) && (rp < &rb[MAX_TEMPSTR])) { |
149 |
|
|
*rp++ = *s++; |
150 |
|
|
} |
151 |
|
|
|
152 |
|
|
/* finish the return-string and return it */ |
153 |
|
|
*rp = '\0'; |
154 |
|
|
return (rb); |
155 |
|
|
} |