1 /*
2 $Id: util.c,v 1.9 2009/03/23 12:42:15 alexsisson Exp $
3
4 (C) Copyright 2002-2004 Alex Sisson (alexsisson@gmail.com)
5
6 This file is part of shed.
7
8 shed is free software; you can redistribute it and/or modify
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 shed is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with shed; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 /* includes */
24 #include <string.h>
25 #include <stdlib.h>
26 #include <math.h>
27 #include <getopt.h>
28 #include <stdint.h>
29
30 #include "util.h"
31
32 /* ascii control char descs */
33 char ascii_short_desc[] = {'0',0,0,0,0,0,0,'a','b','t','n','v','f','r'};
34 char *ascii_long_desc[] = {"NUL","SOH","STX","ETX","EOT","ENQ","ACK","BEL",
35 "BS ","HT ","LF ","VT ","FF ","CR ","SO ","SI ",
36 "DLE","DC1","DC2","DC3","DC4","NAK","SYN","ETB",
37 "CAN","EM ","SUB","ESC","FS ","GS ","RS ","US ","SPC"};
38
39
40
41 /* returns a description of the char if its <32 || >126 */
getascii(unsigned char c,char * s,int mode)42 char *getascii(unsigned char c, char *s, int mode)
43 {
44 if(c>127)
45 strncpy(s," ",3);
46 else if(c>=32 && c<=126) {
47 s[0] = ' ';
48 s[1] = c;
49 s[2] = ' ';
50 } else {
51 switch(mode) {
52 case 1: /* do c-style control chars */
53 if(c!=127 && ascii_short_desc[c]) {
54 s[0] = ' ';
55 s[1] = '\\';
56 s[2] = ascii_short_desc[c];
57 break;
58 }
59
60 case 0: /* no special chars */
61 strncpy(s," ",3);
62 break;
63
64 case 2: /* 3 letter descs */
65 strncpy(s,c!=127?ascii_long_desc[c]:"DEL",3);
66 break;
67 }
68 }
69 s[3] = 0;
70 return s;
71 }
72
73 /* returns string representation of n in base 'base' */
getstring(uint64_t n,char * s,int base,int width)74 char *getstring(uint64_t n, char *s, int base, int width) {
75 uint64_t i,j,c,d = calcwidth(n,base);
76 char *p = s;
77 if(width && d<width) {
78 for(i=d;i<width;i++) {
79 *p = '0';
80 p++;
81 }
82 }
83 for(i=d;i;i--) {
84 j = pow(base,i-1);
85 c = 0;
86 while(n>=j) {
87 n-=j;
88 c++;
89 }
90 *p = c + ((c<10) ? 48 : 55);
91 p++;
92 }
93 *p = 0;
94 return s;
95 }
96
97 /* parses 's' as a 'base' base string */
parsestring(char * s,int base)98 int64_t parsestring(char *s, int base) {
99
100 unsigned int i,j,slen=strlen(s),n=0;
101 int64_t r = 0;
102
103 for(i=0;i<slen;i++) {
104 if(s[i]>='0' && s[i]<='9')
105 n = s[i] - 48;
106 else if(s[i]>='A' && s[i]<='F')
107 n = s[i] - 55;
108 else if(s[i]>='a' && s[i]<='f')
109 n = s[i] - 87;
110 else
111 return -1;
112 if(n>=base)
113 return -1;
114 for(j=1;j<slen-i;j++)
115 n*=base;
116 r+=n;
117 }
118 return r;
119 }
120
121 #include <stdio.h>
122
123 /* calculates the width needed to represent 'n' in base 'base' */
calcwidth(uint64_t n,int base)124 int calcwidth(uint64_t n, int base) {
125 unsigned int i,j;
126 uint64_t b;
127 if(!base)
128 return 0;
129 for(i=0;;i++) {
130 b = base;
131 for(j=0;j<i;j++)
132 b *= base;
133 if(b>n || b<base)
134 return i + 1;
135 }
136 return 0;
137 }
138
139 /* creates optstring arg (short opts) from for getopt */
getopt_makeoptstring(struct option * opt)140 char *getopt_makeoptstring(struct option *opt) {
141 int n = 0;
142 char *optstring,*p;
143 struct option *o = opt;
144
145 while(o->name || o->has_arg || o->flag || o->val) {
146 n += 1 + o->has_arg;
147 if(o->flag)
148 return NULL; /* fail because not returning o->val */
149 o++;
150 }
151
152 p = optstring = malloc(n+1);
153 o = opt;
154
155 while(o->name || o->has_arg || o->flag || o->val) {
156 *p++ = o->val;
157 n = o->has_arg;
158 while(n--)
159 *p++ = ':';
160 o++;
161 }
162 *p = 0;
163
164 return optstring;
165 }
166
167