-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcgen.c
113 lines (86 loc) · 2.07 KB
/
cgen.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include "cgen.h"
extern uint32_t line_num;
extern uint32_t yylex_bufidx;
extern hashtable_t *mac_ht;
extern int yylex_destroy();
extern uint32_t fetch_line_count();
extern char *fetch_incl_name();
extern bool including_file();
uint32_t yyerror_count = 0;
const char *c_prologue =
"#include \"ptuclib.h\"\n"
"\n";
void
ssopen(sstream *S)
{S->stream = open_memstream(&S->buffer, &S->bufsize);}
void
ssflush(sstream *S)
{fflush(S->stream);}
void
ssclose(sstream *S)
{fclose(S->stream);}
/* wrapper for cleaning flex and hashtable */
void
flex_closure()
{yylex_destroy(); ht_destroy(mac_ht);}
/*
This function takes the same arguments as printf,
but returns a new string with the output value in it.
*/
char *
template(const char *pat, ...) {
sstream S = {0};
ssopen(&S);
va_list arg;
va_start(arg, pat);
vfprintf(S.stream, pat, arg);
va_end(arg);
ssflush(&S);
ssclose(&S);
return S.buffer;
}
/* Helper functions */
/*
Make a C string literal out of a PTUC string literal.
Return the corrected string (maybe the same as P).
*/
char *
string_ptuc2c(char *P) {
if (P == NULL) { return P; }
/* Just check and change the first and last characters */
uint32_t len = strlen(P);
/* less than three as P in single chars is "'a'\0"
so that's basically 3 characters plus null
like so: [', a, ', \0]
*/
if (len < 3) { return P; }
else {
P[0] = '"';
P[len - 1] = '"';
return P;
}
}
/*
Report errors
*/
void
yyerror(char const *pat, ...) {
va_list arg;
if (including_file()) {
fprintf(stderr,
" -- \n\tError in include file: %s (depth: %d)\n",
fetch_incl_name(), yylex_bufidx);
}
fprintf(stderr, "\n\tline %d: ", fetch_line_count());
va_start(arg, pat);
vfprintf(stderr, pat, arg);
va_end(arg);
yyerror_count++;
fprintf(stderr, "\n --\n");
}