ia64/xen-unstable

view tools/libxutil/sys_string.c @ 2621:9402048e2325

bitkeeper revision 1.1159.1.218 (416a8128OiHXHyk_Sy8FsA0YUQcEnA)

Merge freefall.cl.cam.ac.uk:/auto/groups/xeno/users/cl349/BK/xeno.bk-26dom0
into freefall.cl.cam.ac.uk:/local/scratch/cl349/xeno.bk-26dom0
author cl349@freefall.cl.cam.ac.uk
date Mon Oct 11 12:48:40 2004 +0000 (2004-10-11)
parents 236a9f2698a3
children 7f7c68433c4c
line source
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 */
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
28 #include "allocate.h"
29 #include "sys_string.h"
31 /** Set the base to use for converting a string to a number. Base is
32 * hex if starts with 0x, otherwise decimal.
33 *
34 * @param s input string
35 * @param base where to put the base
36 * @return rest of s to parse as a number
37 */
38 inline static const char * convert_set_base(const char *s, int *base){
39 *base = 10;
40 if(s){
41 if(*s=='0'){
42 s++;
43 if(*s=='x' || *s=='X'){
44 *base = 16;
45 s++;
46 }
47 }
48 }
49 return s;
50 }
52 /** Get the numerical value of a digit in the given base.
53 *
54 * @param c digit character
55 * @param base to use
56 * @return numerical value of digit in range 0..base-1 or
57 * -1 if not in range for the base
58 */
59 inline static int convert_get_digit(char c, int base){
60 int d;
62 if('0'<=c && c<='9'){
63 d = c - '0';
64 } else if('a'<=c && c<='f'){
65 d = c - 'a' + 10;
66 } else if('A'<=c && c<='F'){
67 d = c - 'A' + 10;
68 } else {
69 d = -1;
70 }
71 return (d < base ? d : -1);
72 }
74 /** Convert a string to an unsigned long by parsing it as a number.
75 * Will accept hex or decimal in usual C syntax.
76 *
77 * @param str input string
78 * @param val where to put the result
79 * @return 0 if converted OK, negative otherwise
80 */
81 int convert_atoul(const char *str, unsigned long *val){
82 int err = 0;
83 unsigned long v = 0;
84 int base;
85 const char *s = str;
87 if(!s) {
88 err = -EINVAL;
89 goto exit;
90 }
91 s = convert_set_base(s, &base);
92 for( ; !err && *s; s++){
93 int digit = convert_get_digit(*s, base);
94 if(digit<0){
95 err = -EINVAL;
96 goto exit;
97 }
98 v *= base;
99 v += digit;
100 }
101 exit:
102 *val = (err ? 0 : v);
103 return err;
104 }
106 /** Combine a directory path with a relative path to produce
107 * a new path.
108 *
109 * @param s directory path
110 * @param t relative path
111 * @return new combined path s/t
112 */
113 int path_concat(char *s, char *t, char **val){
114 int err = 0;
115 int sn, tn, vn;
116 char *v;
117 sn = strlen(s);
118 if(sn > 0 && s[sn-1] == '/'){
119 sn--;
120 }
121 tn = strlen(t);
122 if(tn > 0 && t[0] == '/'){
123 tn--;
124 }
125 vn = sn+tn+1;
126 v = (char*)allocate(vn+1);
127 if(!v){
128 err = -ENOMEM;
129 goto exit;
130 }
131 strncpy(v, s, sn);
132 v[sn] = '/';
133 strncpy(v+sn+1, t, tn);
134 v[vn] = '\0';
135 exit:
136 *val = (err ? NULL : v);
137 return err;
138 }