xref: /curl/src/mkhelp.pl (revision 453d032b)
1#!/usr/bin/env perl
2#***************************************************************************
3#                                  _   _ ____  _
4#  Project                     ___| | | |  _ \| |
5#                             / __| | | | |_) | |
6#                            | (__| |_| |  _ <| |___
7#                             \___|\___/|_| \_\_____|
8#
9# Copyright (C) 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.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# SPDX-License-Identifier: curl
23#
24###########################################################################
25
26if($ARGV[0] eq "-c") {
27    $c=1;
28    shift @ARGV;
29}
30
31push @out, "          _   _ ____  _\n";
32push @out, "      ___| | | |  _ \\| |\n";
33push @out, "     / __| | | | |_) | |\n";
34push @out, "    | (__| |_| |  _ <| |___\n";
35push @out, "     \\___|\\___/|_| \\_\\_____|\n";
36
37while (<STDIN>) {
38    my $line = $_;
39    push @out, $line;
40}
41
42print <<HEAD
43/*
44 * NEVER EVER edit this manually, fix the mkhelp.pl script instead!
45 */
46#ifdef USE_MANUAL
47#include "tool_hugehelp.h"
48#include "tool_help.h"
49
50HEAD
51    ;
52if($c) {
53    # If compression requested, check that the Gzip module is available
54    # or else disable compression
55    $c = eval
56    {
57      require IO::Compress::Gzip;
58      IO::Compress::Gzip->import();
59      1;
60    };
61    print STDERR "Warning: compression requested but Gzip is not available\n" if (!$c)
62}
63
64if($c)
65{
66    my $content = join("", @out);
67    my $gzippedContent;
68    IO::Compress::Gzip::gzip(
69        \$content, \$gzippedContent, Level => 9, TextFlag => 1, Time=>0) or die "gzip failed:";
70    $gzip = length($content);
71    $gzipped = length($gzippedContent);
72
73    print <<HEAD
74#include <zlib.h>
75#include "memdebug.h" /* keep this as LAST include */
76static const unsigned char hugehelpgz[] = {
77  /* This mumbo-jumbo is the huge help text compressed with gzip.
78     Thanks to this operation, the size of this data shrank from $gzip
79     to $gzipped bytes. You can disable the use of compressed help
80     texts by NOT passing -c to the mkhelp.pl tool. */
81HEAD
82;
83
84    my $c=0;
85    print " ";
86    for(split(//, $gzippedContent)) {
87        my $num=ord($_);
88        printf(" 0x%02x,", 0+$num);
89        if(!(++$c % 12)) {
90            print "\n ";
91        }
92    }
93    print "\n};\n";
94
95    print <<EOF
96#define BUF_SIZE 0x10000
97static voidpf zalloc_func(voidpf opaque, unsigned int items, unsigned int size)
98{
99  (void) opaque;
100  /* not a typo, keep it calloc() */
101  return (voidpf) calloc(items, size);
102}
103static void zfree_func(voidpf opaque, voidpf ptr)
104{
105  (void) opaque;
106  free(ptr);
107}
108
109#define HEADERLEN 10
110
111/* Decompress and send to stdout a gzip-compressed buffer */
112void hugehelp(void)
113{
114  unsigned char *buf;
115  int status;
116  z_stream z;
117
118  /* Make sure no gzip options are set */
119  if(hugehelpgz[3] & 0xfe)
120    return;
121
122  memset(&z, 0, sizeof(z_stream));
123  z.zalloc = (alloc_func)zalloc_func;
124  z.zfree = (free_func)zfree_func;
125  z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN);
126  z.next_in = (unsigned char *)hugehelpgz + HEADERLEN;
127
128  if(inflateInit2(&z, -MAX_WBITS) != Z_OK)
129    return;
130
131  buf = malloc(BUF_SIZE);
132  if(buf) {
133    while(1) {
134      z.avail_out = BUF_SIZE;
135      z.next_out = buf;
136      status = inflate(&z, Z_SYNC_FLUSH);
137      if(status == Z_OK || status == Z_STREAM_END) {
138        fwrite(buf, BUF_SIZE - z.avail_out, 1, stdout);
139        if(status == Z_STREAM_END)
140          break;
141      }
142      else
143        break;    /* error */
144    }
145    free(buf);
146  }
147  inflateEnd(&z);
148}
149/* Show the help text for the 'arg' curl argument on stdout */
150void showhelp(const char *trigger, const char *arg, const char *endarg)
151{
152  unsigned char *buf;
153  int status;
154  z_stream z;
155  struct scan_ctx ctx;
156  inithelpscan(&ctx, trigger, arg, endarg);
157
158  /* Make sure no gzip options are set */
159  if(hugehelpgz[3] & 0xfe)
160    return;
161
162  memset(&z, 0, sizeof(z_stream));
163  z.zalloc = (alloc_func)zalloc_func;
164  z.zfree = (free_func)zfree_func;
165  z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN);
166  z.next_in = (unsigned char *)hugehelpgz + HEADERLEN;
167
168  if(inflateInit2(&z, -MAX_WBITS) != Z_OK)
169    return;
170
171  buf = malloc(BUF_SIZE);
172  if(buf) {
173    while(1) {
174      z.avail_out = BUF_SIZE;
175      z.next_out = buf;
176      status = inflate(&z, Z_SYNC_FLUSH);
177      if(status == Z_OK || status == Z_STREAM_END) {
178        size_t len = BUF_SIZE - z.avail_out;
179        if(!helpscan(buf, len, &ctx))
180          break;
181        if(status == Z_STREAM_END)
182          break;
183      }
184      else
185        break;    /* error */
186    }
187    free(buf);
188  }
189  inflateEnd(&z);
190}
191EOF
192    ;
193foot();
194exit;
195}
196else {
197    print <<HEAD
198static const char * const curlman[] = {
199HEAD
200        ;
201}
202
203my $blank;
204for my $n (@out) {
205    chomp $n;
206    $n =~ s/\\/\\\\/g;
207    $n =~ s/\"/\\\"/g;
208    $n =~ s/\t/\\t/g;
209
210    if(!$n) {
211        $blank++;
212    }
213    else {
214        $n =~ s/        /\\t/g;
215        printf("  \"%s%s\",\n", $blank?"\\n":"", $n);
216        $blank = 0;
217    }
218}
219
220print <<ENDLINE
221  NULL
222};
223void hugehelp(void)
224{
225  int i = 0;
226  while(curlman[i])
227    puts(curlman[i++]);
228}
229
230/* Show the help text for the 'arg' curl argument on stdout */
231void showhelp(const char *trigger, const char *arg, const char *endarg)
232{
233  int i = 0;
234  struct scan_ctx ctx;
235  inithelpscan(&ctx, trigger, arg, endarg);
236  while(curlman[i]) {
237    size_t len = strlen(curlman[i]);
238    if(!helpscan((unsigned char *)curlman[i], len, &ctx) ||
239       !helpscan((unsigned char *)"\\n", 1, &ctx))
240      break;
241    i++;
242  }
243}
244ENDLINE
245    ;
246
247foot();
248
249sub foot {
250    print <<FOOT
251#endif /* USE_MANUAL */
252FOOT
253  ;
254}
255