1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
#define DEFAULT_MESSAGE "hello from apheleiaOS"
6
#define BUBBLE_WIDTH 60
7
8
static void print_line(char left, char mid, char right, size_t width) {
9
putchar(left);
10
11
for (size_t i = 0; i < width + 2; i++) {
12
putchar(mid);
13
}14
15
putchar(right);
16
putchar('\n');
17
}18
19
static char *make_message(int argc, char **argv) {
20
if (argc <= 1) {
21
size_t len = strlen(DEFAULT_MESSAGE);
22
char *msg = malloc(len + 1);
23
24
if (msg) {
25
memcpy(msg, DEFAULT_MESSAGE, len + 1);
26
}27
28
return msg;
29
}30
31
size_t len = 0;
32
33
for (int i = 1; i < argc; i++) {
34
if (i > 1) {
35
len++;
36
}37
38
len += strlen(argv[i]);
39
}40
41
char *msg = malloc(len + 1);
42
if (!msg) {
43
return NULL;
44
}45
46
char *out = msg;
47
48
for (int i = 1; i < argc; i++) {
49
if (i > 1) {
50
*out++ = ' ';
51
}52
53
size_t arg_len = strlen(argv[i]);
54
memcpy(out, argv[i], arg_len);
55
out += arg_len;
56
}57
58
*out = '\0';
59
return msg;
60
}61
62
static size_t next_piece(const char *msg, size_t pos, size_t len, size_t *start_out, size_t *next_out) {
63
while (pos < len && msg[pos] == ' ') {
64
pos++;
65
}66
67
if (pos >= len) {
68
*start_out = pos;
69
*next_out = pos;
70
return 0;
71
}72
73
*start_out = pos;
74
75
size_t left = len - pos;
76
size_t take = left < BUBBLE_WIDTH ? left : BUBBLE_WIDTH;
77
78
if (left > BUBBLE_WIDTH) {
79
size_t split = pos + take;
80
81
for (size_t i = pos + take; i > pos; i--) {
82
if (msg[i - 1] == ' ') {
83
split = i - 1;
84
break;
85
}86
}87
88
if (split > pos) {
89
take = split - pos;
90
}91
}92
93
*next_out = pos + take;
94
return take;
95
}96
97
static size_t wrapped_width(const char *msg) {
98
size_t len = strlen(msg);
99
size_t pos = 0;
100
size_t width = 0;
101
102
while (pos < len) {
103
size_t start = 0;
104
size_t next = 0;
105
size_t take = next_piece(msg, pos, len, &start, &next);
106
107
if (take > width) {
108
width = take;
109
}110
111
pos = next;
112
}113
114
return width ? width : 1;
115
}116
117
static void print_wrapped(const char *msg, size_t width) {
118
size_t len = strlen(msg);
119
size_t pos = 0;
120
121
if (!len) {
122
fputs("< >\n", stdout);
123
return;
124
}125
126
while (pos < len) {
127
size_t start = 0;
128
size_t next = 0;
129
size_t take = next_piece(msg, pos, len, &start, &next);
130
131
fputs("< ", stdout);
132
fwrite(msg + start, 1, take, stdout);
133
134
for (size_t i = take; i < width; i++) {
135
putchar(' ');
136
}137
138
fputs(" >\n", stdout);
139
pos = next;
140
}141
}142
143
int main(int argc, char **argv) {
144
char *msg = make_message(argc, argv);
145
if (!msg) {
146
return 1;
147
}148
149
size_t width = wrapped_width(msg);
150
151
print_line(' ', '_', ' ', width);
152
153
print_wrapped(msg, width);
154
155
print_line(' ', '-', ' ', width);
156
157
puts(" \\ ^__^");
158
puts(" \\ (oo)\\_______");
159
puts(" (__)\\ )\\/\\");
160
puts(" ||----w |");
161
puts(" || ||");
162
163
free(msg);
164
return 0;
165
}