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