blob: 019e539985f10dccd150f1e7d0d824763c23aa67 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include <string.h>
#define MAX_WIDTH 40
#define MAX(a, b) ((a > b) ? a : b)
#define MIN(a, b) ((a < b) ? a : b)
// Returns the length of the longst line of the message.
static size_t LongestLineLength(int argc, char** argv) {
size_t max_len = 0;
size_t cur_line = 0;
for (int i = 0; i < argc; i++) {
size_t word_len = strlen(argv[i]) + 1;
// If the word itself is too long to fit in a line, then
// we return the maximum width.
if (word_len >= MAX_WIDTH)
return MAX_WIDTH;
if (cur_line + word_len >= MAX_WIDTH) {
cur_line = word_len;
} else {
cur_line += word_len;
}
max_len = MAX(cur_line, max_len);
}
return max_len;
}
static void PrintPaddedBreak(size_t pad) {
for (size_t i = 0; i < pad; i++) {
printf(" ");
}
printf(" |\n");
}
// Prints the message
static void PrintMessage(int argc, char** argv, size_t longest) {
size_t cur_line_len = 0;
for (int i = 0; i < argc; i++) {
size_t word_len = strlen(argv[i]) + 1;
if (cur_line_len == 0)
printf("| ");
// If it all fits in the line, then print the word and move on.
if (cur_line_len + word_len <= MAX_WIDTH) {
printf("%s ", argv[i]);
if (cur_line_len + word_len == MAX_WIDTH) {
PrintPaddedBreak(longest - cur_line_len - word_len);
cur_line_len = 0;
continue;
}
cur_line_len += word_len;
if (i == argc - 1)
PrintPaddedBreak(longest - cur_line_len);
continue;
}
// Create a line break if the current line is nonempty.
if (cur_line_len > 0) {
PrintPaddedBreak(longest - cur_line_len);
printf("| ");
}
// If the word itself is too long, then we need to break it apart.
// Otherwise, we print the current word and move on.
if (word_len > MAX_WIDTH) {
char* str = argv[i];
size_t processed = 0;
for (size_t j = 0; j <= word_len / MAX_WIDTH; j++) {
size_t len = MIN(MAX_WIDTH, strlen(str));
printf("%.*s", (int)len, str);
PrintPaddedBreak(longest - len);
str += len;
processed += len;
if (processed >= word_len - 1)
break;
printf("| ");
}
cur_line_len = 0;
} else {
printf("%s ", argv[i]);
cur_line_len = word_len;
if (word_len == MAX_WIDTH || i == argc - 1) {
PrintPaddedBreak(longest - cur_line_len);
}
}
}
}
int main(int argc, char** argv) {
if (argc == 1) {
printf("Usage: cowsay [message]\n");
return 1;
}
// No wordwrap because I'm too lazy.
size_t bubble_width = LongestLineLength(argc - 1, argv + 1) + 1;
printf(" _");
for (size_t i = 0; i < bubble_width; i++)
printf("_");
printf(" \n");
PrintMessage(argc - 1, argv + 1, bubble_width - 1);
printf(" -");
for (size_t i = 0; i < bubble_width; i++)
printf("-");
printf(" \n");
printf(" \\ ^__^\n");
printf(" \\ (oo)\\_____\n");
printf(" (__)\\ )\\/\\\n");
printf(" ||----w |\n");
printf(" || ||\n");
return 0;
}