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