-
Notifications
You must be signed in to change notification settings - Fork 0
/
print.c
137 lines (124 loc) · 5.13 KB
/
print.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* JCUnit - a very simple unit testing framework for C
*
* Copyright (C) 2021-2022 Denis Korchagin <denis.korchagin.1995@gmail.com>
*
* This file is part of JCUnit
*
* For the full license information, please view the LICENSE
* file that was distributed with this source code.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation of version 2
* of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <assert.h>
#include "headers/print.h"
#define INDENT_WIDTH (4)
static void do_print_directive_arguments(struct slist * arguments, FILE * output, unsigned int depth);
static void do_print_ast_requirements(struct ast_test * test, FILE * output, unsigned int depth);
static void do_print_ast_requirement(struct ast_requirement * requirement, FILE * output, unsigned int depth, unsigned int requirement_number);
static void do_print_ast_test(struct ast_test * test, FILE * output, unsigned int depth);
static void do_indent(FILE * output, unsigned int depth);
void print_token(struct token * token, FILE * output)
{
assert(token != NULL);
switch (token->kind) {
case TOKEN_KIND_CHARACTER:
fprintf(output, "<TOKEN_CHARACTER '%c'>", token->content.ch);
break;
case TOKEN_KIND_PUNCTUATOR:
fprintf(output, "<TOKEN_PUNCTUATOR '%c'>", token->content.ch);
break;
case TOKEN_KIND_DIRECTIVE:
fprintf(output, "<TOKEN_DIRECTIVE '%.*s'>", token->content.string->len, token->content.string->value);
break;
case TOKEN_KIND_NAME:
fprintf(output, "<TOKEN_NAME '%.*s'>", token->content.string->len, token->content.string->value);
break;
case TOKEN_KIND_STRING:
fprintf(output, "<TOKEN_STRING '%.*s'>", token->content.string->len, token->content.string->value);
break;
case TOKEN_KIND_NEWLINE:
fprintf(output, "<TOKEN_NEWLINE '\\n'>");
break;
case TOKEN_KIND_EOF:
fprintf(output, "<TOKEN_EOF>");
break;
default:
fprintf(output, "<unknown token>");
}
}
void print_ast_test(struct ast_test * test, FILE * output)
{
do_print_ast_test(test, output, 0);
}
void do_print_ast_test(struct ast_test * test, FILE * output, unsigned int depth)
{
fprintf(output, "Test:\n");
do_indent(output, depth + 1);
do_print_directive_arguments(&test->arguments, output, depth + 1);
do_indent(output, depth + 1);
do_print_ast_requirements(test, output, depth + 1);
}
void do_print_ast_requirements(struct ast_test * test, FILE * output, unsigned int depth)
{
fprintf(output, "Requirements:\n");
unsigned int requirement_number = 0;
slist_foreach(iterator, &test->requirements, {
struct ast_requirement * requirement = list_get_owner(iterator, struct ast_requirement, list_entry);
++requirement_number;
do_indent(output, depth + 1);
do_print_ast_requirement(requirement, output, depth + 1, requirement_number);
});
}
void print_ast_requirement(struct ast_requirement * requirement, FILE * output)
{
do_print_ast_requirement(requirement, output, 0, 1);
}
void do_print_ast_requirement(struct ast_requirement * requirement, FILE * output, unsigned int depth, unsigned int requirement_number)
{
fprintf(output, "Requirement #%u:\n", requirement_number);
do_indent(output, depth + 1);
fprintf(output, "Name: \"%s\"\n", requirement->name->value);
do_indent(output, depth + 1);
do_print_directive_arguments(&requirement->arguments, output, depth + 1);
do_indent(output, depth + 1);
if (requirement->content == NULL) {
fprintf(output, "Content: <not provided>\n");
} else {
fprintf(output, "Content: \"%s\"\n", requirement->content->value);
}
}
void do_print_directive_arguments(struct slist * arguments, FILE * output, unsigned int depth)
{
fprintf(output, "Arguments:\n");
unsigned int argument_number = 0;
slist_foreach(iterator, arguments, {
struct ast_requirement_argument * argument = list_get_owner(iterator, struct ast_requirement_argument, list_entry);
++argument_number;
do_indent(output, depth + 1);
if (argument->name != NULL) {
fprintf(output, "Argument #%u: %s=\"%s\"\n", argument_number, argument->name->value, argument->value->value);
} else {
fprintf(output, "Argument #%u: \"%s\" (unnamed)\n", argument_number, argument->value->value);
}
});
}
static void do_indent(FILE * output, unsigned int depth)
{
unsigned int i, len;
for (i = 0, len = depth * INDENT_WIDTH; i < len; ++i) {
fprintf(output, " ");
}
}