1 /*
2  * Copyright (C) 2014 haru <uobikiemukot at gmail dot com>
3  * Copyright (C) 2014 Hayaki Saito <user@zuse.jp>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "config.h"
20 
21 #include <stdio.h>
22 #if HAVE_ERRNO_H
23 # include <errno.h>
24 #endif
25 #if HAVE_LIMITS_H
26 # include <limits.h>
27 #endif
28 #if HAVE_UNISTD_H
29 # include <unistd.h>
30 #endif
31 #if HAVE_STDLIB_H
32 # include <stdlib.h>
33 #endif
34 #if HAVE_STRING_H
35 # include <string.h>
36 #endif
37 
38 #include "yaft.h"
39 
40 /* error functions */
error(char * str)41 void error(char *str)
42 {
43     perror(str);
44     exit(EXIT_FAILURE);
45 }
46 
fatal(char * str)47 void fatal(char *str)
48 {
49     fprintf(stderr, "%s\n", str);
50     exit(EXIT_FAILURE);
51 }
52 
53 /* wrapper of C functions */
ecalloc(size_t nmemb,size_t size)54 void *ecalloc(size_t nmemb, size_t size)
55 {
56     void *ptr;
57 #if HAVE_SYS_ERRNO_H || HAVE_ERRNO_H
58     errno = 0;
59 #endif
60 
61 #if HAVE_CALLOC
62     if ((ptr = calloc(nmemb, size)) == NULL)
63         error("calloc");
64 #else
65     if ((ptr = malloc(nmemb * size)) == NULL)
66         error("malloc");
67     memset(ptr, 0, nmemb * size);
68 #endif
69 
70     return ptr;
71 }
72 
erealloc(void * ptr,size_t size)73 void *erealloc(void *ptr, size_t size)
74 {
75     void *new;
76 #if HAVE_SYS_ERRNO_H || HAVE_ERRNO_H
77     errno = 0;
78 #endif
79 
80     if ((new = realloc(ptr, size)) == NULL)
81         error("realloc");
82 
83     return new;
84 }
85 
estrtol(const char * nptr,char ** endptr,int base)86 static long estrtol(const char *nptr, char **endptr, int base)
87 {
88     long int ret;
89 #if HAVE_SYS_ERRNO_H || HAVE_ERRNO_H
90     errno = 0;
91 #endif
92 
93     ret = strtol(nptr, endptr, base);
94 #if HAVE_LIMITS_H
95     if (ret == LONG_MIN || ret == LONG_MAX) {
96         perror("strtol");
97         return 0;
98     }
99 #endif
100 
101     return ret;
102 }
103 
104 /* parse_arg functions */
reset_parm(struct parm_t * pt)105 void reset_parm(struct parm_t *pt)
106 {
107     int i;
108 
109     pt->argc = 0;
110     for (i = 0; i < MAX_ARGS; i++)
111         pt->argv[i] = NULL;
112 }
113 
add_parm(struct parm_t * pt,char * cp)114 void add_parm(struct parm_t *pt, char *cp)
115 {
116     if (pt->argc >= MAX_ARGS)
117         return;
118 
119     if (DEBUG)
120         fprintf(stderr, "argv[%d]: %s\n",
121             pt->argc, (cp == NULL) ? "NULL": cp);
122 
123     pt->argv[pt->argc] = cp;
124     pt->argc++;
125 }
126 
parse_arg(char * buf,struct parm_t * pt,int delim,int (is_valid)(int c))127 void parse_arg(char *buf, struct parm_t *pt, int delim, int (is_valid)(int c))
128 {
129     /*
130         v..........v d           v.....v d v.....v ... d
131         (valid char) (delimiter)
132         argv[0]                  argv[1]   argv[2] ...   argv[argc - 1]
133     */
134     size_t i, length;
135     char *cp, *vp;
136 
137     if (buf == NULL)
138         return;
139 
140     length = strlen(buf);
141     if (DEBUG)
142         fprintf(stderr, "parse_arg()\nlength:%u\n", (unsigned) length);
143 
144     vp = NULL;
145     for (i = 0; i < length; i++) {
146         cp = buf + i;
147 
148         if (vp == NULL && is_valid(*cp))
149             vp = cp;
150 
151         if (*cp == delim) {
152             *cp = '\0';
153             add_parm(pt, vp);
154             vp = NULL;
155         }
156 
157         if (i == (length - 1) && (vp != NULL || *cp == '\0'))
158             add_parm(pt, vp);
159     }
160 
161     if (DEBUG)
162         fprintf(stderr, "argc:%d\n", pt->argc);
163 }
164 
165 /* other functions */
my_ceil(int val,int div)166 int my_ceil(int val, int div)
167 {
168     return (val + div - 1) / div;
169 }
170 
dec2num(char * str)171 int dec2num(char *str)
172 {
173     if (str == NULL)
174         return 0;
175 
176     return estrtol(str, NULL, 10);
177 }
178 
hex2num(char * str)179 int hex2num(char *str)
180 {
181     if (str == NULL)
182         return 0;
183 
184     return estrtol(str, NULL, 16);
185 }
186 
187 /* emacs, -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
188 /* vim: set expandtab ts=4 : */
189 /* EOF */
190