source: toilet/trunk/src/main.c @ 1116

Last change on this file since 1116 was 1116, checked in by Sam Hocevar, 14 years ago
  • Implemented figlet's -t (adapt to terminal's width).
  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1/*
2 *  TOIlet        The Other Implementation’s letters
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: main.c 1116 2006-09-27 07:18:20Z sam $
7 *
8 *  This program is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14/*
15 * This is the main program entry point.
16 */
17
18#include "config.h"
19
20#if defined(HAVE_INTTYPES_H)
21#   include <inttypes.h>
22#endif
23#if defined(HAVE_GETOPT_H)
24#   include <getopt.h>
25#endif
26#if defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ)
27#   include <sys/ioctl.h>
28#endif
29#include <stdio.h>
30#include <string.h>
31#include <stdlib.h>
32#include <cucul.h>
33
34#include "render.h"
35#include "figlet.h"
36#include "filters.h"
37
38static void version(void);
39#if defined(HAVE_GETOPT_H)
40static void usage(void);
41#endif
42
43int main(int argc, char *argv[])
44{
45    cucul_canvas_t *cv;
46    cucul_buffer_t *buffer;
47
48    uint32_t *string = NULL;
49    unsigned int length;
50
51    int i;
52
53    char const *export = "utf8";
54    char const *font = "mono9";
55    char const *dir = "/usr/share/figlet/";
56    unsigned int flag_gay = 0;
57    unsigned int flag_metal = 0;
58    unsigned int term_width = 80;
59    int infocode = -1;
60
61#if defined(HAVE_GETOPT_H)
62    for(;;)
63    {
64#   ifdef HAVE_GETOPT_LONG
65#       define MOREINFO "Try `%s --help' for more information.\n"
66        int option_index = 0;
67        static struct option long_options[] =
68        {
69            /* Long option, needs arg, flag, short option */
70            { "font", 1, NULL, 'f' },
71            { "directory", 1, NULL, 'd' },
72            { "width", 1, NULL, 'w' },
73            { "termwidth", 0, NULL, 't' },
74            { "gay", 0, NULL, 'g' },
75            { "metal", 0, NULL, 'm' },
76            { "irc", 0, NULL, 'i' },
77            { "help", 0, NULL, 'h' },
78            { "infocode", 1, NULL, 'I' },
79            { "version", 0, NULL, 'v' },
80            { NULL, 0, NULL, 0 }
81        };
82
83        int c = getopt_long(argc, argv, "d:f:I:w:ghimtv",
84                            long_options, &option_index);
85#   else
86#       define MOREINFO "Try `%s -h' for more information.\n"
87        int c = getopt(argc, argv, "d:f:I:w:ghimtv");
88#   endif
89        if(c == -1)
90            break;
91
92        switch(c)
93        {
94        case 'h': /* --help */
95            usage();
96            return 0;
97        case 'I': /* --infocode */
98            infocode = atoi(optarg);
99            break;
100        case 'v': /* --version */
101            version();
102            return 0;
103        case 'f': /* --font */
104            font = optarg;
105            break;
106        case 'd': /* --directory */
107            dir = optarg;
108            break;
109        case 'g': /* --gay */
110            flag_gay = 1;
111            break;
112        case 'm': /* --metal */
113            flag_metal = 1;
114            break;
115        case 'w': /* --width */
116            term_width = atoi(optarg);
117            break;
118        case 't': /* --termwidth */
119        {
120#if defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ)
121            struct winsize ws;
122
123            if((ioctl(1, TIOCGWINSZ, &ws) != -1 ||
124                ioctl(2, TIOCGWINSZ, &ws) != -1 ||
125                ioctl(0, TIOCGWINSZ, &ws) != -1) && ws.ws_col != 0)
126                term_width = ws.ws_col;
127#endif
128            break;
129        }
130        case 'i': /* --irc */
131            export = "irc";
132            break;
133        case '?':
134            printf(MOREINFO, argv[0]);
135            return 1;
136        default:
137            printf("%s: invalid option -- %i\n", argv[0], c);
138            printf(MOREINFO, argv[0]);
139            return 1;
140        }
141    }
142#else
143#   define MOREINFO "Usage: %s message...\n"
144    int optind = 1;
145#endif
146
147    switch(infocode)
148    {
149        case -1:
150            break;
151        case 0:
152            version();
153            return 0;
154        case 1:
155            printf("20201\n");
156            return 0;
157        case 2:
158            printf("%s\n", dir);
159            return 0;
160        case 3:
161            printf("%s\n", font);
162            return 0;
163        case 4:
164            printf("%u\n", term_width);
165            return 0;
166        default:
167            return 0;
168    }
169
170    if(optind >= argc)
171    {
172        printf("%s: too few arguments\n", argv[0]);
173        printf(MOREINFO, argv[0]);
174        return 1;
175    }
176
177    /* Load rest of commandline into a UTF-32 string */
178    for(i = optind, length = 0; i < argc; i++)
179    {
180        unsigned int k, guessed_len, real_len;
181
182        guessed_len = strlen(argv[i]);
183
184        if(i > optind)
185            string[length++] = (uint32_t)' ';
186
187        string = realloc(string, (length + guessed_len + 1) * 4);
188
189        for(k = 0, real_len = 0; k < guessed_len; real_len++)
190        {
191            unsigned int char_len;
192
193            string[length + real_len] =
194                cucul_utf8_to_utf32(argv[i] + k, &char_len);
195
196            k += char_len;
197        }
198
199        length += real_len;
200    }
201
202    /* Render string to canvas */
203    if(!strcasecmp(font, "mono9"))
204    {
205        cv = render_big(string, length);
206        filter_autocrop(cv);
207    }
208    else if(!strcasecmp(font, "term"))
209        cv = render_tiny(string, length);
210    else
211        cv = render_figlet(string, length, font);
212
213    /* Do gay stuff with our string (léopard) */
214    if(flag_metal)
215        filter_metal(cv);
216    if(flag_gay)
217        filter_gay(cv);
218
219    /* Output char */
220    buffer = cucul_export_canvas(cv, export);
221    fwrite(cucul_get_buffer_data(buffer),
222           cucul_get_buffer_size(buffer), 1, stdout);
223    cucul_free_buffer(buffer);
224
225    cucul_free_canvas(cv);
226
227    return 0;
228}
229
230static void version(void)
231{
232    printf("TOIlet Copyright 2006 Sam Hocevar %s\n", VERSION);
233    printf("Internet: <sam@zoy.org> Version: 0, date: 21 Sep 2006\n");
234    printf("\n");
235}
236
237#if defined(HAVE_GETOPT_H)
238static void usage(void)
239{
240    printf("Usage: toilet [ -ghimtv ] [ -d fontdirectory ]\n");
241    printf("              [ -f fontfile ] [ -w outputwidth ]\n");
242    printf("              [ -I infocode ] [ message ]\n");
243#   ifdef HAVE_GETOPT_LONG
244    printf("  -f, --font <fontfile>    select the font\n");
245    printf("  -d, --directory <dir>    specify font directory\n");
246    printf("  -w, --width <width>      set output width\n");
247    printf("  -t, --termwidth          adapt to terminal's width\n");
248    printf("  -g, --gay                add a rainbow effect to the text\n");
249    printf("  -m, --metal              add a metal effect to the text\n");
250    printf("  -i, --irc                output IRC colour codes\n");
251    printf("  -h, --help               display this help and exit\n");
252    printf("  -I, --infocode           print FIGlet-compatible infocode\n");
253    printf("  -v, --version            output version information and exit\n");
254#   else
255    printf("  -f <fontfile>    select the font\n");
256    printf("  -d <dir>         specify font directory\n");
257    printf("  -w <width>       set output width\n");
258    printf("  -t               adapt to terminal's width\n");
259    printf("  -g               add a rainbow effect to the text\n");
260    printf("  -m               add a metal effect to the text\n");
261    printf("  -i               output IRC colour codes\n");
262    printf("  -h               display this help and exit\n");
263    printf("  -I               print FIGlet-compatible infocode\n");
264    printf("  -v               output version information and exit\n");
265#   endif
266}
267#endif
268
Note: See TracBrowser for help on using the repository browser.