Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/core/kernel/src/test/cowsay.c
1067 views
1
/*
2
Since cowasm looks like "CowAsm" which looks like "Cow Assembly", let's assembly a cow.
3
*/
4
5
6
// Copyright 2016 The Fuchsia Authors. All rights reserved.
7
// Use of this source code is governed by a BSD-style license that can be
8
// found in the LICENSE file.
9
#include <stdio.h>
10
#include <string.h>
11
#define MAX_WIDTH 40
12
#define MAX(a, b) ((a > b) ? a : b)
13
#define MIN(a, b) ((a < b) ? a : b)
14
// Returns the length of the longst line of the message.
15
static size_t LongestLineLength(int argc, char** argv) {
16
size_t max_len = 0;
17
size_t cur_line = 0;
18
for (int i = 0; i < argc; i++) {
19
size_t word_len = strlen(argv[i]) + 1;
20
// If the word itself is too long to fit in a line, then
21
// we return the maximum width.
22
if (word_len >= MAX_WIDTH)
23
return MAX_WIDTH;
24
if (cur_line + word_len >= MAX_WIDTH) {
25
cur_line = word_len;
26
} else {
27
cur_line += word_len;
28
}
29
max_len = MAX(cur_line, max_len);
30
}
31
return max_len;
32
}
33
static void PrintPaddedBreak(size_t pad) {
34
for (size_t i = 0; i < pad; i++) {
35
printf(" ");
36
}
37
printf(" |\n");
38
}
39
// Prints the message
40
static void PrintMessage(int argc, char** argv, size_t longest) {
41
size_t cur_line_len = 0;
42
for (int i = 0; i < argc; i++) {
43
size_t word_len = strlen(argv[i]) + 1;
44
if (cur_line_len == 0)
45
printf("| ");
46
// If it all fits in the line, then print the word and move on.
47
if (cur_line_len + word_len <= MAX_WIDTH) {
48
printf("%s ", argv[i]);
49
if (cur_line_len + word_len == MAX_WIDTH) {
50
PrintPaddedBreak(longest - cur_line_len - word_len);
51
cur_line_len = 0;
52
continue;
53
}
54
cur_line_len += word_len;
55
if (i == argc - 1)
56
PrintPaddedBreak(longest - cur_line_len);
57
continue;
58
}
59
// Create a line break if the current line is nonempty.
60
if (cur_line_len > 0) {
61
PrintPaddedBreak(longest - cur_line_len);
62
printf("| ");
63
}
64
// If the word itself is too long, then we need to break it apart.
65
// Otherwise, we print the current word and move on.
66
if (word_len > MAX_WIDTH) {
67
char* str = argv[i];
68
size_t processed = 0;
69
for (size_t j = 0; j <= word_len / MAX_WIDTH; j++) {
70
size_t len = MIN(MAX_WIDTH, strlen(str));
71
printf("%.*s", (int)len, str);
72
PrintPaddedBreak(longest - len);
73
str += len;
74
processed += len;
75
if (processed >= word_len - 1)
76
break;
77
printf("| ");
78
}
79
cur_line_len = 0;
80
} else {
81
printf("%s ", argv[i]);
82
cur_line_len = word_len;
83
if (word_len == MAX_WIDTH || i == argc - 1) {
84
PrintPaddedBreak(longest - cur_line_len);
85
}
86
}
87
}
88
}
89
int main(int argc, char** argv) {
90
if (argc == 1) {
91
printf("Usage: cowsay [message]\n");
92
return 1;
93
}
94
// No wordwrap because I'm too lazy.
95
size_t bubble_width = LongestLineLength(argc - 1, argv + 1) + 1;
96
printf(" _");
97
for (size_t i = 0; i < bubble_width; i++)
98
printf("_");
99
printf(" \n");
100
PrintMessage(argc - 1, argv + 1, bubble_width - 1);
101
printf(" -");
102
for (size_t i = 0; i < bubble_width; i++)
103
printf("-");
104
printf(" \n");
105
printf(" \\ ^__^\n");
106
printf(" \\ (oo)\\_____\n");
107
printf(" (__)\\ )\\/\\\n");
108
printf(" ||----w |\n");
109
printf(" || ||\n");
110
return 0;
111
}
112