From 8733c25cd31561ade2141848dbad24071affc739 Mon Sep 17 00:00:00 2001 From: Hauke D Date: Thu, 9 Aug 2018 19:10:33 +0200 Subject: [PATCH] Initial public release of WebPerl --- .gitignore | 6 + LICENSE_artistic.txt | 158 +++++++++ LICENSE_gpl.txt | 281 ++++++++++++++++ README.md | 39 +++ ToDo.md | 31 ++ build/build.pl | 465 ++++++++++++++++++++++++++ build/emperl_config.sh | 46 +++ build/emscripten_1.38.10_eagain.patch | 20 ++ build/findtodo.sh | 24 ++ web/mini_ide/emscr_ide.css | 36 ++ web/mini_ide/emscr_ide.js | 259 ++++++++++++++ web/mini_ide/webperl_mini_ide.html | 244 ++++++++++++++ web/webperl.js | 350 +++++++++++++++++++ web/webperl.psgi | 31 ++ web/webperl_demo.html | 78 +++++ 15 files changed, 2068 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE_artistic.txt create mode 100644 LICENSE_gpl.txt create mode 100644 README.md create mode 100644 ToDo.md create mode 100755 build/build.pl create mode 100755 build/emperl_config.sh create mode 100644 build/emscripten_1.38.10_eagain.patch create mode 100755 build/findtodo.sh create mode 100644 web/mini_ide/emscr_ide.css create mode 100644 web/mini_ide/emscr_ide.js create mode 100644 web/mini_ide/webperl_mini_ide.html create mode 100644 web/webperl.js create mode 100644 web/webperl.psgi create mode 100644 web/webperl_demo.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2243f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/*.zip +/work/ +/emperl5/ +/web/emperl.js +/web/emperl.wasm +/web/emperl.data diff --git a/LICENSE_artistic.txt b/LICENSE_artistic.txt new file mode 100644 index 0000000..a37cee6 --- /dev/null +++ b/LICENSE_artistic.txt @@ -0,0 +1,158 @@ +NAME + perlartistic - the Perl Artistic License + +SYNOPSIS + You can refer to this document in Pod via "L" + Or you can see this document by entering "perldoc perlartistic" + +DESCRIPTION + Perl is free software; you can redistribute it and/or modify it under + the terms of either: + + a) the GNU General Public License as published by the Free + Software Foundation; either version 1, or (at your option) any + later version, or + + b) the "Artistic License" which comes with this Kit. + + This is "The Artistic License". It's here so that modules, programs, + etc., that want to declare this as their distribution license can link + to it. + + For the GNU General Public License, see perlgpl. + +The "Artistic License" + Preamble + The intent of this document is to state the conditions under which a + Package may be copied, such that the Copyright Holder maintains some + semblance of artistic control over the development of the package, while + giving the users of the package the right to use and distribute the + Package in a more-or-less customary fashion, plus the right to make + reasonable modifications. + + Definitions + "Package" + refers to the collection of files distributed by the Copyright + Holder, and derivatives of that collection of files created through + textual modification. + + "Standard Version" + refers to such a Package if it has not been modified, or has been + modified in accordance with the wishes of the Copyright Holder as + specified below. + + "Copyright Holder" + is whoever is named in the copyright or copyrights for the package. + + "You" + is you, if you're thinking about copying or distributing this + Package. + + "Reasonable copying fee" + is whatever you can justify on the basis of media cost, duplication + charges, time of people involved, and so on. (You will not be + required to justify it to the Copyright Holder, but only to the + computing community at large as a market that must bear the fee.) + + "Freely Available" + means that no fee is charged for the item itself, though there may + be fees involved in handling the item. It also means that recipients + of the item may redistribute it under the same conditions they + received it. + + Conditions + 1. You may make and give away verbatim copies of the source form of the + Standard Version of this Package without restriction, provided that + you duplicate all of the original copyright notices and associated + disclaimers. + + 2. You may apply bug fixes, portability fixes and other modifications + derived from the Public Domain or from the Copyright Holder. A + Package modified in such a way shall still be considered the + Standard Version. + + 3. You may otherwise modify your copy of this Package in any way, + provided that you insert a prominent notice in each changed file + stating how and when you changed that file, and provided that you do + at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise make + them Freely Available, such as by posting said modifications to + Usenet or an equivalent medium, or placing the modifications on + a major archive site such as uunet.uu.net, or by allowing the + Copyright Holder to include your modifications in the Standard + Version of the Package. + + b) use the modified Package only within your corporation or + organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and + provide a separate manual page for each non-standard executable + that clearly documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + + 4. You may distribute the programs of this Package in object code or + executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library + files, together with instructions (in the manual page or + equivalent) on where to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), + together with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + + 5. You may charge a reasonable copying fee for any distribution of this + Package. You may charge any fee you choose for support of this + Package. You may not charge a fee for this Package itself. However, + you may distribute this Package in aggregate with other (possibly + commercial) programs as part of a larger (possibly commercial) + software distribution provided that you do not advertise this + Package as a product of your own. You may embed this Package's + interpreter within an executable of yours (by linking); this shall + be construed as a mere form of aggregation, provided that the + complete Standard Version of the interpreter is so embedded. + + 6. The scripts and library files supplied as input to or produced as + output from the programs of this Package do not automatically fall + under the copyright of this Package, but belong to whoever generated + them, and may be sold commercially, and may be aggregated with this + Package. If such scripts or library files are aggregated with this + Package via the so-called "undump" or "unexec" methods of producing + a binary executable image, then distribution of such an image shall + neither be construed as a distribution of this Package nor shall it + fall under the restrictions of Paragraphs 3 and 4, provided that you + do not represent such an executable image as a Standard Version of + this Package. + + 7. C subroutines (or comparably compiled subroutines in other + languages) supplied by you and linked into this Package in order to + emulate subroutines and variables of the language defined by this + Package shall not be considered part of this Package, but are the + equivalent of input as in Paragraph 6, provided these subroutines do + not change the language in any way that would cause it to fail the + regression tests for the language. + + 8. Aggregation of this Package with a commercial distribution is always + permitted provided that the use of this Package is embedded; that + is, when no overt attempt is made to make this Package's interfaces + visible to the end user of the commercial distribution. Such use + shall not be construed as a distribution of this Package. + + 9. The name of the Copyright Holder may not be used to endorse or + promote products derived from this software without specific prior + written permission. + + 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End + diff --git a/LICENSE_gpl.txt b/LICENSE_gpl.txt new file mode 100644 index 0000000..d29d956 --- /dev/null +++ b/LICENSE_gpl.txt @@ -0,0 +1,281 @@ +NAME + perlgpl - the GNU General Public License, version 1 + +SYNOPSIS + You can refer to this document in Pod via "L" + Or you can see this document by entering "perldoc perlgpl" + +DESCRIPTION + Perl is free software; you can redistribute it and/or modify it under + the terms of either: + + a) the GNU General Public License as published by the Free + Software Foundation; either version 1, or (at your option) any + later version, or + + b) the "Artistic License" which comes with this Kit. + + This is the "GNU General Public License, version 1". It's here so that + modules, programs, etc., that want to declare this as their distribution + license can link to it. + + For the Perl Artistic License, see perlartistic. + +GNU GENERAL PUBLIC LICENSE + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users + at the mercy of those companies. By contrast, our General Public + License is intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users. The + General Public License applies to the Free Software Foundation's + software and to any other program whose authors commit to using it. + You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not + price. Specifically, the General Public License is designed to make + sure that you have the freedom to give away or sell copies of free + software, that you receive source code or can get it if you want it, + that you can change the software or use pieces of it in new free + programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether + gratis or for a fee, you must give the recipients all the rights that + you have. You must make sure that they, too, receive or can get the + source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, + and (2) offer you this license which gives you legal permission to + copy, distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain + that everyone understands that there is no warranty for this free + software. If the software is modified by someone else and passed on, + we want its recipients to know that what they have is not the original, + so that any problems introduced by others will not reflect on the + original authors' reputations. + + The precise terms and conditions for copying, distribution and + modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which + contains a notice placed by the copyright holder saying it may be + distributed under the terms of this General Public License. The + "Program", below, refers to any such program or work, and a "work based + on the Program" means either the Program or any work containing the + Program or a portion of it, either verbatim or with modifications. + Each licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's + source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate + copyright notice and disclaimer of warranty; keep intact all the + notices that refer to this General Public License and to the absence of + any warranty; and give any other recipients of the Program a copy of + this General Public License along with the Program. You may charge a + fee for the physical act of transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion + of it, and copy and distribute such modifications under the terms of + Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, + either with or without modifications, to be licensed at no charge + to all third parties under the terms of this General Public License + (except that you may choose to grant warranty protection to some or + all third parties, at your option). + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the simplest and most usual way, to print or + display an announcement including an appropriate copyright notice + and a notice that there is no warranty (or else, saying that you + provide a warranty) and that users may redistribute the program + under these conditions, and telling the user how to view a copy of + this General Public License. + + d) You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + + Mere aggregation of another independent work with the Program (or its + derivative) on a volume of a storage or distribution medium does not + bring the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or + derivative of it, under Paragraph 2) in object code or executable form + under the terms of Paragraphs 1 and 2 above provided that you also do + one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of + the corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + + Source code for a work means the preferred form of the work for making + modifications to it. For an executable file, complete source code + means all the source code for all modules it contains; but, as a + special exception, it need not include source code for modules which + are standard libraries that accompany the operating system on which the + executable file runs, or for standard header files or definitions files + that accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the + Program except as expressly provided under this General Public License. + Any attempt otherwise to copy, modify, sublicense, distribute or + transfer the Program is void, and will automatically terminate your + rights to use the Program under this License. However, parties who + have received copies, or rights to use copies, from you under this + General Public License will not have their licenses terminated so long + as such parties remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work + based on the Program) you indicate your acceptance of this license to + do so, and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further + restrictions on the recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new + versions of the General Public License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the Program + specifies a version number of the license which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Program does not specify a + version number of the license, you may choose any version ever + published by the Free Software Foundation. + + 8. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted by the + Free Software Foundation, write to the Free Software Foundation; we + sometimes make exceptions for this. Our decision will be guided by the + two goals of preserving the free status of all derivatives of our free + software and of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR + OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, + EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS + WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF + ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest + possible use to humanity, the best way to achieve this is to make it + free software which everyone can redistribute and change under these + terms. + + To do so, attach the following notices to the program. It is safest + to attach them to the start of each source file to most effectively + convey the exclusion of warranty; and each file should have at least + the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 1, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA + + + Also add information on how to contact you by electronic and paper + mail. + + If the program is interactive, make it output a short notice like this + when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type + 'show w'. This is free software, and you are welcome to + redistribute it under certain conditions; type 'show c' for + details. + + The hypothetical commands 'show w' and 'show c' should show the + appropriate parts of the General Public License. Of course, the + commands you use may be called something other than 'show w' and 'show + c'; they could even be mouse-clicks or menu items--whatever suits your + program. + + You should also get your employer (if you work as a programmer) or your + school, if any, to sign a "copyright disclaimer" for the program, if + necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program 'Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + + That's all there is to it! + diff --git a/README.md b/README.md new file mode 100644 index 0000000..5550b03 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ + +WebPerl +======= + +This is the main WebPerl repository. +Please see the documentation on the main site ****: + +\[ [Home](https://webperl.zero-g.net/index.html) - +[Using WebPerl](https://webperl.zero-g.net/using.html) - +[Building WebPerl](https://webperl.zero-g.net/building.html) - +[Wiki](https://github.com/haukex/webperl/wiki) - +[GitHub](https://github.com/haukex/webperl) - +[Notes](https://webperl.zero-g.net/notes.html) - +[Legal](https://webperl.zero-g.net/legal.html) \] + + +Author, Copyright, and License +============================== + +**WebPerl ** + +Copyright (c) 2018 Hauke Daempfling (haukex@zero-g.net) +at the Leibniz Institute of Freshwater Ecology and Inland Fisheries (IGB), +Berlin, Germany, + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl 5 itself: either the GNU General Public +License as published by the Free Software Foundation (either version 1, +or, at your option, any later version), or the "Artistic License" which +comes with Perl 5. + +This program is distributed in the hope that it will be useful, but +**WITHOUT ANY WARRANTY**; without even the implied warranty of +**MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE**. +See the licenses for details. + +You should have received a copy of the licenses along with this program. +If not, see . + diff --git a/ToDo.md b/ToDo.md new file mode 100644 index 0000000..1b14e22 --- /dev/null +++ b/ToDo.md @@ -0,0 +1,31 @@ + +WebPerl TODOs +============= + + + +1. Documentation (Website) + + - Using WebPerl + - the user must explicitly "unregister" anonymous Perl subs (or show alternatives) to prevent %CodeTable from growing too large + - the user shouldn't mess with the symbol table (delete subs, redefine them, etc.) + - + - Building WebPerl + - test out perl -Mlazy to install all the deps (and if it works well, document) + +2. Testing + + - Continue work on `WebPerl.t` + - More tests for Unicode support (Perl/JS interface, Perl.eval(), plus Emscripten's virtual FS) + - I should focus on getting the tests running in the browser instead of node.js + - How to package tests? How does `make test` find&handle all the various modules' `t`s? + - How to best disable individual tests that we know won't work? (qx etc.) + - How to handle the many tests that call an external Perl? + - patching t/test.pl's runperl() seems easiest at the moment, and we can use the iframe method from the IDE + +3. Misc + + - Test if a CDN would work + +See also: "TODO" tags in code (use `findtodo.sh`) + diff --git a/build/build.pl b/build/build.pl new file mode 100755 index 0000000..172b243 --- /dev/null +++ b/build/build.pl @@ -0,0 +1,465 @@ +#!/usr/bin/env perl +use warnings; +use 5.026; + +=head1 SYNOPSIS + +Build script for WebPerl; see L. + + build.pl [OPTIONS] + OPTIONS: + --showconf - Show configuration + --reconfig - Force regeneration config.sh + --forceext - Force fetching of extensions + --applyconfig - Apply any changes to config.sh (sh Configure -S) + --remakeout - Force rebuild of the output directory + --forceemperl - Force rebuild of emperl.js + --dist=FN - Create a distro file "FN.zip" + --verbose - Be more verbose + +=head1 Author, Copyright, and License + +B<< WebPerl L >> + +Copyright (c) 2018 Hauke Daempfling (haukex@zero-g.net) +at the Leibniz Institute of Freshwater Ecology and Inland Fisheries (IGB), +Berlin, Germany, L + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl 5 itself: either the GNU General Public +License as published by the Free Software Foundation (either version 1, +or, at your option, any later version), or the "Artistic License" which +comes with Perl 5. + +This program is distributed in the hope that it will be useful, but +B; without even the implied warranty of +B. +See the licenses for details. + +You should have received a copy of the licenses along with this program. +If not, see L. + +=cut + +use Getopt::Long qw/ HelpMessage :config posix_default gnu_compat bundling auto_version auto_help /; +use Hash::Util qw/lock_hash/; +use Data::Dump; +use Path::Class qw/file dir/; +use IPC::Run3::Shell {show_cmd=>1}, qw/ :FATAL :run git make emmake /; +use ExtUtils::MakeMaker qw/prompt/; +use FindBin (); +use Carp; +use Cwd qw/getcwd abs_path/; +use URI (); +use IO::Socket::SSL 1.56 (); # for HTTP::Tiny +use Net::SSLeay 1.49 (); # for HTTP::Tiny +use HTTP::Tiny (); +use Cpanel::JSON::XS qw/decode_json/; +use File::Temp qw/tempdir/; +use Archive::Tar (); +use File::Copy::Recursive qw/dirmove/; +use File::Replace qw/replace3/; +use Pod::Strip (); +use Archive::Zip qw/AZ_OK/; + +GetOptions(\my %opts,'showconf','reconfig','forceext','applyconfig', + 'forceemperl','remakeout','dist=s','verbose') + or HelpMessage(-exitval=>255); + +# check that emperl_config.sh has been run +die "Please run '. emperl_config.sh' to set up the environment variables.\n" + unless $ENV{EMPERL_PERLVER}; +die "Please edit 'emperl_config.sh' to point it to the correct location of 'emsdk_env.sh'\n" + unless $ENV{EMSCRIPTEN} && -d $ENV{EMSCRIPTEN} && $ENV{EMSDK} && -d $ENV{EMSDK}; + +# copy over config variables from environment +my %C = map {$_=>$ENV{'EMPERL_'.$_}} qw/ EXTENSIONS + HOSTPERLDIR OUTPUTDIR DOWNLOADDIR PERLSRCDIR + PREFIX PERLVER + PERL_REPO PERL_BRANCH CLOBBER_BRANCH /; +$C{$_} = dir($C{$_}) for qw/ HOSTPERLDIR OUTPUTDIR DOWNLOADDIR PERLSRCDIR /; +$C{EXTENSIONS} = [ split ' ', $C{EXTENSIONS} ]; +lock_hash %C; # typo prevention +dd \%C if $opts{showconf}; + +my $VERBOSE = $opts{verbose}?1:0; +my $needs_reconfig = !!$opts{reconfig}; + +# ##### ##### ##### Step: Patch Emscripten ##### ##### ##### + +{ + my $d = pushd( dir($ENV{EMSCRIPTEN}, 'src') ); + # Emscripten's fork() (and system()) stubs return EAGAIN, meaning "Resource temporarily unavailable". + # So perl will wait 5 seconds and try again, which is not helpful to us, since Emscripten doesn't support those functions at all. + # This patch fixes that on the Emscripten side, so the stubs return ENOTSUP. + #TODO Later: we should probably verify the Emscripten version too, and in the future we may need different patches for different versions + if ( try_patch_file( file($FindBin::Bin,'emscripten_1.38.10_eagain.patch') ) ) { + say STDERR "# Emscripten was newly patched, forcing a rebuild"; + # not sure if the following is needed, but playing it safe: + run 'emcc', '--clear-cache'; # force Emscripten to rebuild libs (takes a bit of time) + $needs_reconfig=1; + } +} + +# ##### ##### ##### Step: Check out Perl sources ##### ##### ##### + +if (!-e $C{PERLSRCDIR}) { + say STDERR "# $C{PERLSRCDIR} doesn't exist, checking out"; + my $d = pushd($C{PERLSRCDIR}->parent); + git 'clone', '--branch', $C{PERL_BRANCH}, $C{PERL_REPO}, $C{PERLSRCDIR}->basename; + die "something went wrong with git clone" unless -d $C{PERLSRCDIR}; + $needs_reconfig=1; +} +{ + my $d = pushd($C{PERLSRCDIR}); + git 'fetch'; + my $myhead = git 'log', '-1', '--format=%h', $C{PERL_BRANCH}, {chomp=>1,show_cmd=>$VERBOSE}; + my $remhead = git 'log', '-1', '--format=%h', 'origin/'.$C{PERL_BRANCH}, {chomp=>1,show_cmd=>$VERBOSE}; + say STDERR "# Local branch is at $myhead, remote is $remhead"; + if ($myhead ne $remhead) { + if (prompt("Would you like to update? WARNING: Unsaved local changes may be lost! [Yn]","y")=~/^\s*y/i) { + eval { + if ($C{CLOBBER_BRANCH}) { + say "WARNING: I am about to clobber the branch $C{PERL_BRANCH} in $C{PERLSRCDIR}!"; + verify_perlsrc_modify(1); + git 'checkout', '-q', $C{PERLVER}; + git 'branch', '-D', $C{PERL_BRANCH}; + git 'branch', $C{PERL_BRANCH}, 'origin/'.$C{PERL_BRANCH}; + git 'checkout', $C{PERL_BRANCH}; + } + else { + git 'checkout', $C{PERL_BRANCH}; + git 'pull'; + } + 1 } or die "$@\nA git step failed - perhaps you have uncommited changes in $C{PERLSRCDIR}?\n"; + $needs_reconfig=1; + } + } + my $tags = git 'tag', '--list', {show_cmd=>$VERBOSE}; + die "could not find tag '$C{PERLVER}', is this the right repository?" + unless $tags=~/^\Q$C{PERLVER}\E$/m; + my $branches = git 'branch', '--list', {show_cmd=>$VERBOSE}; + die "could not find branch '$C{PERL_BRANCH}', is this the right repository?" + unless $branches=~/^\*?\s*\b\Q$C{PERL_BRANCH}\E$/m; + say STDERR "# Found tag '$C{PERLVER}' and branch '$C{PERL_BRANCH}' in $C{PERLSRCDIR}"; +} +sub verify_perlsrc_modify { + my $force = shift; + state $already_prompted = 0; + $already_prompted=0 if $force; + return if $already_prompted; + if (prompt("WARNING: You will lose any changes to the working copy and index in $C{PERLSRCDIR}!\n" + ." Continue? [yN]","n")!~/^\s*y/i) { + say STDERR "Aborting."; + exit 1; + } else { $already_prompted = 1 } +} + +# ##### ##### ##### Step: Check/build hostperl ##### ##### ##### + +sub verify_hostperl { + my $miniperl = $C{HOSTPERLDIR}->file('miniperl'); + return 0 unless -e $miniperl; + my $miniperlver = run $miniperl, '-e', 'print $^V', {show_cmd=>$VERBOSE}; + say STDERR "# Detected hostperl / miniperl '$miniperlver' (need '$C{PERLVER}')"; + my $perl = $C{HOSTPERLDIR}->file('perl'); + if (-e $perl) { # currently just an optional check + my $perlver = run $perl, '-e', 'print $^V', {show_cmd=>$VERBOSE}; + say STDERR "# Detected hostperl / perl '$perlver'"; + die "miniperl ('$miniperlver') / perl ('$perlver') version mismatch" + unless $miniperlver eq $perlver; + } + return $miniperlver eq $C{PERLVER}; +} +if (!verify_hostperl()) { + say STDERR "# A rebuild of hostperl is required"; + $C{HOSTPERLDIR}->rmtree(1); + $C{HOSTPERLDIR}->mkpath(1); + verify_perlsrc_modify(); + { + my $d = pushd($C{PERLSRCDIR}); + git 'checkout', '-qf', $C{PERLVER}; + git 'clean', '-dxf'; + } + { + my $d = pushd($C{HOSTPERLDIR}); + run {stdin=>\undef}, 'sh', file($C{PERLSRCDIR},'Configure'), + '-des', '-Dusedevel', '-Dmksymlinks'; + make 'miniperl'; + make 'minitest'; + make 'generate_uudmap'; + #TODO Later: do we really need the following full perl build as well? (good for testing?) + # if we do, make the test for "perl" in verify_hostperl required, not optional + make 'perl'; + make 'test'; + } + $needs_reconfig=1; + die "something went wrong with hostperl" unless verify_hostperl(); +} + +# ##### ##### ##### Step: Prep "emperl" sources (for next steps) ##### ##### ##### + +my $config_sh = $C{PERLSRCDIR}->file('config.sh'); +if (!-e $config_sh) { + say STDERR "# config.sh NOT found, forcing a reconfig"; + $needs_reconfig=1 } +else { say STDERR "# config.sh found" } + +if (-e $config_sh) { + my $our_mtime = file($FindBin::Bin, 'emperl_config.sh')->stat->mtime; + my $perl_mtime = $config_sh->stat->mtime; + if ($perl_mtime>$our_mtime) + { say STDERR "# config.sh is newer than emperl_config.sh" } + else { + say STDERR "# config.sh is OLDER than emperl_config.sh, forcing a reconfig"; + $needs_reconfig=1 } +} + +if ($needs_reconfig) { + exit 1 if prompt("Looks like we need a full reconfig. Continue? [Yn]","y")!~/^\s*y/i; + verify_perlsrc_modify(); + my $d = pushd($C{PERLSRCDIR}); + # Note: could get the current branch with: git 'rev-parse', '--abbrev-ref', 'HEAD', {chomp=>1}; + # but since we're clobbering anyway... + git 'checkout', '-qf', $C{PERL_BRANCH}; + git 'clean', '-dxf'; +} + +# ##### ##### ##### Step: Add custom extensions ##### ##### ##### + +if ($needs_reconfig || $opts{forceext}) { + my $http = HTTP::Tiny->new; + $C{DOWNLOADDIR}->mkpath(1); + for my $modname ($C{EXTENSIONS}->@*) { + my $apiuri = URI->new('https://fastapi.metacpan.org/v1/download_url'); + $apiuri->path_segments( $apiuri->path_segments, $modname ); + say STDERR "# Fetching $apiuri..."; + my $resp1 = $http->get($apiuri); + die "$apiuri: $resp1->{status} $resp1->{reason}\n" unless $resp1->{success}; + my $apiresp = decode_json($resp1->{content}); + my $version = $apiresp->{version}; + my $dluri = URI->new($apiresp->{download_url}); + + my $file = $C{DOWNLOADDIR}->file( ($dluri->path_segments)[-1] ); + die "I don't know what to do with this file type (yet): $file" + unless $file->basename=~/(?:\.tar\.gz|\.tgz)$/i; + + say STDERR "# Fetching $dluri into $file..."; + my $resp2 = $http->mirror($dluri, $file); + die "$dluri: $resp2->{status} $resp2->{reason}\n" unless $resp2->{success}; + say STDERR "# $dluri: $resp2->{status} $resp2->{reason}"; + + my $tempd = dir( tempdir(DIR=>$C{DOWNLOADDIR}, CLEANUP => 1) ); + { + my $d = pushd($tempd); + my @files = Archive::Tar->new->extract_archive($file, Archive::Tar::COMPRESS_GZIP); + say STDERR "# Extracted ",0+@files," files into $tempd"; + } + + my @dirs = $tempd->children; + die "Can't handle the directory structure of this file (yet): $file" + unless @dirs==1 && $dirs[0]->is_dir; + my ($dirname) = $dirs[0]->basename =~ /^(.+)-\Q$version\E$/g + or die "Failed to parse ".$dirs[0]->basename; + my $targdir = $C{PERLSRCDIR}->subdir( 'ext', $dirname ); + my $domove = 1; + if (-e $targdir) { + if ( prompt("WARNING: $targdir exists, Keep or Delete? [Kd]","k")=~/^\s*d/i ) + { $targdir->rmtree(1) } + else { $domove=0 } + } + if ($domove) { + say STDERR "# Moving $dirs[0] to $targdir"; + dirmove($dirs[0], $targdir) + or die "move failed: $!"; + } + } + say STDERR "# Done setting up modules"; +} +else { say STDERR "# Since we don't need a reconfig, not looking at extensions" } + +# ##### ##### ##### Step: Run configure ##### ##### ##### + +if ($needs_reconfig) { # this means that we cleaned the source tree above + say STDERR "# Running Configure..."; + my $d = pushd($C{PERLSRCDIR}); + # note that we don't use -Dmksymlinks here because something in the + # Emscripten build process seems to have issues with the symlinks (?) + run {stdin=>\undef}, 'emconfigure', 'sh', 'Configure', '-des', + '-Dhintfile=emscripten'; +} +elsif ($opts{applyconfig}) { + say STDERR "# Running Configure -S..."; + my $d = pushd($C{PERLSRCDIR}); + run {stdin=>\undef}, 'emconfigure', 'sh', 'Configure', '-S'; +} + +# ##### ##### ##### Step: Build perl into outputdir ##### ##### ##### + +my $destdir = dir($C{OUTPUTDIR},$C{PREFIX}); +if ($needs_reconfig || !-e $destdir || $opts{remakeout}) { + say STDERR "# Rebuilding $destdir..."; + $destdir->rmtree(1); + # make the target dir here so that nodeperl_dev_prerun.js can mount it during build + $destdir->mkpath(1); + + my $d = pushd($C{PERLSRCDIR}); + + emmake 'make', 'perl'; + + # a really basic test to see if the build succeeded + my $perltest = run file($C{PERLSRCDIR},'perl'), '-e', q{print "$^O $^V"}, + {chomp=>1,show_cmd=>$VERBOSE,fail_on_stderr=>1}; + die "something went wrong building perl (got: '$perltest')" + unless $perltest eq 'emscripten '.$C{PERLVER}; + + # note that installperl requires ./perl to be executable (our Makefile patch currently takes care of that) + run $C{HOSTPERLDIR}.'/miniperl', 'installperl', '-p', '--destdir='.$C{OUTPUTDIR}; + + # clean out the stuff we really don't need + $destdir->subdir('bin')->rmtree(1); + $destdir->recurse( callback => sub { + my $f = shift; + return if $f->is_dir; + if ( ( $f->basename=~/\.(?:h|a|pod)$/i ) || ( $f->basename eq 'extralibs.ld' && (-s $f)==1 ) + || ( $f->basename eq '.packlist' ) ) { + print STDERR "removing $f\n"; + $f->remove or die "failed to remove $f"; + } + elsif ( $f->basename=~/\.(?:pm|pl)$/i && $f->basename ne 'WebPerl.pm' ) { + print STDERR "stripping POD from $f\n"; + my $strip = Pod::Strip->new; + my ($infh,$outfh,$repl) = replace3($f); + $strip->output_fh($outfh); + $strip->parse_file($infh); + $repl->finish; + } + }); + CLEAN_EMPTY: { + my @todel; + $destdir->recurse( callback => sub { push @todel, $_[0] if $_[0]->is_dir && !$_[0]->children } ); + for my $f (@todel) { + print STDERR "removing $f\n"; + $f->remove or die "failed to remove $f"; + } + redo CLEAN_EMPTY if @todel; + } + + # Development aides: + $destdir->subdir('dev')->mkpath(1); + # we make them hard links so that edits to WebPerl.pm don't require a full + # rebuild of the output directory (a rebuild of emperl.js is enough) + safelink( $C{PERLSRCDIR}->file('ext','WebPerl','WebPerl.t'), + $destdir->file('dev','WebPerl.t') ); + safelink( $C{PERLSRCDIR}->file('ext','WebPerl','WebPerl.pm'), + $destdir->file('lib','5.28.0','wasm','WebPerl.pm') ); #TODO: should figure this directory out dynamically + + say STDERR "# Done rebuilding $destdir"; +} + +# ##### ##### ##### Step: Build emperl.js ##### ##### ##### + +{ + say STDERR "# Making emperl.js..."; + if ($opts{forceemperl}) + { $C{PERLSRCDIR}->file('emperl.js')->remove + or die "failed to delete emperl.js" } + my $d = pushd($C{PERLSRCDIR}); + emmake 'make', 'emperl.js'; + say STDERR "# Done making emperl.js"; +} +for my $f (qw/ emperl.js emperl.wasm emperl.data /) { + $C{PERLSRCDIR}->file($f) + ->copy_to( dir($FindBin::Bin)->parent->subdir('web') ) + or die "failed to copy $f: $!"; +} +say STDERR "# Copied emperl.* files to web dir"; + +# ##### ##### ##### Step: Build distro ##### ##### ##### + +if (my $dist = $opts{dist}) { + my $basedir = dir($FindBin::Bin)->parent; + my $zipfn = $basedir->file("$dist.zip"); + my $zip = Archive::Zip->new(); + $zip->addTree($basedir->subdir('web').'', dir($dist).''); + $zip->writeToFileNamed("$zipfn") == AZ_OK or die "$zipfn write error"; + say STDERR "# Wrote to $zipfn:"; + my $unzip = Archive::Zip->new("$zipfn"); + say "\t$_" for $unzip->memberNames; +} + + +# ##### ##### ##### subs ##### ##### ##### + +sub safelink { # like link(OLDFILE,NEWFILE) but with extra checks + my ($oldfile,$newfile) = @_; + die "not a file: $oldfile" unless -f $oldfile; + if (-e $newfile) { + die "files don't match: $oldfile vs. $newfile" + unless do { open my $fh, '<:raw', $oldfile or die "$oldfile: $!"; local $/; <$fh> } + eq do { open my $fh, '<:raw', $newfile or die "$newfile: $!"; local $/; <$fh> }; + file($newfile)->remove or die "failed to remove $newfile: $!"; + } + link($oldfile,$newfile) + or die "link('$oldfile','$newfile'): $!"; +} + +# First argument: the filename of the .patch file +# Any following arguments are additionally passed to "patch" (e.g. "-p1") +# Attempts to run "patch", will fail gracefully if the patch has already been applied. +# Dies if anything goes wrong (patch not applied cleanly, etc.). +# Returns false (0) if the patch was already applied previously, true (1) if the patch was newly applied. +sub try_patch_file { + my ($patchf,@args) = @_; + say STDERR "# Attempting to apply patch $patchf..."; + run 'patch', @args, '-r-', '-sNi', $patchf, {allow_exit=>[0,1],show_cmd=>$VERBOSE}; + if ($?==1<<8) { + # Slightly hackish way to test if the patch did not apply cleanly, or it's just already been applied: + # Apply the patch in reverse once, and then apply it again, if both go through without errors all is ok. + # There is probably a better way to do this, I'm just feeling a little lazy at the moment. + run 'patch', @args, '-sRi', $patchf, {show_cmd=>$VERBOSE}; + run 'patch', @args, '-si', $patchf, {show_cmd=>$VERBOSE}; + say STDERR "# Verified that $patchf was previously applied"; + return 0; + } + elsif ($?) { die "patch $patchf \$?=$?" } + else { say STDERR "# Successfully applied patch $patchf"; return 1 } +} + +# A simplified version of File::pushd that outputs debug info. TODO Later: should probably propose a patch for a debug option. +sub pushd { + if (not defined wantarray) { carp "pushd in void context"; return } + croak "bad arguments to pushd" unless @_==1 && defined $_[0]; + my $targ = abs_path(shift); + croak "not a directory: $targ" unless -d $targ; + my $orig = getcwd; + if ($targ ne $orig) { + say STDERR "\$ cd $targ"; + chdir $targ or croak "chdir to $targ failed: $!"; + } + return bless { orig=>$orig }, 'PushedDir'; +} +sub PushedDir::DESTROY { + my $self = shift; + if (getcwd ne $self->{orig}) { + say STDERR "\$ cd ".$self->{orig}; + chdir $self->{orig} or croak "chdir to ".$self->{orig}." failed: $!"; + } +} + +__END__ + +#TODO Later: Fix the following (note setting d_getgrgid_r and d_getgrnam_r in the hints file didn't seem to help) +warning: unresolved symbol: getgrgid +warning: unresolved symbol: getgrnam +warning: unresolved symbol: llvm_fma_f64 +warning: unresolved symbol: sigsuspend + +#TODO Later: Fix the following "miniperl make_ext.pl" errors (warnings?) +./miniperl -Ilib make_ext.pl lib/auto/Encode/Byte/Byte.a MAKE="make" LIBPERL_A=libperl.a LINKTYPE=static CCCDLFLAGS= +Can't find extension Encode/Byte in any of cpan dist ext at make_ext.pl line 251. +./miniperl -Ilib make_ext.pl lib/auto/Encode/Symbol/Symbol.a MAKE="make" LIBPERL_A=libperl.a LINKTYPE=static CCCDLFLAGS= +Can't find extension Encode/Symbol in any of cpan dist ext at make_ext.pl line 251. +./miniperl -Ilib make_ext.pl lib/auto/Encode/Unicode/Unicode.a MAKE="make" LIBPERL_A=libperl.a LINKTYPE=static CCCDLFLAGS= +Can't find extension Encode/Unicode in any of cpan dist ext at make_ext.pl line 251. + diff --git a/build/emperl_config.sh b/build/emperl_config.sh new file mode 100755 index 0000000..60a6877 --- /dev/null +++ b/build/emperl_config.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# This is the configuration file for building WebPerl. +# You should edit it according to the comments below. +# Remember to reload this file after making changes! (". emperl_config.sh") + +# You must edit this to point to your Emscripten SDK's emsdk_env.sh. +. $HOME/emsdk/emsdk_env.sh + +# A whitespace-separated list of modules to download and add to the build. +# Note: Cpanel::JSON::XS is required for WebPerl! +export EMPERL_EXTENSIONS="Cpanel::JSON::XS Devel::StackTrace" + +# Modules from the above list that have XS code need to be linked statically. +# Add them here, separated by whitespace (see also the "static_ext" variable +# in https://perl5.git.perl.org/perl.git/blob/HEAD:/Porting/Glossary ). +export EMPERL_STATIC_EXT="Cpanel/JSON/XS" + +# Do not edit (this gets this script's parent directory) +BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. >/dev/null && pwd )" + +# Various working directories, you normally don't need to edit these +export EMPERL_PERLSRCDIR="$BASEDIR/emperl5" +export EMPERL_HOSTPERLDIR="$BASEDIR/work/hostperl" +export EMPERL_DOWNLOADDIR="$BASEDIR/work/download" +export EMPERL_OUTPUTDIR="$BASEDIR/work/outputperl" + +# Don't edit the following options unless you know what you're doing! +# Note to self: In build.pl, we take advantage of the fact that on Perls >=v5.10.0, "$^V" is the same as the tag name. +export EMPERL_PERLVER="v5.28.0" +export EMPERL_PREFIX="/opt/perl" +export EMPERL_PRELOAD_FILE="$EMPERL_OUTPUTDIR$EMPERL_PREFIX@$EMPERL_PREFIX" +export EMPERL_OPTIMIZ="-O2" +export EMPERL_LINK_FLAGS="--pre-js common_preamble.js -s EXPORTED_FUNCTIONS=['_main','_emperl_end_perl','_Perl_call_sv','_Perl_call_pv','_Perl_call_method','_Perl_call_argv','_Perl_eval_pv','_Perl_eval_sv','_webperl_eval_perl'] -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap']" +# Note: not including "-s SAFE_HEAP=1" in the debug flags because we're building to WebAssembly, which doesn't require alignment +#TODO Later: Can some of the SAFE_HEAP functionality (null pointer access I think?) be replaced by the WASM error traps? +# http://kripken.github.io/emscripten-site/docs/compiling/WebAssembly.html#binaryen-codegen-options +export EMPERL_DEBUG_FLAGS="-s ASSERTIONS=2 -s STACK_OVERFLOW_CHECK=2" + +# Location and branch of the perl git repository that contains the emperl branch +export EMPERL_PERL_REPO="https://github.com/haukex/emperl5.git" +export EMPERL_PERL_BRANCH="emperl_$EMPERL_PERLVER" +# Enabling this setting causes the local emperl branch to be deleted and re-fetched from the origin. +# This is useful during development, when rewrites of the (unpublished!) git history of the branch might happen. +export EMPERL_CLOBBER_BRANCH=0 + diff --git a/build/emscripten_1.38.10_eagain.patch b/build/emscripten_1.38.10_eagain.patch new file mode 100644 index 0000000..74c44dc --- /dev/null +++ b/build/emscripten_1.38.10_eagain.patch @@ -0,0 +1,20 @@ +--- emscripten/src/library.js 2018-08-01 18:58:49.428051969 +0200 ++++ emsdk/emscripten/1.38.10/src/library.js 2018-08-01 18:58:03.288051969 +0200 +@@ -250,7 +250,7 @@ + // pid_t fork(void); + // http://pubs.opengroup.org/onlinepubs/000095399/functions/fork.html + // We don't support multiple processes. +- ___setErrNo(ERRNO_CODES.EAGAIN); ++ ___setErrNo(ERRNO_CODES.ENOTSUP); + return -1; + }, + vfork: 'fork', +@@ -545,7 +545,7 @@ + // int system(const char *command); + // http://pubs.opengroup.org/onlinepubs/000095399/functions/system.html + // Can't call external programs. +- ___setErrNo(ERRNO_CODES.EAGAIN); ++ ___setErrNo(ERRNO_CODES.ENOTSUP); + return -1; + }, + diff --git a/build/findtodo.sh b/build/findtodo.sh new file mode 100755 index 0000000..4832ea1 --- /dev/null +++ b/build/findtodo.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e +# Finds and displays TODOs for the WebPerl project. +# the output can be piped into e.g. "less -R" +if [ -z ${EMPERL_PERLVER+x} ]; then + echo "Please source emperl_config.sh first" + exit 1 +fi +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. >/dev/null && pwd )" +TEMPFILE="`mktemp`" +trap 'rm -f "$TEMPFILE"' EXIT +( + cd "$DIR/emperl5" + # only look at files that have been added + git diff --numstat --diff-filter=A $EMPERL_PERLVER $EMPERL_PERL_BRANCH \ + | BASEDIR=$DIR perl -wMstrict -MFile::Spec::Functions=abs2rel,rel2abs -nl0 \ + -e '/^\d+\s+\d+\s+(.+)$/ or die $_; -e $1 and print abs2rel(rel2abs($1),$ENV{BASEDIR})' +) >>"$TEMPFILE" +cd $DIR +find . -mindepth 1 \( -path ./.git -o -path ./work -o -path ./emperl5 \) -prune \ + -o ! -name 'emperl.*' ! -type d -print0 \ + | perl -wMstrict -MFile::Spec::Functions=canonpath -n0le 'print canonpath($_)' >>"$TEMPFILE" +xargs -0 -a "$TEMPFILE" \ + grep --color=always -C1 -niE '\bto.?do\b' diff --git a/web/mini_ide/emscr_ide.css b/web/mini_ide/emscr_ide.css new file mode 100644 index 0000000..810980e --- /dev/null +++ b/web/mini_ide/emscr_ide.css @@ -0,0 +1,36 @@ + +/** CSS file for emscr_ide.js **/ + +.emide { + font-family: Calibri, Ubuntu, "Droid Sans", Tahoma, Arial, Helvetica, sans-serif; +} +.CodeMirror,.code { + font-family: Consolas, "Ubuntu Mono", "Droid Sans Mono", "Lucida Console", "Courier New", Courier, monospace; +} + +.toolbar button { + margin: 0 0.2em; +} + +.statusbar { + padding: 0.2em; + height: 1em; + font-size: 10pt; +} + +.filebrowser { + border: 1px solid black; + padding: 0.2em 0.5em; + overflow: auto; + height: 20em; +} +.fb-link { cursor:pointer; } +.fb-link:hover { color:#000090; background:rgba(255,255,102,0.4); } +.fb-link:active { color:#FF0000; } + +.cm-resize-frame { + overflow: hidden; + resize: vertical; + height: 24em; + border: 1px solid grey; +} diff --git a/web/mini_ide/emscr_ide.js b/web/mini_ide/emscr_ide.js new file mode 100644 index 0000000..7d60fd6 --- /dev/null +++ b/web/mini_ide/emscr_ide.js @@ -0,0 +1,259 @@ +"use strict"; + +/** ***** WebPerl - http://webperl.zero-g.net ***** + * + * Copyright (c) 2018 Hauke Daempfling (haukex@zero-g.net) + * at the Leibniz Institute of Freshwater Ecology and Inland Fisheries (IGB), + * Berlin, Germany, http://www.igb-berlin.de + * + * This program is free software; you can redistribute it and/or modify + * it under the same terms as Perl 5 itself: either the GNU General Public + * License as published by the Free Software Foundation (either version 1, + * or, at your option, any later version), or the "Artistic License" which + * comes with Perl 5. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the licenses for details. + * + * You should have received a copy of the licenses along with this program. + * If not, see http://perldoc.perl.org/index-licence.html +**/ + +function make_emscr_ide (textarea, callbacks) { + + var defaulttext = "use warnings;\nuse 5.028;\nuse WebPerl qw/js/;\n\n"; + var div = $('
').addClass("emide"); + var ide = { elem: div, cleanval: '' }; + + var tb = $('
').addClass("toolbar").appendTo(div); + var file_new = $(' + +
+
State: None
+
+
+
+
+
+ STDOUT and STDERR:
+ +
+
+ + +
+
+
+ ARGV: (JSON) + +
+ (Remember to store code in a persistent storage like /mnt/idb!) +
+
State: None
+
+ STDOUT and STDERR:
+ +
+
+
+ + + diff --git a/web/webperl.js b/web/webperl.js new file mode 100644 index 0000000..552e41c --- /dev/null +++ b/web/webperl.js @@ -0,0 +1,350 @@ +"use strict"; + +/** ***** WebPerl - http://webperl.zero-g.net ***** + * + * Copyright (c) 2018 Hauke Daempfling (haukex@zero-g.net) + * at the Leibniz Institute of Freshwater Ecology and Inland Fisheries (IGB), + * Berlin, Germany, http://www.igb-berlin.de + * + * This program is free software; you can redistribute it and/or modify + * it under the same terms as Perl 5 itself: either the GNU General Public + * License as published by the Free Software Foundation (either version 1, + * or, at your option, any later version), or the "Artistic License" which + * comes with Perl 5. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the licenses for details. + * + * You should have received a copy of the licenses along with this program. + * If not, see http://perldoc.perl.org/index-licence.html +**/ + +/** Public Interface: + * Perl.output - override this for output somewhere else + * Perl.stateChanged - callback for state changes + * Perl.trace - enables debug/trace messages + * Perl.endAfterMain - see exit(0) discussion below + * Perl.init - initializes the Perl interpreter. Pass this function a callback to be called when init is done + * Perl.start - starts up the Perl interpreter + * Perl.eval - evaluates the given Perl string + * Perl.end - Ends the Perl interpreter + * Perl.makeOutputTextarea - creates a