source: trunk/packages/xen-3.1/xen-3.1/tools/vnet/libxutil/sys_string.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 5.0 KB
Line 
1/*
2 * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * This library 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 Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#ifdef __KERNEL__
20#  include <linux/config.h>
21#  include <linux/module.h>
22#  include <linux/kernel.h>
23#  include <linux/errno.h>
24#else
25#  include <errno.h>
26#endif
27
28#include "allocate.h"
29#include "sys_string.h"
30
31#ifdef __KERNEL__
32
33#define deferr(_err) case _err: return #_err
34
35extern char *strerror(int err)
36{
37    switch(err){
38        deferr(EPERM);
39        deferr(ENOENT);
40        deferr(ESRCH);
41        deferr(EINTR);
42        deferr(EIO);
43        deferr(EINVAL);
44        deferr(ENOMEM);
45        deferr(EACCES);
46        deferr(EFAULT);
47        deferr(EBUSY);
48       
49    default:
50        return "ERROR";
51    }
52}
53
54#endif
55
56/** Set the base to use for converting a string to a number.  Base is
57 * hex if starts with 0x, otherwise decimal.
58 *
59 * @param s input string
60 * @param base where to put the base
61 * @return rest of s to parse as a number
62 */
63inline static const char * convert_set_base(const char *s, int *base){
64    *base = 10;
65    if(s){
66        if(*s=='0'){
67            s++;
68            if(*s=='x' || *s=='X'){
69                *base = 16;
70                s++;
71            }
72        }
73    }
74    return s;
75}
76
77/** Set the sign to use for converting a string to a number.
78 * Value is 1 for positive, -1 for negative.
79 *
80 * @param s input string
81 * @param sign where to put the sign
82 * @return rest of s to parse as a number
83 */
84inline static const char * convert_set_sign(const char *s, int *sign){
85    *sign = 1;
86    if(s){
87        if(*s == '+'){
88            *sign = 1;
89            s++;
90        } else if (*s == '-'){
91            *sign = -1;
92            s++;
93        }
94    }
95    return s;
96}
97
98/** Get the numerical value of a digit in the given base.
99 *
100 * @param c digit character
101 * @param base to use
102 * @return numerical value of digit in range 0..base-1 or
103 * -1 if not in range for the base
104 */
105inline static int convert_get_digit(char c, int base){
106    int d;
107
108    if('0'<=&& c<='9'){
109        d = c - '0';
110    } else if('a'<=c && c<='f'){
111        d = c - 'a' + 10;
112    } else if('A'<=c && c<='F'){
113        d = c - 'A' + 10;
114    } else {
115        d = -1;
116    }
117    return (d < base ? d : -1);
118}
119
120/** Convert a string to an unsigned long by parsing it as a number.
121 * Will accept hex or decimal in usual C syntax.
122 *
123 * @param str input string
124 * @param val where to put the result
125 * @return 0 if converted OK, negative otherwise
126 */
127int convert_atoul(const char *str, unsigned long *val){
128    int err = 0;
129    unsigned long v = 0;
130    int base;
131    const char *s = str;
132
133    if(!s) {
134        err = -EINVAL;
135        goto exit;
136    }
137    s = convert_set_base(s, &base);
138    for( ; !err && *s; s++){
139        int digit = convert_get_digit(*s, base);
140        if(digit<0){
141            err = -EINVAL;
142            goto exit;
143        }
144        v *= base;
145        v += digit;
146    } 
147  exit:
148    *val = (err ? 0 : v);
149    return err;
150}
151
152/** Convert a string to a long by parsing it as a number.
153 * Will accept hex or decimal in usual C syntax.
154 *
155 * @param str input string
156 * @param val where to put the result
157 * @return 0 if converted OK, negative otherwise
158 */
159int convert_atol(const char *str, long *val){
160    int err = 0;
161    unsigned long v = 0;
162    int base, sign = 1;
163    const char *s = str;
164
165    if(!s) {
166        err = -EINVAL;
167        goto exit;
168    }
169    s = convert_set_sign(s, &sign);
170    s = convert_set_base(s, &base);
171    for( ; !err && *s; s++){
172        int digit = convert_get_digit(*s, base);
173        if(digit<0){
174            err = -EINVAL;
175            goto exit;
176        }
177        v *= base;
178        v += digit;
179    } 
180    if(sign < 0) v = -v;
181  exit:
182    *val = (err ? 0 : v);
183    return err;
184}
185
186/** Combine a directory path with a relative path to produce
187 * a new path.
188 *
189 * @param s directory path
190 * @param t relative path
191 * @return new combined path s/t
192 */
193int path_concat(char *s, char *t, char **val){
194    int err = 0;
195    int sn, tn, vn;
196    char *v;
197    sn = strlen(s);
198    if(sn > 0 && s[sn-1] == '/'){
199        sn--;
200    }
201    tn = strlen(t);
202    if(tn > 0 && t[0] == '/'){
203        tn--;
204    }
205    vn = sn+tn+1;
206    v = (char*)allocate(vn+1);
207    if(!v){
208        err = -ENOMEM;
209        goto exit;
210    }
211    strncpy(v, s, sn);
212    v[sn] = '/';
213    strncpy(v+sn+1, t, tn);
214    v[vn] = '\0';
215  exit:
216    *val = (err ? NULL : v);
217    return err;   
218}
Note: See TracBrowser for help on using the repository browser.