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 } 156