]> git.buserror.net Git - polintos/scott/priv.git/blob - idlcomp/util.cc
Update copyright year.
[polintos/scott/priv.git] / idlcomp / util.cc
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <unistd.h>
4 #include <dirent.h>
5 #include <errno.h>
6 #include <cctype>
7
8 #include <idlc.h>
9 #include <util.h>
10
11 std::ostream &operator << (std::ostream &ostr, Indent &ind)
12 {
13         for (int i = 0; i < ind.indent_level; i++)
14                 ostr << '\t';
15         
16         for (int i = 0; i < ind.align_spaces; i++)
17                 ostr << ' ';
18                         
19         return ostr;
20 }
21
22 static bool check_empty(const char *dirname)
23 {
24         struct dirent ent, *entp;
25
26         DIR *dir = opendir(dirname);
27         if (!dir) {
28                 fprintf(stderr, "Cannot open directory \"%s\".\n",
29                         dirname);
30                 
31                 throw UserError();
32         }
33
34         do {
35                 // readdir_r is buggy on osx 10.2, and will fail if errno is
36                 // non-zero.
37                 errno = 0;
38
39                 if (readdir_r(dir, &ent, &entp) && errno != EEXIST) {
40                         fprintf(stderr, "2 Cannot readdir on \"%s\": %s.\n",
41                                 dirname, strerror(errno));
42                 
43                         closedir(dir);
44                         throw UserError();
45                 }
46         } while (entp && (!strcmp(ent.d_name, ".") ||
47                           !strcmp(ent.d_name, "..")));
48                 
49         closedir(dir);
50         
51         if (!entp)
52                 return true;
53         
54         return false;
55 }
56
57 void makepath(const char *_path, bool require_empty)
58 {
59         string path(_path);
60         string::size_type pos = 0, last = 0;
61         
62         while (pos != string::npos) {
63                 pos = path.find('/', pos + 1);
64                 string component(path, 0, pos);
65                 
66                 if (component.length() - last == 1) {
67                         last = pos;
68                         continue;
69                 }
70
71                 last = pos;
72                 
73                 if (mkdir(component.c_str(), 0777) && errno != EEXIST) {
74                         fprintf(stderr, "Cannot create directory \"%s\": %s.\n",
75                                 component.c_str(), strerror(errno));
76
77                         throw UserError();
78                 }
79         }
80         
81         if (require_empty && !check_empty(_path)) {
82                 fprintf(stderr, "Directory \"%s\" is not empty.\n", _path);
83                 throw UserError();
84         }
85 }
86
87 static inline int hex_to_bin(int hex)
88 {
89         if (hex >= 'a')
90                 return hex - 'a' + 10;
91
92         if (hex >= 'A')
93                 return hex - 'A' + 10;
94
95         return hex - '0';
96 }
97
98 void parse_guid(const char *guid_str, char *guid_bin)
99 {
100         bool second_hex_digit = false;
101         int i;
102
103         for (i = 0; i < 36; i++) {
104                 if (i == 8 || i == 13 || i == 18 || i == 23) {
105                         if (guid_str[i] != '-')
106                                 goto bad;
107                 } else {
108                         if (!isxdigit(guid_str[i]))
109                                 goto bad;
110                         
111                         if (second_hex_digit) {
112                                 *guid_bin++ |= hex_to_bin(guid_str[i]);
113                                 second_hex_digit = false;
114                         } else {
115                                 *guid_bin = hex_to_bin(guid_str[i]) << 4;
116                                 second_hex_digit = true;
117                         }
118                 }
119         }
120         
121         if (guid_str[i] == 0)
122                 return;
123
124 bad:
125         yyerrorf("\"%s\" is not a valid GUID.", guid_str);
126         throw UserError();
127 }