8
#define INDENT_STRING " "
13
char *last_label=NULL;
15
extern void yyerror(const char *x);
16
extern char *get_label(const char *label);
17
extern void set_label(const char *label, const char *target);
18
char *new_counter(const char *key);
29
%token NEW_COUNTER LABEL HASH CHAR NEWLINE NO_INDENT RIGHT
30
%type <string> stuff text
42
if (strlen($2) > (PAPER_WIDTH-(indent ? strlen(INDENT_STRING):0))) {
43
yyerror("line too long");
45
printf("%s%s\n", indent ? INDENT_STRING:"", $2);
50
| doc stuff RIGHT stuff NEWLINE {
51
char fixed[PAPER_WIDTH+1];
54
len = PAPER_WIDTH-(strlen($2)+strlen($4));
57
memset(fixed, ' ', len);
60
yyerror("line too wide");
63
printf("%s%s%s\n", $2, fixed, $4);
69
| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
70
char fixed[PAPER_WIDTH+1];
73
len = PAPER_WIDTH-(strlen($2)+strlen($4));
77
yyerror("line too wide");
81
memset(fixed, ' ', l);
83
printf("%s%s%s", $2, fixed, $4);
88
memset(fixed, ' ', l);
90
printf("%s%s\n", fixed, $6);
96
| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
97
char fixed[PAPER_WIDTH+1];
100
len = PAPER_WIDTH-(strlen($2)+strlen($4));
104
yyerror("line too wide");
108
memset(fixed, ' ', l);
110
printf("%s%s%s", $2, fixed, $4);
115
memset(fixed, ' ', l);
117
printf("%s%s\n", fixed, $6);
129
$$ = malloc(strlen($1)+strlen($2)+1);
130
sprintf($$,"%s%s", $1, $2);
140
$$ = malloc(strlen($1)+2);
141
sprintf($$,"%s%s", $1, yytext);
152
if (($$ = get_label(yytext)) == NULL) {
153
set_label(yytext, last_label);
158
$$ = new_counter(yytext);
164
typedef struct node_s {
165
struct node_s *left, *right;
170
node_t label_root = NULL;
171
node_t counter_root = NULL;
173
const char *find_key(node_t root, const char *key)
176
int cmp = strcmp(key, root->key);
189
node_t set_key(node_t root, const char *key, const char *value)
192
int cmp = strcmp(key, root->key);
194
root->right = set_key(root->right, key, value);
196
root->left = set_key(root->left, key, value);
199
root->value = strdup(value);
202
root = malloc(sizeof(struct node_s));
203
root->right = root->left = NULL;
204
root->key = strdup(key);
205
root->value = strdup(value);
210
void yyerror(const char *x)
212
fprintf(stderr, "line %d: %s\n", line, x);
215
char *get_label(const char *label)
217
const char *found = find_key(label_root, label);
220
return strdup(found);
225
void set_label(const char *label, const char *target)
227
if (target == NULL) {
228
yyerror("no hanging value for label");
231
label_root = set_key(label_root, label, target);
234
char *new_counter(const char *key)
236
int i=0, j, ndollars = 0;
240
if (key[i++] != '#') {
241
yyerror("bad index");
242
return strdup("<???>");
245
while (key[i] == '$') {
251
old = find_key(counter_root, key);
252
new = malloc(20*ndollars);
255
for (j=0; ndollars > 1 && old[j]; ) {
256
if (old[j++] == '.' && --ndollars <= 0) {
261
strncpy(new, old, j);
271
while (--ndollars > 0) {
278
sprintf(new+j, "%d", ++i);
280
counter_root = set_key(counter_root, key, new);
285
last_label = strdup(new);