Control flow optimization: Merge consecutive blocks.
[libfirm] / support / lpp_server / lpp_server.h
1 /**
2  * @file   lpp_server.h
3  * @date   19.07.2005
4  * @author Sebastian Hack
5  *
6  * Copyright (C) 2005 Universitaet Karlsruhe
7  * Released under the GPL
8  */
9
10 #ifndef LPP_SERVER_H
11 #define LPP_SERVER_H
12
13 #include <stdio.h>
14 #include <stdarg.h>
15 #include <stdint.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <netinet/in.h>
19
20 enum {
21 #define LPP_CMD(x) x,
22 #include "lpp_cmd.def"
23 #undef LPP_CMD
24   LPP_CMD_LAST
25 };
26
27 #define BASIC_ERR_CHECK(expr,cond,fmt,last) \
28   if((expr) cond) { \
29     fprintf(stderr, "%s(%d): %s %s: ", __FILE__, __LINE__, #expr, #cond); \
30     print_err fmt; \
31     fprintf(stderr, "\n"); \
32     last; \
33   }
34
35 #define BASIC_ERRNO_CHECK(expr,cond,last) \
36   if((expr) cond) { \
37     fprintf(stderr, "%s(%d): %s %s: %s\n", \
38         __FILE__, __LINE__, #expr, #cond, strerror(errno)); \
39     last; \
40   }
41
42 #define ERR_CHECK_RETURN(expr, cond, fmt, retval) \
43   BASIC_ERR_CHECK(expr, cond, fmt, return retval)
44
45 #define ERRNO_CHECK_RETURN(expr, cond, retval) \
46   BASIC_ERRNO_CHECK(expr, cond, return retval)
47
48 #define ERR_CHECK_RETURN_VOID(expr, cond, fmt) \
49   BASIC_ERR_CHECK(expr, cond, fmt, return)
50
51 #define ERRNO_CHECK_RETURN_VOID(expr, cond) \
52   BASIC_ERRNO_CHECK(expr, cond, return)
53
54 #define ERR_CHECK(expr, cond, fmt) \
55   BASIC_ERR_CHECK(expr, cond, fmt, (void) 0)
56
57 #define ERRNO_CHECK(expr, cond) \
58   BASIC_ERRNO_CHECK(expr, cond, (void) 0)
59
60 static void print_err(const char *fmt, ...)
61 {
62         va_list args;
63
64         va_start(args, fmt);
65         vfprintf(stderr, fmt, args);
66         va_end(args);
67 }
68
69 static  void writel(int fd, uint32_t x)
70 {
71         x = htonl(x);
72         ERRNO_CHECK(write(fd, &x, sizeof(x)), == -1);
73 }
74
75 static  void writed(int fd, double dbl)
76 {
77         ERRNO_CHECK(write(fd, &dbl, sizeof(dbl)), == -1);
78 }
79
80 static  void writes(int fd, const char *str)
81 {
82         size_t n = strlen(str);
83         writel(fd, n);
84         ERRNO_CHECK(write(fd, str, n), == -1);
85 }
86
87 static  uint32_t readl(int fd)
88 {
89         uint32_t res;
90
91         ERRNO_CHECK(read(fd, &res, sizeof(res)), == -1);
92         return ntohl(res);
93 }
94
95 static  double readd(int fd)
96 {
97         double res;
98         ERRNO_CHECK(read(fd, &res, sizeof(res)), == -1);
99         return res;
100 }
101
102 static  char *reads(int fd)
103 {
104         size_t len = readl(fd);
105         char *res = malloc(sizeof(char) * (len + 1));
106
107         ERRNO_CHECK(read(fd, res, len), == -1);
108         res[len] = '\0';
109         return res;
110 }
111
112 static char *readbuf(int fd, size_t buflen, char *buf)
113 {
114         char dummy[1024];
115         size_t i;
116         size_t n         = buflen - 1;
117         size_t len       = readl(fd);
118         size_t max_read  = n < len ? n : len;
119         size_t rest      = len - max_read;
120
121         if(buflen > 0 && buf != NULL) {
122                 ERRNO_CHECK(read(fd, buf, max_read), == -1);
123                 buf[max_read] = '\0';
124         }
125
126         /* eat up data that didnt fit into the string */
127         for(i = 0, n = rest / sizeof(dummy); i < n; ++i)
128                 read(fd, dummy, sizeof(dummy));
129
130         if(rest % sizeof(dummy) > 0)
131                 read(fd, dummy, rest % sizeof(dummy));
132
133         return buf;
134 }
135
136 static int ack(int fd, size_t buflen, char *buf)
137 {
138         int res = 0;
139         int cmd = readl(fd);
140
141         switch(cmd) {
142                 case LPP_CMD_OK:
143                         res = 1;
144                         break;
145                 case LPP_CMD_BAD:
146                         readbuf(fd, buflen, buf);
147                 default:
148                         res = 0;
149         }
150
151         return res;
152 }
153
154 static void send_res(int fd, int ok, const char *fmt, ...)
155 {
156         if(!ok) {
157                 char buf[1024];
158                 va_list args;
159
160                 va_start(args, fmt);
161                 vsnprintf(buf, sizeof(buf), fmt, args);
162                 va_end(args);
163
164                 writel(fd, LPP_CMD_BAD);
165                 writes(fd, buf);
166         }
167
168         else
169                 writel(fd, LPP_CMD_OK);
170 }
171
172 static void send_ack(int fd)
173 {
174         send_res(fd, 1, "");
175 }
176
177 #endif