1#!/usr/local/bin/perl
2#***************************************************************************
3#                                  _   _ ____  _
4#  Project                     ___| | | |  _ \| |
5#                             / __| | | | |_) | |
6#                            | (__| |_| |  _ <| |___
7#                             \___|\___/|_| \_\_____|
8#
9# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
10#
11# This software is licensed as described in the file COPYING, which
12# you should have received as part of this distribution. The terms
13# are also available at https://curl.haxx.se/docs/copyright.html.
14#
15# You may opt to use, copy, modify, merge, publish, distribute and/or sell
16# copies of the Software, and permit persons to whom the Software is
17# furnished to do so, under the terms of the COPYING file.
18#
19# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20# KIND, either express or implied.
21#
22###########################################################################
23
24# Yeah, I know, probably 1000 other persons already wrote a script like
25# this, but I'll tell ya:
26
27# THEY DON'T FIT ME :-)
28
29# Get readme file as parameter:
30
31if($ARGV[0] eq "-c") {
32    $c=1;
33    shift @ARGV;
34}
35
36my $README = $ARGV[0];
37
38if($README eq "") {
39    print "usage: mkreadme.pl [-c] <README> < manpage\n";
40    exit;
41}
42
43
44push @out, "                                  _   _ ____  _\n";
45push @out, "  Project                     ___| | | |  _ \\| |\n";
46push @out, "                             / __| | | | |_) | |\n";
47push @out, "                            | (__| |_| |  _ <| |___\n";
48push @out, "                             \\___|\\___/|_| \\_\\_____|\n";
49
50my $olen=0;
51while (<STDIN>) {
52    my $line = $_;
53
54    # this should be removed:
55    $line =~ s/(.|_)//g;
56
57    # remove trailing CR from line. msysgit checks out files as line+CRLF
58    $line =~ s/\r$//;
59
60    if($line =~ /^([ \t]*\n|curl)/i) {
61        # cut off headers and empty lines
62        $wline++; # count number of cut off lines
63        next;
64    }
65
66    my $text = $line;
67    $text =~ s/^\s+//g; # cut off preceding...
68    $text =~ s/\s+$//g; # and trailing whitespaces
69
70    $tlen = length($text);
71
72    if($wline && ($olen == $tlen)) {
73        # if the previous line with contents was exactly as long as
74        # this line, then we ignore the newlines!
75
76        # We do this magic because a header may abort a paragraph at
77        # any line, but we don't want that to be noticed in the output
78        # here
79        $wline=0;
80    }
81    $olen = $tlen;
82
83    if($wline) {
84        # we only make one empty line max
85        $wline = 0;
86        push @out, "\n";
87    }
88    push @out, $line;
89}
90push @out, "\n"; # just an extra newline
91
92open(READ, "<$README") ||
93    die "couldn't read the README infile $README";
94
95while(<READ>) {
96    my $line = $_;
97
98    # remove trailing CR from line. msysgit checks out files as line+CRLF
99    $line =~ s/\r$//;
100
101    push @out, $line;
102}
103close(READ);
104
105# if compressed
106if($c) {
107    my @test = `gzip --version 2>&1`;
108    if($test[0] =~ /gzip/) {
109        open(GZIP, ">dumpit") ||
110            die "can't create the dumpit file, try without -c";
111        binmode GZIP;
112        for(@out) {
113            print GZIP $_;
114            $gzip += length($_);
115        }
116        close(GZIP);
117
118        system("gzip --best --no-name dumpit");
119
120        open(GZIP, "<dumpit.gz") ||
121             die "can't read the dumpit.gz file, try without -c";
122        binmode GZIP;
123        while(<GZIP>) {
124            push @gzip, $_;
125            $gzipped += length($_);
126        }
127        close(GZIP);
128
129        unlink("dumpit.gz");
130    }
131    else {
132        # no gzip, no compression!
133        undef $c;
134        print STDERR "MEEEP: Couldn't find gzip, disable compression\n";
135    }
136}
137
138$now = localtime;
139print <<HEAD
140/*
141 * NEVER EVER edit this manually, fix the mkhelp.pl script instead!
142 * Generation time: $now
143 */
144#ifdef USE_MANUAL
145#include "tool_hugehelp.h"
146HEAD
147    ;
148if($c) {
149    print <<HEAD
150#include <zlib.h>
151#include "memdebug.h" /* keep this as LAST include */
152static const unsigned char hugehelpgz[] = {
153  /* This mumbo-jumbo is the huge help text compressed with gzip.
154     Thanks to this operation, the size of this data shrunk from $gzip
155     to $gzipped bytes. You can disable the use of compressed help
156     texts by NOT passing -c to the mkhelp.pl tool. */
157HEAD
158;
159    my $c=0;
160    print " ";
161    for(@gzip) {
162        my @all=split(//, $_);
163        for(@all) {
164            my $num=ord($_);
165            printf(" 0x%02x,", 0+$num);
166            if(++$c>11) {
167                print "\n ";
168                $c=0;
169            }
170        }
171    }
172    print "\n};\n";
173
174    print <<EOF
175#define BUF_SIZE 0x10000
176static voidpf zalloc_func(voidpf opaque, unsigned int items, unsigned int size)
177{
178  (void) opaque;
179  /* not a typo, keep it calloc() */
180  return (voidpf) calloc(items, size);
181}
182static void zfree_func(voidpf opaque, voidpf ptr)
183{
184  (void) opaque;
185  free(ptr);
186}
187/* Decompress and send to stdout a gzip-compressed buffer */
188void hugehelp(void)
189{
190  unsigned char* buf;
191  int status,headerlen;
192  z_stream z;
193
194  /* Make sure no gzip options are set */
195  if (hugehelpgz[3] & 0xfe)
196    return;
197
198  headerlen = 10;
199  memset(&z, 0, sizeof(z_stream));
200  z.zalloc = (alloc_func)zalloc_func;
201  z.zfree = (free_func)zfree_func;
202  z.avail_in = (unsigned int)(sizeof(hugehelpgz) - headerlen);
203  z.next_in = (unsigned char *)hugehelpgz + headerlen;
204
205  if (inflateInit2(&z, -MAX_WBITS) != Z_OK)
206    return;
207
208  buf = malloc(BUF_SIZE);
209  if (buf) {
210    while(1) {
211      z.avail_out = BUF_SIZE;
212      z.next_out = buf;
213      status = inflate(&z, Z_SYNC_FLUSH);
214      if (status == Z_OK || status == Z_STREAM_END) {
215        fwrite(buf, BUF_SIZE - z.avail_out, 1, stdout);
216        if (status == Z_STREAM_END)
217          break;
218      }
219      else
220        break;    /* Error */
221    }
222    free(buf);
223  }
224  inflateEnd(&z);
225}
226EOF
227    ;
228foot();
229exit;
230}
231else {
232    print <<HEAD
233void hugehelp(void)
234{
235   fputs(
236HEAD
237         ;
238}
239
240$outsize=0;
241for(@out) {
242    chop;
243
244    $new = $_;
245
246    $outsize += length($new)+1; # one for the newline
247
248    $new =~ s/\\/\\\\/g;
249    $new =~ s/\"/\\\"/g;
250
251    # gcc 2.96 claims ISO C89 only is required to support 509 letter strings
252    if($outsize > 500) {
253        # terminate and make another fputs() call here
254        print ", stdout);\n fputs(\n";
255        $outsize=length($new)+1;
256    }
257    printf("\"%s\\n\"\n", $new);
258
259}
260
261print ", stdout) ;\n}\n";
262
263foot();
264
265sub foot {
266  print <<FOOT
267#else /* !USE_MANUAL */
268/* built-in manual is disabled, blank function */
269#include "tool_hugehelp.h"
270void hugehelp(void) {}
271#endif /* USE_MANUAL */
272FOOT
273  ;
274}
275