1use 5.005;
2use ExtUtils::MakeMaker;
3use Config;
4use File::Spec;
5#use strict;
6use warnings;
7
8$Verbose = 1;
9
10my ($INC, $DEFINE, $LIBS, $O_FILES, $STATIC_BUILD);
11
12our $VERSION='';
13eval `grep 'VERSION *=' lib/HTML/Template/Pro.pm`;
14
15if (grep {/^DYNAMIC=1/} @ARGV) {
16    $STATIC_BUILD=0;
17    $INC='-I/usr/include/htmltmplpro';
18    $DEFINE='-DUSE_SYSTEM_HTP_HEADER';
19    $LIBS='-lhtmltmplpro';
20    $O_FILES='';
21} else {
22    $STATIC_BUILD=1;
23    $INC='-I.';
24    $DEFINE='-DHTMLTMPLPRO_STATIC';
25    $LIBS='-lm';
26    $O_FILES='$(O_FILES)';
27}
28
29my %DEF=(
30    MAINTAINER  => $^O eq 'linux' && -d '.git' ? 1 : 0,
31    PCRE  => 1,
32    DEBUG => 0,
33    MMAP  => 1,
34    IMITATE=>0,
35);
36$DEF{PACKAGE_VERSION}=$VERSION if $VERSION;
37
38
39&configure() if $STATIC_BUILD;
40
41### --------------------------------------
42### testing whether sources are consistent
43### --------------------------------------
44
45unless ((stat('test_crlf.out'))[7] == 47) {
46    my @tests_to_skip=('HTML-Template-Pro.t', 'HTML-Template.t', 'realloc.t');
47    print <<ENDTEXT;
48#=================================
49#
50#          WARNING!!!
51#   test data are corrupted!
52#   may be CRLF conversion?
53#   skipping most of tests!!!!
54#   skipped: 
55#   @tests_to_skip
56#
57#=================================
58ENDTEXT
59    sleep(2);
60    chdir 't';
61    # test that fail with corrupted data
62    unlink @tests_to_skip;
63    chdir '..';
64}
65
66WriteMakefile(
67    NAME              => 'HTML::Template::Pro',
68    VERSION_FROM      => 'lib/HTML/Template/Pro.pm', # finds $VERSION
69    PREREQ_PM         => {'JSON', => 2.0, # safe to skip
70			  'File::Path' => 2.0,
71			  'File::Spec' => 0,
72			  'Test::More' => 0,
73			  }, # e.g., Module::Name => 1.1
74    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
75      (ABSTRACT_FROM  => 'lib/HTML/Template/Pro.pm', # retrieve abstract from module
76       AUTHOR         => 'I. Yu. Vlasenko <viy@altlinux.org>') : ()),
77    LIBS              => [$LIBS],
78    DEFINE            => $DEFINE, # e.g., '-DHAVE_SOMETHING'
79    INC               => $INC,
80    OBJECT            => $O_FILES, # link all the C files too
81    # license is: as perl itself or Artistic or GPL2+ or LGPL2+.
82    # 'perl' is a valid string for META1.4 spec
83    # https://rt.cpan.org/Public/Bug/Display.html?id=44210
84    LICENSE           => 'perl',
85#   PERL_MALLOC_OK    => 1 # read first, static only
86    depend => {
87        'expr.o'    => 'calc.inc exprtool.inc exprpstr.inc',
88        'procore.o' => 'proscope.inc pstrutils.inc loadfile.inc loopvar.inc',
89    },
90);
91
92sub MY::postamble {
93    return '' unless $DEF{MAINTAINER};
94    return <<'MAKE_FRAG';
95expr.c: calc.inc exprtool.inc exprpstr.inc
96procore\$(OBJ_EXT): loadfile.inc tagstack.inc
97optint.c: optint.re2c.m4
98
99#proparam.c proparam.h: pparam.h
100#	./pparam2proparam
101
102rpm: dist
103	rpmbuild -ta --clean HTML-Template-Pro-$(VERSION).tar.gz
104
105.re2c.c:
106	re2c $< > $@
107
108%.re2c: %.re2c.m4
109	m4 -P $< > $@
110
111MANIFEST.git::
112	git-ls-files > MANIFEST.git
113
114index.html: README Makefile
115	echo '<html><body><p><a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.php?group_id=138507&amp;type=5" width="210" height="62" border="0" alt="SourceForge.net Logo" /></a><br> <a href="http://sourceforge.net/projects/html-tmpl-pro/">SourceForge Summary page of the project</a><br><a href="http://www.imath.kiev.ua/~vlasenko/">Home page of the author</a><br><a href="http://prdownloads.sourceforge.net/html-tmpl-pro/HTML-Template-Pro-$(VERSION).tar.gz?download">Download</a><p><pre>' > $@
116	cat $< >> $@
117	echo '</pre></body></html>' >> $@
118
119TARBALL=HTML-Template-Pro-$(VERSION).tar.gz
120SF_HOME='viy2@html-tmpl-pro.sf.net:/home/groups/h/ht/html-tmpl-pro/htdocs/'
121sourceforge: tardist index.html
122	ssh-add ~/.ssh/id_dsa.sf
123	( echo cd uploads;	\
124	  echo put $(TARBALL);	\
125	  echo quit ) | /usr/bin/sftp viy2@frs.sourceforge.net
126	scp index.html $(SF_HOME)
127
128json::
129	rm -rf templates-Pro/json
130	export HTP_DUMP=1; $(MAKE) test
131
132.SUFFIXES: .re2c
133MAKE_FRAG
134}
135
136# those tests are based on ones from Time-HiRes-01.20
137
138sub try_compile_and_link {
139    my ($c, $cccmd, $ccflags, $verbose) = @_;
140    $verbose = 1 unless defined $verbose;
141    my ($ok) = 0;
142    my ($tmp) =  File::Spec->catfile( File::Spec->tmpdir(), "tmp$$" );
143    local(*TMPC);
144
145    my $obj_ext = $Config{obj_ext} || ".o";
146    unlink("$tmp.c", "$tmp$obj_ext");
147
148    if (open(TMPC, ">$tmp.c")) {
149	print TMPC $c;
150	close(TMPC);
151	my $COREincdir = File::Spec->canonpath(File::Spec->catfile($Config{'archlibexp'}, 'CORE'));
152	$ccflags .= ' '. $Config{'ccflags'} . ' ' . "-I$COREincdir";
153	my $cc=$Config{'cc'};
154	$cc||='cc';
155	if ($^O eq 'VMS') {
156	    my $perl_core = $Config{'installarchlib'};
157	    $perl_core =~ s/\]$/.CORE]/;
158	    $cccmd = "$cc /include=(perl_root:[000000],$perl_core) $tmp.c";
159	}
160	$cccmd = "$cc -o $tmp $ccflags $tmp.c @$LIBS"
161	 unless (defined $cccmd);
162	print "trying $cccmd\n" if $verbose;
163	system($cccmd);
164	if ($^O eq 'VMS') {
165	    $ok = -s "$tmp$obj_ext" && -x _;
166	    unlink("$tmp.c", "$tmp$obj_ext");
167	}
168	else
169	{
170		my $exe = $tmp . ($Config{_exe} || '');
171	    $ok = -s $exe && -x _;
172	    unlink("$tmp.c", $exe);
173	}
174    }
175
176    $ok;
177}
178
179sub has_header {
180    my $header=shift;
181    print "looking for $header...\n";
182    if (try_compile_and_link('
183#include <'.$header.'>
184    static int foo()
185    {
186	return 0;
187    }
188    int main (int argc, char** argv)
189    {
190	foo();
191    }
192',undef, '')){
193	print "$header found.\n";
194	return 1;
195    }
196    print "$header not found.\n";
197    return 0;
198}
199
200sub has_pcre {
201    print "looking for pcre...\n";
202    if (try_compile_and_link('
203#include <pcre.h>
204    static int foo()
205    {
206	return 0;
207    }
208    int main (int argc, char** argv)
209    {
210	foo();
211    }
212',undef, '-I/usr/include/pcre -lpcre')){
213	print "pcre found.\n";
214	return 1;
215    }
216    print "pcre not found.\n";
217    return 0;
218}
219
220sub has_mmap {
221    print "looking for mmap...\n";
222    if (try_compile_and_link('
223#include <sys/stat.h>
224#include <sys/mman.h>
225#include <fcntl.h>
226#include <unistd.h>
227
228static
229char*
230mmap_load_file (const char* filepath) {
231  int fd;
232  struct stat st;
233  size_t size_in_bytes;
234  char* memarea=NULL;
235  fd = open(filepath, O_RDONLY);
236  if (fd == -1) return memarea; /* {NULL,NULL} */
237  fstat(fd, &st);
238  size_in_bytes = st.st_size;
239  /* mmap size_in_bytes+1 to avoid crash with empty file */
240  memarea = (char *) mmap(0, size_in_bytes+1,  PROT_READ,  MAP_SHARED, fd, 0);
241  close(fd);
242  return memarea;
243}
244    int main (int argc, char** argv)
245    {
246	mmap_load_file("file");
247    }
248',undef, '')){
249	print "mmap found.\n";
250	return 1;
251    }
252    print "mmap not found.\n";
253    return 0;
254}
255
256sub has_func {
257    my ($func_call)=@_;
258    print "looking for $func_call\n";
259    if (try_compile_and_link('
260#include <string.h>
261    int main (int argc, char** argv)
262    {
263	'.$func_call.';
264    }
265',undef, '')){
266	print "$func_call found.\n";
267	return 1;
268    }
269    print "$func_call not found.\n";
270    return 0;
271}
272
273sub find_int64 {
274    foreach my $type ('__int64','long long','int64_t','long','int') {
275	return $type if try_as_int64($type);
276    }
277    return;
278}
279
280sub try_as_int64 {
281    my $type=shift;
282    print "looking for int64: trying $type...";
283    if (try_compile_and_link('
284    int main (int argc, char** argv)
285    {
286	if (sizeof('.$type.')==8) return 0;
287        return sizeof('.$type.');
288    }
289',undef, '',0)){
290	print "Ok.\n";
291	return 1;
292    }
293    print "no.\n";
294    return 0;
295}
296
297sub configure {
298    $DEF{PCRE}=has_pcre();
299    if ($^O eq 'os2' or $^O eq 'dos') {
300	$DEF{MMAP}=0;
301    } elsif ($^O eq 'MSWin32') {
302    # win 32 mmap is disabled by default
303#    $DEF{MMAP}=1;
304    $DEF{MMAP}=0;
305    # no, compiler is yet unknown here;
306    # and some creepy M**soft tools may not understand long long :(
307    # $DEF{INT64_NAME} = "long long";?
308    } else {
309	$DEF{HAS_MMAP}=has_mmap();
310    }
311    $DEF{INT64_NAME} ||= find_int64();
312    $DEF{INT64_NAME} ||= $Config{i64type};
313
314    my $i;
315    for ($i=0; $i<@ARGV; $i++)  {
316	if ($ARGV[$i]=~/^(PCRE|PEDANTIC|DEBUG|MMAP|IMITATE)=(.+)/) {
317	    $DEF{$1}=$2;
318	} else {
319	    next;
320	}
321	splice @ARGV, $i, 1;
322	$i--;
323    }
324
325    #$DEF{MMAP}=0 if $^O =~ /MSWin32/ and $DEF{'IMITATE'};
326    $DEFINE.=' -DDEBUG' if $DEF{DEBUG};
327    $DEFINE.=' -DUSE_MMAP ' if $DEF{MMAP};
328
329    $DEFINE.=' -DHAVE_STDINT_H ' if has_header('stdint.h');
330    $DEFINE.=' -DHAVE_INTTYPES_H ' if has_header('inttypes.h');
331    $DEFINE.=' -DHAVE_STRDUP' if  has_func('strdup("str")');
332    $DEFINE.=' -DHAVE__STRDUP' if  has_func('_strdup("str")');
333
334    $DEFINE.=' -DHAVE_SYS_MMAN_H -DHAVE_SYS_STAT_H' if ($DEF{HAS_MMAP});
335    $DEFINE.=' -DCOMPAT_ON_BROKEN_QUOTE -DCOMPAT_ALLOW_NAME_IN_CLOSING_TAG' if ($DEF{'IMITATE'});
336    $DEFINE.=' -pedantic -DPEDANTIC' if ($DEF{'PEDANTIC'});
337    $DEFINE.=' -DINT64_NAME="' . $DEF{'INT64_NAME'}.'"' if ($DEF{'INT64_NAME'});
338    if ($DEF{'INT64_NAME'}) {
339	if ($DEF{'INT64_NAME'} eq "long long") {
340	    $DEFINE.=' -DSIZEOF_LONG_LONG=8';
341	} elsif ($DEF{'INT64_NAME'} eq "long") {
342	    $DEFINE.=' -DSIZEOF_LONG=8';
343	}
344    }
345
346    if ($DEF{PCRE}) {
347	$INC.=' -I/usr/include/pcre';
348	$DEFINE.=' -DHAVE_PCRE';
349	$LIBS.=' -lpcre';
350	print "
351=====================================================================
352build with libpcre (Stanislav Yadykin's regexp extension) is enabled.
353=====================================================================
354if you have not installed libpcre, you still can build the module
355without libpcre (with this extension disabled) using
356perl Makefile.PL PCRE=0
357";
358    } else {
359	print "
360=================================================
361build with libpcre is disabled.
362=================================================
363Stanislav Yadykin's regexp extension is disabled.
364";
365    }
366
367    if ($DEF{IMITATE}) {
368	print "
369=====================================================================
370Compatibility mode for syntactically incorrect templates is enabled.
371Note, that this mode could be a bit slower than default but it will be
372useful if you rely on HTML::Template behaviour in undefined cases.
373=====================================================================
374";
375    } else {
376	print "
377=====================================================================
378Compatibility mode for syntactically incorrect templates is disabled.
379It is the fast default.
380=====================================================================
381";
382    }
383}
384