Merge branch 'release-2.140.101' 2.140.101
authorChris Koeritz <fred@gruntose.com>
Sat, 18 Nov 2017 02:43:53 +0000 (21:43 -0500)
committerChris Koeritz <fred@gruntose.com>
Sat, 18 Nov 2017 02:43:53 +0000 (21:43 -0500)
bringing in the dev branch's changes.

153 files changed:
documentation/cygwin_install_list.txt
documentation/feisty_meow_command_reference.txt [new file with mode: 0644]
examples/bashisms/bashrc_with_localtmp_code.sh [deleted file]
examples/bashisms/comma_separated_string_to_array.sh [deleted file]
examples/bashisms/dot.bash_logout [deleted file]
examples/bashisms/example_getops_parsing.txt [deleted file]
examples/bashisms/fred_techniques.txt [deleted file]
examples/bashisms/it_is_possible_to_cleanly_copy_array_elems.txt [deleted file]
examples/bashisms/qs_handy_unix_examples.sh [deleted file]
examples/bashisms/script_location.sh [deleted file]
examples/building/vs_var.bat [deleted file]
examples/cpp_grammar_code/CxxLexer.cpp [deleted file]
examples/cpp_grammar_code/CxxLexer.l [deleted file]
examples/cpp_grammar_code/CxxLexing.cxx [deleted file]
examples/cpp_grammar_code/CxxLexing.hxx [deleted file]
examples/cpp_grammar_code/CxxParser.cpp [deleted file]
examples/cpp_grammar_code/CxxParser.y [deleted file]
examples/cpp_grammar_code/CxxParsing.cxx [deleted file]
examples/cpp_grammar_code/CxxParsing.hxx [deleted file]
examples/cpp_grammar_code/CxxToken.cpp [deleted file]
examples/cpp_grammar_code/CxxToken.cxx [deleted file]
examples/cpp_grammar_code/CxxToken.hxx [deleted file]
examples/cpp_grammar_code/README [deleted file]
examples/cpp_grammar_code/index.html [deleted file]
examples/cpp_grammar_code/makefile [deleted file]
examples/cpp_grammar_code/makefile.gmake [deleted file]
examples/cpp_grammar_code/makefile.macros [deleted file]
examples/cpp_grammar_code/makefile.unix [deleted file]
examples/cpp_grammar_code/willink_note_re_grammar.txt [deleted file]
examples/graphics/pdf_picture_extractor.sh [deleted file]
examples/legacy/gpg-daemon-launcher.sh [deleted file]
examples/legacy/template.pl [deleted file]
examples/os_related/OS_crusher.bat [deleted file]
examples/os_related/OS_crusher.sh [deleted file]
examples/os_related/block_ip_address.sh [deleted file]
examples/os_related/example_registry_ops.sh [deleted file]
examples/os_related/set_tcp_config.sh [deleted file]
examples/os_related/user_sudoing.sh [deleted file]
examples/perlisms/example_perl_array_and_hash.pl [deleted file]
examples/readme.txt [deleted file]
examples/ripping_and_burning_examples.txt [deleted file]
infobase/configuration/cron/aa_cron_defaults.crontab
infobase/examples/bashisms/bashrc_with_localtmp_code.sh [new file with mode: 0644]
infobase/examples/bashisms/comma_separated_string_to_array.sh [new file with mode: 0644]
infobase/examples/bashisms/dot.bash_logout [new file with mode: 0644]
infobase/examples/bashisms/example_getops_parsing.txt [new file with mode: 0644]
infobase/examples/bashisms/fred_techniques.txt [new file with mode: 0644]
infobase/examples/bashisms/it_is_possible_to_cleanly_copy_array_elems.txt [new file with mode: 0644]
infobase/examples/bashisms/qs_handy_unix_examples.sh [new file with mode: 0644]
infobase/examples/bashisms/script_location.sh [new file with mode: 0644]
infobase/examples/building/vs_var.bat [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxLexer.cpp [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxLexer.l [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxLexing.cxx [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxLexing.hxx [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxParser.cpp [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxParser.y [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxParsing.cxx [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxParsing.hxx [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxToken.cpp [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxToken.cxx [new file with mode: 0644]
infobase/examples/cpp_grammar_code/CxxToken.hxx [new file with mode: 0644]
infobase/examples/cpp_grammar_code/README [new file with mode: 0644]
infobase/examples/cpp_grammar_code/index.html [new file with mode: 0644]
infobase/examples/cpp_grammar_code/makefile [new file with mode: 0644]
infobase/examples/cpp_grammar_code/makefile.gmake [new file with mode: 0644]
infobase/examples/cpp_grammar_code/makefile.macros [new file with mode: 0644]
infobase/examples/cpp_grammar_code/makefile.unix [new file with mode: 0644]
infobase/examples/cpp_grammar_code/willink_note_re_grammar.txt [new file with mode: 0644]
infobase/examples/graphics/pdf_picture_extractor.sh [new file with mode: 0644]
infobase/examples/legacy/gpg-daemon-launcher.sh [new file with mode: 0644]
infobase/examples/legacy/template.pl [new file with mode: 0644]
infobase/examples/os_related/OS_crusher.bat [new file with mode: 0644]
infobase/examples/os_related/OS_crusher.sh [new file with mode: 0644]
infobase/examples/os_related/block_ip_address.sh [new file with mode: 0644]
infobase/examples/os_related/example_registry_ops.sh [new file with mode: 0644]
infobase/examples/os_related/set_tcp_config.sh [new file with mode: 0644]
infobase/examples/os_related/user_sudoing.sh [new file with mode: 0644]
infobase/examples/perlisms/example_perl_array_and_hash.pl [new file with mode: 0644]
infobase/examples/readme.txt [new file with mode: 0644]
infobase/examples/ripping_and_burning_examples.txt [new file with mode: 0644]
infobase/feisty_inits/dot.bashrc-normal-user
infobase/feisty_inits/dot.bashrc-root
infobase/fortunes.dat
infobase/sounds/were_sorry_youre_a_spammer.mp3 [new file with mode: 0644]
production/feisty_meow_config.ini
production/sites/cakelampvm.com/docs/manual/cakelampvm_guide_v002.html [new file with mode: 0644]
production/sites/cakelampvm.com/docs/manual/images/host_only_adapter_dhcp_server.png [new file with mode: 0644]
production/sites/cakelampvm.com/docs/manual/images/host_only_network_adapter.png [new file with mode: 0644]
production/sites/cakelampvm.com/docs/manual/images/nat_network_config.png [new file with mode: 0644]
production/sites/cakelampvm.com/goog_maps_helper_mod/GoogleMapHelper.php [new file with mode: 0644]
production/sites/cakelampvm.com/goog_maps_helper_mod/compare_with_install.sh [new file with mode: 0644]
production/sites/cakelampvm.com/hello.txt [new file with mode: 0644]
production/sites/cakelampvm.com/images/green-check-mark-in-circle-hi.png [new file with mode: 0644]
production/sites/cakelampvm.com/images/green_globe_exclamation_point_570.jpg [new file with mode: 0644]
production/sites/cakelampvm.com/images/red_exclamation_mark_icon_256.png [new file with mode: 0644]
production/sites/cakelampvm.com/images/red_x_1194985626525719339tasto_11_architetto_fran_01.svg.med.png [new file with mode: 0644]
production/sites/cakelampvm.com/index.html [new file with mode: 0644]
production/sites/cakelampvm.com/rolling/default_page.001/001-default-http.conf [new file with mode: 0644]
production/sites/cakelampvm.com/rolling/default_page.001/001-default-ssl.conf [new file with mode: 0644]
production/sites/cakelampvm.com/vm_index.html [new file with mode: 0644]
readme.txt
scripts/agenda/info_overload_report.sh
scripts/archival/general_updater.sh [new file with mode: 0644]
scripts/archival/shared_updater_parts.sh [deleted file]
scripts/archival/snarf_feisty_meow.pl
scripts/core/common.alias
scripts/core/connect_feisty_meow.sh
scripts/core/functions.sh
scripts/core/generate_aliases.pl
scripts/core/inventory.sh
scripts/core/launch_feisty_meow.sh
scripts/core/reconfigure_feisty_meow.sh
scripts/core/variables.sh
scripts/customize/fred/fred_common.alias
scripts/customize/fred/fred_variables.sh
scripts/customize/fred/refred.sh
scripts/customize/fred/scripts/archival/compare_soapbox.sh [new file with mode: 0644]
scripts/customize/fred/scripts/archival/euphrosyne_comparator.sh [new file with mode: 0644]
scripts/customize/fred/scripts/archival/raw_surya_synch_.sh [new file with mode: 0644]
scripts/customize/fred/scripts/cakelampvm/revamp_web_permissions.sh [deleted file]
scripts/customize/fred/scripts/disk_synch/compare_soapbox.sh [deleted file]
scripts/customize/fred/scripts/disk_synch/euphrosyne_comparator.sh [deleted file]
scripts/customize/fred/scripts/disk_synch/musical_wand.sh [deleted file]
scripts/customize/fred/scripts/disk_synch/raw_synch_from_surya.sh [deleted file]
scripts/customize/fred/scripts/disk_synch/update_barkuptree.sh [deleted file]
scripts/customize/fred/scripts/disk_synch/update_fredmusicprime.sh [deleted file]
scripts/customize/fred/scripts/disk_synch/update_soapbox.sh [deleted file]
scripts/files/remove_here_if_not_there.sh
scripts/rev_control/puffer.sh [new file with mode: 0644]
scripts/rev_control/push_repo_downstream.sh
scripts/rev_control/rfluffer.sh [deleted file]
scripts/rev_control/rpuffer.sh [new file with mode: 0644]
scripts/rev_control/version_control.sh
scripts/site_avenger/avcoreup.sh
scripts/site_avenger/clean_mapsdemo.sh [new file with mode: 0644]
scripts/site_avenger/config/default.app
scripts/site_avenger/config/mapsdemo.app
scripts/site_avenger/powerup.sh
scripts/site_avenger/revamp_cakelampvm.sh [new file with mode: 0644]
scripts/site_avenger/shared_site_mgr.sh
scripts/site_avenger/sitepush.sh
scripts/site_avenger/siteup.sh
scripts/site_avenger/standup.sh
scripts/site_avenger/teardown.sh
scripts/system/add_apache_site.sh
scripts/system/add_domain.sh
scripts/system/common_sysadmin.sh [new file with mode: 0644]
scripts/system/remove_apache_site.sh [new file with mode: 0644]
scripts/system/remove_domain.sh [new file with mode: 0644]
scripts/text/nechung_signature.sh
scripts/tty/terminal_titler.sh
walrus/utilities/multimedia/multimedia_tools.txt

index acd8d7775c871f938d4a091a34bbb927dc43123a..0d881b6175209f60236d7f09bf01844d1a2da7b8 100644 (file)
@@ -1,65 +1,69 @@
-\r
-recommended packages to install in cygwin's setup\r
-if you're going to use cygwin on windows:\r
-\r
-first, keep all the standard packages that cygwin will enable.\r
-second, add these packages to get the full recommended set...\r
-\r
-===========\r
-\r
-using apt-cyg (https://github.com/transcode-open/apt-cyg),\r
-this is the only command needed:\r
-\r
-apt-cyg install bc crypt emacs email expect gcc-g++ git gitk gvim inetutils \\r
-  libcrypt-devel libcurl-devel libgnutls-devel make mutt ncftp openssh \\r
-  openssl-devel perl python subversion time unzip util-linux vim xinit \\r
-  xterm zip\r
-\r
-\r
-===========\r
-\r
-list broken out by category:\r
-\r
-shells:\r
-  python\r
-  perl\r
-\r
-network:\r
-  ncftp\r
-  openssh\r
-\r
-editors:\r
-  vim\r
-  gvim\r
-  emacs\r
-\r
-revision control:\r
-  git\r
-  gitk\r
-  subversion\r
-\r
-general tools:\r
-  bc\r
-  expect\r
-  util-linux\r
-  inetutils\r
-  email\r
-  mutt\r
-  unzip\r
-  zip\r
-  crypt\r
-  time\r
-\r
-libraries:\r
-  libcurl-devel\r
-  libgnutls-devel \r
-  openssl-devel\r
-\r
-build tools:\r
-  gcc4\r
-  make\r
-\r
-x window support:\r
-  xterm\r
-  xinit\r
-\r
+
+The cygwin setup app is available at: http://cygwin.com
+
+The default packages selected by Cygwin are a good starting point for running
+Feisty Meow on windows.  If you supplement this set with a few additional
+packages, you can rely on the apt-cyg tool rather than having to run the
+Cygwin setup program (which can be a little fiddly).  Here is a step by step
+process to getting going with apt-cyg:
+
+1) Install Cygwin.
+
+Run the Cygwin setup exe from their website.  Keep all the default packages
+that the installer suggests, but add the following additional ones (the
+easiest way to add additional packages is to switch to the "Full" view for the
+package list and then search for the terms below):
+
+  + lynx
+  + wget
+  + subversion
+
+2) Install apt-cyg.
+
+The apt-cyg program brings the convenience of the Debian and Ubuntu installer
+application (apt) to Cygwin.  This program does require a couple of additional
+setup steps.
+
+This material is drawn from the apt-cyg home page:
+  https://github.com/transcode-open/apt-cyg
+
+Start the cygwin bash prompt (there should be a desktop icon or start menu
+icon for it called something like "cygwin64") and run the following
+commands (omitting the '#' in front):
+
+  # lynx -source rawgit.com/transcode-open/apt-cyg/master/apt-cyg > apt-cyg
+  # install apt-cyg /bin
+
+3) Install the basic set of cygwin apps and libraries.
+
+These tools are not necessarily needed by the Feisty Meow scripts, but they
+are all required to create a sane and useful Unix or Linux environment on
+MS-Windows.  You may find you will want additional packages installed in the
+future, and you can use this same approach.
+
+In the cygwin bash prompt, type this command:
+
+# apt-cyg install bc crypt cygutils emacs email expect gcc-g++ git gitk \
+  gvim inetutils less lynx make mutt ncftp openssh perl procps python \
+  sharutils shutdown subversion time unzip util-linux vim wget xinit \
+  xterm zip
+
+You may have cleverly spotted that we repeated some package names that were
+already installed using the Cygwin setup program in step 1.  That is fine and
+should just fetch the latest versions.
+
+Later, to update the apt-cyg package datebase to the latest available on the
+internet, you can run this command:
+
+# apt-cyg update
+
+We don't currently know of an analog in apt-cyg of the "apt dist-upgrade"
+command, which fetches all updated versions of the installed packages.  We
+think the install command above will upgrade packages when there are new ones
+available.  Also, the cygwin setup tool (bless its heart) may automatically
+update packages if you run it again (you don't need to select anything again,
+but just run through the install process to get the latest).
+
+==> hmmm: verify above claims.
+
+
diff --git a/documentation/feisty_meow_command_reference.txt b/documentation/feisty_meow_command_reference.txt
new file mode 100644 (file)
index 0000000..75371b1
--- /dev/null
@@ -0,0 +1,199 @@
+
+Welcome, adventurous script user.
+
+These are the handiest commands available in the Feisty Meow scripts.
+Note that each script is expected to be self-documenting.  Try running it
+with a "--help" flag (or with no parameters in some cases) to print the
+built-in docs.  At worst, you may have to read the script (that is a
+"documentation fail" on our part; please let us know).
+
+setup and loading commands
+==========================
+
++ read "readme.txt" in the top of the feisty meow codebase, or
++ read it online at: https://feistymeow.org/feisty_meow/readme.txt
+
+generally useful commands
+=========================
+
+  pwd:
+  reports similarly to the good old system "pwd", but translates the $HOME
+  variable into the '~' name.  e.g., if you're fred in /home/fred/turnips
+  and you run 'pwd', then it will print: ~/turnips
+
+  i:
+  take inventory.  prints out some time and relative dimension in space
+  information and shows the current directory's contents.
+
+  dir or l (lower-case L):
+  show the directory with a "summing" feature that calculates the full size
+  consumed by all files in the listing, with somewhat esthetic output.
+
+  ls:
+  the standard ls command (not the summing directory), but with ls colors
+  enabled.
+
+  del or rm:
+  invoke "safedel" feature to remove the files specified.  this archives the
+  deleted files in "$TMP/zz_safedel_keep" and writes a report of the deletion
+  history in "$TMP/zz_safedel_report.txt".
+
+note: currently there is no "empty the trash" function aside from running a
+command such as:
+  # \rm -rf $TMP/zz_safedel*
+the backslash forces bash to run the "rm" tool from the path rather than
+using the feisty meow alias.  a trash flushing feature is planned for the
+somewhat near future.
+
+revision control commands
+=========================
+
+all revision control commands bring up the editor in the EDITOR environment
+variable when creating commit messages.  you need to actually save and quit
+from that editor when you're done writing your commit message.
+
+  here's a guide to writing good commit messages:
+  + https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message
+
+========
+the first suite of commands takes a list of directory names as parameters and
+then operates on those names.
+========
+
+  rgetem:
+  does a simple update (or pull) of the repository paths provided on the
+  command line.  this will only get things from the main origin that the
+  repository is hooked up with, so it is super quick compared to the next
+  couple commands.
+
+  rpuffer:
+  update the repositories provided on the command line by "puffing them out",
+  which means that the upstream repositories that feed the local one will be
+  synched up with it.  this is quite important to do when a git repository has
+  multiple branches, since unmerged changes upstream can really snarl up your
+  checkin.  this is basically a heavyweight version of rgetem.
+
+  rcheckin:
+  checks in the list of repositories passed on the command line.  in git
+  parlance, this adds all modified or untracked files, then commits all
+  changes in the repository, and finally pushes up the changes to the remote
+  online repository.  before doing the checkin, this will do a full "rpuffer"
+  update on the repository to ensure that there are no unmerged upstream
+  changes that could cause problems later.
+
+========
+the next suite of commands uses the REPOSITORY_LIST environment variable as
+the set of revision controlled folders to operate on.  the feisty meow scripts
+automatically add the feisty meow top-level (the apex) to this list to ensure
+that updates are received when available.
+========
+
+  getem:
+  update all repositories in the REPOSITORY_LIST from their upstream remote
+  counterparts.  fast.
+
+  puffer:
+  puffs out the REPOSITORY_LIST items to merge upstream changes.
+
+  checkin:
+  checks in all changes in the REPOSITORY_LIST to their remote repositories.
+
+========
+some assorted other revision control commands:
+========
+
+  feisty_branch:
+  shows the current branch that is checked out.
+
+  this command will move your feisty meow codebase to the development branch:
+  pushd $FEISTY_MEOW_APEX; git checkout dev; popd
+
+  and this command will get you back onto the mainline branch:
+  pushd $FEISTY_MEOW_APEX; git checkout master; popd
+
+=============================
+the site avenger script suite
+=============================
+
+the site avenger tools (inherited from the avbash project) are commands for
+managing web sites.  these scripts offer a lot of power to the developer, and
+of course that comes with great responsibility...
+
+the site avenger scripts are configured by "app" files stored in the "config"
+directory (in $FEISTY_MEOW_SCRIPTS/scripts/site_avenger/config).  the scripts
+seek out a config file named after the application, e.g. they look for
+"winterportlibrary.app" if the application name is "winterportlibrary".
+the basic config file "default.app" is used for any application that is unknown
+in the config directory.  any of the variable definitions provided in
+default.app can be overridden to change how the applications, and associated
+web site and domain, are configured.  see "mapsdemo.app" for an example of
+overriding the domain name for the mapsdemo application.
+
+  revamp_cakelampvm:
+  establishes permissions and ownership to make the virtual machine and its
+  services behave properly.  if something goes wonky, try running this script.
+  this script is also the main vehicle for delivering configuration changes
+  to the cakelampvm.  we are trying really hard to never release a version 2
+  of the vm, since we can patch it as needed using the revamp script.  let's
+  see how well that works out...
+
+  standup:
+  brings up an application or web site from scratch (potentially) by creating
+  an appropriate domain name, writing a basic apache site config file, pulling
+  the application from a git repository, and "powering up" the application via
+  composer.  this is most powerful and effective on php sites, but can also be
+  used for other types of websites.  note that this, and all of the scripts
+  here, are heavily biased for site avenger based development at saco designs.
+  to make these scripts truly your own, write configuration files (see above)
+  that define the proper folders and repository for your applications.
+
+  teardown:
+  takes down a site previously brought up by the standup command.  this just
+  eliminates the domain and the apache site though; the code is left in place
+  to prevent disaster.
+  
+  powerup:
+  similar to standup, but just gets the application source out and powers it
+  up with composer.
+
+(note: automatic database configuration and inflation is in the pipeline for
+the powerup command, but is not ready yet.)
+  
+  avcoreup:
+  updates the avcore portion of a site avenger application.  this command can
+  accept an application name within which to update, or it can auto-pick the
+  applicatin for you from the available checked out ones in ~/apps (the default
+  storage folder for all site avenger style sites).
+
+  siteup:
+  updates the entire checked out repository for a site avenger application.
+  supports app name on the command line, or auto-picks the app.
+
+  sitepush:
+  checks in the source code and other site assets for a site avenger app.
+  supports passing an app name on the command line, or auto-picks the app.
+
+  satis-refresh:
+  updates satis for a site(?).
+
+note: satis-refresh is the one site avenger command that hasn't been "feisty meowicized" yet.
+
+lower level scripts used by site avenger scripts
+------------------------------------------------
+
+  add_domain and remove_domain: (from system script collection)
+  adds (or removes) a DNS domain to the bind9 configuration.  the domain
+  tools, are very sensitive to any edits within the chunks of code they have
+  written.  when it comes time to remove the domain again, the script will eat
+  the number of lines it expects to find after the beginning of the domain
+  definition that it added.  to avoid any issues, if you need to edit the bind
+  config files, be sure to do it way above or way below the auto-generated
+  domain chunks.
+
+  add_apache_site and remove_apache_site: (from system script collection)
+  creates (or removes) an apache compatible site definition.  this will rely
+  on the site's domain previously having been added to the DNS.
+
+note: currently we only implement the http site, but we're planning to add https support via self-signed certificates soon.
+
+
diff --git a/examples/bashisms/bashrc_with_localtmp_code.sh b/examples/bashisms/bashrc_with_localtmp_code.sh
deleted file mode 100644 (file)
index 0df81b5..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# snippet of code to set all the temp folders and genesis2 state dir on a stable local
-# temporary directory.  do not use /localtmp if it will be deleted!  this stuff is
-# expected to persist until the user decides to clean things up.
-
-# use a local temporary directory if possible.
-if [ -d /localtmp ]; then
-  export FAST_LOCAL_STORAGE=/localtmp/$USER
-  export TMP=$FAST_LOCAL_STORAGE/tempo
-  mkdir -p $TMP &>/dev/null
-  chmod -R 700 $FAST_LOCAL_STORAGE
-
-  # plan on putting the state directory onto there.
-  export GENII_USER_DIR=$FAST_LOCAL_STORAGE/state-dir
-fi
-
-# after the above, load feisty meow scripts and they will take advantage of the
-# TMP folder we set above.
-
diff --git a/examples/bashisms/comma_separated_string_to_array.sh b/examples/bashisms/comma_separated_string_to_array.sh
deleted file mode 100644 (file)
index 64c05b3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-#taking a comma (or any char) separated list and turning it into an array:
-
-commaSeparatedList=tony,tiger,detroit,sugar,biscuits
-
-IFS="," read -ra argArray <<< "$commaSeparatedList"
-
-for ((i = 0; i < ${#argArray[@]}; i++)); do
-  echo "arg $(($i + 1)): ${argArray[$i]}"
-done
-
diff --git a/examples/bashisms/dot.bash_logout b/examples/bashisms/dot.bash_logout
deleted file mode 100644 (file)
index ab2ba32..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# runs the nechung oracle program at exit from bash.
-
-sep 79
-$FEISTY_MEOW_GENERATED_STORE/runtime/binaries/nechung 
-echo
-
diff --git a/examples/bashisms/example_getops_parsing.txt b/examples/bashisms/example_getops_parsing.txt
deleted file mode 100644 (file)
index 1f26b80..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-
-# shell option parsing -- old school version only handles single dash options.
-
-while getopts "fr:q:a:h" opt; do
-    case "${opt}" in
-        f) force_query=1; ;;
-        r) row_num="${OPTARG}"; ;;
-        q) queue_name="${OPTARG}"; ;;
-        a) alias_name="${OPTARG}"; ;;
-        h) usage 1>&2;  exit ${EX_OK}; ;;
-        ?) usage 1>&2;  exit ${EX_USAGE}; ;;
-    esac
-done
-
-shift $(($OPTIND - 1))
-
diff --git a/examples/bashisms/fred_techniques.txt b/examples/bashisms/fred_techniques.txt
deleted file mode 100644 (file)
index c841a89..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/bash
-
-##############
-#  Name   : fred_techniques
-#  Author : Chris Koeritz
-#  Rights : Copyright (C) 2010-$now by Author
-##############
-# Copyright (c) 2010-$now By Author.  This script is free software; you can
-# redistribute it and/or modify it under the terms of the simplified BSD
-# license.  See: http://www.opensource.org/licenses/bsd-license.php
-# Please send updates for this code to: fred@gruntose.com -- Thanks, fred.
-##############
-
-# this script is a collection of helpful bash practices that unfortunately
-# sometimes slip my mind when i need them.  it's intended to collect all the
-# good bits so they don't slip away.  feel free to re-use them in your own
-# code as needed.
-
-##############
-
-# clean for loops in bash:
-
-for ((i=0; i < 5; i++)) do
-  echo $i
-done
-
-##############
-
-# removing an array element
-# --> only works on arrays that have no elements containing a space character.
-
-# define a 5 element array.
-arr=(a b c d e)
-
-# remove element 2 (the 'c').
-removepoint=2
-
-# set the array to slices of itself.
-arr=(${arr[*]:0:$removepoint} ${arr[*]:(($removepoint+1))} )
-
-# show the new contents.
-echo ${arr[*]}
-# shows: a b d e
-
-##############
-
-# store to a variable name by derefercing it.
-
-# shows how you can store into a variable when you are given only its name.
-function store_to_named_var()
-{
-  local name="$1"; shift
-  eval ${name}=\(gorbachev "perestroikanator 12000" chernenko\)
-}
-
-declare -a ted=(petunia "butter cup" smorgasbord)
-echo ted is ${ted[@]}
-store_to_named_var ted
-echo ted is now ${ted[@]}
-
-##############
-
diff --git a/examples/bashisms/it_is_possible_to_cleanly_copy_array_elems.txt b/examples/bashisms/it_is_possible_to_cleanly_copy_array_elems.txt
deleted file mode 100644 (file)
index 8be73c9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-# when the array elements have spaces, it is still possible to get them back right.
-
-
-a=("ted row" "boon" "moopy dongle")
-echo ${#a[@]}
-# 3
-borg=( "${a[@]}" )
-echo ${#borg[@]}
-# 3
-
-# normally the setting of borg would not preserve the elements with spaces in them as separate.
-# but by using the @ to get all the array members and the spaces around the reference, you get
-# the list back properly.
-
diff --git a/examples/bashisms/qs_handy_unix_examples.sh b/examples/bashisms/qs_handy_unix_examples.sh
deleted file mode 100644 (file)
index 5293f3b..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-#!/bin/bash
-
-#
-# these great examples of handy unix tidbits were donated by "q. black".
-#
-
-# list a directory tree
-ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
-
-# list directory sizes (biggest first)
-du -h $(du -s * |sort -nr|awk '{print $2}')
-
-# this will sort a date field of the form: DD-MON-YYYY HH:MM:SS
-sort +0.7 -1 +0.3M -0.6 +0 -0.2 +1
-
-# this will sort a date field of the form: MON DD HH:MM:SS YYYY
-sort +3 -4 +0M +1n
-
-# this will sort a date field of the form: MON DD HH:MM:SS
-sort +0M +1n
-# this will sort a date field of the form: Date: Tue Feb  3 09:17:58 EST 2004
-sort +6 -7 +2M +3n +4
-
-# display all lines from a certain line onward
-start_line=132
-|awk "{if (NR >= ${start_line}){print \$0}}"
-
-# display all lines after a token
-sed '1,/CUT HERE/d'
-
-# print the first and last lines
-sed -n '1,1p;$,$p'
-
-# signal bash about a window size change
-kill -winch $$
-
-# show the date 1 year, 2 months and 3 days ago
-date -v -1y -v -2m -v -3d
-
-# set the date back 1 year
-sudo date $(date -v -1y +%Y%m%d%H%M)
-
-# output the standard date format for setting the time
-# get the date
-date -u +%Y%m%d%H%M.%S
-# set the date
-date -u (cut and paste from above)
-
-# convert one date format to another (output is in the current time zone)
-old_date="Aug 27 15:24:33 2005 GMT"
-new_date=$(date -j -f "%b %e %T %Y %Z" "${old_date}" +%D)
-echo ${new_date}
-# returns "08/27/05"
-
-# output the modification time of a file in different format
-file=
-date -j -f "%b %e %T %Y" "$(ls -lT ${file} |awk '{print $6,$7,$8,$9}')"
-
-# output the number of days until a certain date
-target_date="Sep  2 15:20:20 2005 GMT"
-target_seconds=$(date -j -f "%b %e %T %Y" +%s "${target_date}" 2>/dev/null)
-diff_seconds=$(expr ${target_seconds} - $(date +%s))
-diff_days=$(expr ${diff_seconds} / 86400)
-echo "${diff_days} day(s)"
-
-# these commands can be used to fill in missing times in a "uniq -c" count
-# of times.
-# output 24 hours in one minute increments
-for h in $(jot -w %02d - 0 23 1); do
-    for m in $(jot -w %02d - 0 59 1); do
-       echo "   0 ${h}:${m}"
-    done
-done
-# sort them together, and remove any 0 counts if an count already exists
-sort +1 +0rn out1 out2 |uniq -f 1
-
-# output with w3m to get basic html word wrap
-w3m -T "text/html" -dump -cols 72 <<EOF
-    <p>
-    This test verifies basic networking and that the ${product_short_name}
-    can reach it's default gateway.
-EOF
-
-# another way to format text for output
-fmt 72 <<EOF
-This test verifies basic networking and that the ${product_short_name}
-can reach it's default gateway.
-EOF
-
-# smtpcrypt "printf"
-{
-char *jkwbuf = NULL;
-asprintf(&jkwbuf, "JKW: msg->used = %ld\n", msg->used);
-BIO_write(sc->log, jkwbuf, strlen(jkwbuf)+1);
-free(jkwbuf);
-}
-
-# rolling diff of a list of files (diff a & b, then b & c,...)
-last=
-for i in $(ls -1rt); do
-    if [ ! -z "${last}" ]; then
-       diff -u ${last} ${i}
-    fi
-    last=${i}
-done
-
-# clearing and restoring chflags
-file=
-old_chflags=$(ls -lo ${file}|awk '{print $5}')
-chflags 0 ${file}
-# do whatever
-if [ ."${old_chflags}" != ."-" ]; then
-    chflags ${old_chflags} ${file}
-fi
-
-# way to do standard edits to files
-file=
-{
-    # append line(s) after a line, "i" to insert before
-    echo '/www_recovery/a'
-    echo 'mithril ALL = (root) NOPASSWD: /usr/local/libexec/destroyer'
-    echo '.'
-    # modify a line
-    echo 'g/^xntpd_program=/s,^xntpd_program=.*$,xntpd_program="ntpd",'
-    # delete a line
-    echo 'g/^controls key secret =/d'
-    echo 'x!'
-} | ex - ${file}
-
-# how to search for errors in the last 24 hours
-# note that this command does not work quite right.  The sort is off early
-# in the year because the dates do not have the year.
-# Also sed never sees the /CUT HERE/ when it is the first line.
-(echo "$(date -v-24H "+%b %e %H:%M:%S") --CUT HERE--"; \
-    zgrep -h "cookie" /var/log/messages*)|sort +0M| \
-    sed '1,/CUT HERE/d'
-# This version fixes those problems.  It adds the file year to the date
-# and puts a marker at the start of the list.
-(echo "$(date -j -f "%s" 0 "+%Y %b %e %H:%M:%S") --ALWAYS FIRST--"; \
-    echo "$(date -v-24H "+%Y %b %e %H:%M:%S") --CUT HERE--"; \
-    for i in /var/log/messages*; do
-       year=$(ls -lT ${i}|awk '{print $9}')
-       zgrep -h "cookie" ${i}|while read line; do
-           echo "${year} ${line}"
-       done
-    done)|sort +0n +1M| sed '1,/CUT HERE/d'
-
-# process a list of quoted values
-{
-    # It tends to be easiest to use a 'here-document' to feed in the list.
-    # I prefer to have the list at the start instead of the end
-    cat <<EOF
-       'general' 'network node0' 'private address'
-       'general' 'options node2' 'kern securelevel'
-EOF
-}| while read line; do
-    eval set -- ${line}
-    config=$1; shift
-    section=$1; shift
-    key=$1; shift
-
-    echo "confutil value \"${config}\" \"${section}\" \"${key}\""
-done
-
-# Method to read lines with a "for" loop, without spawning a subshell
-NEWLINE='
-'
-OIFS="${IFS}"
-IFS="${NEWLINE}"
-for line in $(cat /etc/passwd | sort -r); do
-    IFS="${OIFS}"
-
-    # do whatever you want here
-    echo "line = ${line}"
-
-    IFS="${NEWLINE}"
-done
-IFS="${OIFS}"
-
-# generate a histogram of characters in a file
-cat file|
-    awk '{for (i=1; i <= length($0); i++) {printf("%s\n",substr($0,i,1))}}'|
-    sort|uniq -c
-
-# show line lengths for a file
-cat file| awk '{print length($0)}'| sort -n
-
-
-
-
-# get the modification time of a directory or file and then reset the time.
-target=/usr/local/etc/pkdb
-save_date=$(ls -ldT ${target}|awk '{print $6,$7,$8,$9}')
-save_date=$(date -j -f "%b %e %T %Y" "${save_date}" +"%Y%m%d%H%M.%S")
-# later
-touch -t ${save_date} ${target}
-
-
-# detect NULL bytes in a file
-file=
-hexdump -e '"%_u\n"' ${file}|grep -q '^nul$'
-if [ $? -eq 0 ]; then
-else
-fi
-
-
-# calculate average
-cd /tmp
-uudecode
-begin 644 bc.average
-M<V-A;&4],PIT;W1A;#TP"F-O=6YT/3`*=VAI;&4@*#$I('L*("`@(&YU;2`]
-M(')E860H*0H@("`@:68@*&YU;2`]/2`P*2!B<F5A:SL*("`@(&-O=6YT*RL*
-M("`@('1O=&%L("L](&YU;0I]"B)T;W1A;"`]("([('1O=&%L"B)C;W5N="`]
-K("([(&-O=6YT"B)A=F5R86=E(#T@(CL@=&]T86P@+R!C;W5N=`IQ=6ET"@``
-`
-end
-(cat data; echo "0") |bc -q bc.average
-
-
diff --git a/examples/bashisms/script_location.sh b/examples/bashisms/script_location.sh
deleted file mode 100644 (file)
index 7fa942a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-# find out the location where this script is running from.  this will not
-# work properly in a bash script that is included via 'source' or '.'.
-# the first letter of each command is escaped to eliminate the danger of
-# personal aliases or functions disrupting the results.
-ORIGINATING_FOLDER="$( \cd "$(\dirname "$0")" && /bin/pwd )"
-
-# another slightly tighter version:
-export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
-
diff --git a/examples/building/vs_var.bat b/examples/building/vs_var.bat
deleted file mode 100644 (file)
index de9ecc1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-"c:/Program Files (x86)/Microsoft Visual Studio 10.0/Common7/Tools/vsvars32.bat"
diff --git a/examples/cpp_grammar_code/CxxLexer.cpp b/examples/cpp_grammar_code/CxxLexer.cpp
deleted file mode 100644 (file)
index 4914908..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-//       Title:                        C++ Grammar Lexer support compilation unit.
-//
-//       File Name:            CxxLexer.cpp
-//
-//       Author:                       E.D.Willink
-//END
-//
-#include <CxxLexer.cxx>
diff --git a/examples/cpp_grammar_code/CxxLexer.l b/examples/cpp_grammar_code/CxxLexer.l
deleted file mode 100644 (file)
index 926719c..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *       Title:                        Miniature lexer for C++ parser.
- *
- *       File Name:            CxxLexer.l
- *
- *       Author:                       E.D.Willink
- *
- *     This is a complete lexer for C++, intended for use with CxxParser.y.
- *     All actions are done by macros, so that there is some chance that customisation
- *     can be performed within the bounds of the CxxLexing.hxx and CxxLexing.cxx
- *     include files.
- *END
- */
-%{
-#include <CxxLexing.hxx>
-%}
-%a 5000
-%e 1500
-%n 1000
-%o 10000
-%p 10000
-ws                                                             [ \f\v\t]
-
-digit                                                  [0-9]
-hex                                                            [0-9A-Fa-f]
-letter                                                 [A-Z_a-z]
-simple_escape_sequence                 (\\\'|\\\"|\\\?|\\\\|\\a|\\b|\\f|\\n|\\r|\\t|\\v)
-octal_escape_sequence                  (\\[0-7]|\\[0-7][0-7]|\\[0-7][0-7][0-7])
-hexadecimal_escape_sequence            (\\x{hex}+)
-escape_sequence                                        ({simple_escape_sequence}|{octal_escape_sequence}|{hexadecimal_escape_sequence})
-universal_character_name               (\\u{hex}{hex}{hex}{hex}|\\U{hex}{hex}{hex}{hex}{hex}{hex}{hex}{hex})
-non_digit                                              ({letter}|{universal_character_name})
-identifier                                             ({non_digit}({non_digit}|{digit})*)
-
-character_lit                                  (L?\'([^\'\\\n]|\\.)*)
-character_literal                              ({character_lit}\')
-
-string_lit                                             (L?\"([^\"\\\n]|\\.)*)
-string_literal                                 ({string_lit}\")
-
-pp_number                                              (\.?{digit}({digit}|{non_digit}|[eE][-+]|\.)*)
-%%
-^.*\n                                                  { LEX_SAVE_LINE(yytext, yyleng); REJECT; }
-^{ws}*"#".*                                            { /* Throw away preprocessor lines - hopefully only #line and equivalent. */ }
-
-{character_lit}\'                              { LEX_CHARACTER_TOKEN(yytext, yyleng-1); };
-{character_lit}\\                              { ERRMSG("End of line assumed to terminate character with trailing escape.");
-                                                                 LEX_CHARACTER_TOKEN(yytext, yyleng-1); };
-{character_lit}                                        { ERRMSG("End of line assumed to terminate character.");
-                                                                 LEX_CHARACTER_TOKEN(yytext, yyleng); };
-
-{string_lit}\"                                 { LEX_STRING_TOKEN(yytext, yyleng-1); };
-{string_lit}\\                                 { ERRMSG("End of line assumed to terminate string with trailing escape.");
-                                                                 LEX_STRING_TOKEN(yytext, yyleng-1); };
-{string_lit}                                   { ERRMSG("End of line assumed to terminate string.");
-                                                                 LEX_STRING_TOKEN(yytext, yyleng); };
-
-"asm"                                                  { LEX_STATIC_TOKEN(ASM); }
-"auto"                                                 { LEX_STATIC_TOKEN(AUTO); }
-"bool"                                                 { LEX_C_STATIC_TOKEN(BOOL); }
-"break"                                                        { LEX_STATIC_TOKEN(BREAK); }
-"case"                                                 { LEX_STATIC_TOKEN(CASE); }
-"catch"                                                        { LEX_C_STATIC_TOKEN(CATCH); }
-"char"                                                 { LEX_STATIC_TOKEN(CHAR); }
-"class"                                                        { LEX_C_STATIC_TOKEN(CLASS); }
-"const"                                                        { LEX_STATIC_TOKEN(CONST); }
-"const_cast"                                   { LEX_C_STATIC_TOKEN(CONST_CAST); }
-"continue"                                             { LEX_STATIC_TOKEN(CONTINUE); }
-"default"                                              { LEX_STATIC_TOKEN(DEFAULT); }
-"delete"                                               { LEX_C_STATIC_TOKEN(DELETE); }
-"do"                                                   { LEX_STATIC_TOKEN(DO); }
-"double"                                               { LEX_STATIC_TOKEN(DOUBLE); }
-"dynamic_cast"                                 { LEX_C_STATIC_TOKEN(DYNAMIC_CAST); }
-"else"                                                 { LEX_STATIC_TOKEN(ELSE); }
-"enum"                                                 { LEX_STATIC_TOKEN(ENUM); }
-"explicit"                                             { LEX_C_STATIC_TOKEN(EXPLICIT); }
-"export"                                               { LEX_C_STATIC_TOKEN(EXPORT); }
-"extern"                                               { LEX_STATIC_TOKEN(EXTERN); }
-"false"                                                        { LEX_C_STATIC_TOKEN(FALSE); }
-"float"                                                        { LEX_STATIC_TOKEN(FLOAT); }
-"for"                                                  { LEX_STATIC_TOKEN(FOR); }
-"friend"                                               { LEX_STATIC_TOKEN(FRIEND); }
-"goto"                                                 { LEX_STATIC_TOKEN(GOTO); }
-"if"                                                   { LEX_STATIC_TOKEN(IF); }
-"inline"                                               { LEX_C_STATIC_TOKEN(INLINE); }
-"int"                                                  { LEX_STATIC_TOKEN(INT); }
-"long"                                                 { LEX_STATIC_TOKEN(LONG); }
-"mutable"                                              { LEX_C_STATIC_TOKEN(MUTABLE); }
-"namespace"                                            { LEX_C_STATIC_TOKEN(NAMESPACE); }
-"new"                                                  { LEX_C_STATIC_TOKEN(NEW); }
-"operator"                                             { LEX_C_STATIC_TOKEN(OPERATOR); }
-"private"                                              { LEX_C_STATIC_TOKEN(PRIVATE); }
-"protected"                                            { LEX_C_STATIC_TOKEN(PROTECTED); }
-"public"                                               { LEX_C_STATIC_TOKEN(PUBLIC); }
-"register"                                             { LEX_STATIC_TOKEN(REGISTER); }
-"reinterpret_cast"                             { LEX_C_STATIC_TOKEN(REINTERPRET_CAST); }
-"return"                                               { LEX_STATIC_TOKEN(RETURN); }
-"short"                                                        { LEX_STATIC_TOKEN(SHORT); }
-"signed"                                               { LEX_C_STATIC_TOKEN(SIGNED); }
-"sizeof"                                               { LEX_STATIC_TOKEN(SIZEOF); }
-"static"                                               { LEX_STATIC_TOKEN(STATIC); }
-"static_cast"                                  { LEX_C_STATIC_TOKEN(STATIC_CAST); }
-"struct"                                               { LEX_STATIC_TOKEN(STRUCT); }
-"switch"                                               { LEX_STATIC_TOKEN(SWITCH); }
-"template"                                             { LEX_C_STATIC_TOKEN(TEMPLATE); }
-"this"                                                 { LEX_C_STATIC_TOKEN(THIS); }
-"throw"                                                        { LEX_C_STATIC_TOKEN(THROW); }
-"true"                                                 { LEX_C_STATIC_TOKEN(TRUE); }
-"try"                                                  { LEX_C_STATIC_TOKEN(TRY); }
-"typedef"                                              { LEX_STATIC_TOKEN(TYPEDEF); }
-"typeid"                                               { LEX_C_STATIC_TOKEN(TYPEID); }
-"typename"                                             { LEX_C_STATIC_TOKEN(TYPENAME); }
-"union"                                                        { LEX_STATIC_TOKEN(UNION); }
-"unsigned"                                             { LEX_STATIC_TOKEN(UNSIGNED); }
-"using"                                                        { LEX_C_STATIC_TOKEN(USING); }
-"virtual"                                              { LEX_STATIC_TOKEN(VIRTUAL); }
-"void"                                                 { LEX_STATIC_TOKEN(VOID); }
-"volatile"                                             { LEX_STATIC_TOKEN(VOLATILE); }
-"wchar_t"                                              { LEX_C_STATIC_TOKEN(WCHAR_T); }
-"while"                                                        { LEX_STATIC_TOKEN(WHILE); }
-
-"::"                                                   { LEX_C_STATIC_TOKEN(SCOPE); }
-"..."                                                  { LEX_STATIC_TOKEN(ELLIPSIS); }
-"<<"                                                   { LEX_STATIC_TOKEN(SHL); }
-">>"                                                   { LEX_STATIC_TOKEN(SHR); }
-"=="                                                   { LEX_STATIC_TOKEN(EQ); }
-"!="                                                   { LEX_STATIC_TOKEN(NE); }
-"<="                                                   { LEX_STATIC_TOKEN(LE); }
-">="                                                   { LEX_STATIC_TOKEN(GE); }
-"&&"                                                   { LEX_STATIC_TOKEN(LOG_AND); }
-"||"                                                   { LEX_STATIC_TOKEN(LOG_OR); }
-"++"                                                   { LEX_STATIC_TOKEN(INC); }
-"--"                                                   { LEX_STATIC_TOKEN(DEC); }
-"->*"                                                  { LEX_STATIC_TOKEN(ARROW_STAR); }
-"->"                                                   { LEX_STATIC_TOKEN(ARROW); }
-".*"                                                   { LEX_STATIC_TOKEN(DOT_STAR); }
-"+="                                                   { LEX_STATIC_TOKEN(ASS_ADD); }
-"-="                                                   { LEX_STATIC_TOKEN(ASS_SUB); }
-"*="                                                   { LEX_STATIC_TOKEN(ASS_MUL); }
-"/="                                                   { LEX_STATIC_TOKEN(ASS_DIV); }
-"%="                                                   { LEX_STATIC_TOKEN(ASS_MOD); }
-"^="                                                   { LEX_STATIC_TOKEN(ASS_XOR); }
-"&="                                                   { LEX_STATIC_TOKEN(ASS_AND); }
-"|="                                                   { LEX_STATIC_TOKEN(ASS_OR); }
-">>="                                                  { LEX_STATIC_TOKEN(ASS_SHR); }
-"<<="                                                  { LEX_STATIC_TOKEN(ASS_SHL); }
-
-{pp_number}                                            { LEX_NUMBER_TOKEN(yytext, yyleng); }
-
-{identifier}                                   { LEX_IDENTIFIER_TOKEN(yytext, yyleng); }
-
-{escape_sequence}                              |
-{universal_character_name}             { LEX_ESCAPED_TOKEN(yytext, yyleng); }
-
-\n                                                             |
-{ws}+                                                  { /* Throw away whitespace */ }
-.                                                              { LEX_ASCII_TOKEN(yytext[0]); }
-
-%%
-#include <CxxLexing.cxx>
diff --git a/examples/cpp_grammar_code/CxxLexing.cxx b/examples/cpp_grammar_code/CxxLexing.cxx
deleted file mode 100644 (file)
index d57b0f1..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifdef FLEX_PP_CLASS
-FLEX_PP_CLASS theLexer;
-#define LEX_DOT theLexer .
-#else
-#define LEX_DOT
-#endif
-
-bool c_keywords = false;
-bool echo_line_numbers = false;
-bool echo_line_text = false;
-size_t line_number = 0;
-
-#ifdef NEEDS_YYWRAP
-int yywrap() { return 1; }
-#endif
-
-CxxToken *yylex_token()
-{
-       if (!LEX_DOT yylex())
-               return 0;
-       return yyToken;
-}
-
-//
-//     Configure the lexer to reflect successful parsing of a character value, assigning it to yylval.
-//
-//     The source someText[aLength] should correspond to the parsed text including any L or ' prefix
-//     but excluding any ' suffix. In this way the return can indicate whether a wide character has
-//     been detected and the routine can accommodate a variety of erroneous terminations.
-//
-CxxToken *make_character(const char *someText, size_t aLength)
-{
-       bool isWide = false;
-       if (someText && aLength)
-       {
-               if (*someText == 'L')
-               {
-                       isWide = true;
-                       someText++;
-                       aLength--;
-               }
-               if (!aLength || (*someText != '\''))
-                       ERRMSG("BUG - bad start of character literal.");
-               if (aLength)
-               {
-                       someText++;
-                       aLength--;
-               }
-       }
-       if (isWide)
-               return make_wide_character(someText, aLength);
-       else
-               return make_narrow_character(someText, aLength);
-}
-
-CxxToken *make_identifier(const char *someText, size_t aLength)
-{
-       return new CxxNaffToken(PARSE_TOKEN(Identifier), someText, aLength);
-}
-
-//
-//     Buffer the incoming line, before any characters are analysed.
-//
-void make_line(const char *yyText, size_t yyLeng)
-{
-       if (echo_line_text)
-               cout << tokenMarkDepth << ": "  << line_number << ": " << yyText << flush; 
-       else if (echo_line_numbers)
-               cout << line_number << endl; 
-       line_number++ ; 
-}
-
-CxxToken *make_literal_character(const char *someText, size_t aLength)
-{
-       return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
-}
-
-CxxToken *make_narrow_character(const char *someText, size_t aLength)
-{
-       return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
-}
-
-CxxToken *make_narrow_string(const char *someText, size_t aLength)
-{
-       return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
-}
-
-CxxToken *make_number(const char *someText, size_t aLength)
-{
-       return new CxxNaffToken(PARSE_TOKEN(IntegerLiteral), someText, aLength);
-}
-
-//
-//     Configure the lexer to reflect successful parsing of a categorised string.
-//
-//     The source someText[aLength] should correspond to the parsed text including any
-//     L or " prefix but excluding any " suffix. In this way the return can indicate whether a wide
-//     character has been detected and the routine can accommodate a variety of erroneous terminations.
-//
-CxxToken *make_string(const char *someText, size_t aLength)
-{
-       bool isWide = false;
-       if (someText && aLength)
-       {
-               if (*someText == 'L')
-               {
-                       isWide = true;
-                       someText++;
-                       aLength--;
-               }
-               if (!aLength || (*someText != '"'))
-                       ERRMSG("BUG - bad start of string literal.");
-               if (aLength)
-               {
-                       someText++;
-                       aLength--;
-               }
-       }
-       if (isWide)
-               return make_wide_string(someText, aLength);
-       else
-               return make_narrow_string(someText, aLength);
-}
-
-//
-//     Return the appropriate 1 of 256 flyweight tokens for the ASCII characters.
-//
-CxxToken *make_token(size_t tokenValue)
-{
-       static CxxToken *asciiTokens[256];
-       if (tokenValue >= (sizeof(asciiTokens)/sizeof(asciiTokens[0])))
-       {
-               ERRMSG("Cannot make_token for " << tokenValue);
-               return 0;
-       }
-       CxxToken **p = &asciiTokens[tokenValue];
-       CxxToken *theToken = *p;
-       if (!theToken)
-               *p = theToken = new CxxToken(tokenValue);
-       return theToken;
-}
-
-CxxToken *make_wide_character(const char *someText, size_t aLength)
-{
-       return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
-}
-
-CxxToken *make_wide_string(const char *someText, size_t aLength)
-{
-       return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
-}
-
diff --git a/examples/cpp_grammar_code/CxxLexing.hxx b/examples/cpp_grammar_code/CxxLexing.hxx
deleted file mode 100644 (file)
index 03c122d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <CxxToken.hxx>
-
-#include <CxxParser.hxx>
-
-static CxxToken *yyToken;
-static CxxToken *make_character(const char *someText, size_t aLength);
-static CxxToken *make_string(const char *someText, size_t aLength);
-static CxxToken *make_identifier(const char *someText, size_t aLength);
-static void make_line(const char *yyText, size_t yyLeng);
-static CxxToken *make_literal_character(const char *someText, size_t aLength);
-static CxxToken *make_narrow_character(const char *someText, size_t aLength);
-static CxxToken *make_narrow_string(const char *someText, size_t aLength);
-static CxxToken *make_number(const char *someText, size_t aLength);
-static CxxToken *make_token(size_t aCxxToken);
-static CxxToken *make_wide_character(const char *someText, size_t aLength);
-static CxxToken *make_wide_string(const char *someText, size_t aLength);
-
-#define LEX_SAVE_LINE(yyText, yyLeng) make_line(yyText, yyLeng);
-#define LEX_ASCII_TOKEN(a) yyToken = make_token(a); return true;
-#define LEX_STATIC_TOKEN(a) static CxxToken theToken(PARSE_TOKEN(a)); yyToken = &theToken; return true;
-#define LEX_C_STATIC_TOKEN(a) \
-       if (c_keywords) { LEX_IDENTIFIER_TOKEN(yytext, yyleng) } \
-       else { LEX_STATIC_TOKEN(a) } return true;
-#define LEX_ESCAPED_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral)
-//     yyToken = make_literal_character(yytext, yyleng); return true;
-#define LEX_CHARACTER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral)
-//     yyToken = make_character(yyText, yyLeng); return true;
-#define LEX_STRING_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(StringLiteral)
-//     yyToken = make_string(yyText, yyLeng); return true;
-#define LEX_IDENTIFIER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(Identifier)
-//     yyToken = make_identifier(yyText, yyLeng); return true;
-#define LEX_NUMBER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(IntegerLiteral)
-//     yyToken = make_number(yyText, yyLeng); return true;
diff --git a/examples/cpp_grammar_code/CxxParser.cpp b/examples/cpp_grammar_code/CxxParser.cpp
deleted file mode 100644 (file)
index 43f94c4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-//
-//       Title:                        C++ Grammar Parser support compilation unit.
-//
-//       File Name:            CxxParser.cpp
-//
-//       Author:                       E.D.Willink
-//END
-//
-#include <CxxParser.cxx>
-
diff --git a/examples/cpp_grammar_code/CxxParser.y b/examples/cpp_grammar_code/CxxParser.y
deleted file mode 100644 (file)
index 44cb9d8..0000000
+++ /dev/null
@@ -1,1162 +0,0 @@
-/* This is a yacc-able parser for the entire ISO C++ grammar with no unresolved conflicts. */
-/* The parse is SYNTACTICALLY consistent and requires no template or type name assistance.
- * The grammar in the C++ standard notes that its grammar is a superset of the true
- * grammar requiring semantic constraints to resolve ambiguities. This grammar is a really big
- * superset unifying expressions and declarations, eliminating the type/non-type distinction,
- * and iterating to find a consistent solution to the template/arith,metoic < ambiguity.
- * As a result the grammar is much simpler, but requires the missing semantic constraints to be
- * performed in a subsequent semantic pass, which is of course where they belong. This grammar will
- * support conversion of C++ tokens into an Abstract Syntax Tree. A lot of further work is required to
- * make that tree useful.
- *
- * The principles behind this grammar are described in my thesis on Meta-Compilation for C++, which
- * may be found via http://www.computing.surrey.ac.uk/research/dsrg/fog/FogThesis.html.
- *
- *  Author:         E.D.Willink             Ed.Willink@rrl.co.uk
- *  Date:           19-Jun-2001
- */
-/*StartTester*/
-%{
-#include <CxxParsing.hxx>
-%}
-/*EndTester*/
-/*
- * The lexer (and/or a preprocessor) is expected to identify the following
- *
- *  Punctuation:
- */
-%type <keyword> '+' '-' '*' '/' '%' '^' '&' '|' '~' '!' '<'  '>' '=' ':' '[' ']' '{' '}' '(' ')'
-%type <keyword> '?' '.' '\'' '\"' '\\' '@' '$' ';' ','
-/*
- *  Punctuation sequences
- */
-%term <keyword> ARROW ARROW_STAR DEC EQ GE INC LE LOG_AND LOG_OR NE SHL SHR
-%term <keyword> ASS_ADD ASS_AND ASS_DIV ASS_MOD ASS_MUL ASS_OR ASS_SHL ASS_SHR ASS_SUB ASS_XOR
-%term <keyword> DOT_STAR ELLIPSIS SCOPE
-/*
- *  Reserved words
- */
-%term <access_specifier> PRIVATE PROTECTED PUBLIC
-%term <built_in_id> BOOL CHAR DOUBLE FLOAT INT LONG SHORT SIGNED UNSIGNED VOID WCHAR_T
-%term <class_key> CLASS ENUM NAMESPACE STRUCT TYPENAME UNION
-%term <cv_qualifiers> CONST VOLATILE
-%term <decl_specifier_id> AUTO EXPLICIT EXPORT EXTERN FRIEND INLINE MUTABLE REGISTER STATIC TEMPLATE TYPEDEF USING VIRTUAL
-%term <keyword> ASM BREAK CASE CATCH CONST_CAST CONTINUE DEFAULT DELETE DO DYNAMIC_CAST
-%term <keyword> ELSE FALSE FOR GOTO IF NEW OPERATOR REINTERPRET_CAST RETURN
-%term <keyword> SIZEOF STATIC_CAST SWITCH THIS THROW TRUE TRY TYPEID WHILE
-/*
- *  Parametric values.
- */
-%term <character_literal> CharacterLiteral
-%term <floating_literal> FloatingLiteral
-%term <identifier> Identifier
-%term <integer_literal> IntegerLiteral
-%term <number_literal> NumberLiteral
-%term <string_literal> StringLiteral
-/*
- *  The lexer need not treat '0' as distinct from IntegerLiteral in the hope that pure-specifier can
- *  be distinguished, It isn't. Semantic rescue from = constant-expression is necessary.
- *
- *  The lexer is not required to distinguish template or type names, although a slight simplification to the
- *  grammar and elaboration of the action rules could make good use of template name information.
- *
- *  In return for not needing to use semantic information, the lexer must support back-tracking, which
- *  is easily achieved by a simple linear buffer, a reference implementation of which may be found in the
- *  accompanying CxxParsing.cxx. Back-tracking is used to support:
- *
- *  Binary search for a consistent parse of the template/arithmetic ambiguity.
- *      start_search() initialises the search
- *      advance_search() iterates the search
- *      end_search() cleans up after a search
- *      template_test() maintains context during a search
- *
- *  Lookahead to resolve the inheritance/anonymous bit-field similarity
- *      mark() saves the starting context
- *      unmark() pops it
- *      rewind_colon() restores the context and forces the missing :
- *
- *  Lookahead to resolve type 1 function parameter ambiguities
- *      mark_type1() potentially marks the starting position
- *      mark() marks the pre { position
- *      remark() rewinds to the starting position
- *      unmark() pops the starting position
- *
- *  Note that lookaheads may nest. 
- */
-
-/*
- *  The parsing philosophy is unusual. The major ambiguities are resolved by creating a unified superset
- *  grammar rather than non-overlapping subgrammars. Thus the grammar for parameter-declaration covers an
- *  assignment-expression. Minor ambiguities whose resolution by supersetting would create more
- *  ambiguities are resolved the normal way with partitioned subgrammars.
- *  This eliminates the traditional expression/declaration and constructor/parenthesised declarator
- *  ambiguities at the syntactic level. A subsequent semantic level has to sort the problems out.
- *  The generality introduces four bogus ambiguities and defers the cast ambiguity for resolution
- *  once semantic information is available.
- *
- *  The C++ grammar comprises 561 rules and uses 897 states in yacc, with 0 unresolved conflicts.
- *  23 conflicts from 10 ambiguities are resolved by 8 %prec's, so that yacc and bison report 0 conflicts.
- *
- *  The ambiguities are:
- *  1) dangling else resolved to inner-most if
- *      1 conflict in 1 state on else
- *  2) < as start-template or less-than
- *      1 conflict in 1 states on <
- *  3) a :: b :: c resolved to favour a::b::c rather than a::b ::c or a ::b::c
- *      1 conflicts in 1 state for ::
- *  4) pointer operators maximised at end of conversion id/new in preference to binary operators
- *      2 conflicts in 4 states on * and &
- *  5a) (a)@b resolved to favour binary a@b rather than cast unary (a)(@b)
- *  5b) (a)(b) resolved to favour cast rather than call
- *      8 conflicts in 1 state for the 8 prefix operators: 6 unaries and ( and [.
- *  6) enum name { resolved to enum-specifier rather than function
- *      1 conflict in 1 state on {
- *  7) class name { resolved to class-specifier rather than function
- *      1 conflict in 1 state on {
- *  8) extern "C" resolved to linkage-specification rather than declaration
- *      1 conflict in 1 state on StringLiteral
- *  9) class X : forced to go through base-clause look-ahead
- *      1 conflict in 1 state on :
- *  10) id : forced to label_statement rather than constructor_head
- *      0 conflicts - but causes a double state for 2)
- *  of which
- *      1 is a fundamental C conflict - always correctly resolved
- *          can be removed - see the Java spec
- *      2, 3, 4 are fundamental C++ conflicts
- *          2 always consistently resolved by iteration
- *          3 always correctly resolved
- *          4 always correctly resolved
- *      5 is a result of not using type information - deferred for semantic repair
- *      6,7 are caused by parsing over-generous superset - always correctly resolved
- *      8 is caused by parsing over-generous superset - always correctly resolved
- *          can be removed at the expense of 7 rules and 5 states.
- *      9 is a look-ahead trick - always correctly resolved
- *          could be removed by marking one token sooner
- *      10 is caused by parsing over-generous superset - always correctly resolved
- *
- *  The hard problem of distinguishing
- *      class A { class B : C, D, E {           -- A::B privately inherits C, D and E
- *      class A { class B : C, D, E ;           -- C is width of anon bit-field
- *  is resolved by using a lookahead that assumes inheritance and rewinds for the bit-field.
- *
- *  The potential shift-reduce conflict on > is resolved by flattening part of the expression grammar
- *  to know when the next > is template end or arithmetic >.
- *
- *  The grammar is SYNTACTICALLY context-free with respect to type. No semantic assistance is required
- *  during syntactic analysis. However the cast ambiguity is deferred and must be recovered
- *  after syntactic analysis of a statement has completed. 
- *
- *  The grammar is SYNTACTICALLY context-free with respect to template-names. This is achieved by
- *  organising a binary search over all possible template/arithmetic ambiguities with respect to
- *  the enclosing statement. This is potentially exponentially inefficient but well-behaved in practice.
- *  Approximately 1% of statements trigger a search and approximately 1% of those are misparsed,
- *  requiring the semantic analysis to check and correct once template information is available.
- *  1.5 parse attempts are required on average per ambiguous statement.
- *
- *  The grammar supports type I function declarations at severe impediment to efficiency. A lookahead
- *  has to be performed after almost every non-statement close parenthesis. A one-line plus corollary
- *  change to postfix_expression is commented and strongly recommended to make this grammar as
- *  efficient as the rather large number of reduction levels permits.
- *
- *  Error recovery occurs mostly at the statement/declaration level. Recovery also occurs at
- *  the list-element level where this poses no hazard to statement/declaration level recovery. 
- *  Note that since error propagation interacts with the lookaheads for template iteration or
- *  type 1 function arguments, introduction of finer grained error recovery may repair a false
- *  parse and so cause a misparse.
- *
- *  The following syntactic analysis errors occur, but are correctable semantically:
- *  (cast)unary-op expr         is parsed as (parenthesised)binary-op expr
- *      The semantic test should look for a binary/call with a (type) as its left child.
- *  (parenthesised)(arguments)  is parsed as (cast)(parenthesised)
- *      The semantic test should look for a cast with a non-type as its left child.
- *  template < and arithmetic < may be cross-parsed (unless semnatic help is provided)
- *      approximately 0.01% are misparsed, and must be sorted out - not easy.
- *
- *  The syntactic analysis defers the following ambiguities for semantic resolution:
- *  declaration/expression is parsed as a unified concept
- *      Use type and context to complete the parse.
- *  ~class-name                 is parsed as unary~ name
- *      The semantic test should look for ~ with a type as its child.
- *  delete[] expr               is parsed as delete []expr
- *      The semantic test should look for delete with a [] cast of its child.
- *  operator new/delete[]       are parsed as array of operator new/delete
- *      The semantic test should look for array of operator new/delete
- *      or activate the two extra commented rules in operator
- *  template of an explicit_instantiation is buried deep in the tree
- *      dig it out 
- *  pure-specifier and constant-initializer are covered by assignment-expression
- *      just another of the deferred declaration/expression ambiguities
- *  sizeof and typeid don't distinguish type/value syntaxes
- *      probably makes life polymorphically easier
- */
-/*  Action code is supplied by a large number of YACC_xxx macros that can be redefined
- *  by rewriting the include file rather than the grammar. The number of macros is
- *  slightly reduced by using the following protocols
- *
- *  YACC_LIST(0,0)      create empty list (may safely return 0).
- *  YACC_LIST(0,E)      create new list with content E (may return 0 if above returned non-0).
- *  YACC_LIST(L,E)      add E to L
- *  YACC_LIST(L,0)      error propagation, adding nothing to L.
- */
-%type <bang> bang
-%type <mark> colon_mark mark mark_type1
-%type <nest> nest
-
-%type <access_specifier> access_specifier
-%type <base_specifier> base_specifier
-%type <base_specifiers> base_specifier_list
-%type <built_in_id> built_in_type_id built_in_type_specifier
-%type <_class> class_specifier_head
-%type <class_key> class_key
-%type <condition> condition condition.opt
-%type <cv_qualifiers> cv_qualifier cv_qualifier_seq.opt
-%type <decl_specifier_id>  decl_specifier_affix decl_specifier_prefix decl_specifier_suffix function_specifier storage_class_specifier
-%type <declaration> accessibility_specifier asm_definition block_declaration declaration explicit_specialization
-%type <declaration> looped_declaration looping_declaration namespace_alias_definition
-%type <declaration> specialised_block_declaration specialised_declaration template_declaration using_directive
-%type <declarations> compound_declaration declaration_seq.opt
-%type <declarator> nested_ptr_operator ptr_operator
-%type <delete_expression> delete_expression
-%type <enumerator> enumerator_definition
-%type <enumerators> enumerator_clause enumerator_list enumerator_list_head
-%type <exception_declaration> exception_declaration
-%type <exception_specification> exception_specification
-%type <expression> abstract_declarator.opt abstract_expression abstract_parameter_declaration abstract_pointer_declaration
-%type <expression> additive_expression and_expression assignment_expression
-%type <expression> bit_field_declaration bit_field_init_declaration bit_field_width boolean_literal
-%type <expression> cast_expression conditional_expression constant_expression conversion_type_id ctor_definition
-%type <expression> direct_abstract_declarator direct_abstract_declarator.opt direct_new_declarator
-%type <expression> equality_expression exclusive_or_expression expression expression.opt
-%type <expression> for_init_statement func_definition function_definition 
-%type <expression> inclusive_or_expression init_declaration literal logical_and_expression logical_or_expression
-%type <expression> multiplicative_expression new_declarator new_type_id
-%type <expression> pm_expression postfix_expression primary_expression ptr_operator_seq ptr_operator_seq.opt
-%type <expression> relational_expression shift_expression simple_declaration special_parameter_declaration
-%type <expression> templated_throw_expression throw_expression templated_abstract_declaration templated_and_expression 
-%type <expression>templated_assignment_expression templated_conditional_expression templated_equality_expression
-%type <expression> templated_exclusive_or_expression templated_expression templated_inclusive_or_expression templated_logical_and_expression
-%type <expression> templated_logical_or_expression templated_relational_expression type_id unary_expression
-%type <expressions> constructor_head expression_list expression_list.opt init_declarations
-%type <expressions> new_initializer.opt templated_expression_list type_id_list
-%type <function_body> function_block function_body function_try_block try_block
-%type <handler> handler
-%type <handlers> handler_seq
-%type <initializer_clause> braced_initializer initializer_clause looped_initializer_clause looping_initializer_clause
-%type <initializer_clauses> initializer_list
-%type <is_template> global_scope
-%type <keyword> assignment_operator
-%type <line> start_search start_search1
-%type <mem_initializer> mem_initializer
-%type <mem_initializers> ctor_initializer ctor_initializer.opt mem_initializer_list mem_initializer_list_head
-%type <name> class_specifier conversion_function_id declarator_id destructor_id
-%type <name> elaborated_class_specifier elaborated_enum_specifier elaborated_type_specifier elaborate_type_specifier
-%type <name> enum_specifier enumerator id identifier_word id_scope identifier linkage_specification
-%type <name> namespace_definition nested_id nested_pseudo_destructor_id nested_special_function_id
-%type <name> mem_initializer_id operator operator_function_id pseudo_destructor_id scoped_id scoped_pseudo_destructor_id scoped_special_function_id
-%type <name> simple_type_specifier special_function_id suffix_built_in_decl_specifier suffix_named_decl_specifier.bi
-%type <name> suffix_built_in_decl_specifier.raw suffix_decl_specified_ids suffix_named_decl_specifiers
-%type <name> suffix_named_decl_specifiers.sf suffix_decl_specified_scope suffix_named_decl_specifier
-%type <name> template_id type_specifier
-%type <new_expression> new_expression
-%type <parameter> parameter_declaration templated_parameter_declaration
-%type <parameters> parameters_clause parameter_declaration_clause parameter_declaration_list
-%type <parenthesised> parenthesis_clause
-%type <pointer_declarator> star_ptr_operator
-%type <simple_type_parameter> simple_type_parameter
-%type <statement> compound_statement control_statement declaration_statement iteration_statement jump_statement
-%type <statement> labeled_statement looped_statement looping_statement selection_statement statement
-%type <statements> statement_seq.opt
-%type <strings> string
-%type <template_argument> template_argument
-%type <template_arguments> template_argument_list
-%type <template_parameter> template_parameter
-%type <template_parameters> template_parameter_clause template_parameter_list
-%type <templated_type_parameter> templated_type_parameter
-%type <type1_parameters> type1_parameters
-%type <utility> util
-
-/*
- *  C++ productions replaced by more generalised FOG productions
- */
-%type <declaration> looped_member_declaration looping_member_declaration member_declaration using_declaration
-%type <declarations> member_specification.opt
-%type <expression> member_init_declaration simple_member_declaration
-%type <expressions> member_init_declarations
-
-\f
-%nonassoc SHIFT_THERE
-%nonassoc SCOPE ELSE INC DEC '+' '-' '*' '&' '[' '{' '<' ':' StringLiteral
-%nonassoc REDUCE_HERE_MOSTLY
-%nonassoc '('
-/*%nonassoc REDUCE_HERE */
-
-%start translation_unit
-%%
-
-/*
- *  The %prec resolves a conflict in identifier_word : which is forced to be a shift of a label for
- *  a labeled-statement rather than a reduction for the name of a bit-field or generalised constructor.
- *  This is pretty dubious syntactically but correct for all semantic possibilities.
- *  The shift is only activated when the ambiguity exists at the start of a statement. In this context
- *  a bit-field declaration or constructor definition are not allowed.
- */
-identifier_word:                    Identifier                                                  { $$ = $1; }
-identifier:                         identifier_word                     %prec SHIFT_THERE
-/*
- *  The %prec resolves the $014.2-3 ambiguity:
- *  Identifier '<' is forced to go through the is-it-a-template-name test
- *  All names absorb TEMPLATE with the name, so that no template_test is performed for them.
- *  This requires all potential declarations within an expression to perpetuate this policy
- *  and thereby guarantee the ultimate coverage of explicit_instantiation.
- */
-id:                                 identifier                          %prec SHIFT_THERE       /* Force < through test */ { $$ = YACC_NAME($1); }
-    |                               identifier template_test '+' template_argument_list '>'     { $$ = YACC_TEMPLATE_NAME($1, $4); }
-    |                               identifier template_test '+' '>'                            { $$ = $1; ERRMSG("Empty template-argument-list"); }
-    |                               identifier template_test '-'                                /* requeued < follows */  { $$ = YACC_NAME($1); }
-    |                               template_id 
-template_test:                      '<'             /* Queue '+' or '-' < as follow on */       { template_test(); }
-global_scope:                       SCOPE                                                       { $$ = IS_DEFAULT; }
-    |                               TEMPLATE global_scope                                       { $$ = IS_TEMPLATE; }
-id_scope:                           id SCOPE                                                    { $$ = YACC_NESTED_SCOPE($1); }
-/*
- *  A :: B :: C; is ambiguous How much is type and how much name ?
- *  The %prec maximises the (type) length which is the $07.1-2 semantic constraint.
- */
-nested_id:                          id                                  %prec SHIFT_THERE       /* Maximise length */
-    |                               id_scope nested_id                                          { $$ = YACC_NESTED_ID($1, $2); }
-scoped_id:                          nested_id
-    |                               global_scope nested_id                                      { $$ = YACC_GLOBAL_ID($1, $2); }
-
-/*
- *  destructor_id has to be held back to avoid a conflict with a one's complement as per $05.3.1-9,
- *  It gets put back only when scoped or in a declarator_id, which is only used as an explicit member name.
- *  Declarations of an unscoped destructor are always parsed as a one's complement.
- */
-destructor_id:                      '~' id                                                      { $$ = YACC_DESTRUCTOR_ID($2); }
-    |                               TEMPLATE destructor_id                                      { $$ = YACC_SET_TEMPLATE_ID($2); }
-special_function_id:                conversion_function_id
-    |                               operator_function_id
-    |                               TEMPLATE special_function_id                                { $$ = YACC_SET_TEMPLATE_ID($2); }
-nested_special_function_id:         special_function_id
-    |                               id_scope destructor_id                                      { $$ = YACC_NESTED_ID($1, $2); }
-    |                               id_scope nested_special_function_id                         { $$ = YACC_NESTED_ID($1, $2); }
-scoped_special_function_id:         nested_special_function_id
-    |                               global_scope nested_special_function_id                     { $$ = YACC_GLOBAL_ID($1, $2); }
-
-/* declarator-id is all names in all scopes, except reserved words */
-declarator_id:                      scoped_id
-    |                               scoped_special_function_id
-    |                               destructor_id
-
-/*  The standard defines pseudo-destructors in terms of type-name, which is class/enum/typedef, of which
- *  class-name is covered by a normal destructor. pseudo-destructors are supposed to support ~int() in
- *  templates, so the grammar here covers built-in names. Other names are covered by the lack of
- *  identifier/type discrimination.
- */
-built_in_type_id:                   built_in_type_specifier
-    |                               built_in_type_id built_in_type_specifier                    { $$ = YACC_BUILT_IN_IDS($1, $2); }
-pseudo_destructor_id:               built_in_type_id SCOPE '~' built_in_type_id                 { $$ = YACC_PSEUDO_DESTRUCTOR_ID($1, $4); }
-    |                               '~' built_in_type_id                                        { $$ = YACC_PSEUDO_DESTRUCTOR_ID(0, $2); }
-    |                               TEMPLATE pseudo_destructor_id                               { $$ = YACC_SET_TEMPLATE_ID($2); }
-nested_pseudo_destructor_id:        pseudo_destructor_id
-    |                               id_scope nested_pseudo_destructor_id                        { $$ = YACC_NESTED_ID($1, $2); }
-scoped_pseudo_destructor_id:        nested_pseudo_destructor_id
-    |                               global_scope scoped_pseudo_destructor_id                    { $$ = YACC_GLOBAL_ID($1, $2); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.2 Lexical conventions
- *---------------------------------------------------------------------------------------------------*/
-/*
- *  String concatenation is a phase 6, not phase 7 activity so does not really belong in the grammar.
- *  However it may be convenient to have it here to make this grammar fully functional.
- *  Unfortunately it introduces a conflict with the generalised parsing of extern "C" which
- *  is correctly resolved to maximise the string length as the token source should do anyway.
- */
-string:                             StringLiteral                                               { $$ = $1; }
-/*string:                           StringLiteral                           %prec SHIFT_THERE   { $$ = YACC_STRINGS($1, 0); } */
-/*  |                               StringLiteral string  -- Perverse order avoids conflicts -- { $$ = YACC_STRINGS($1, $2); } */
-literal:                            IntegerLiteral                                              { $$ = YACC_INTEGER_LITERAL_EXPRESSION($1); }
-    |                               CharacterLiteral                                            { $$ = YACC_CHARACTER_LITERAL_EXPRESSION($1); }
-    |                               FloatingLiteral                                             { $$ = YACC_FLOATING_LITERAL_EXPRESSION($1); }
-    |                               string                                                      { $$ = YACC_STRING_LITERAL_EXPRESSION($1); }
-    |                               boolean_literal
-boolean_literal:                    FALSE                                                       { $$ = YACC_FALSE_EXPRESSION(); }
-    |                               TRUE                                                        { $$ = YACC_TRUE_EXPRESSION(); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.3 Basic concepts
- *---------------------------------------------------------------------------------------------------*/
-translation_unit:                   declaration_seq.opt                                         { YACC_RESULT($1); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.4 Expressions
- *---------------------------------------------------------------------------------------------------
- *  primary_expression covers an arbitrary sequence of all names with the exception of an unscoped destructor,
- *  which is parsed as its unary expression which is the correct disambiguation (when ambiguous).
- *  This eliminates the traditional A(B) meaning A B ambiguity, since we never have to tack an A onto
- *  the front of something that might start with (. The name length got maximised ab initio. The downside
- *  is that semantic interpretation must split the names up again.
- *
- *  Unification of the declaration and expression syntax means that unary and binary pointer declarator operators:
- *      int * * name
- *  are parsed as binary and unary arithmetic operators (int) * (*name). Since type information is not used
- *  ambiguities resulting from a cast
- *      (cast)*(value)
- *  are resolved to favour the binary rather than the cast unary to ease AST clean-up.
- *  The cast-call ambiguity must be resolved to the cast to ensure that (a)(b)c can be parsed.
- *
- *  The problem of the functional cast ambiguity
- *      name(arg)
- *  as call or declaration is avoided by maximising the name within the parsing kernel. So
- *  primary_id_expression picks up 
- *      extern long int const var = 5;
- *  as an assignment to the syntax parsed as "extern long int const var". The presence of two names is
- *  parsed so that "extern long into const" is distinguished from "var" considerably simplifying subsequent
- *  semantic resolution.
- *
- *  The generalised name is a concatenation of potential type-names (scoped identifiers or built-in sequences)
- *  plus optionally one of the special names such as an operator-function-id, conversion-function-id or
- *  destructor as the final name. 
- */
-primary_expression:                 literal
-    |                               THIS                                                    { $$ = YACC_THIS_EXPRESSION(); }
-    |                               suffix_decl_specified_ids                               { $$ = $1; }
-/*  |                               SCOPE identifier                                        -- covered by suffix_decl_specified_ids */
-/*  |                               SCOPE operator_function_id                              -- covered by suffix_decl_specified_ids */
-/*  |                               SCOPE qualified_id                                      -- covered by suffix_decl_specified_ids */
-    |                               abstract_expression           %prec REDUCE_HERE_MOSTLY  /* Prefer binary to unary ops, cast to call */
-/*  |                               id_expression                                           -- covered by suffix_decl_specified_ids */
-
-/*
- *  Abstract-expression covers the () and [] of abstract-declarators.
- */
-abstract_expression:                parenthesis_clause                                      { $$ = YACC_ABSTRACT_FUNCTION_EXPRESSION($1); }
-    |                               '[' expression.opt ']'                                  { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); }
-    |                               TEMPLATE parenthesis_clause                             { $$ = YACC_SET_TEMPLATE_EXPRESSION(YACC_ABSTRACT_FUNCTION_EXPRESSION($2)); }
-
-/*  Type I function parameters are ambiguous with respect to the generalised name, so we have to do a lookahead following
- *  any function-like parentheses. This unfortunately hits normal code, so kill the -- lines and add the ++ lines for efficiency.
- *  Supporting Type I code under the superset causes perhaps 25% of lookahead parsing. Sometimes complete class definitions
- *  get traversed since they are valid generalised type I parameters!
- */
-type1_parameters:       /*----*/    parameter_declaration_list ';'                          { $$ = YACC_TYPE1_PARAMETERS(0, $1); }
-    |                   /*----*/    type1_parameters parameter_declaration_list ';'         { $$ = YACC_TYPE1_PARAMETERS($1, $2); }
-mark_type1:                         /* empty */                                             { $$ = mark_type1(); }
-postfix_expression:                 primary_expression
-/*  |                   /++++++/    postfix_expression parenthesis_clause                   { $$ = YACC_CALL_EXPRESSION($1, $2); } */
-    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '-'    { $$ = YACC_CALL_EXPRESSION($1, $2); }
-    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark '{' error 
-                        /*----*/                    { yyerrok; remark_type1($6); unmark(); unmark($5); $$ = YACC_TYPE1_EXPRESSION($1, $2, $5); }
-    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark error 
-                        /*----*/                    { yyerrok; remark_type1($3); unmark(); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); }
-    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '+' error
-                        /*----*/                    { yyerrok; remark_type1($3); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); }
-    |                               postfix_expression '[' expression.opt ']'               { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
-/*  |                               destructor_id '[' expression.opt ']'                    -- not semantically valid */
-/*  |                               destructor_id parenthesis_clause                        -- omitted to resolve known ambiguity */
-/*  |                               simple_type_specifier '(' expression_list.opt ')'       -- simple_type_specifier is a primary_expression */
-    |                               postfix_expression '.' declarator_id                    { $$ = YACC_DOT_EXPRESSION($1, $3); }
-/*  |                               postfix_expression '.' TEMPLATE declarator_id           -- TEMPLATE absorbed into declarator_id. */
-    |                               postfix_expression '.' scoped_pseudo_destructor_id      { $$ = YACC_DOT_EXPRESSION($1, $3); }
-    |                               postfix_expression ARROW declarator_id                  { $$ = YACC_ARROW_EXPRESSION($1, $3); }
-/*  |                               postfix_expression ARROW TEMPLATE declarator_id         -- TEMPLATE absorbed into declarator_id. */
-    |                               postfix_expression ARROW scoped_pseudo_destructor_id    { $$ = YACC_ARROW_EXPRESSION($1, $3); }   
-    |                               postfix_expression INC                                  { $$ = YACC_POST_INCREMENT_EXPRESSION($1); }
-    |                               postfix_expression DEC                                  { $$ = YACC_POST_DECREMENT_EXPRESSION($1); }
-    |                               DYNAMIC_CAST '<' type_id '>' '(' expression ')'         { $$ = YACC_DYNAMIC_CAST_EXPRESSION($3, $6); }
-    |                               STATIC_CAST '<' type_id '>' '(' expression ')'          { $$ = YACC_STATIC_CAST_EXPRESSION($3, $6); }
-    |                               REINTERPRET_CAST '<' type_id '>' '(' expression ')'     { $$ = YACC_REINTERPRET_CAST_EXPRESSION($3, $6); }
-    |                               CONST_CAST '<' type_id '>' '(' expression ')'           { $$ = YACC_CONST_CAST_EXPRESSION($3, $6); }
-    |                               TYPEID parameters_clause                                { $$ = YACC_TYPEID_EXPRESSION($2); }
-/*  |                               TYPEID '(' expression ')'                               -- covered by parameters_clause */
-/*  |                               TYPEID '(' type_id ')'                                  -- covered by parameters_clause */
-expression_list.opt:                /* empty */                                             { $$ = YACC_EXPRESSIONS(0, 0); }
-    |                               expression_list
-expression_list:                    assignment_expression                                   { $$ = YACC_EXPRESSIONS(0, $1); }
-    |                               expression_list ',' assignment_expression               { $$ = YACC_EXPRESSIONS($1, $3); }
-
-unary_expression:                   postfix_expression
-    |                               INC cast_expression                                     { $$ = YACC_PRE_INCREMENT_EXPRESSION($2); }
-    |                               DEC cast_expression                                     { $$ = YACC_PRE_DECREMENT_EXPRESSION($2); }
-    |                               ptr_operator cast_expression                            { $$ = YACC_POINTER_EXPRESSION($1, $2); }
-/*  |                               '*' cast_expression                                     -- covered by ptr_operator */
-/*  |                               '&' cast_expression                                     -- covered by ptr_operator */
-/*  |                               decl_specifier_seq '*' cast_expression                  -- covered by binary operator */
-/*  |                               decl_specifier_seq '&' cast_expression                  -- covered by binary operator */
-    |                               suffix_decl_specified_scope star_ptr_operator cast_expression   /* covers e.g int ::type::* const t = 4 */
-                                                                                            { $$ = YACC_SCOPED_POINTER_EXPRESSION($1, $2, $3); }
-    |                               '+' cast_expression                                     { $$ = YACC_PLUS_EXPRESSION($2); }
-    |                               '-' cast_expression                                     { $$ = YACC_MINUS_EXPRESSION($2); }
-    |                               '!' cast_expression                                     { $$ = YACC_NOT_EXPRESSION($2); }
-    |                               '~' cast_expression                                     { $$ = YACC_COMPLEMENT_EXPRESSION($2); }
-    |                               SIZEOF unary_expression                                 { $$ = YACC_SIZEOF_EXPRESSION($2); }
-/*  |                               SIZEOF '(' type_id ')'                                  -- covered by unary_expression */
-    |                               new_expression                                          { $$ = $1; }
-    |                               global_scope new_expression                             { $$ = YACC_GLOBAL_EXPRESSION($1, $2); }
-    |                               delete_expression                                       { $$ = $1; }
-    |                               global_scope delete_expression                          { $$ = YACC_GLOBAL_EXPRESSION($1, $2); }
-/*  |                               DELETE '[' ']' cast_expression       -- covered by DELETE cast_expression since cast_expression covers ... */
-/*  |                               SCOPE DELETE '[' ']' cast_expression //  ... abstract_expression cast_expression and so [] cast_expression */
-
-delete_expression:                  DELETE cast_expression                                  /* also covers DELETE[] cast_expression */
-                                                                                            { $$ = YACC_DELETE_EXPRESSION($2); }
-new_expression:                     NEW new_type_id new_initializer.opt                     { $$ = YACC_NEW_TYPE_ID_EXPRESSION(0, $2, $3); }
-    |                               NEW parameters_clause new_type_id new_initializer.opt   { $$ = YACC_NEW_TYPE_ID_EXPRESSION($2, $3, $4); }
-    |                               NEW parameters_clause                                   { $$ = YACC_NEW_EXPRESSION($2, 0, 0); }
-/*  |                               NEW '(' type-id ')'                                     -- covered by parameters_clause */
-    |                               NEW parameters_clause parameters_clause new_initializer.opt { $$ = YACC_NEW_EXPRESSION($2, $3, $4); }
-/*  |                               NEW '(' type-id ')' new_initializer                     -- covered by parameters_clause parameters_clause */
-/*  |                               NEW parameters_clause '(' type-id ')'                   -- covered by parameters_clause parameters_clause */
-                                                                                /* ptr_operator_seq.opt production reused to save a %prec */
-new_type_id:                        type_specifier ptr_operator_seq.opt                     { $$ = YACC_TYPED_EXPRESSION($1, $2); }
-    |                               type_specifier new_declarator                           { $$ = YACC_TYPED_EXPRESSION($1, $2); }
-    |                               type_specifier new_type_id                              { $$ = YACC_TYPED_EXPRESSION($1, $2); }
-new_declarator:                     ptr_operator new_declarator                             { $$ = YACC_POINTER_EXPRESSION($1, $2); }
-    |                               direct_new_declarator
-direct_new_declarator:              '[' expression ']'                                      { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); }
-    |                               direct_new_declarator '[' constant_expression ']'       { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
-new_initializer.opt:                /* empty */                                             { $$ = YACC_EXPRESSIONS(0, 0); }
-    |                               '(' expression_list.opt ')'                             { $$ = $2; }
-
-/*  cast-expression is generalised to support a [] as well as a () prefix. This covers the omission of DELETE[] which when
- *  followed by a parenthesised expression was ambiguous. It also covers the gcc indexed array initialisation for free.
- */
-cast_expression:                    unary_expression
-    |                               abstract_expression cast_expression                         { $$ = YACC_CAST_EXPRESSION($1, $2); }
-/*  |                               '(' type_id ')' cast_expression                             -- covered by abstract_expression */
-
-pm_expression:                      cast_expression
-    |                               pm_expression DOT_STAR cast_expression                      { $$ = YACC_DOT_STAR_EXPRESSION($1, $3); }
-    |                               pm_expression ARROW_STAR cast_expression                    { $$ = YACC_ARROW_STAR_EXPRESSION($1, $3); }
-multiplicative_expression:          pm_expression
-    |                               multiplicative_expression star_ptr_operator pm_expression   { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); }
-    |                               multiplicative_expression '/' pm_expression                 { $$ = YACC_DIVIDE_EXPRESSION($1, $3); }
-    |                               multiplicative_expression '%' pm_expression                 { $$ = YACC_MODULUS_EXPRESSION($1, $3); }
-additive_expression:                multiplicative_expression
-    |                               additive_expression '+' multiplicative_expression           { $$ = YACC_ADD_EXPRESSION($1, $3); }
-    |                               additive_expression '-' multiplicative_expression           { $$ = YACC_SUBTRACT_EXPRESSION($1, $3); }
-shift_expression:                   additive_expression
-    |                               shift_expression SHL additive_expression                    { $$ = YACC_SHIFT_LEFT_EXPRESSION($1, $3); }
-    |                               shift_expression SHR additive_expression                    { $$ = YACC_SHIFT_RIGHT_EXPRESSION($1, $3); }
-relational_expression:              shift_expression
-    |                               relational_expression '<' shift_expression                  { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); }
-    |                               relational_expression '>' shift_expression                  { $$ = YACC_GREATER_THAN_EXPRESSION($1, $3); }
-    |                               relational_expression LE shift_expression                   { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); }
-    |                               relational_expression GE shift_expression                   { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); }
-equality_expression:                relational_expression
-    |                               equality_expression EQ relational_expression                { $$ = YACC_EQUAL_EXPRESSION($1, $3); }
-    |                               equality_expression NE relational_expression                { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); }
-and_expression:                     equality_expression
-    |                               and_expression '&' equality_expression                      { $$ = YACC_AND_EXPRESSION($1, $3); }
-exclusive_or_expression:            and_expression
-    |                               exclusive_or_expression '^' and_expression                  { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); }
-inclusive_or_expression:            exclusive_or_expression
-    |                               inclusive_or_expression '|' exclusive_or_expression         { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); }
-logical_and_expression:             inclusive_or_expression
-    |                               logical_and_expression LOG_AND inclusive_or_expression      { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); }
-logical_or_expression:              logical_and_expression
-    |                               logical_or_expression LOG_OR logical_and_expression         { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); }
-conditional_expression:             logical_or_expression
-    |                               logical_or_expression '?' expression ':' assignment_expression
-                                                                                                { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
-
-/*  assignment-expression is generalised to cover the simple assignment of a braced initializer in order to contribute to the
- *  coverage of parameter-declaration and init-declaration.
- */
-assignment_expression:              conditional_expression
-    |                               logical_or_expression assignment_operator assignment_expression { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
-    |                               logical_or_expression '=' braced_initializer                    { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
-    |                               throw_expression
-assignment_operator:                '=' | ASS_ADD | ASS_AND | ASS_DIV | ASS_MOD | ASS_MUL | ASS_OR | ASS_SHL | ASS_SHR | ASS_SUB | ASS_XOR
-
-/*  expression is widely used and usually single-element, so the reductions are arranged so that a
- *  single-element expression is returned as is. Multi-element expressions are parsed as a list that
- *  may then behave polymorphically as an element or be compacted to an element. */ 
-expression.opt:                     /* empty */                                                 { $$ = YACC_EXPRESSION(0); }
-    |                               expression
-expression:                         assignment_expression
-    |                               expression_list ',' assignment_expression                   { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); }
-constant_expression:                conditional_expression
-
-/*  The grammar is repeated for when the parser stack knows that the next > must end a template.
- */
-templated_relational_expression:    shift_expression
-    |                               templated_relational_expression '<' shift_expression        { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); }
-    |                               templated_relational_expression LE shift_expression         { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); }
-    |                               templated_relational_expression GE shift_expression         { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); }
-templated_equality_expression:      templated_relational_expression
-    |                               templated_equality_expression EQ templated_relational_expression    { $$ = YACC_EQUAL_EXPRESSION($1, $3); }
-    |                               templated_equality_expression NE templated_relational_expression    { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); }
-templated_and_expression:           templated_equality_expression
-    |                               templated_and_expression '&' templated_equality_expression  { $$ = YACC_AND_EXPRESSION($1, $3); }
-templated_exclusive_or_expression:  templated_and_expression
-    |                               templated_exclusive_or_expression '^' templated_and_expression
-                                                                                                { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); }
-templated_inclusive_or_expression:  templated_exclusive_or_expression
-    |                               templated_inclusive_or_expression '|' templated_exclusive_or_expression
-                                                                                                { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); }
-templated_logical_and_expression:   templated_inclusive_or_expression
-    |                               templated_logical_and_expression LOG_AND templated_inclusive_or_expression
-                                                                                                { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); }
-templated_logical_or_expression:    templated_logical_and_expression
-    |                               templated_logical_or_expression LOG_OR templated_logical_and_expression
-                                                                                                { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); }
-templated_conditional_expression:   templated_logical_or_expression
-    |                               templated_logical_or_expression '?' templated_expression ':' templated_assignment_expression
-                                                                                                { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
-templated_assignment_expression:    templated_conditional_expression
-    |                               templated_logical_or_expression assignment_operator templated_assignment_expression
-                                                                                                { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
-    |                               templated_throw_expression
-templated_expression:               templated_assignment_expression
-    |                               templated_expression_list ',' templated_assignment_expression
-                                                                                                { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); }
-templated_expression_list:          templated_assignment_expression                             { $$ = YACC_EXPRESSIONS(0, $1); }
-    |                               templated_expression_list ',' templated_assignment_expression    { $$ = YACC_EXPRESSIONS($1, $3); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.5 Statements
- *---------------------------------------------------------------------------------------------------
- *  Parsing statements is easy once simple_declaration has been generalised to cover expression_statement.
- */
-looping_statement:                  start_search looped_statement                               { $$ = YACC_LINED_STATEMENT($2, $1); end_search($$); }
-looped_statement:                   statement
-    |                               advance_search '+' looped_statement                         { $$ = $3; }
-    |                               advance_search '-'                                          { $$ = 0; }
-statement:                          control_statement
-/*  |                               expression_statement                                        -- covered by declaration_statement */
-    |                               compound_statement
-    |                               declaration_statement
-    |                               try_block                                                   { $$ = YACC_TRY_BLOCK_STATEMENT($1); }
-control_statement:                  labeled_statement
-    |                               selection_statement
-    |                               iteration_statement
-    |                               jump_statement
-labeled_statement:                  identifier_word ':' looping_statement                       { $$ = YACC_LABEL_STATEMENT($1, $3); }
-    |                               CASE constant_expression ':' looping_statement              { $$ = YACC_CASE_STATEMENT($2, $4); }
-    |                               DEFAULT ':' looping_statement                               { $$ = YACC_DEFAULT_STATEMENT($3); }
-/*expression_statement:             expression.opt ';'                                          -- covered by declaration_statement */
-compound_statement:                 '{' statement_seq.opt '}'                                   { $$ = YACC_COMPOUND_STATEMENT($2); }
-    |                               '{' statement_seq.opt looping_statement '#' bang error '}'  { $$ = $2; YACC_UNBANG($5, "Bad statement-seq."); }
-statement_seq.opt:                  /* empty */                                                 { $$ = YACC_STATEMENTS(0, 0); }
-    |                               statement_seq.opt looping_statement                         { $$ = YACC_STATEMENTS($1, YACC_COMPILE_STATEMENT($2)); }
-    |                               statement_seq.opt looping_statement '#' bang error ';'      { $$ = $1; YACC_UNBANG($4, "Bad statement."); }
-/*
- *  The dangling else conflict is resolved to the innermost if.
- */
-selection_statement:                IF '(' condition ')' looping_statement    %prec SHIFT_THERE { $$ = YACC_IF_STATEMENT($3, $5, 0); }
-    |                               IF '(' condition ')' looping_statement ELSE looping_statement { $$ = YACC_IF_STATEMENT($3, $5, $7); }
-    |                               SWITCH '(' condition ')' looping_statement                  { $$ = YACC_SWITCH_STATEMENT($3, $5); }
-condition.opt:                      /* empty */                                                 { $$ = YACC_CONDITION(0); }
-    |                               condition
-condition:                          parameter_declaration_list                                  { $$ = YACC_CONDITION($1); }
-/*  |                               expression                                                  -- covered by parameter_declaration_list */
-/*  |                               type_specifier_seq declarator '=' assignment_expression     -- covered by parameter_declaration_list */
-iteration_statement:                WHILE '(' condition ')' looping_statement                   { $$ = YACC_WHILE_STATEMENT($3, $5); }
-    |                               DO looping_statement WHILE '(' expression ')' ';'           { $$ = YACC_DO_WHILE_STATEMENT($2, $5); }
-    |                               FOR '(' for_init_statement condition.opt ';' expression.opt ')' looping_statement
-                                                                                                { $$ = YACC_FOR_STATEMENT($3, $4, $6, $8); }
-for_init_statement:                 simple_declaration
-/*  |                               expression_statement                                        -- covered by simple_declaration */
-jump_statement:                     BREAK ';'                                                   { $$ = YACC_BREAK_STATEMENT(); }
-    |                               CONTINUE ';'                                                { $$ = YACC_CONTINUE_STATEMENT(); }
-    |                               RETURN expression.opt ';'                                   { $$ = YACC_RETURN_STATEMENT($2); }
-    |                               GOTO identifier ';'                                         { $$ = YACC_GOTO_STATEMENT($2); }
-declaration_statement:              block_declaration                                           { $$ = YACC_DECLARATION_STATEMENT($1); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.6 Declarations
- *---------------------------------------------------------------------------------------------------*/
-compound_declaration:               '{' nest declaration_seq.opt '}'                            { $$ = $3; unnest($2); }
-    |                               '{' nest declaration_seq.opt util looping_declaration '#' bang error '}'
-                                                                                                { $$ = $3; unnest($2); YACC_UNBANG($7, "Bad declaration-seq."); }
-declaration_seq.opt:                /* empty */                                                 { $$ = YACC_DECLARATIONS(0, 0); }
-    |                               declaration_seq.opt util looping_declaration                { $$ = YACC_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); }
-    |                               declaration_seq.opt util looping_declaration '#' bang error ';' { $$ = $1; YACC_UNBANG($5, "Bad declaration."); }
-looping_declaration:                start_search1 looped_declaration                            { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); }
-looped_declaration:                 declaration
-    |                               advance_search '+' looped_declaration                       { $$ = $3; }
-    |                               advance_search '-'                                          { $$ = 0; }
-declaration:                        block_declaration
-    |                               function_definition                                         { $$ = YACC_SIMPLE_DECLARATION($1); }
-    |                               template_declaration
-/*  |                               explicit_instantiation                                      -- covered by relevant declarations */
-    |                               explicit_specialization
-    |                               specialised_declaration
-specialised_declaration:            linkage_specification                                       { $$ = YACC_LINKAGE_SPECIFICATION($1); }
-    |                               namespace_definition                                        { $$ = YACC_NAMESPACE_DECLARATION($1); }
-    |                               TEMPLATE specialised_declaration                            { $$ = YACC_SET_TEMPLATE_DECLARATION($2); }
-block_declaration:                  simple_declaration                                          { $$ = YACC_SIMPLE_DECLARATION($1); }
-    |                               specialised_block_declaration
-specialised_block_declaration:      asm_definition
-    |                               namespace_alias_definition
-    |                               using_declaration
-    |                               using_directive
-    |                               TEMPLATE specialised_block_declaration                      { $$ = YACC_SET_TEMPLATE_DECLARATION($2); }
-simple_declaration:                 ';'                                                         { $$ = YACC_EXPRESSION(0); }
-    |                               init_declaration ';'
-    |                               init_declarations ';'                                       { $$ = $1; }
-    |                               decl_specifier_prefix simple_declaration                    { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
-
-/*  A decl-specifier following a ptr_operator provokes a shift-reduce conflict for
- *      * const name
- *  which is resolved in favour of the pointer, and implemented by providing versions
- *  of decl-specifier guaranteed not to start with a cv_qualifier.
- *
- *  decl-specifiers are implemented type-centrically. That is the semantic constraint
- *  that there must be a type is exploited to impose structure, but actually eliminate
- *  very little syntax. built-in types are multi-name and so need a different policy.
- *
- *  non-type decl-specifiers are bound to the left-most type in a decl-specifier-seq,
- *  by parsing from the right and attaching suffixes to the right-hand type. Finally
- *  residual prefixes attach to the left.                
- */
-suffix_built_in_decl_specifier.raw: built_in_type_specifier                                     { $$ = $1; }
-    |                               suffix_built_in_decl_specifier.raw built_in_type_specifier  { $$ = YACC_BUILT_IN_NAME($1, $2); }
-    |                               suffix_built_in_decl_specifier.raw decl_specifier_suffix    { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); }
-suffix_built_in_decl_specifier:     suffix_built_in_decl_specifier.raw                          { $$ = $1; }
-    |                               TEMPLATE suffix_built_in_decl_specifier                     { $$ = YACC_SET_TEMPLATE_NAME($2); }
-suffix_named_decl_specifier:        scoped_id                                                   { $$ = $1; }
-    |                               elaborate_type_specifier                                    { $$ = $1; }
-    |                               suffix_named_decl_specifier decl_specifier_suffix           { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); }
-suffix_named_decl_specifier.bi:     suffix_named_decl_specifier                                 { $$ = YACC_NAME_EXPRESSION($1); }
-    |                               suffix_named_decl_specifier suffix_built_in_decl_specifier.raw  { $$ = YACC_TYPED_NAME($1, $2); }
-suffix_named_decl_specifiers:       suffix_named_decl_specifier.bi
-    |                               suffix_named_decl_specifiers suffix_named_decl_specifier.bi { $$ = YACC_TYPED_NAME($1, $2); }
-suffix_named_decl_specifiers.sf:    scoped_special_function_id          /* operators etc */     { $$ = YACC_NAME_EXPRESSION($1); }
-    |                               suffix_named_decl_specifiers
-    |                               suffix_named_decl_specifiers scoped_special_function_id     { $$ = YACC_TYPED_NAME($1, $2); }
-suffix_decl_specified_ids:          suffix_built_in_decl_specifier
-    |                               suffix_built_in_decl_specifier suffix_named_decl_specifiers.sf { $$ = YACC_TYPED_NAME($1, $2); }
-    |                               suffix_named_decl_specifiers.sf
-suffix_decl_specified_scope:        suffix_named_decl_specifiers SCOPE
-    |                               suffix_built_in_decl_specifier suffix_named_decl_specifiers SCOPE { $$ = YACC_TYPED_NAME($1, $2); }
-    |                               suffix_built_in_decl_specifier SCOPE                        { $$ = YACC_NAME_EXPRESSION($1); }
-
-decl_specifier_affix:               storage_class_specifier
-    |                               function_specifier
-    |                               FRIEND                                                          
-    |                               TYPEDEF
-    |                               cv_qualifier                                                { $$ = $1; }
-
-decl_specifier_suffix:              decl_specifier_affix
-
-decl_specifier_prefix:              decl_specifier_affix
-    |                               TEMPLATE decl_specifier_prefix                              { $$ = YACC_SET_TEMPLATE_DECL_SPECIFIER($2); }
-
-storage_class_specifier:            REGISTER | STATIC | MUTABLE
-    |                               EXTERN                  %prec SHIFT_THERE                   /* Prefer linkage specification */
-    |                               AUTO
-
-function_specifier:                 EXPLICIT
-    |                               INLINE
-    |                               VIRTUAL
-
-type_specifier:                     simple_type_specifier
-    |                               elaborate_type_specifier
-    |                               cv_qualifier                                                { $$ = YACC_CV_DECL_SPECIFIER($1); }
-
-elaborate_type_specifier:           class_specifier
-    |                               enum_specifier
-    |                               elaborated_type_specifier
-    |                               TEMPLATE elaborate_type_specifier                           { $$ = YACC_SET_TEMPLATE_ID($2); }
-simple_type_specifier:              scoped_id
-    |                               built_in_type_specifier                                     { $$ = YACC_BUILT_IN_ID_ID($1); }
-built_in_type_specifier:            CHAR | WCHAR_T | BOOL | SHORT | INT | LONG | SIGNED | UNSIGNED | FLOAT | DOUBLE | VOID
-
-/*
- *  The over-general use of declaration_expression to cover decl-specifier-seq.opt declarator in a function-definition means that
- *      class X {};
- *  could be a function-definition or a class-specifier.
- *      enum X {};
- *  could be a function-definition or an enum-specifier.
- *  The function-definition is not syntactically valid so resolving the false conflict in favour of the
- *  elaborated_type_specifier is correct.
- */
-elaborated_type_specifier:          elaborated_class_specifier
-    |                               elaborated_enum_specifier
-    |                               TYPENAME scoped_id                                          { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
-
-elaborated_enum_specifier:          ENUM scoped_id               %prec SHIFT_THERE              { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
-enum_specifier:                     ENUM scoped_id enumerator_clause                            { $$ = YACC_ENUM_SPECIFIER_ID($2, $3); }
-    |                               ENUM enumerator_clause                                      { $$ = YACC_ENUM_SPECIFIER_ID(0, $2); }
-enumerator_clause:                  '{' enumerator_list_ecarb                                   { $$ = YACC_ENUMERATORS(0, 0); }
-    |                               '{' enumerator_list enumerator_list_ecarb                   { $$ = $2; }
-    |                               '{' enumerator_list ',' enumerator_definition_ecarb         { $$ = $2; }
-enumerator_list_ecarb:              '}'                                                         { }
-    |                               bang error '}'                                              { YACC_UNBANG($1, "Bad enumerator-list."); }
-enumerator_definition_ecarb:        '}'                                                         { }
-    |                               bang error '}'                                              { YACC_UNBANG($1, "Bad enumerator-definition."); }
-enumerator_definition_filler:       /* empty */
-    |                               bang error ','                                              { YACC_UNBANG($1, "Bad enumerator-definition."); }
-enumerator_list_head:               enumerator_definition_filler                                { $$ = YACC_ENUMERATORS(0, 0); }
-    |                               enumerator_list ',' enumerator_definition_filler
-enumerator_list:                    enumerator_list_head enumerator_definition                  { $$ = YACC_ENUMERATORS($1, $2); }
-enumerator_definition:              enumerator                                                  { $$ = YACC_ENUMERATOR($1, 0); }
-    |                               enumerator '=' constant_expression                          { $$ = YACC_ENUMERATOR($1, $3); }
-enumerator:                         identifier
-
-namespace_definition:               NAMESPACE scoped_id compound_declaration                    { $$ = YACC_NAMESPACE_DEFINITION($2, $3); }
-    |                               NAMESPACE compound_declaration                              { $$ = YACC_NAMESPACE_DEFINITION(0, $2); }
-namespace_alias_definition:         NAMESPACE scoped_id '=' scoped_id ';'                       { $$ = YACC_NAMESPACE_ALIAS_DEFINITION($2, $4); }
-
-using_declaration:                  USING declarator_id ';'                                     { $$ = YACC_USING_DECLARATION(false, $2); }
-    |                               USING TYPENAME declarator_id ';'                            { $$ = YACC_USING_DECLARATION(true, $3); }
-
-using_directive:                    USING NAMESPACE scoped_id ';'                               { $$ = YACC_USING_DIRECTIVE($3); }
-asm_definition:                     ASM '(' string ')' ';'                                      { $$ = YACC_ASM_DEFINITION($3); }
-linkage_specification:              EXTERN string looping_declaration                           { $$ = YACC_LINKAGE_SPECIFIER($2, $3); }
-    |                               EXTERN string compound_declaration                          { $$ = YACC_LINKAGE_SPECIFIER($2, $3); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.7 Declarators
- *---------------------------------------------------------------------------------------------------*/
-/*init-declarator is named init_declaration to reflect the embedded decl-specifier-seq.opt*/
-init_declarations:                  assignment_expression ',' init_declaration                  { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); }
-    |                               init_declarations ',' init_declaration                      { $$ = YACC_EXPRESSIONS($1, $3); }
-init_declaration:                   assignment_expression
-/*  |                               assignment_expression '=' initializer_clause                -- covered by assignment_expression */
-/*  |                               assignment_expression '(' expression_list ')'               -- covered by another set of call arguments */
-
-/*declarator:                                                                                   -- covered by assignment_expression */
-/*direct_declarator:                                                                            -- covered by postfix_expression */
-
-star_ptr_operator:                  '*'                                                         { $$ = YACC_POINTER_DECLARATOR(); }
-    |                               star_ptr_operator cv_qualifier                              { $$ = YACC_CV_DECLARATOR($1, $2); }
-nested_ptr_operator:                star_ptr_operator                                           { $$ = $1; }
-    |                               id_scope nested_ptr_operator                                { $$ = YACC_NESTED_DECLARATOR($1, $2); }
-ptr_operator:                       '&'                                                         { $$ = YACC_REFERENCE_DECLARATOR(); }
-    |                               nested_ptr_operator                                         { $$ = $1; }
-    |                               global_scope nested_ptr_operator                            { $$ = YACC_GLOBAL_DECLARATOR($1, $2); }
-ptr_operator_seq:                   ptr_operator                                                { $$ = YACC_POINTER_EXPRESSION($1, YACC_EPSILON()); }
-    |                               ptr_operator ptr_operator_seq                               { $$ = YACC_POINTER_EXPRESSION($1, $2); }
-/* Independently coded to localise the shift-reduce conflict: sharing just needs another %prec */
-ptr_operator_seq.opt:               /* empty */                         %prec SHIFT_THERE       /* Maximise type length */ { $$ = YACC_EXPRESSION(0); }
-    |                               ptr_operator ptr_operator_seq.opt                           { $$ = YACC_POINTER_EXPRESSION($1, $2); }
-
-cv_qualifier_seq.opt:               /* empty */                                                 { $$ = YACC_CV_QUALIFIERS(0, 0); }
-    |                               cv_qualifier_seq.opt cv_qualifier                           { $$ = YACC_CV_QUALIFIERS($1, $2); }
-cv_qualifier:                       CONST | VOLATILE /* | CvQualifier */
-
-/*type_id                                                                                       -- also covered by parameter declaration */
-type_id:                            type_specifier abstract_declarator.opt                      { $$ = YACC_TYPED_EXPRESSION($1, $2); }
-    |                               type_specifier type_id                                      { $$ = YACC_TYPED_EXPRESSION($1, $2); }
-
-/*abstract_declarator:                                                                          -- also covered by parameter declaration */
-abstract_declarator.opt:            /* empty */                                                 { $$ = YACC_EPSILON(); }
-    |                               ptr_operator abstract_declarator.opt                        { $$ = YACC_POINTER_EXPRESSION($1, $2); }
-    |                               direct_abstract_declarator
-direct_abstract_declarator.opt:     /* empty */                                                 { $$ = YACC_EPSILON(); }
-    |                               direct_abstract_declarator
-direct_abstract_declarator:         direct_abstract_declarator.opt parenthesis_clause           { $$ = YACC_CALL_EXPRESSION($1, $2); }
-    |                               direct_abstract_declarator.opt '[' ']'                      { $$ = YACC_ARRAY_EXPRESSION($1, 0); }
-    |                               direct_abstract_declarator.opt '[' constant_expression ']'  { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
-/*  |                               '(' abstract_declarator ')'                                 -- covered by parenthesis_clause */
-
-parenthesis_clause:                 parameters_clause cv_qualifier_seq.opt                      { $$ = YACC_PARENTHESISED($1, $2, 0); }
-    |                               parameters_clause cv_qualifier_seq.opt exception_specification  { $$ = YACC_PARENTHESISED($1, $2, $3); }
-parameters_clause:                  '(' parameter_declaration_clause ')'                        { $$ = $2; }
-/* parameter_declaration_clause also covers init_declaration, type_id, declarator and abstract_declarator. */
-parameter_declaration_clause:       /* empty */                                                 { $$ = YACC_PARAMETERS(0, 0); }
-    |                               parameter_declaration_list
-    |                               parameter_declaration_list ELLIPSIS                         { $$ = YACC_PARAMETERS($1, YACC_ELLIPSIS_EXPRESSION()); }
-parameter_declaration_list:         parameter_declaration                                       { $$ = YACC_PARAMETERS(0, $1); }
-    |                               parameter_declaration_list ',' parameter_declaration        { $$ = YACC_PARAMETERS($1, $3); }
-
-/* A typed abstract qualifier such as
- *      Class * ...
- * looks like a multiply, so pointers are parsed as their binary operation equivalents that
- * ultimately terminate with a degenerate right hand term.
- */
-abstract_pointer_declaration:       ptr_operator_seq
-    |                               multiplicative_expression star_ptr_operator ptr_operator_seq.opt { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); }
-abstract_parameter_declaration:     abstract_pointer_declaration
-    |                               and_expression '&'                                          { $$ = YACC_AND_EXPRESSION($1, YACC_EPSILON()); }
-    |                               and_expression '&' abstract_pointer_declaration             { $$ = YACC_AND_EXPRESSION($1, $3); }
-special_parameter_declaration:      abstract_parameter_declaration
-    |                               abstract_parameter_declaration '=' assignment_expression    { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
-    |                               ELLIPSIS                                                    { $$ = YACC_ELLIPSIS_EXPRESSION(); }
-parameter_declaration:              assignment_expression                                       { $$ = YACC_EXPRESSION_PARAMETER($1); }
-    |                               special_parameter_declaration                               { $$ = YACC_EXPRESSION_PARAMETER($1); }
-    |                               decl_specifier_prefix parameter_declaration                 { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); }
-
-/*  The grammar is repeated for use within template <>
- */
-templated_parameter_declaration:    templated_assignment_expression                             { $$ = YACC_EXPRESSION_PARAMETER($1); }
-    |                               templated_abstract_declaration                              { $$ = YACC_EXPRESSION_PARAMETER($1); }
-    |                               templated_abstract_declaration '=' templated_assignment_expression
-                                                    { $$ = YACC_EXPRESSION_PARAMETER(YACC_ASSIGNMENT_EXPRESSION($1, $2, $3)); }
-    |                               decl_specifier_prefix templated_parameter_declaration       { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); }
-templated_abstract_declaration:     abstract_pointer_declaration
-    |                               templated_and_expression '&'                                { $$ = YACC_AND_EXPRESSION($1, 0); }
-    |                               templated_and_expression '&' abstract_pointer_declaration   { $$ = YACC_AND_EXPRESSION($1, $3); }
-
-/*  function_definition includes constructor, destructor, implicit int definitions too.
- *  A local destructor is successfully parsed as a function-declaration but the ~ was treated as a unary operator.
- *  constructor_head is the prefix ambiguity between a constructor and a member-init-list starting with a bit-field.
- */
-function_definition:        ctor_definition
-    |                       func_definition
-func_definition:            assignment_expression function_try_block                    { $$ = YACC_FUNCTION_DEFINITION($1, $2); }
-    |                       assignment_expression function_body                         { $$ = YACC_FUNCTION_DEFINITION($1, $2); }
-    |                       decl_specifier_prefix func_definition                       { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
-ctor_definition:            constructor_head function_try_block                         { $$ = YACC_CTOR_DEFINITION($1, $2); }
-    |                       constructor_head function_body                              { $$ = YACC_CTOR_DEFINITION($1, $2); }
-    |                       decl_specifier_prefix ctor_definition                       { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
-constructor_head:           bit_field_init_declaration                                  { $$ = YACC_EXPRESSIONS(0, $1); }
-    |                       constructor_head ',' assignment_expression                  { $$ = YACC_EXPRESSIONS($1, $3); }
-function_try_block:         TRY function_block handler_seq                              { $$ = YACC_TRY_FUNCTION_BLOCK($2, $3); }
-function_block:             ctor_initializer.opt function_body                          { $$ = YACC_CTOR_FUNCTION_BLOCK($2, $1); }
-function_body:              compound_statement                                          { $$ = YACC_FUNCTION_BLOCK($1); }
-
-/*  An = initializer looks like an extended assignment_expression.
- *  An () initializer looks like a function call.
- *  initializer is therefore flattened into its generalised customers.
- *initializer:              '=' initializer_clause                                      -- flattened into caller
- *  |                       '(' expression_list ')'                                     -- flattened into caller */
-initializer_clause:         assignment_expression                                       { $$ = YACC_INITIALIZER_EXPRESSION_CLAUSE($1); }
-    |                       braced_initializer
-braced_initializer:         '{' initializer_list '}'                                    { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); }
-    |                       '{' initializer_list ',' '}'                                { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); }
-    |                       '{' '}'                                                     { $$ = YACC_INITIALIZER_LIST_CLAUSE(0); }
-    |                       '{' looping_initializer_clause '#' bang error '}'           { $$ = 0; YACC_UNBANG($4, "Bad initializer_clause."); }
-    |                       '{' initializer_list ',' looping_initializer_clause '#' bang error '}'
-                                                                                        { $$ = $2; YACC_UNBANG($6, "Bad initializer_clause."); }
-initializer_list:           looping_initializer_clause                                  { $$ = YACC_INITIALIZER_CLAUSES(0, $1); }
-    |                       initializer_list ',' looping_initializer_clause             { $$ = YACC_INITIALIZER_CLAUSES($1, $3); }
-looping_initializer_clause: start_search looped_initializer_clause                      { $$ = $2; end_search($$); }
-looped_initializer_clause:  initializer_clause
-    |                       advance_search '+' looped_initializer_clause                { $$ = $3; }
-    |                       advance_search '-'                                          { $$ = 0; }
-
-/*---------------------------------------------------------------------------------------------------
- * A.8 Classes
- *---------------------------------------------------------------------------------------------------
- *
- *  An anonymous bit-field declaration may look very like inheritance:
- *      class A : B = 3;
- *      class A : B ;
- *  The two usages are too distant to try to create and enforce a common prefix so we have to resort to
- *  a parser hack by backtracking. Inheritance is much the most likely so we mark the input stream context
- *  and try to parse a base-clause. If we successfully reach a { the base-clause is ok and inheritance was
- *  the correct choice so we unmark and continue. If we fail to find the { an error token causes back-tracking
- *  to the alternative parse in elaborated_class_specifier which regenerates the : and declares unconditional success.
- */
-colon_mark:                 ':'                                                         { $$ = mark(); }
-elaborated_class_specifier: class_key scoped_id                    %prec SHIFT_THERE    { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
-    |                       class_key scoped_id colon_mark error                        { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); rewind_colon($3, $$); }
-class_specifier_head:       class_key scoped_id colon_mark base_specifier_list '{'      { unmark($4); $$ = YACC_CLASS_SPECIFIER_ID($1, $2, $4); }
-    |                       class_key ':' base_specifier_list '{'                       { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, $3); }
-    |                       class_key scoped_id '{'                                     { $$ = YACC_CLASS_SPECIFIER_ID($1, $2, 0); }
-    |                       class_key '{'                                               { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, 0); }
-class_key:                  CLASS | STRUCT | UNION
-class_specifier:            class_specifier_head member_specification.opt '}'           { $$ = YACC_CLASS_MEMBERS($1, $2); }
-    |                       class_specifier_head member_specification.opt util looping_member_declaration '#' bang error '}'
-                                            { $$ = YACC_CLASS_MEMBERS($1, $2); YACC_UNBANG($6, "Bad member_specification.opt."); }
-member_specification.opt:   /* empty */                                                 { $$ = YACC_MEMBER_DECLARATIONS(0, 0); }
-    |                       member_specification.opt util looping_member_declaration    { $$ = YACC_MEMBER_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); }
-    |                       member_specification.opt util looping_member_declaration '#' bang error ';'
-                                                                                                { $$ = $1; YACC_UNBANG($5, "Bad member-declaration."); }
-looping_member_declaration: start_search looped_member_declaration                      { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); }
-looped_member_declaration:  member_declaration
-    |                       advance_search '+' looped_member_declaration                { $$ = $3; }
-    |                       advance_search '-'                                          { $$ = 0; }
-member_declaration:         accessibility_specifier
-    |                       simple_member_declaration                                   { $$ = YACC_SIMPLE_DECLARATION($1); }
-    |                       function_definition                                         { $$ = YACC_SIMPLE_DECLARATION($1); }
-/*  |                       function_definition ';'                                     -- trailing ; covered by null declaration */
-/*  |                       qualified_id ';'                                            -- covered by simple_member_declaration */
-    |                       using_declaration
-    |                       template_declaration
-
-/*  The generality of constructor names (there need be no parenthesised argument list) means that that
- *          name : f(g), h(i)
- *  could be the start of a constructor or the start of an anonymous bit-field. An ambiguity is avoided by
- *  parsing the ctor-initializer of a function_definition as a bit-field.
- */
-simple_member_declaration:  ';'                                                         { $$ = YACC_EXPRESSION(0); }
-    |                       assignment_expression ';'
-    |                       constructor_head ';'                                        { $$ = $1; }
-    |                       member_init_declarations ';'                                { $$ = $1; }
-    |                       decl_specifier_prefix simple_member_declaration             { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
-member_init_declarations:   assignment_expression ',' member_init_declaration           { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); }
-    |                       constructor_head ',' bit_field_init_declaration             { $$ = YACC_EXPRESSIONS($1, $3); }
-    |                       member_init_declarations ',' member_init_declaration        { $$ = YACC_EXPRESSIONS($1, $3); }
-member_init_declaration:    assignment_expression
-/*  |                       assignment_expression '=' initializer_clause                -- covered by assignment_expression */
-/*  |                       assignment_expression '(' expression_list ')'               -- covered by another set of call arguments */
-    |                       bit_field_init_declaration
-accessibility_specifier:    access_specifier ':'                                        { $$ = YACC_ACCESSIBILITY_SPECIFIER($1); }
-bit_field_declaration:      assignment_expression ':' bit_field_width                   { $$ = YACC_BIT_FIELD_EXPRESSION($1, $3); }
-    |                       ':' bit_field_width                                         { $$ = YACC_BIT_FIELD_EXPRESSION(0, $2); }
-bit_field_width:            logical_or_expression
-/*  |                       logical_or_expression '?' expression ':' assignment_expression  -- has SR conflict w.r.t later = */
-    |                       logical_or_expression '?' bit_field_width ':' bit_field_width { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
-bit_field_init_declaration: bit_field_declaration
-    |                       bit_field_declaration '=' initializer_clause                { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.9 Derived classes
- *---------------------------------------------------------------------------------------------------*/
-/*base_clause:              ':' base_specifier_list                                     -- flattened */
-base_specifier_list:        base_specifier                                              { $$ = YACC_BASE_SPECIFIERS(0, $1); }
-    |                       base_specifier_list ',' base_specifier                      { $$ = YACC_BASE_SPECIFIERS($1, $3); }
-base_specifier:             scoped_id                                                   { $$ = YACC_BASE_SPECIFIER($1); }
-    |                       access_specifier base_specifier                             { $$ = YACC_ACCESS_BASE_SPECIFIER($2, $1); }
-    |                       VIRTUAL base_specifier                                      { $$ = YACC_VIRTUAL_BASE_SPECIFIER($2); }
-access_specifier:           PRIVATE | PROTECTED | PUBLIC
-
-/*---------------------------------------------------------------------------------------------------
- * A.10 Special member functions
- *---------------------------------------------------------------------------------------------------*/
-conversion_function_id:     OPERATOR conversion_type_id                                 { $$ = YACC_CONVERSION_FUNCTION_ID($2); }
-conversion_type_id:         type_specifier ptr_operator_seq.opt                         { $$ = YACC_TYPED_EXPRESSION($1, $2); }
-    |                       type_specifier conversion_type_id                           { $$ = YACC_TYPED_EXPRESSION($1, $2); }
-/*
- *  Ctor-initialisers can look like a bit field declaration, given the generalisation of names:
- *      Class(Type) : m1(1), m2(2) {}
- *      NonClass(bit_field) : int(2), second_variable, ...
- *  The grammar below is used within a function_try_block or function_definition.
- *  See simple_member_declaration for use in normal member function_definition.
- */
-ctor_initializer.opt:       /* empty */                                                 { $$ = YACC_MEM_INITIALIZERS(0, 0); }
-    |                       ctor_initializer
-ctor_initializer:           ':' mem_initializer_list                                    { $$ = $2; }
-    |                       ':' mem_initializer_list bang error                         { $$ = $2; YACC_UNBANG($3, "Bad ctor-initializer."); }
-mem_initializer_list:       mem_initializer                                             { $$ = YACC_MEM_INITIALIZERS(0, $1); }
-    |                       mem_initializer_list_head mem_initializer                   { $$ = YACC_MEM_INITIALIZERS($1, $2); }
-mem_initializer_list_head:  mem_initializer_list ','
-    |                       mem_initializer_list bang error ','                         { YACC_UNBANG($2, "Bad mem-initializer."); }
-mem_initializer:            mem_initializer_id '(' expression_list.opt ')'              { $$ = YACC_MEM_INITIALIZER($1, $3); }
-mem_initializer_id:         scoped_id
-
-/*---------------------------------------------------------------------------------------------------
- * A.11 Overloading
- *---------------------------------------------------------------------------------------------------*/
-operator_function_id:       OPERATOR operator                                           { $$ = YACC_OPERATOR_FUNCTION_ID($2); }
-/*
- *  It is not clear from the ANSI standard whether spaces are permitted in delete[]. If not then it can
- *  be recognised and returned as DELETE_ARRAY by the lexer. Assuming spaces are permitted there is an
- *  ambiguity created by the over generalised nature of expressions. operator new is a valid delarator-id
- *  which we may have an undimensioned array of. Semantic rubbish, but syntactically valid. Since the
- *  array form is covered by the declarator consideration we can exclude the operator here. The need
- *  for a semantic rescue can be eliminated at the expense of a couple of shift-reduce conflicts by
- *  removing the comments on the next four lines.
- */
-operator:             /*++++*/      NEW                                                         { $$ = YACC_OPERATOR_NEW_ID(); }
-    |                 /*++++*/      DELETE                                                      { $$ = YACC_OPERATOR_DELETE_ID(); }
-/*  |                 / ---- /      NEW                 %prec SHIFT_THERE                       { $$ = YACC_OPERATOR_NEW_ID(); }
-/*  |                 / ---- /      DELETE              %prec SHIFT_THERE                       { $$ = YACC_OPERATOR_DELETE_ID(); }
-/*  |                 / ---- /      NEW '[' ']'                                                 -- Covered by array of OPERATOR NEW */
-/*  |                 / ---- /      DELETE '[' ']'                                              -- Covered by array of OPERATOR DELETE */
-    |                               '+'                                                         { $$ = YACC_OPERATOR_ADD_ID(); }
-    |                               '-'                                                         { $$ = YACC_OPERATOR_SUB_ID(); }
-    |                               '*'                                                         { $$ = YACC_OPERATOR_MUL_ID(); }
-    |                               '/'                                                         { $$ = YACC_OPERATOR_DIV_ID(); }
-    |                               '%'                                                         { $$ = YACC_OPERATOR_MOD_ID(); }
-    |                               '^'                                                         { $$ = YACC_OPERATOR_XOR_ID(); }
-    |                               '&'                                                         { $$ = YACC_OPERATOR_BIT_AND_ID(); }
-    |                               '|'                                                         { $$ = YACC_OPERATOR_BIT_OR_ID(); }
-    |                               '~'                                                         { $$ = YACC_OPERATOR_BIT_NOT_ID(); }
-    |                               '!'                                                         { $$ = YACC_OPERATOR_LOG_NOT_ID(); }
-    |                               '='                                                         { $$ = YACC_OPERATOR_ASS_ID(); }
-    |                               '<'                                                         { $$ = YACC_OPERATOR_LT_ID(); }
-    |                               '>'                                                         { $$ = YACC_OPERATOR_GT_ID(); }
-    |                               ASS_ADD                                                     { $$ = YACC_OPERATOR_ASS_ADD_ID(); }
-    |                               ASS_SUB                                                     { $$ = YACC_OPERATOR_ASS_SUB_ID(); }
-    |                               ASS_MUL                                                     { $$ = YACC_OPERATOR_ASS_MUL_ID(); }
-    |                               ASS_DIV                                                     { $$ = YACC_OPERATOR_ASS_DIV_ID(); }
-    |                               ASS_MOD                                                     { $$ = YACC_OPERATOR_ASS_MOD_ID(); }
-    |                               ASS_XOR                                                     { $$ = YACC_OPERATOR_ASS_XOR_ID(); }
-    |                               ASS_AND                                                     { $$ = YACC_OPERATOR_ASS_BIT_AND_ID(); }
-    |                               ASS_OR                                                      { $$ = YACC_OPERATOR_ASS_BIT_OR_ID(); }
-    |                               SHL                                                         { $$ = YACC_OPERATOR_SHL_ID(); }
-    |                               SHR                                                         { $$ = YACC_OPERATOR_SHR_ID(); }
-    |                               ASS_SHR                                                     { $$ = YACC_OPERATOR_ASS_SHR_ID(); }
-    |                               ASS_SHL                                                     { $$ = YACC_OPERATOR_ASS_SHL_ID(); }
-    |                               EQ                                                          { $$ = YACC_OPERATOR_EQ_ID(); }
-    |                               NE                                                          { $$ = YACC_OPERATOR_NE_ID(); }
-    |                               LE                                                          { $$ = YACC_OPERATOR_LE_ID(); }
-    |                               GE                                                          { $$ = YACC_OPERATOR_GE_ID(); }
-    |                               LOG_AND                                                     { $$ = YACC_OPERATOR_LOG_AND_ID(); }
-    |                               LOG_OR                                                      { $$ = YACC_OPERATOR_LOG_OR_ID(); }
-    |                               INC                                                         { $$ = YACC_OPERATOR_INC_ID(); }
-    |                               DEC                                                         { $$ = YACC_OPERATOR_DEC_ID(); }
-    |                               ','                                                         { $$ = YACC_OPERATOR_COMMA_ID(); }
-    |                               ARROW_STAR                                                  { $$ = YACC_OPERATOR_ARROW_STAR_ID(); }
-    |                               ARROW                                                       { $$ = YACC_OPERATOR_ARROW_ID(); }
-    |                               '(' ')'                                                     { $$ = YACC_OPERATOR_CALL_ID(); }
-    |                               '[' ']'                                                     { $$ = YACC_OPERATOR_INDEX_ID(); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.12 Templates
- *---------------------------------------------------------------------------------------------------*/
-template_declaration:               template_parameter_clause declaration                       { $$ = YACC_TEMPLATE_DECLARATION($1, $2); }
-    |                               EXPORT template_declaration                                 { $$ = YACC_DECL_SPECIFIER_DECLARATION($2, $1); }
-template_parameter_clause:          TEMPLATE '<' template_parameter_list '>'                    { $$ = $3; }
-template_parameter_list:            template_parameter                                          { $$ = YACC_TEMPLATE_PARAMETERS(0, $1); }
-    |                               template_parameter_list ',' template_parameter              { $$ = YACC_TEMPLATE_PARAMETERS($1, $3); }
-template_parameter:                 simple_type_parameter                                       { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, 0); }
-    |                               simple_type_parameter '=' type_id                           { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, $3); }
-    |                               templated_type_parameter                                    { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, 0); }
-    |                               templated_type_parameter '=' identifier                     { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, $3); }
-    |                               templated_parameter_declaration                             { $$ = YACC_TEMPLATE_PARAMETER($1); }
-    |                               bang error                                                  { $$ = 0; YACC_UNBANG($1, "Bad template-parameter."); }
-simple_type_parameter:              CLASS                                                       { $$ = YACC_CLASS_TYPE_PARAMETER(0); }
-/*  |                               CLASS identifier                                            -- covered by parameter_declaration */
-    |                               TYPENAME                                                    { $$ = YACC_TYPENAME_TYPE_PARAMETER(0); }
-/*  |                               TYPENAME identifier                                         -- covered by parameter_declaration */
-templated_type_parameter:           template_parameter_clause CLASS                             { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, 0); }
-    |                               template_parameter_clause CLASS identifier                  { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, $3); }
-template_id:                        TEMPLATE identifier '<' template_argument_list '>'          { $$ = YACC_TEMPLATE_NAME($2, $4); }
-    |                               TEMPLATE template_id                                        { $$ = $2; }
-/*
- *  template-argument is evaluated using a templated...expression so that > resolves to end of template.
- */
-template_argument_list:             template_argument                                           { $$ = YACC_TEMPLATE_ARGUMENTS(0, $1); }
-    |                               template_argument_list ',' template_argument                { $$ = YACC_TEMPLATE_ARGUMENTS($1, $3); }
-template_argument:                  templated_parameter_declaration                             { $$ = YACC_TEMPLATE_ARGUMENT($1); }
-/*  |                               type_id                                                     -- covered by templated_parameter_declaration */
-/*  |                               template_name                                               -- covered by templated_parameter_declaration */
-/*  |                               error                                                       -- must allow template failure to re-search */
-
-/*
- *  Generalised naming makes identifier a valid declaration, so TEMPLATE identifier is too.
- *  The TEMPLATE prefix is therefore folded into all names, parenthesis_clause and decl_specifier_prefix.
- */
-/*explicit_instantiation:           TEMPLATE declaration */
-explicit_specialization:            TEMPLATE '<' '>' declaration                                { $$ = YACC_EXPLICIT_SPECIALIZATION($4); }
-
-/*---------------------------------------------------------------------------------------------------
- * A.13 Exception Handling
- *---------------------------------------------------------------------------------------------------*/
-try_block:                          TRY compound_statement handler_seq                          { $$ = YACC_TRY_BLOCK($2, $3); }
-/*function_try_block:                                                                           -- moved near function_block */
-handler_seq:                        handler                                                     { $$ = YACC_HANDLERS(0, $1); }
-    |                               handler handler_seq                                         { $$ = YACC_HANDLERS($2, $1); }
-handler:                            CATCH '(' exception_declaration ')' compound_statement      { $$ = YACC_HANDLER($3, $5); }
-exception_declaration:              parameter_declaration                                       { $$ = YACC_EXCEPTION_DECLARATION($1); }
-/*                                  ELLIPSIS                                                    -- covered by parameter_declaration */
-throw_expression:                   THROW                                                       { $$ = YACC_THROW_EXPRESSION(0); }
-    |                               THROW assignment_expression                                 { $$ = YACC_THROW_EXPRESSION($2); }
-templated_throw_expression:         THROW                                                       { $$ = YACC_THROW_EXPRESSION(0); }
-    |                               THROW templated_assignment_expression                       { $$ = YACC_THROW_EXPRESSION($2); }
-exception_specification:            THROW '(' ')'                                               { $$ = YACC_EXCEPTION_SPECIFICATION(0); }
-    |                               THROW '(' type_id_list ')'                                  { $$ = YACC_EXCEPTION_SPECIFICATION($3); }
-type_id_list:                       type_id                                                     { $$ = YACC_EXPRESSIONS(0, $1); }
-    |                               type_id_list ',' type_id                                    { $$ = YACC_EXPRESSIONS($1, $3); }
-
-/*---------------------------------------------------------------------------------------------------
- * Back-tracking and context support
- *---------------------------------------------------------------------------------------------------*/
-advance_search:                     error               { yyerrok; advance_search(); } /* Rewind and queue '+' or '-' '#' */       
-bang:                               /* empty */         { $$ = YACC_BANG(); }   /* set flag to suppress "parse error" */ 
-mark:                               /* empty */         { $$ = mark(); }        /* Push lookahead and input token stream context onto a stack */
-nest:                               /* empty */         { $$ = nest(); }        /* Push a declaration nesting depth onto the parse stack */
-start_search:                       /* empty */         { $$ = YACC_LINE(); start_search(false); }    /* Create/reset binary search context */
-start_search1:                      /* empty */         { $$ = YACC_LINE(); start_search(true); }     /* Create/reset binary search context */
-util:                               /* empty */         { $$ = YACC_UTILITY_MODE(); }           /* Get current utility mode */
-/*StartTester*/
-%%
-#include <CxxParsing.cxx>
-/*EndTester*/
diff --git a/examples/cpp_grammar_code/CxxParsing.cxx b/examples/cpp_grammar_code/CxxParsing.cxx
deleted file mode 100644 (file)
index 19be7e8..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-#include <iostream.h>
-#include <memory.h>
-#include <CxxToken.hxx>
-
-extern CxxToken *yylex_token();
-
-#ifdef BISON_PP_CLASS
-BISON_PP_CLASS theParser;
-#define PARSE_DOT theParser .
-#define PARSE_SCOPE BISON_PP_CLASS ::
-#else
-#define PARSE_DOT
-#define PARSE_SCOPE
-extern int yydebug;
-#ifndef YYEMPTY
-#define YYEMPTY -1
-#endif
-#endif
-
-class CxxSearchContext
-{
-    friend class ios;                   // Suppress GNU error message for no public constructors.
-       CxxSearchContext *_next;
-       size_t _index;
-       size_t _depth;
-       size_t _size;
-       size_t _mark;
-       bool _enable_type1;
-       size_t _line;
-       size_t _advances;
-       bool _status[32];
-private:
-       CxxSearchContext(CxxSearchContext *nextSearch)
-               : _next(nextSearch), _index(0), _depth(0), _size(sizeof(_status)/sizeof(_status[0])),
-               _mark(0), _enable_type1(false), _line(0), _advances(0) {}
-       CxxSearchContext(const CxxSearchContext&);
-       CxxSearchContext& operator=(const CxxSearchContext&);
-       bool did_search() const { return _depth > 0 ? true : false; }
-       void initialise(size_t markIndex, bool enableType1);
-       CxxSearchContext *queue(CxxSearchContext *& listHead);
-       void reset();
-public:
-       bool advance();
-       bool enable_type1() const { return _enable_type1; }
-       bool is_template();
-       size_t mark() const { return _mark; }
-private:
-       static CxxSearchContext *_current;
-       static CxxSearchContext *_free;
-public:
-       static size_t actual_searches;
-       static size_t advances[16];
-       static size_t max_search_depth;
-       static size_t nested_searches;
-       static size_t releases;
-       static size_t search_advances;
-       static size_t unnested_searches;
-public:
-       static CxxSearchContext *current() { return _current; }
-       static void release();
-       static void start(YACC_MARK_TYPE anIndex, bool enableType1);
-};
-
-size_t bang_depth = 0;
-size_t error_count = 0;
-size_t marked_error_count = 0;
-bool in_type1 = false;
-bool show_marked = false;
-
-int main(int argc, char *argv[])
-{
-       for (--argc, ++argv; argc-- > 0; ++argv)
-       {
-               char *p = *argv;
-               if (*p == '-')
-               {
-                       switch (*(p+1))
-                       {
-                               case 'c':
-                                       c_keywords = true;
-                                       break;
-                               case 't':
-                                       echo_line_text = true;
-                                       break;
-                               case 'm':
-                                       show_marked = true;
-                                       break;
-                               case 'n':
-                                       echo_line_numbers = true;
-                                       break;
-                               case 'y':
-                                       PARSE_DOT yydebug = true;
-                                       break;
-                       }
-               }
-       }
-       if (PARSE_DOT yyparse() != 0)
-               ERRMSG("Failed to parse to end of file,");
-       cout << "error_count = " << error_count
-                << ", marked_error_count = " << marked_error_count
-                << ", lines = " << line_number
-                << ", unnested_searches = " << CxxSearchContext::unnested_searches
-                << ", nested_searches = " << CxxSearchContext::nested_searches
-                << ", releases = " << CxxSearchContext::releases
-                << ", actual_searches = " << CxxSearchContext::actual_searches
-                << ", max_search_depth = " << CxxSearchContext::max_search_depth
-                << ", search_advances = " << CxxSearchContext::search_advances << endl;
-       cout << "number of occurences of each advance"; 
-       for (size_t i = 0; i < sizeof(CxxSearchContext::advances)/sizeof(CxxSearchContext::advances[0]); i++)
-               cout << ' ' << CxxSearchContext::advances[i];
-       cout << endl;   
-       return 0;
-}
-
-static CxxToken **tokenBuffer = 0;                             // Allocated buffer
-static YACC_MARK_TYPE tokenReadIndex = 0;              // Read index
-static size_t tokenSize = 0;                                   // Allocate buffer size
-static YACC_MARK_TYPE tokenWriteIndex = 0;             // Write index
-int tokenMarkDepth = 0;                                                // Write index
-static CxxToken *primed_tokens[3] = {0, 0};            // Restarting sequence
-static void token_put(CxxToken *aToken);
-
-CxxSearchContext *CxxSearchContext::_current = 0;
-CxxSearchContext *CxxSearchContext::_free = 0;
-size_t CxxSearchContext::actual_searches = 0;
-size_t CxxSearchContext::advances[16] = { 0 };
-size_t CxxSearchContext::max_search_depth = 0;
-size_t CxxSearchContext::nested_searches = 0;
-size_t CxxSearchContext::releases = 0;
-size_t CxxSearchContext::search_advances;
-size_t CxxSearchContext::unnested_searches;
-
-//
-//     Implements a binary search counter, performing the increment at the
-//     _index of othe failed search.
-//
-bool CxxSearchContext::advance()
-{
-       _advances++;
-       size_t i = _depth;
-       if (i <= 0)
-               return false;
-       while (--i > _index)
-               _status[i] = false;
-       while (true)
-       {
-               if (!_status[i])
-               {
-                       _status[i] = true;
-                       _index = 0;
-                       return true;
-               }
-               if (i <= 0)
-                       return false;
-               _status[i--] = false;
-       }
-}
-
-void CxxSearchContext::initialise(size_t markIndex, bool enableType1)
-{
-       _index = 0;
-       _depth = 0;
-       _mark = markIndex;
-    _enable_type1 = enableType1;
-       _line = line_number;
-       _advances = 0;
-}
-
-bool CxxSearchContext::is_template()
-{
-       if (_index >= _depth)
-       {
-               if (_depth >= _size)
-               {
-                       ERRMSG("Binary search depth exceeded.");
-                       return false;
-               }
-               _status[_depth++] = false;
-               if (_depth > max_search_depth)
-                       max_search_depth = _depth;
-       }
-       return _status[_index++] ? false : true;
-}
-
-//
-//     Put this element onto listHead, returning element under this one.
-//
-CxxSearchContext *CxxSearchContext::queue(CxxSearchContext *& listHead)
-{
-       CxxSearchContext *oldNext = _next;
-       _next = listHead;
-       listHead = this;
-       return oldNext;
-}
-
-//
-//     Release the current search buffer.
-//
-void CxxSearchContext::release()
-{
-       if (_current)
-       {
-               releases++;
-               _current->reset();
-               _current = _current->queue(_free);
-       }
-}
-
-void CxxSearchContext::reset()
-{
-       if (did_search())
-       {
-               _advances++;
-               actual_searches++;
-       }
-       if (_advances >= sizeof(advances)/sizeof(advances[0]))
-               advances[sizeof(advances)/sizeof(advances[0])-1]++;
-       else
-               advances[_advances]++;
-}
-
-void CxxSearchContext::start(YACC_MARK_TYPE anIndex, bool enableType1)
-{
-       if (!_current)
-               unnested_searches++;
-       else
-               nested_searches++;
-       if (!_free)
-               _current = new CxxSearchContext(_current);
-       else
-               _free = _free->queue(_current);
-       _current->initialise(anIndex, enableType1);
-}
-
-static CxxToken angleToken('<');
-static CxxToken colonToken(':');
-static CxxToken hashToken('#');
-static CxxToken plusToken('+');
-static CxxToken minusToken('-');
-
-void PARSE_SCOPE yyerror(const char *s)
-{
-       if (!bang_depth && (tokenMarkDepth == 0))
-       {
-               cout << s << endl;
-               increment_error_count();
-       }
-       else
-       {
-               if (show_marked)
-                       cout << "Marked " << s << endl;         
-               marked_error_count++;
-       }
-}
-
-//
-//     Get the next token for the parser, invoking yylex_token to get the next token from the lexer.
-//     This routine gets renamed to buffered_yylex by a #define when using yacc so that the two purposes
-//     above are split allowing lookahead buffering and primimimg to occur.
-//
-int PARSE_SCOPE yylex()
-{
-       CxxToken *aToken = primed_tokens[0];
-       if (aToken)
-       {
-               primed_tokens[0] = primed_tokens[1];
-               primed_tokens[1] = primed_tokens[2];
-               primed_tokens[2] = 0;
-       }
-       else if (tokenReadIndex < tokenWriteIndex)
-               aToken = tokenBuffer[tokenReadIndex++];
-       else
-       {
-               aToken = yylex_token();
-               if (!aToken)
-                       return 0;
-               if (tokenMarkDepth > 0)
-                       token_put(aToken);
-               else
-               {
-                       tokenWriteIndex = 0;
-                       tokenReadIndex = 0;
-               }
-       }
-       yylval.token = aToken;
-       return aToken->value();
-}
-
-//
-//     Advance the binary search of template attempts. Rewinds and forces true into the input sequence
-//     to proceed with the search. Rewinds and forces false to terminate it. Also forces a # that may then
-//     be used to initiate error propagation.
-//
-void advance_search()
-{
-       CxxSearchContext::search_advances++;
-       remark(CxxSearchContext::current()->mark());
-       if (CxxSearchContext::current() && CxxSearchContext::current()->advance())
-       {
-               primed_tokens[0] = &plusToken;
-               primed_tokens[1] = 0;
-       }
-       else
-       {
-               primed_tokens[0] = &minusToken;
-               primed_tokens[1] = &hashToken;
-       }
-}
-
-//
-//     Complete a search, releasing the search context object and popping a mark off the stack.
-//
-void end_search(CxxToken *aToken)
-{
-       CxxSearchContext::release();
-       unmark(aToken);
-}
-
-//
-//     Notch up an error and establish a good break point.
-//
-void increment_error_count()
-{
-       error_count++;
-}
-
-//
-//     Push a new marked context onto the stack, returning its identity for use by remark().
-//     Any parser readahead is incorporated within the marked region.
-//
-YACC_MARK_TYPE mark()
-{
-       if (primed_tokens[0])
-               ERRMSG("Unexpected primed_tokens[0] in mark.");
-       YACC_MARK_TYPE markIndex = tokenReadIndex;
-       if (PARSE_DOT yychar != YYEMPTY)
-       {
-//             if (primed_tokens[2])
-//                     token_put(primed_tokens[2]);
-//             if (primed_tokens[1])
-//                     token_put(primed_tokens[1]);
-//             if (primed_tokens[0])
-//                     token_put(primed_tokens[0]);
-//             if (!tokenMarkDepth)
-               if (!tokenReadIndex && !tokenWriteIndex)
-               {
-                       token_put(PARSE_DOT yylval.token);
-                       tokenReadIndex = 0;
-               }
-               else if (!tokenReadIndex)
-                       ERRMSG("Unexpected 0 read index in mark.");
-               else if (tokenBuffer[--tokenReadIndex] != PARSE_DOT yylval.token)
-                       ERRMSG("Unexpected unget in mark.");
-               markIndex = tokenReadIndex;
-               yyclearin;
-               primed_tokens[0] = 0;
-               primed_tokens[1] = 0;
-       }
-       tokenMarkDepth++; 
-       bang_depth++;
-       return markIndex;
-}
-
-//
-//     If it is appropriate to do type I function parameter parsing perform a mark and force a rrue token
-//     into the input stream. Otherwise just force a false token in.
-//
-YACC_MARK_TYPE mark_type1()
-{
-       if (!in_type1 && CxxSearchContext::current() && CxxSearchContext::current()->enable_type1())
-       {
-               YACC_MARK_TYPE markIndex = mark();
-               primed_tokens[0] = &plusToken;
-               primed_tokens[1] = 0;
-               in_type1 = true;
-        yyclearin; 
-               return markIndex;
-       }
-       else
-       {
-               primed_tokens[0] = &minusToken;
-               primed_tokens[1] = PARSE_DOT yychar != YYEMPTY ? PARSE_DOT yylval.token : 0;
-        yyclearin; 
-               return 0;                       // Never used.
-       }
-}      
-
-//
-//     Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang.
-//
-void pop_bang(YACC_BANG_TYPE bangValue)
-{
-       bang_depth = bangValue;
-}
-
-//
-//     Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang.
-//
-YACC_BANG_TYPE push_bang()
-{
-       return bang_depth++;
-}
-
-//
-//     Reposition the input to restart at the position returned by a mark().
-//
-void remark(YACC_MARK_TYPE anIndex)
-{
-       tokenReadIndex = anIndex;
-    yyclearin;
-}
-
-//
-//     Reposition the input to restart at the position returned by a mark().
-//
-void remark_type1(YACC_MARK_TYPE anIndex)
-{
-       remark(anIndex);
-       in_type1 = false;
-}
-
-//
-//     Rewind the input stream back to anIndex and force a : prior to resuming input.
-//
-void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken)
-{
-       remark(anIndex);
-       unmark();
-       primed_tokens[0] = &colonToken;
-       primed_tokens[1] = PARSE_DOT yylval.token;
-}
-
-//
-//     Start a new binary search over the template/arithmetic alternative parses of a statement.
-//     Marks the current position and saves it in a binary search context maintained on a private stack.
-//
-void start_search(bool enableType1)
-{
-       bool type1Enabled = !CxxSearchContext::current() || CxxSearchContext::current()->enable_type1() ? true : false;
-       CxxSearchContext::start(mark(), enableType1 && type1Enabled ? true : false);
-}
-
-//
-//     Determine whether the just parsed < should be interpreted as a template or arithmetic operator.
-//     The implementation here intersacts with a binary search to traverse all possibilities in
-//     multiple passes. The search proceeds by branch and bound presuming the template interpretation.
-//     A true token is forced into the input stream to take the template interpretaion. A false token
-//     otherwise.
-//
-//     An alternate implementation that keeps track of scopes may interact with semantic knowledge to make
-//     the correct decision directly.
-//
-void template_test()
-{
-       if (!CxxSearchContext::current() || CxxSearchContext::current()->is_template())
-       {
-               primed_tokens[0] = &plusToken;
-               primed_tokens[1] = 0;
-       }
-       else
-       {
-               primed_tokens[0] = &minusToken;
-               primed_tokens[1] = &angleToken;
-       }
-}
-
-void token_put(CxxToken *aToken)
-{
-       if (!tokenBuffer || !tokenSize)
-               tokenBuffer = new CxxToken *[tokenSize = 256];
-       else if (tokenWriteIndex >= tokenSize)
-       {
-               CxxToken **oldTokenBuffer = tokenBuffer;
-               size_t oldTokenSize = tokenSize;
-               tokenBuffer = new CxxToken *[tokenSize *= 2];
-               memcpy(tokenBuffer, oldTokenBuffer, oldTokenSize * sizeof(*oldTokenBuffer));
-               delete[] oldTokenBuffer;
-       }
-       tokenBuffer[tokenWriteIndex++] = aToken;
-       tokenReadIndex = tokenWriteIndex;
-}
-
-//
-//     Pop a marked context off the stack.
-//
-void unmark(const CxxToken *aToken)
-{
-    if (bang_depth)
-        bang_depth--;
-    else
-        ERRMSG("BUG - should not unmark with 0 bang.");
-       if (tokenMarkDepth <= 0)
-               ERRMSG("Unexpected unmark.");
-       else
-               tokenMarkDepth--;
-}
diff --git a/examples/cpp_grammar_code/CxxParsing.hxx b/examples/cpp_grammar_code/CxxParsing.hxx
deleted file mode 100644 (file)
index d5dc031..0000000
+++ /dev/null
@@ -1,667 +0,0 @@
-#include <CxxToken.hxx>
-#include <stdio.h>
-#ifndef _MSC_VER
-#include <alloca.h>
-#else
-#include <malloc.h>
-//#define alloca _alloca
-#endif
-void advance_search();
-void end_search(CxxToken *aToken);
-YACC_MARK_TYPE mark();
-YACC_MARK_TYPE mark_type1();
-size_t nest() { return 0; }
-void pop_bang(YACC_BANG_TYPE bangValue);
-YACC_BANG_TYPE push_bang();
-void remark(YACC_MARK_TYPE anIndex);
-void remark_type1(YACC_MARK_TYPE anIndex);
-void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken);
-void start_search(bool enableType1);
-void template_test();
-void unmark(const CxxToken *aToken = 0);
-void unnest(size_t aNest) {}
-
-void classify_argument();
-void classify_function();
-void dollar_kill();
-CxxTokens *get_code(CxxToken *);
-CxxTokens *get_expr();
-CxxTokens *get_for_init();
-CxxTokens *get_for_next();
-CxxTokens *get_for_test();
-CxxTokens *get_func();
-CxxTokens *get_raw(CxxToken *);
-CxxTokens *get_statement();
-void make(CxxToken *);
-void queue(CxxToken *);
-int set_replace_formals(int);
-
-extern CxxToken *_list_token;
-
-#ifndef BISON_PP_CLASS
-void yyerror(const char *s);
-#define yylex buffered_yylex
-int yylex();
-#endif
-
-#define YACC_ABSTRACT_ARRAY_EXPRESSION(a) make_abstract_array_expression(a)
-#define YACC_ABSTRACT_FUNCTION_EXPRESSION(a) make_abstract_function_expression(a)
-#define YACC_ACCESSIBILITY_SPECIFIER(a) make_accessibility_specifier(a)
-#define YACC_ACCESS_BASE_SPECIFIER(a,b) make_access_base_specifier(a,b)
-#define YACC_ACCESS_SPECIFIER_ID(a) make_access_specifier_id(a)
-#define YACC_ADD_EXPRESSION(a,b) make_add_expression(a, b)
-#define YACC_AND_EXPRESSION(a,b) make_and_expression(a,b)
-#define YACC_ARRAY_EXPRESSION(a,b) make_array_expression(a,b)
-#define YACC_ARROW_EXPRESSION(a,b) make_arrow_expression(a,b)
-#define YACC_ARROW_STAR_EXPRESSION(a,b) make_arrow_star_expression(a,b)
-#define YACC_ASM_DEFINITION(a) make_asm_definition(a)
-#define YACC_ASSIGNMENT_EXPRESSION(a,b,c) make_assignment_expression(a,b,c)
-#define YACC_BASE_SPECIFIER(a) make_base_specifier(a)
-#define YACC_BASE_SPECIFIERS(a,b) make_base_specifiers(a,b)
-#define YACC_BIT_FIELD_EXPRESSION(a,b) make_bit_field_expression(a,b)
-#define YACC_BREAK_STATEMENT() make_break_statement()
-#define YACC_BUILT_IN_ID(a) make_built_in_id(a)
-#define YACC_BUILT_IN_ID_ID(a) make_built_in_id_id(a)
-#define YACC_BUILT_IN_IDS(a,b) make_built_in_ids(a,b)
-#define YACC_BUILT_IN_NAME(a,b) make_built_in_name(a,b)
-#define YACC_CALL_EXPRESSION(a,b) make_call_expression(a,b)
-#define YACC_CASE_STATEMENT(a,b) make_case_statement(a,b)
-#define YACC_CAST_EXPRESSION(a,b) make_cast_expression(a,b)
-#define YACC_CHARACTER_LITERAL_EXPRESSION(a) make_character_literal_expression(a)
-#define YACC_CLASS_MEMBERS(a,b) make_class_members(a,b)
-#define YACC_CLASS_SPECIFIER_ID(a,b,c) make_class_specifier_id(a,b,c)
-#define YACC_CLASS_TEMPLATE_PARAMETER(a) make_class_template_parameter(a)
-#define YACC_CLASS_TYPE_PARAMETER(a) make_class_type_parameter(a)
-#define YACC_COMPILE_DECLARATION(a,b) compile_declaration(a,b)
-#define YACC_COMPILE_STATEMENT(a) compile_statement(a)
-#define YACC_COMPLEMENT_EXPRESSION(a) make_complement_expression(a)
-#define YACC_COMPOUND_STATEMENT(a) make_compound_statement(a)
-#define YACC_CONDITION(a) make_condition(a)
-#define YACC_CONDITIONAL_EXPRESSION(a,b,c) make_conditional_expression(a,b,c)
-#define YACC_CONST_CAST_EXPRESSION(a,b) make_const_cast_expression(a,b)
-#define YACC_CONTINUE_STATEMENT() make_continue_statement()
-#define YACC_CONVERSION_FUNCTION_ID(a) make_conversion_function_id(a)
-#define YACC_CTOR_DEFINITION(a,b) make_ctor_definition(a,b)
-#define YACC_CTOR_FUNCTION_BLOCK(a,b) make_ctor_function_block(a,b)
-#define YACC_CV_DECLARATOR(a,b) make_cv_declarator(a,b)
-#define YACC_CV_DECL_SPECIFIER(a) make_cv_decl_specifier(a)
-#define YACC_CV_QUALIFIERS(a,b) make_cv_qualifiers(a,b)
-#define YACC_DECLARATIONS(a,b) make_declarations(a,b)
-#define YACC_DECLARATION_STATEMENT(a) make_declaration_statement(a)
-#define YACC_DECL_SPECIFIER_DECLARATION(a,b) make_decl_specifier_declaration(a,b)
-#define YACC_DECL_SPECIFIER_EXPRESSION(a,b) make_decl_specifier_expression(a,b)
-#define YACC_DECL_SPECIFIER_NAME(a,b) make_decl_specifier_name(a,b)
-#define YACC_DECL_SPECIFIER_PARAMETER(a,b) make_decl_specifier_parameter(a,b)
-#define YACC_DECL_SPECIFIERS(a,b) make_decl_specifiers(a,b)
-#define YACC_DECL_SPECIFIER_TREE_ARGUMENT(a,b) make_decl_specifier_tree_argument(a,b)
-#define YACC_DECL_SPECIFIER_TREE_ARGUMENTS(a,b) make_decl_specifier_tree_arguments(a,b)
-#define YACC_DEFAULT_STATEMENT(a) make_default_statement(a)
-#define YACC_DELETE_EXPRESSION(a) make_delete_expression(a)
-#define YACC_DERIVED_CLAUSE(a,b) make_derived_clause(a,b)
-#define YACC_DESTRUCTOR_ID(a) make_destructor_id(a)
-#define YACC_DIVIDE_EXPRESSION(a,b) make_divide_expression(a,b)
-#define YACC_DOT_EXPRESSION(a,b) make_dot_expression(a,b)
-#define YACC_DOT_STAR_EXPRESSION(a,b) make_dot_star_expression(a,b)
-#define YACC_DO_WHILE_STATEMENT(a,b) make_do_while_statement(a,b)
-#define YACC_DYNAMIC_CAST_EXPRESSION(a,b) make_dynamic_cast_expression(a,b)
-#define YACC_ELABORATED_TYPE_SPECIFIER(a,b) make_elaborated_type_specifier(a,b)
-#define YACC_ELLIPSIS_EXPRESSION() make_ellipsis_expression()
-#define YACC_ENUMERATOR(a,b) make_enumerator(a,b)
-#define YACC_ENUMERATORS(a,b) make_enumerators(a,b)
-#define YACC_ENUM_SPECIFIER_ID(a,b) make_enum_specifier_id(a,b)
-#define YACC_ENUM_TREE_ID(a) make_enum_tree_id(a)
-#define YACC_EPSILON() make_epsilon()
-#define YACC_EQUAL_EXPRESSION(a,b) make_equal_expression(a,b)
-#define YACC_EXCEPTION_DECLARATION(a) make_exception_declaration(a)
-#define YACC_EXCEPTION_SPECIFICATION(a) make_exception_specification(a)
-#define YACC_EXCLUSIVE_OR_EXPRESSION(a,b) make_exclusive_or_expression(a,b)
-#define YACC_EXPLICIT_IMPLEMENTATION_DECLARATION(a) make_explicit_implementation_declaration(a)
-#define YACC_EXPLICIT_INTERFACE_DECLARATION(a) make_explicit_interface_declaration(a)
-#define YACC_EXPLICIT_SPECIALIZATION(a) make_explicit_specialization(a)
-#define YACC_EXPORT_IMPLEMENTATION_DECLARATION(a) make_export_implementation_declaration(a)
-#define YACC_EXPORT_INTERFACE_DECLARATION(a) make_export_interface_declaration(a)
-#define YACC_EXPORT_NOIMPLEMENTATION_DECLARATION() make_export_noimplementation_declaration()
-#define YACC_EXPRESSION(a) make_expression(a)
-#define YACC_EXPRESSIONS(a,b) make_expressions(a,b)
-#define YACC_EXPRESSION_PARAMETER(a) make_expression_parameter(a)
-#define YACC_FALSE_EXPRESSION() make_false_expression()
-#define YACC_FILESPACE_DECLARATION(a) make_filespace_declaration(a)
-#define YACC_FILESPACE_SPECIFIER(a,b) make_filespace_specifier(a,b)
-#define YACC_FILE_ID(a) make_file_id(a)
-#define YACC_FILE_ID_IMPLEMENTATION(a) make_file_id_implementation(a)
-#define YACC_FILE_ID_INTERFACE(a) make_file_id_interface(a)
-#define YACC_FILE_IDS(a,b) make_file_ids(a,b)
-#define YACC_FILE_NAME(a) make_file_name(a)
-#define YACC_FILE_NAME_GUARD(a,b) make_file_name_guard(a,b)
-#define YACC_FILE_NAME_IMPLEMENTATION(a) make_file_name_implementation(a)
-#define YACC_FILE_NAME_INTERFACE(a) make_file_name_interface(a)
-#define YACC_FILE_NAME_NOGUARD(a) make_file_name_noguard(a)
-#define YACC_FILE_NAME_PATH(a,b) make_file_name_path(a,b)
-#define YACC_FILE_NAME_PREFIX(a,b) make_file_name_prefix(a,b)
-#define YACC_FILE_NAME_SUFFIX(a,b) make_file_name_suffix(a,b)
-#define YACC_FILE_NAME_TEMPLATE(a) make_file_name_template(a)
-#define YACC_FILE_NAME_UTILITY(a,b) make_file_name_utility(a,b)
-#define YACC_FLOATING_LITERAL_EXPRESSION(a) make_floating_literal_expression(a)
-#define YACC_FOR_STATEMENT(a,b,c,d) make_for_statement(a,b,c,d)
-#define YACC_FUNCTION_BLOCK(a) make_function_block(a)
-#define YACC_FUNCTION_DECLARATIONS(a,b) make_function_declarations(a,b)
-#define YACC_FUNCTION_DEFINITION(a,b) make_function_definition(a,b)
-#define YACC_GLOBAL_DECLARATOR(a,b) make_global_declarator(a,b)
-#define YACC_GLOBAL_EXPRESSION(a, b) make_global_expression(a,b)
-#define YACC_GLOBAL_ID(a,b) make_global_id(a,b)
-#define YACC_GOTO_STATEMENT(a) make_goto_statement(a)
-#define YACC_GREATER_EQUAL_EXPRESSION(a,b) make_greater_equal_expression(a,b)
-#define YACC_GREATER_THAN_EXPRESSION(a,b) make_greater_than_expression(a,b)
-#define YACC_HANDLER(a,b) make_handler(a,b)
-#define YACC_HANDLERS(a,b) make_handlers(a,b)
-#define YACC_IF_STATEMENT(a,b,c) make_if_statement(a,b,c)
-#define YACC_INCLUDE_DECLARATION(a,b) make_include_declaration(a,b)
-#define YACC_INCLUSIVE_OR_EXPRESSION(a,b) make_inclusive_or_expression(a,b)
-#define YACC_INITIALIZED_PARAMETER(a,b) make_initialized_parameter(a, b)
-#define YACC_INITIALIZER_CLAUSES(a,b) make_initializer_clauses(a,b)
-#define YACC_INITIALIZER_EXPRESSION_CLAUSE(a) make_initializer_expression_clause(a)
-#define YACC_INITIALIZER_LIST_CLAUSE(a) make_initializer_list_clause(a)
-#define YACC_INIT_SIMPLE_TYPE_PARAMETER(a,b) make_init_simple_type_parameter(a,b)
-#define YACC_INIT_TEMPLATED_PARAMETER(a,b) make_init_templated_parameter(a,b)
-#define YACC_INLINE_AS_FRIEND() make_inline_as_friend()
-#define YACC_INLINE_IF_SHORT() make_inline_if_short()
-#define YACC_INLINE_IN_IMPLEMENTATION() make_inline_in_implementation()
-#define YACC_INLINE_IN_INTERFACE() make_inline_in_interface()
-#define YACC_INDEX_CAST_EXPRESSION(a,b) make_index_cast_expression(a,b)
-#define YACC_INPUT_FILE(a) make_input_file(a)
-#define YACC_INTEGER_LITERAL_EXPRESSION(a) make_integer_literal_expression(a)
-#define YACC_LABEL_STATEMENT(a,b) make_label_statement(a,b)
-#define YACC_LESS_EQUAL_EXPRESSION(a,b) make_less_equal_expression(a,b)
-#define YACC_LESS_THAN_EXPRESSION(a,b) make_less_than_expression(a,b)
-#define YACC_LINE() make_line()
-#define YACC_LINED_DECLARATION(a,b) make_lined_declaration(a,b)
-#define YACC_LINED_STATEMENT(a,b) make_lined_statement(a,b)
-#define YACC_LINED_TOKEN(a,b) make_lined_token(a,b)
-#define YACC_LINKAGE_SPECIFICATION(a) make_linkage_specification(a)
-#define YACC_LINKAGE_SPECIFIER(a,b) make_linkage_specifier(a,b)
-#define YACC_LOGICAL_AND_EXPRESSION(a,b) make_logical_and_expression(a,b)
-#define YACC_LOGICAL_OR_EXPRESSION(a,b) make_logical_or_expression(a,b)
-#define YACC_MEMBER_DECLARATIONS(a,b) make_member_declarations(a,b)
-#define YACC_MEM_INITIALIZER(a,b) make_mem_initializer(a,b)
-#define YACC_MEM_INITIALIZERS(a,b) make_mem_initializers(a,b)
-#define YACC_META_ASSIGNMENT_EXPRESSION(a,b,c) make_meta_assignment_expression(a,b,c)
-#define YACC_META_BASE_SPECIFIER(a) make_meta_base_specifier(a)
-#define YACC_META_BREAK_STATEMENT() make_meta_break_statement()
-#define YACC_META_BUILT_IN_TYPE(a) make_meta_built_in_type(a)
-#define YACC_META_CASE_STATEMENT(a,b) make_meta_case_statement(a,b)
-#define YACC_META_CLASS(a,b,c) make_meta_class(a,b,c)
-#define YACC_META_CONTINUE_STATEMENT() make_meta_continue_statement()
-#define YACC_META_DEFAULT_STATEMENT(a) make_meta_default_statement(a)
-#define YACC_META_DO_WHILE_STATEMENT(a,b,c) make_meta_do_while_statement(a,b,c)
-#define YACC_META_FOR_STATEMENT(a,b,c,d,e) make_meta_for_statement(a,b,c,d,e)
-#define YACC_META_FUNCTION(a,b,c) make_meta_function(a,b,c)
-#define YACC_META_IF_STATEMENT(a,b,c,d) make_meta_if_statement(a,b,c,d)
-#define YACC_META_INITIALIZER(a,b) make_meta_initializer(a,b)
-#define YACC_META_INITIALIZERS(a,b) make_meta_initializers(a,b)
-#define YACC_META_RETURN_STATEMENT(a) make_meta_return_statement(a)
-#define YACC_META_STATEMENT(a) make_meta_statement(a)
-#define YACC_META_STATEMENT_DECLARATION(a) make_meta_statement_declaration(a)
-#define YACC_META_SWITCH_STATEMENT(a,b,c) make_meta_switch_statement(a,b,c)
-#define YACC_META_TYPE(a) make_meta_type(a)
-#define YACC_META_TYPE_ID(a) make_meta_type_id(a)
-#define YACC_META_WHILE_STATEMENT(a,b,c) make_meta_while_statement(a,b,c)
-#define YACC_MINUS_EXPRESSION(a) make_minus_expression(a)
-#define YACC_MODULUS_EXPRESSION(a,b) make_modulus_expression(a,b)
-#define YACC_MULTIPLY_EXPRESSION(a,b,c) make_multiply_expression(a,b,c)
-#define YACC_NAME(a) make_name(a)
-#define YACC_NAMESPACE_ALIAS_DEFINITION(a,b) make_namespace_alias_definition(a,b)
-#define YACC_NAMESPACE_DECLARATION(a) make_namespace_declaration(a)
-#define YACC_NAMESPACE_DEFINITION(a,b) make_namespace_definition(a,b)
-#define YACC_NAME_EXPRESSION(a) make_name_expression(a)
-#define YACC_NESTED_DECLARATOR(a,b) make_nested_declarator(a,b)
-#define YACC_NESTED_ID(a,b) make_nested_id(a,b)
-#define YACC_NESTED_SCOPE(a) make_nested_scope(a)
-#define YACC_NEW_EXPRESSION(a,b,c) make_new_expression(a,b,c)
-#define YACC_NEW_TYPE_ID_EXPRESSION(a,b,c) make_new_type_id_expression(a,b,c)
-#define YACC_NOT_CONST() make_not_const()
-#define YACC_NOT_EQUAL_EXPRESSION(a,b) make_not_equal_expression(a,b)
-#define YACC_NOT_EXPRESSION(a) make_not_expression(a)
-#define YACC_NOT_INLINE() make_not_inline()
-#define YACC_NOT_STATIC() make_not_static()
-#define YACC_NOT_VIRTUAL() make_not_virtual()
-#define YACC_NOT_VIRTUAL_BASE_SPECIFIER(a) make_not_virtual_base_specifier(a)
-#define YACC_NOT_VOLATILE() make_not_volatile()
-#define YACC_NUMBER_LITERAL_EXPRESSION(a) make_number_literal_expression(a)
-#define YACC_OBJECT_SCOPE_EXPRESSION(a,b) make_object_scope_expression(a,b)
-#define YACC_OPERATOR_ADD_ID() make_operator_add_id()
-#define YACC_OPERATOR_ARROW_ID() make_operator_arrow_id()
-#define YACC_OPERATOR_ARROW_STAR_ID() make_operator_arrow_star_id()
-#define YACC_OPERATOR_ASS_ADD_ID() make_operator_ass_add_id()
-#define YACC_OPERATOR_ASS_BIT_AND_ID() make_operator_ass_bit_and_id()
-#define YACC_OPERATOR_ASS_BIT_OR_ID() make_operator_ass_bit_or_id()
-#define YACC_OPERATOR_ASS_DIV_ID() make_operator_ass_div_id()
-#define YACC_OPERATOR_ASS_ID() make_operator_ass_id()
-#define YACC_OPERATOR_ASS_MOD_ID() make_operator_ass_mod_id()
-#define YACC_OPERATOR_ASS_MUL_ID() make_operator_ass_mul_id()
-#define YACC_OPERATOR_ASS_SHL_ID() make_operator_ass_shl_id()
-#define YACC_OPERATOR_ASS_SHR_ID() make_operator_ass_shr_id()
-#define YACC_OPERATOR_ASS_SUB_ID() make_operator_ass_sub_id()
-#define YACC_OPERATOR_ASS_XOR_ID() make_operator_ass_xor_id()
-#define YACC_OPERATOR_BIT_AND_ID() make_operator_bit_and_id()
-#define YACC_OPERATOR_BIT_NOT_ID() make_operator_bit_not_id()
-#define YACC_OPERATOR_BIT_OR_ID() make_operator_bit_or_id()
-#define YACC_OPERATOR_CALL_ID() make_operator_call_id()
-#define YACC_OPERATOR_COMMA_ID() make_operator_comma_id()
-#define YACC_OPERATOR_DEC_ID() make_operator_dec_id()
-#define YACC_OPERATOR_DELETE_ID() make_operator_delete_id()
-#define YACC_OPERATOR_DIV_ID() make_operator_div_id()
-#define YACC_OPERATOR_EQ_ID() make_operator_eq_id()
-#define YACC_OPERATOR_FUNCTION_ID(a) make_operator_function_id(a)
-#define YACC_OPERATOR_GE_ID() make_operator_ge_id()
-#define YACC_OPERATOR_GT_ID() make_operator_gt_id()
-#define YACC_OPERATOR_INC_ID() make_operator_inc_id()
-#define YACC_OPERATOR_INDEX_ID() make_operator_index_id()
-#define YACC_OPERATOR_LE_ID() make_operator_le_id()
-#define YACC_OPERATOR_LOG_AND_ID() make_operator_log_and_id()
-#define YACC_OPERATOR_LOG_NOT_ID() make_operator_log_not_id()
-#define YACC_OPERATOR_LOG_OR_ID() make_operator_log_or_id()
-#define YACC_OPERATOR_LT_ID() make_operator_lt_id()
-#define YACC_OPERATOR_MOD_ID() make_operator_mod_id()
-#define YACC_OPERATOR_MUL_ID() make_operator_mul_id()
-#define YACC_OPERATOR_NE_ID() make_operator_ne_id()
-#define YACC_OPERATOR_NEW_ID() make_operator_new_id()
-#define YACC_OPERATOR_SHL_ID() make_operator_shl_id()
-#define YACC_OPERATOR_SHR_ID() make_operator_shr_id()
-#define YACC_OPERATOR_SUB_ID() make_operator_sub_id()
-#define YACC_OPERATOR_XOR_ID() make_operator_xor_id()
-#define YACC_PARAMETERS(a,b) make_parameters(a,b)
-#define YACC_PARENTHESISED(a,b,c) make_parenthesised(a,b,c)
-#define YACC_POINTER_DECLARATOR() make_pointer_declarator()
-#define YACC_POINTER_EXPRESSION(a,b) make_pointer_expression(a,b)
-#define YACC_PLUS_EXPRESSION(a) make_plus_expression(a)
-#define YACC_POSITION(a,b) make_position(a)
-#define YACC_POSITION_FUNCTION_BLOCK(a,b) make_position_function_block(a,b)
-#define YACC_POST_DECREMENT_EXPRESSION(a) make_post_decrement_expression(a)
-#define YACC_POST_INCREMENT_EXPRESSION(a) make_post_increment_expression(a)
-#define YACC_PRE_DECREMENT_EXPRESSION(a) make_pre_decrement_expression(a)
-#define YACC_PRE_INCREMENT_EXPRESSION(a) make_pre_increment_expression(a)
-#define YACC_PSEUDO_DESTRUCTOR_ID(a,b) make_pseudo_destructor_id(a,b)
-#define YACC_PURE_VIRTUAL() make_pure_virtual()
-#define YACC_READ_ONLY_RESULT(a) make_read_only_result(a)
-#define YACC_READ_WRITE_RESULT(a) make_read_write_result(a)
-#define YACC_REFERENCE_DECLARATOR() make_reference_declarator()
-#define YACC_REINTERPRET_CAST_EXPRESSION(a,b) make_reinterpret_cast_expression(a,b)
-#define YACC_RESULT(a) make_result(a)
-#define YACC_RETURN_STATEMENT(a) make_return_statement(a)
-#define YACC_SCOPED_POINTER_EXPRESSION(a,b,c) make_scoped_pointer_expression(a,b,c)
-#define YACC_SCOPED_ID(a,b) make_scoped_id(a,b)
-#define YACC_SEGMENT(a,b) make_segment(a)
-#define YACC_SEGMENT_FUNCTION_BLOCK(a,b) make_segment_function_block(a,b)
-#define YACC_SET_TEMPLATE_DECLARATION(a) make_set_template_declaration(a)
-#define YACC_SET_TEMPLATE_DECL_SPECIFIER(a) make_set_template_decl_specifier(a)
-#define YACC_SET_TEMPLATE_EXPRESSION(a) make_set_template_expression(a)
-#define YACC_SET_TEMPLATE_ID(a) make_set_template_id(a)
-#define YACC_SET_TEMPLATE_NAME(a) make_set_template_name(a)
-#define YACC_SET_TEMPLATE_SCOPE(a) make_set_template_scope(a)
-#define YACC_SHIFT_LEFT_EXPRESSION(a,b) make_shift_left_expression(a,b)
-#define YACC_SHIFT_RIGHT_EXPRESSION(a,b) make_shift_right_expression(a,b)
-#define YACC_SIMPLE_DECLARATION(a) make_simple_declaration(a)
-#define YACC_SIZEOF_EXPRESSION(a) make_sizeof_expression(a)
-#define YACC_STATEMENTS(a,b) make_statements(a,b)
-#define YACC_STATIC_CAST_EXPRESSION(a,b) make_static_cast_expression(a,b)
-#define YACC_STRINGS(a,b) make_strings(a,b)
-#define YACC_STRING_LITERAL_EXPRESSION(a) make_string_literal_expression(a)
-#define YACC_SUBTRACT_EXPRESSION(a,b) make_subtract_expression(a,b)
-#define YACC_SWITCH_STATEMENT(a,b) make_switch_statement(a,b)
-#define YACC_SYNTAX_MACRO_DEFINITION(a,b,c,d,e) make_syntax_macro_definition(a,b,c,d,e)
-#define YACC_SYNTAX_MACRO_PARAMETER(a,b,c) make_syntax_macro_parameter(a,b,c)
-#define YACC_SYNTAX_MACRO_PARAMETERS(a,b) make_syntax_macro_parameters(a,b)
-#define YACC_TEMPLATE_ARGUMENT(a) make_template_argument(a)
-#define YACC_TEMPLATE_ARGUMENTS(a,b) make_template_arguments(a,b)
-#define YACC_TEMPLATED_TEMPLATE_PARAMETER(a,b) make_templated_template_parameter(a,b)
-#define YACC_TEMPLATED_TYPE_PARAMETER(a,b) make_templated_type_parameter(a,b)
-#define YACC_TEMPLATE_DECLARATION(a,b) make_template_declaration(a,b)
-#define YACC_TEMPLATE_NAME(a,b) make_template_name(a,b)
-#define YACC_TEMPLATE_PARAMETER(a) make_template_parameter(a)
-#define YACC_TEMPLATE_PARAMETERS(a,b) make_template_parameters(a,b)
-#define YACC_THIS_EXPRESSION() make_this_expression()
-#define YACC_THROW_EXPRESSION(a) make_throw_expression(a)
-#define YACC_TOKENS_EXPRESSION(a) make_tokens_expression(a)
-#define YACC_TREE_ARGUMENT(a) make_tree_argument(a)
-#define YACC_TREE_ARGUMENTS(a,b) make_tree_arguments(a,b)
-#define YACC_TREE_ARRAY_EXPRESSION(a,b) make_tree_array_expression(a,b)
-#define YACC_TREE_ARROW_EXPRESSION(a,b) make_tree_arrow_expression(a,b)
-#define YACC_TREE_ARROW_CALL_EXPRESSION(a,b,c) make_tree_arrow_call_expression(a,b,c)
-#define YACC_TREE_CALL_EXPRESSION(a,b) make_tree_call_expression(a,b)
-#define YACC_TREE_DOT_EXPRESSION(a,b) make_tree_dot_expression(a,b)
-#define YACC_TREE_DOT_CALL_EXPRESSION(a,b,c) make_tree_dot_call_expression(a,b,c)
-#define YACC_TREE_EXPRESSION(a) make_tree_expression(a)
-#define YACC_TREE_ID(a) make_tree_id(a)
-#define YACC_TREE_POINTER_EXPRESSION(a) make_tree_pointer_expression(a)
-#define YACC_TRUE_EXPRESSION() make_true_expression()
-#define YACC_TRY_BLOCK(a,b) make_try_block(a,b)
-#define YACC_TRY_BLOCK_STATEMENT(a) make_try_block_statement(a)
-#define YACC_TRY_FUNCTION_BLOCK(a,b) make_try_function_block(a,b)
-#define YACC_TYPE1_EXPRESSION(a,b,c) make_type1_expression(a,b,c)
-#define YACC_TYPE1_PARAMETERS(a,b) make_type1_parameters(a,b)
-#define YACC_TYPED_EXPRESSION(a,b) make_typed_expression(a,b)
-#define YACC_TYPED_NAME(a,b) make_typed_name(a,b)
-#define YACC_TYPEID_EXPRESSION(a) make_typeid_expression(a)
-#define YACC_TYPENAME_TEMPLATE_PARAMETER(a) make_typename_template_parameter(a)
-#define YACC_TYPENAME_TYPE_PARAMETER(a) make_typename_type_parameter(a)
-#define YACC_TYPE_TEMPLATE_PARAMETER(a,b) make_type_template_parameter(a,b)
-#define YACC_USING_DECLARATION(a,b) make_using_declaration(a,b)
-#define YACC_USING_DIRECTIVE(a) make_using_directive(a)
-#define YACC_USING_FUNCTION_BLOCK(a,b) make_using_function_block(a,b)
-#define YACC_USING_IMPLEMENTATION_DECLARATION(a) make_using_implementation_declaration(a)
-#define YACC_USING_INTERFACE_DECLARATION(a) make_using_interface_declaration(a)
-#define YACC_UTILITY(a) make_utility(0)
-#define YACC_UTILITY_MODE() make_utility_mode()
-#define YACC_VIRTUAL_BASE_SPECIFIER(a) make_virtual_base_specifier(a)
-#define YACC_WHILE_STATEMENT(a,b) make_while_statement(a,b)
-
-CxxDeclaration *compile_declaration(CxxUtility *utilityMode, CxxDeclaration *aDeclaration) { return 0; }
-CxxStatement *compile_statement(CxxStatement *aDeclaration) { return 0; }
-void make_result(CxxToken *aResult) {}
-
-CxxExpression *make_abstract_array_expression(CxxExpression *sizeExpr) { return 0; }
-CxxExpression *make_abstract_function_expression(CxxParenthesised *aparenthesis) { return 0; }
-CxxBaseSpecifier *make_access_base_specifier(CxxBaseSpecifier *baseSpecifier, CxxAccessSpecifier *accessSpecifier) { return 0; }
-CxxDeclSpecifierId *make_access_specifier_id(CxxAccessSpecifier *aName) { return 0; }
-CxxDeclaration *make_accessibility_specifier(CxxAccessSpecifier *accessSpecifier) { return 0; }
-CxxExpression *make_add_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_array_expression(CxxExpression *anExpr, CxxExpression *indexExpr) { return 0; }
-CxxExpression *make_arrow_expression(CxxExpression *anExpr, CxxName *aName) { return 0; }
-CxxExpression *make_arrow_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; }
-CxxDeclaration *make_asm_definition(CxxStrings *aString) { return 0; }
-CxxExpression *make_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxExpression *rightExpr) { return 0; }
-CxxBaseSpecifier *make_base_specifier(CxxName *aName) { return 0; }
-CxxBaseSpecifiers *make_base_specifiers(CxxBaseSpecifiers *aList, CxxBaseSpecifier *anElement) { return 0; }
-CxxExpression *make_bit_field_expression(CxxExpression *nameExpr, CxxExpression *sizeExpr) { return 0; }
-CxxStatement *make_break_statement() { return 0; }
-CxxName *make_built_in_id(CxxBuiltInId *aName) { return 0; }
-CxxName *make_built_in_id_id(CxxBuiltInId *aName) { return 0; }
-CxxBuiltInId *make_built_in_ids(CxxBuiltInId *anExpr, CxxBuiltInId *anElement) { return 0; }
-CxxName *make_built_in_name(CxxName *aName, CxxBuiltInId *anElement) { return 0; }
-CxxExpression *make_call_expression(CxxExpression *anExpr, CxxParenthesised *aParenthesis) { return 0; }
-CxxStatement *make_case_statement(CxxExpression *anExpr, CxxStatement *aStmt) { return 0; }
-CxxExpression *make_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; }
-CxxExpression *make_character_literal_expression(CxxCharacterLiteral *aLiteral) { return 0; }
-CxxName *make_class_members(CxxClass *aClass, CxxMemberDeclarations *memberDeclarations) { return 0; }
-CxxClass *make_class_specifier_id(CxxClassKey *classKey, CxxName *aName, CxxBaseSpecifiers *baseSpecifiers) { return 0; }
-CxxSimpleTypeParameter *make_class_template_parameter(CxxName *aName) { return 0; }
-CxxSimpleTypeParameter *make_class_type_parameter(CxxName *aName) { return 0; }
-CxxStatement *make_compound_statement(CxxStatements *statementList) { return 0; }
-CxxExpression *make_complement_expression(CxxExpression *anExpr) { return 0; }
-CxxCondition *make_condition(CxxParameters *aList) { return 0; }
-CxxExpression *make_conditional_expression(CxxExpression *testExpr, CxxExpression *trueExpr, CxxExpression *falseExpr) { return 0; }
-CxxExpression *make_const_cast_expression(CxxExpression *aType, CxxExpression *anExpr)  { return 0; }
-CxxStatement *make_continue_statement() { return 0; }
-CxxName *make_conversion_function_id(CxxExpression *typeId) { return 0; }
-CxxExpression *make_ctor_definition(CxxExpressions *anExpr, CxxFunctionBody *functionBody) { return 0; }
-CxxFunctionBody *make_ctor_function_block(CxxFunctionBody *functionBody, CxxMemInitializers *ctorList) { return 0; }
-CxxDeclSpecifierId *make_cv_decl_specifier(CxxCvQualifiers *cvQualifiers) { return 0; }
-CxxPointerDeclarator *make_cv_declarator(CxxPointerDeclarator *aDeclarator, CxxCvQualifiers *cvQualifiers) { return 0; }
-CxxCvQualifiers *make_cv_qualifiers(CxxCvQualifiers *aList, CxxCvQualifiers *anElement) { return 0; }
-CxxDeclaration *make_decl_specifier_declaration(CxxDeclaration *aDeclaration, CxxDeclSpecifierId *declSpecifier) { return 0; }
-CxxExpression *make_decl_specifier_expression(CxxExpression *anExpr, CxxDeclSpecifierId *declSpecifier) { return 0; }
-CxxName *make_decl_specifier_name(CxxName *aName, CxxDeclSpecifierId *declSpecifier) { return 0; }
-CxxParameter *make_decl_specifier_parameter(CxxParameter *aName, CxxDeclSpecifierId *declSpecifier) { return 0; }
-CxxToken *make_decl_specifier_tree_argument(CxxToken *treeArgument, CxxDeclSpecifierId *aName) { return 0; }
-CxxTokens *make_decl_specifier_tree_arguments(CxxTokens *treeArguments, CxxDeclSpecifierId *aName) { return 0; }
-CxxDeclSpecifierId *make_decl_specifiers(CxxDeclSpecifierId *aList, CxxDeclSpecifierId *anElement) { return 0; }
-CxxDeclarations *make_declarations(CxxDeclarations *aList, CxxDeclaration *anElement) { return 0; }
-CxxStatement *make_declaration_statement(CxxDeclaration *aDecl) { return 0; }
-CxxStatement *make_default_statement(CxxStatement *aStmt) { return 0; }
-CxxExpression *make_delete_expression(CxxExpression *anExpr) { return 0; }
-CxxDeclaration *make_derived_clause(CxxExpression *derivedPredicate, CxxDeclaration *aDeclaration) { return 0; }
-CxxName *make_destructor_id(CxxName *aName) { return 0; }
-CxxExpression *make_divide_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxStatement *make_do_while_statement(CxxStatement *aStmt, CxxExpression *testExpr) { return 0; }
-CxxExpression *make_dot_expression(CxxExpression *anExpr, CxxName *aName) { return 0; }
-CxxExpression *make_dot_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; }
-CxxExpression *make_dynamic_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
-CxxName *make_elaborated_type_specifier(CxxClassKey *classKey, CxxName *aName) { return 0; }
-CxxParameter *make_ellipsis_expression() { return 0; }
-CxxName *make_enum_specifier_id(CxxName *aName, CxxEnumerators *aList) { return 0; }
-CxxEnumerator *make_enumerator(CxxName *aName, CxxExpression *anExpr) { return 0; }
-CxxEnumerators *make_enumerators(CxxEnumerators *aList, CxxEnumerator *anElement) { return 0; }
-CxxName *make_epsilon() { return 0; }
-CxxExpression *make_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExceptionDeclaration *make_exception_declaration(CxxParameter *aParameter) { return 0; }
-CxxExceptionSpecification *make_exception_specification(CxxExpressions *typeIds) { return 0; }
-CxxExpression *make_exclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxDeclaration *make_explicit_implementation_declaration(CxxTokens *someTokens) { return 0; }
-CxxDeclaration *make_explicit_interface_declaration(CxxTokens *someTokens) { return 0; }
-CxxDeclaration *make_explicit_specialization(CxxDeclaration *aDeclaration) { return 0; }
-CxxDeclaration *make_export_implementation_declaration(CxxFileId *fileId) { return 0; }
-CxxDeclaration *make_export_interface_declaration(CxxFileId *fileId) { return 0; }
-CxxDeclaration *make_export_noimplementation_declaration() { return 0; }
-CxxExpression *make_expression(CxxExpressions *aList) { return 0; }
-CxxParameter *make_expression_parameter(CxxExpression *anExpr) { return 0; }
-CxxExpressions *make_expressions(CxxExpressions *aList, CxxExpression *anElement) { return 0; }
-CxxExpression *make_false_expression() { return 0; }
-CxxFileId *make_file_id(CxxFileName *fileName) { return 0; }
-CxxFileId *make_file_id_implementation(CxxName *aName) { return 0; }
-CxxFileId *make_file_id_interface(CxxName *aName) { return 0; }
-CxxFileIds *make_file_ids(CxxFileIds *aList, CxxFileId *anElement) { return 0; }
-CxxFileName *make_file_name(CxxStrings *aString) { return 0; }
-CxxFileName *make_file_name_guard(CxxFileName *fileName, CxxStrings *aString) { return 0; }
-CxxFileName *make_file_name_implementation(CxxFileName *fileName) { return 0; }
-CxxFileName *make_file_name_interface(CxxFileName *fileName) { return 0; }
-CxxFileName *make_file_name_noguard(CxxFileName *fileName) { return 0; }
-CxxFileName *make_file_name_path(CxxFileName *fileName, CxxStrings *aString) { return 0; }
-CxxFileName *make_file_name_prefix(CxxFileName *fileName, CxxStrings *aString) { return 0; }
-CxxFileName *make_file_name_suffix(CxxFileName *fileName, CxxStrings *aString) { return 0; }
-CxxFileName *make_file_name_template(CxxFileName *fileName) { return 0; }
-CxxFileName *make_file_name_utility(CxxFileName *fileName, CxxUtility *aUtility) { return 0; }
-CxxDeclaration *make_filespace_declaration(CxxName *aName) { return 0; }
-CxxName *make_filespace_specifier(CxxFileName *fileName, CxxDeclarations *aDeclaration) { return 0; }
-CxxExpression *make_floating_literal_expression(CxxFloatingLiteral *aLiteral) { return 0; }
-CxxStatement *make_for_statement(CxxExpression *initExpr, CxxCondition *testExpr, CxxExpression *stepExpr, CxxStatement *aStmt) { return 0; }
-CxxFunctionBody *make_function_block(CxxStatement *aStatement) { return 0; }
-CxxFunctionDeclarations *make_function_declarations(CxxFunctionDeclarations *aList, CxxDeclaration *anElement) { return 0; }
-CxxExpression *make_function_definition(CxxExpression *anExpr, CxxFunctionBody *functionBody) { return 0; }
-CxxDeclarator *make_global_declarator(CxxIsTemplate isTemplate, CxxDeclarator *aDeclarator) { return 0; }
-CxxExpression *make_global_expression(CxxIsTemplate isTemplate, CxxNewExpression *anExpr) { return 0; }
-CxxName *make_global_id(CxxIsTemplate isTemplate, CxxName *nestedId) { return 0; }
-CxxStatement *make_goto_statement(CxxToken *aLabel) { return 0; }
-CxxExpression *make_greater_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_greater_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxHandler *make_handler(CxxExceptionDeclaration *exceptionDeclaration, CxxStatement *aStatement) { return 0; }
-CxxHandlers *make_handlers(CxxHandlers *aList, CxxHandler *anElement) { return 0; }
-CxxStatement *make_if_statement(CxxCondition *testExpr, CxxStatement *trueStmt, CxxStatement *falseStmt) { return 0; }
-CxxDeclaration *make_include_declaration(CxxStrings *aString, CxxUtility *aUtility) { return 0; }
-CxxExpression *make_inclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_index_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; }
-CxxParameter *make_initialized_parameter(CxxParameter *aParameter, CxxExpression *anExpr) { return 0; }
-CxxInitializerClauses *make_initializer_clauses(CxxInitializerClauses *aList, CxxInitializerClause *anElement) { return 0; }
-CxxInitializerClause *make_initializer_expression_clause(CxxExpression *anExpr) { return 0; }
-CxxInitializerClause *make_initializer_list_clause(CxxInitializerClauses *aList) { return 0; }
-CxxSimpleTypeParameter *make_init_simple_type_parameter(CxxSimpleTypeParameter *templateParameters, CxxExpression *anExpr) { return 0; }
-CxxTemplatedTypeParameter *make_init_templated_parameter(CxxTemplatedTypeParameter *typeParameter, CxxName *aName) { return 0; }
-CxxDeclSpecifierId *make_inline_as_friend() { return 0; }
-CxxDeclSpecifierId *make_inline_if_short() { return 0; }
-CxxDeclSpecifierId *make_inline_in_implementation() { return 0; }
-CxxDeclSpecifierId *make_inline_in_interface() { return 0; }
-CxxFileId *make_input_file(CxxFileId *fileId) { return 0; }
-CxxExpression *make_integer_literal_expression(CxxIntegerLiteral *aLiteral) { return 0; }
-CxxStatement *make_label_statement(CxxToken *aLabel, CxxStatement *aStmt) { return 0; }
-CxxExpression *make_less_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_less_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxLine *make_line() { return 0; }
-CxxDeclaration *make_lined_declaration(CxxDeclaration *aDeclaration, CxxLine *aLine) { return 0; }
-CxxStatement *make_lined_statement(CxxStatement *aStatement, CxxLine *aLine) { return 0; }
-CxxToken *make_lined_token(CxxToken *aToken, CxxLine *aLine) { return 0; }
-CxxName *make_linkage_specifier(CxxStrings *aString, CxxDeclaration *aDeclaration) { return 0; }
-CxxExpression *make_logical_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_logical_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxMemInitializer *make_mem_initializer(CxxName *aName, CxxExpression *anExpr) { return 0; }
-CxxMemInitializers *make_mem_initializers(CxxMemInitializers *aList, CxxMemInitializer *anElement) { return 0; }
-CxxMemberDeclarations *make_member_declarations(CxxMemberDeclarations *aList, CxxDeclaration *aDeclaration) { return 0; }
-CxxExpression *make_meta_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxToken *rightExpr) { return 0; }
-CxxBaseSpecifier *make_meta_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
-CxxMetaType *make_meta_built_in_type(CxxBuiltInId *aName) { return 0; }
-CxxStatement *make_meta_break_statement() { return 0; }
-CxxStatement *make_meta_case_statement(CxxExpression *anExpr, CxxToken *someTokens) { return 0; }
-CxxMetaClass *make_meta_class(CxxName *metaClass, CxxBaseSpecifiers *baseSpecifiers, CxxToken *classBody) { return 0; }
-CxxStatement *make_meta_continue_statement() { return 0; }
-CxxDeclaration *make_meta_declaration_declaration(CxxDeclaration *metaDeclaration) { return 0; }
-CxxStatement *make_meta_default_statement(CxxToken *someTokens) { return 0; }
-CxxStatement *make_meta_do_while_statement(CxxLine *aLine, CxxToken *bodyTokens, CxxToken *testTokens) { return 0; }
-CxxStatement *make_meta_expression_statement(CxxName *aName, CxxToken *bodyTokens) { return 0; }
-CxxStatement *make_meta_for_statement(CxxLine *aLine, CxxExpression *initTokens, CxxToken *testTokens,
-                       CxxToken *stepTokens, CxxToken *bodyTokens) { return 0; }
-CxxExpression *make_meta_function(CxxExpression *anExpr, CxxTokens *aList, CxxToken *aBody) { return 0; }
-CxxStatement *make_meta_if_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *trueTokens, CxxToken *falseTokens) { return 0; }
-CxxDeclaration *make_linkage_specification(CxxName *aName) { return 0; }
-//CxxMetaInitializers *make_meta_initializers(CxxMetaInitializers *aList, CxxToken *anElement) { return 0; }
-CxxMetaParameter *make_meta_parameter(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxToken *anInit) { return 0; }
-CxxMetaParameters *make_meta_parameters(CxxMetaParameters *aList, CxxMetaParameter *anElement) { return 0; }
-CxxStatement *make_meta_return_statement(CxxExpression *anExpr) { return 0; }
-CxxStatement *make_meta_statement(CxxStatement *aStatement) { return 0; }
-CxxDeclaration *make_meta_statement_declaration(CxxStatement *metaStatement) { return 0; }
-CxxStatement *make_meta_statement_statement(CxxStatement *metaStatement) { return 0; }
-CxxStatement *make_meta_switch_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *bodyTokens) { return 0; }
-CxxMetaType *make_meta_type(CxxName *aName) { return 0; }
-CxxName *make_meta_type_id(CxxMetaType *metaType) { return 0; }
-CxxStatement *make_meta_while_statement(CxxLine *aLine, CxxToken *testTokens, CxxToken *bodyTokens) { return 0; }
-CxxExpression *make_minus_expression(CxxExpression *anExpr) { return 0; }
-CxxExpression *make_modulus_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_multiply_expression(CxxExpression *leftExpr, CxxDeclarator *aDeclarator, CxxExpression *rightExpr) { return 0; }
-CxxName *make_name(CxxName *aName) { return 0; }
-CxxName *make_name_expression(CxxName *aName) { return 0; }
-CxxDeclaration *make_namespace_alias_definition(CxxName *aName, CxxName *forId) { return 0; }
-CxxDeclaration *make_namespace_declaration(CxxName *aName) { return 0; }
-CxxName *make_namespace_definition(CxxName *aName, CxxDeclarations *aDeclaration) { return 0; }
-CxxDeclarator *make_nested_declarator(CxxName *aName, CxxDeclarator *aDeclarator) { return 0; }
-CxxName *make_nested_id(CxxName *nestingId, CxxName *nestedId) { return 0; }
-CxxName *make_nested_scope(CxxName *nestingId) { return 0; }
-CxxExpression *make_new_expression(CxxParameters *aPlace, CxxParameters *aType, CxxExpression *anInit) { return 0; }
-CxxExpression *make_new_type_id_expression(CxxParameters *aPlace, CxxExpression *aType, CxxExpression *anInit) { return 0; }
-CxxDeclSpecifierId *make_not_const() { return 0; }
-CxxExpression *make_not_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_not_expression(CxxExpression *anExpr) { return 0; }
-CxxDeclSpecifierId *make_not_inline() { return 0; }
-CxxDeclSpecifierId *make_not_static() { return 0; }
-CxxDeclSpecifierId *make_not_virtual() { return 0; }
-CxxBaseSpecifier *make_not_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
-CxxDeclSpecifierId *make_not_volatile() { return 0; }
-CxxExpression *make_number_literal_expression(CxxExpression *anExpr) { return 0; }
-CxxExpression *make_object_scope_expression(CxxExpression *anExpr, CxxDeclaration *functionDeclarations) { return 0; }
-CxxName *make_operator_add_id() { return 0; }
-CxxName *make_operator_arrow_id() { return 0; }
-CxxName *make_operator_arrow_star_id() { return 0; }
-CxxName *make_operator_ass_add_id() { return 0; }
-CxxName *make_operator_ass_bit_and_id() { return 0; }
-CxxName *make_operator_ass_bit_or_id() { return 0; }
-CxxName *make_operator_ass_div_id() { return 0; }
-CxxName *make_operator_ass_id() { return 0; }
-CxxName *make_operator_ass_mod_id() { return 0; }
-CxxName *make_operator_ass_mul_id() { return 0; }
-CxxName *make_operator_ass_shl_id() { return 0; }
-CxxName *make_operator_ass_shr_id() { return 0; }
-CxxName *make_operator_ass_sub_id() { return 0; }
-CxxName *make_operator_ass_xor_id() { return 0; }
-CxxName *make_operator_bit_and_id() { return 0; }
-CxxName *make_operator_bit_not_id() { return 0; }
-CxxName *make_operator_bit_or_id() { return 0; }
-CxxName *make_operator_call_id() { return 0; }
-CxxName *make_operator_comma_id() { return 0; }
-CxxName *make_operator_dec_id() { return 0; }
-CxxName *make_operator_delete_id() { return 0; }
-CxxName *make_operator_div_id() { return 0; }
-CxxName *make_operator_eq_id() { return 0; }
-CxxName *make_operator_function_id(CxxName *operatorId) { return 0; }
-CxxName *make_operator_ge_id() { return 0; }
-CxxName *make_operator_gt_id() { return 0; }
-CxxName *make_operator_inc_id() { return 0; }
-CxxName *make_operator_index_id() { return 0; }
-CxxName *make_operator_le_id() { return 0; }
-CxxName *make_operator_log_and_id() { return 0; }
-CxxName *make_operator_log_not_id() { return 0; }
-CxxName *make_operator_log_or_id() { return 0; }
-CxxName *make_operator_lt_id() { return 0; }
-CxxName *make_operator_mod_id() { return 0; }
-CxxName *make_operator_mul_id() { return 0; }
-CxxName *make_operator_ne_id() { return 0; }
-CxxName *make_operator_new_id() { return 0; }
-CxxName *make_operator_shl_id() { return 0; }
-CxxName *make_operator_shr_id() { return 0; }
-CxxName *make_operator_sub_id() { return 0; }
-CxxName *make_operator_xor_id() { return 0; }
-CxxParameters *make_parameters(CxxParameters *aList, CxxParameter *anElement) { return 0; }
-CxxParenthesised *make_parenthesised(CxxParameters *aList, CxxCvQualifiers *cvQualifiers, CxxExceptionSpecification *exceptionSpecification) { return 0; }
-CxxExpression *make_plus_expression(CxxExpression *anExpr) { return 0; }
-CxxPointerDeclarator *make_pointer_declarator() { return 0; }
-CxxExpression *make_pointer_expression(CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; }
-CxxExpression *make_post_decrement_expression(CxxExpression *anExpr) { return 0; }
-CxxExpression *make_post_increment_expression(CxxExpression *anExpr) { return 0; }
-CxxExpression *make_pre_decrement_expression(CxxExpression *anExpr) { return 0; }
-CxxExpression *make_pre_increment_expression(CxxExpression *anExpr) { return 0; }
-CxxName *make_pseudo_destructor_id(CxxBuiltInId *aScope, CxxBuiltInId *aName) { return 0; }
-CxxDeclSpecifierId *make_pure_virtual() { return 0; }
-CxxDeclarator *make_reference_declarator() { return 0; }
-CxxExpression *make_reinterpret_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
-CxxStatement *make_return_statement(CxxExpression *anExpr) { return 0; }
-CxxName *make_scoped_id(CxxName *globalId, CxxName *nestedId) { return 0; }
-CxxExpression *make_scoped_pointer_expression(CxxExpression *aScope, CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; }
-CxxSegment *make_segment(CxxSegment *aSegment) { return 0; }
-CxxFunctionBody *make_segment_function_block(CxxFunctionBody *functionBody, CxxSegment *aSegment) { return 0; }
-CxxDeclSpecifierId *make_set_template_decl_specifier(CxxDeclSpecifierId *aName) { return 0; }
-CxxDeclaration *make_set_template_declaration(CxxDeclaration *aDeclaration) { return 0; }
-CxxExpression *make_set_template_expression(CxxExpression *anExpr) { return 0; }
-CxxName *make_set_template_id(CxxName *aName) { return 0; }
-CxxName *make_set_template_name(CxxName *aName) { return 0; }
-CxxName *make_set_template_scope(CxxName *aName) { return 0; }
-CxxExpression *make_shift_left_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxExpression *make_shift_right_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxDeclaration *make_simple_declaration(CxxExpression *anExpr) { return 0; }
-CxxExpression *make_sizeof_expression(CxxExpression *anExpr) { return 0; }
-CxxStatements *make_statements(CxxStatements *, CxxStatement *aStmt) { return 0; }
-CxxExpression *make_static_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
-CxxExpression *make_string_literal_expression(CxxStrings *aString) { return 0; }
-CxxStrings *make_strings(CxxStringLiteral *anElement, CxxStrings *aList) { return 0; }
-CxxExpression *make_subtract_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
-CxxStatement *make_switch_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; }
-CxxExpression *make_syntax_macro_definition(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxSyntaxMacroParameters *aList, CxxToken *aBody) { return 0; }
-CxxSyntaxMacroParameter *make_syntax_macro_parameter(CxxToken *metaType, CxxIsTree isTree, CxxName *aName) { return 0; }
-CxxSyntaxMacroParameters *make_syntax_macro_parameters(CxxSyntaxMacroParameters *aList, CxxSyntaxMacroParameter *anElement) { return 0; }
-CxxTemplateArgument *make_template_argument(CxxParameter *aParameter) { return 0; }
-CxxTemplateArguments *make_template_arguments(CxxTemplateArguments *aList, CxxTemplateArgument *anElement) { return 0; }
-CxxDeclaration *make_template_declaration(CxxTemplateParameters *aList, CxxDeclaration *aDeclaration) { return 0; }
-CxxName *make_template_name(CxxName *aName, CxxTemplateArguments *templateArguments) { return 0; }
-CxxTemplateParameter *make_templated_template_parameter(CxxTemplateParameter *typeParameter, CxxName *aName) { return 0; }
-CxxTemplateParameter *make_template_parameter(CxxParameter *aParameter) { return 0; }
-CxxTemplateParameters *make_template_parameters(CxxTemplateParameters *aList, CxxTemplateParameter *anElement) { return 0; }
-CxxTemplatedTypeParameter *make_templated_type_parameter(CxxTemplateParameters *templateParameters, CxxName *aName) { return 0; }
-CxxExpression *make_this_expression() { return 0; }
-CxxExpression *make_throw_expression(CxxExpression *anExpr) { return 0; }
-CxxExpression *make_tokens_expression(CxxTokens *someTokens) { return 0; }
-CxxToken *make_tree_argument(CxxToken *aToken) { return 0; }
-CxxTokens *make_tree_arguments(CxxTokens *aList, CxxToken *anElement) { return 0; }
-CxxTreeExpression *make_tree_array_expression(CxxTreeExpression *anExpr, CxxExpression *indexExpr) { return 0; }
-CxxTreeExpression *make_tree_arrow_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; }
-CxxTreeExpression *make_tree_call_expression(CxxTreeExpression *anExpr, CxxTokens *aList) { return 0; }
-CxxTreeExpression *make_tree_dot_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; }
-CxxTreeExpression *make_tree_expression(CxxName *aName) { return 0; }
-CxxName *make_tree_id(CxxName *aName) { return 0; }
-CxxTreeExpression *make_tree_pointer_expression(CxxTreeExpression *anExpr) { return 0; }
-CxxExpression *make_true_expression() { return 0; }
-CxxFunctionBody *make_try_block(CxxStatement *aStatement, CxxHandlers *exceptionHandlers) { return 0; }
-CxxStatement *make_try_block_statement(CxxFunctionBody *tryBlock) { return 0; }
-CxxFunctionBody *make_try_function_block(CxxFunctionBody *functionBody, CxxHandlers *exceptionHandlers) { return 0; }
-CxxExpression *make_type1_expression(CxxExpression *functionName, CxxParenthesised *aParenthesis, CxxType1Parameters *type1Parameters) { return 0; }
-CxxTemplateParameter *make_type_template_parameter(CxxSimpleTypeParameter *typeParameter, CxxExpression *typeId) { return 0; }
-CxxExpression *make_typed_expression(CxxName *frontName, CxxExpression *backName) { return 0; }
-CxxName *make_typed_name(CxxName *frontName, CxxName *backName) { return 0; }
-CxxExpression *make_typeid_expression(CxxExpression *aList) { return 0; }
-CxxSimpleTypeParameter *make_typename_template_parameter(CxxName *aName) { return 0; }
-CxxSimpleTypeParameter *make_typename_type_parameter(CxxName *aName) { return 0; }
-CxxType1Parameters *make_type1_parameters(CxxType1Parameters *aList, CxxParameters *someParameters) { return 0; }
-CxxDeclaration *make_using_declaration(bool isTypename, CxxName *aName) { return 0; }
-CxxDeclaration *make_using_directive(CxxName *aName) { return 0; }
-CxxFunctionBody *make_using_function_block(CxxFunctionBody *functionBody, CxxFileIds *fileIds) { return 0; }
-CxxDeclaration *make_using_implementation_declaration(CxxFileId *fileId) { return 0; }
-CxxDeclaration *make_using_interface_declaration(CxxFileId *fileId) { return 0; }
-CxxUtility *make_utility(CxxUtility *aUtility) { return 0; }
-CxxUtility *make_utility_mode() { return 0; }
-CxxBaseSpecifier *make_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
-CxxStatement *make_while_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; }
-
diff --git a/examples/cpp_grammar_code/CxxToken.cpp b/examples/cpp_grammar_code/CxxToken.cpp
deleted file mode 100644 (file)
index 7efca54..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-//       Title:                        C++ Grammar Token support compilation unit.
-//
-//       File Name:            CxxToken.cpp
-//
-//       Author:                       E.D.Willink
-//END
-//
-#include <CxxToken.cxx>
diff --git a/examples/cpp_grammar_code/CxxToken.cxx b/examples/cpp_grammar_code/CxxToken.cxx
deleted file mode 100644 (file)
index 6ad6227..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <CxxToken.hxx>
-#include <memory.h>
-
-//CxxToken::CxxToken()
-//:
-//     _value(0)
-//{}
-
-CxxNaffToken::CxxNaffToken(int tokenValue, const char *yyText, int yyLeng)
-:
-       Super(tokenValue), _text(new char[yyLeng+1]), _leng(yyLeng)
-{
-       memcpy(_text, yyText, yyLeng);
-       _text[_leng] = 0;
-}
-
-CxxNaffToken::~CxxNaffToken() { delete[] _text; }
diff --git a/examples/cpp_grammar_code/CxxToken.hxx b/examples/cpp_grammar_code/CxxToken.hxx
deleted file mode 100644 (file)
index 9455f9b..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-#ifndef CXXTOKEN_HXX
-#define CXXTOKEN_HXX
-
-#include <iostream.h>
-#include <stdlib.h>
-
-#define YYSTYPE CxxTokenType
-#define YY_parse_STYPE CxxTokenType
-#define YACC_BANG_TYPE size_t
-#define YACC_MARK_TYPE size_t
-
-#define YACC_BANG() push_bang()
-#define YACC_UNBANG(bangValue, msg) pop_bang(bangValue); yyerrok; yyclearin; yyerror(msg);
-
-#define ERRMSG(a) do { cout << "ERROR -- " << a << endl; increment_error_count(); } while (0)
-
-#ifdef NEEDS_BOOL
-enum bool { false, true };
-#endif
-
-#ifdef BISON_PP_CLASS
-#define PARSE_TOKEN(a) BISON_PP_CLASS::a
-#else
-#define PARSE_TOKEN(a) a
-#endif
-
-extern size_t line_number;
-extern bool c_keywords;
-extern bool echo_line_numbers;
-extern bool echo_line_text;
-extern void increment_error_count();
-extern int tokenMarkDepth;
-
-class CxxToken
-{
-       int _value;
-private:
-       CxxToken(const CxxToken&);
-       CxxToken& operator=(const CxxToken&);
-public:
-       CxxToken(int tokenValue = 0) : _value(tokenValue) {}
-       virtual ~CxxToken() {}
-       int value() const { return _value; }
-};
-
-enum CxxIsTemplate { IS_DEFAULT, IS_TEMPLATE };
-enum CxxIsTree { IS_SCALAR, IS_TREE };
-typedef CxxToken CxxTreeArgument;
-
-class CxxStatement : public CxxToken {};
-typedef CxxStatement CxxDeclaration;
-class CxxExpression : public CxxStatement {};
-class CxxName : public CxxExpression {};
-class CxxTokens : public CxxToken {};
-class CxxMetaObject : public CxxExpression {};
-class CxxMetaStatement : public CxxStatement {};
-
-class CxxStatements : public CxxStatement {};
-typedef CxxStatements CxxDeclarations;
-typedef CxxDeclarations CxxMemberDeclarations;
-typedef CxxExpression CxxTreeExpression;
-
-class CxxKeyword : public CxxName {};
-class CxxDeclSpecifierId : public CxxKeyword {};
-
-class CxxAccessSpecifier : public CxxKeyword {};
-class CxxBaseSpecifier : public CxxToken {};
-class CxxBaseSpecifiers : public CxxTokens {};
-class CxxBrace : public CxxToken {};
-class CxxBuiltInId : public CxxName {};
-class CxxCharacterLiteral : public CxxToken {};
-class CxxClass : public CxxToken {};
-class CxxClassKey : public CxxKeyword {};
-class CxxCondition : public CxxExpression {};
-class CxxCvQualifiers : public CxxDeclSpecifierId {};
-class CxxDeclarator : public CxxToken {};
-typedef CxxExpression CxxDeleteExpression;
-//class CxxDerived : public CxxToken {};
-//class CxxEnum : public CxxToken {};
-class CxxEnumerator : public CxxToken {};
-class CxxEnumerators : public CxxTokens {};
-class CxxExceptionDeclaration : public CxxToken {};
-class CxxExceptionSpecification : public CxxToken {};
-class CxxExpressions : public CxxExpression {};
-class CxxFileId : public CxxToken {};
-class CxxFileIds : public CxxTokens {};
-class CxxFileName : public CxxToken {};
-class CxxFloatingLiteral : public CxxToken {};
-class CxxFunctionBody : public CxxStatement {};
-class CxxFunctionDeclarations : public CxxDeclarations {};
-class CxxHandler : public CxxToken {};
-class CxxHandlers : public CxxTokens {};
-class CxxIdentifier : public CxxName {};
-//class CxxIds : public CxxTokens {};
-class CxxInitializerClause : public CxxExpression {};
-class CxxInitializerClauses : public CxxInitializerClause {};
-class CxxIntegerLiteral : public CxxToken {};
-class CxxLine : public CxxToken {};
-//class CxxList : public CxxTokens {};
-class CxxMemInitializer : public CxxToken {};
-class CxxMemInitializers : public CxxTokens {};
-class CxxMetaClass : public CxxStatement {};
-class CxxMetaFunction : public CxxMetaObject {};
-class CxxMetaInitializer : public CxxToken {};
-class CxxMetaInitializers : public CxxTokens {};
-class CxxMetaParameter : public CxxToken {};
-class CxxMetaParameters : public CxxTokens {};
-//class CxxMetaPrototype : public CxxToken {};
-//class CxxMetaPrototypes : public CxxTokens {};
-class CxxMetaType : public CxxName {};
-class CxxMetaVariable : public CxxMetaObject {};
-class CxxNamespace : public CxxToken {};
-typedef CxxExpression CxxNewExpression;
-class CxxNumberLiteral : public CxxExpression {};
-class CxxParameter : public CxxExpression {};
-class CxxParameters : public CxxExpression {};
-class CxxParenthesised : public CxxToken {};
-class CxxPointerDeclarator : public CxxDeclarator {};
-class CxxPosition : public CxxName {};
-class CxxSegment : public CxxName {};
-class CxxSpacing : public CxxToken {};
-class CxxStrings : public CxxToken {};
-typedef CxxStrings CxxStringLiteral;
-class CxxSubspace : public CxxToken {};
-class CxxSyntaxMacroParameter : public CxxToken {};
-class CxxSyntaxMacroParameters : public CxxTokens {};
-class CxxTemplateArgument : public CxxToken {};
-class CxxTemplateArguments : public CxxTokens {};
-class CxxTemplateParameter : public CxxToken {};
-class CxxTemplateParameters : public CxxTokens {};
-class CxxSimpleTypeParameter : public CxxTemplateParameter {};
-class CxxTemplatedTypeParameter : public CxxTemplateParameter {};
-class CxxTokenStatements : public CxxTokens {};
-class CxxTreeArguments : public CxxTokens {};
-class CxxType1Parameters : public CxxTokens {};
-class CxxTypeId : public CxxToken {};
-class CxxTypeIds : public CxxTokens {};
-class CxxUtility : public CxxToken {};
-
-#define FOGPARSERVALUE_ENUM(T,N) \
-       const T *name2(u_,N); \
-       const T& N() const { return *name2(u_,N); } \
-       const T* & N() { return name2(u_,N); }
-#define FOGPARSERVALUE_POINTER(T,N) T *N;
-#define FOGPARSERVALUE_VALUE(T,N) T N;
-
-union CxxTokenType
-{
-               CxxToken *_token;
-
-               FOGPARSERVALUE_VALUE(bool, _bool)
-               FOGPARSERVALUE_VALUE(long, _long)
-               FOGPARSERVALUE_POINTER(CxxBrace, brace)
-               FOGPARSERVALUE_POINTER(CxxSpacing, spacing)
-
-               FOGPARSERVALUE_POINTER(CxxAccessSpecifier, access_specifier)
-               FOGPARSERVALUE_POINTER(CxxBaseSpecifier, base_specifier)
-               FOGPARSERVALUE_POINTER(CxxBaseSpecifiers, base_specifiers)
-               FOGPARSERVALUE_POINTER(CxxBuiltInId, built_in_id)
-               FOGPARSERVALUE_POINTER(CxxCharacterLiteral, character_literal)
-               FOGPARSERVALUE_POINTER(CxxClass, _class)
-               FOGPARSERVALUE_POINTER(CxxClassKey, class_key)
-               FOGPARSERVALUE_POINTER(CxxCondition, condition)
-               FOGPARSERVALUE_POINTER(CxxCvQualifiers, cv_qualifiers)
-               FOGPARSERVALUE_POINTER(CxxDeclSpecifierId, decl_specifier_id)
-               FOGPARSERVALUE_POINTER(CxxDeclaration, declaration)
-               FOGPARSERVALUE_POINTER(CxxDeclarations, declarations)
-               FOGPARSERVALUE_POINTER(CxxDeclarator, declarator)
-               FOGPARSERVALUE_POINTER(CxxDeleteExpression, delete_expression)
-               FOGPARSERVALUE_POINTER(CxxEnumerator, enumerator)
-               FOGPARSERVALUE_POINTER(CxxEnumerators, enumerators)
-               FOGPARSERVALUE_POINTER(CxxExceptionDeclaration, exception_declaration)
-               FOGPARSERVALUE_POINTER(CxxExceptionSpecification, exception_specification)
-               FOGPARSERVALUE_POINTER(CxxExpression, expression)
-               FOGPARSERVALUE_POINTER(CxxExpressions, expressions)
-               FOGPARSERVALUE_POINTER(CxxFileId, file_id)
-               FOGPARSERVALUE_POINTER(CxxFileIds, file_ids)
-               FOGPARSERVALUE_POINTER(CxxFileName, file_name)
-               FOGPARSERVALUE_POINTER(CxxFloatingLiteral, floating_literal)
-               FOGPARSERVALUE_POINTER(CxxFunctionBody, function_body)
-               FOGPARSERVALUE_POINTER(CxxHandler, handler)
-               FOGPARSERVALUE_POINTER(CxxHandlers, handlers)
-               FOGPARSERVALUE_POINTER(CxxIdentifier, identifier)
-               FOGPARSERVALUE_POINTER(CxxInitializerClause, initializer_clause)
-               FOGPARSERVALUE_POINTER(CxxInitializerClauses, initializer_clauses)
-               FOGPARSERVALUE_POINTER(CxxIntegerLiteral, integer_literal)
-               FOGPARSERVALUE_POINTER(CxxKeyword, keyword)
-               FOGPARSERVALUE_POINTER(CxxLine, line)
-               FOGPARSERVALUE_POINTER(CxxMemInitializer, mem_initializer)
-               FOGPARSERVALUE_POINTER(CxxMemInitializers, mem_initializers)
-               FOGPARSERVALUE_POINTER(CxxMemberDeclarations, member_declarations)
-               FOGPARSERVALUE_POINTER(CxxMetaClass, meta_class)
-               FOGPARSERVALUE_POINTER(CxxMetaFunction, meta_function)
-               FOGPARSERVALUE_POINTER(CxxMetaInitializer, meta_initializer)
-               FOGPARSERVALUE_POINTER(CxxMetaInitializers, meta_initializers)
-               FOGPARSERVALUE_POINTER(CxxMetaObject, meta_object)
-               FOGPARSERVALUE_POINTER(CxxMetaStatement, meta_statement)
-               FOGPARSERVALUE_POINTER(CxxMetaType, meta_type)
-               FOGPARSERVALUE_POINTER(CxxMetaVariable, meta_variable)
-               FOGPARSERVALUE_POINTER(CxxName, name)
-               FOGPARSERVALUE_POINTER(CxxNewExpression, new_expression)
-               FOGPARSERVALUE_POINTER(CxxNumberLiteral, number_literal)
-               FOGPARSERVALUE_POINTER(CxxParameter, parameter)
-               FOGPARSERVALUE_POINTER(CxxParameters, parameters)
-               FOGPARSERVALUE_POINTER(CxxParenthesised, parenthesised)
-               FOGPARSERVALUE_POINTER(CxxPointerDeclarator, pointer_declarator)
-               FOGPARSERVALUE_POINTER(CxxPosition, position)
-               FOGPARSERVALUE_POINTER(CxxSegment, segment)
-               FOGPARSERVALUE_POINTER(CxxSimpleTypeParameter, simple_type_parameter)
-               FOGPARSERVALUE_POINTER(CxxStatement, statement)
-               FOGPARSERVALUE_POINTER(CxxStatements, statements)
-               FOGPARSERVALUE_POINTER(CxxStringLiteral, string_literal)
-               FOGPARSERVALUE_POINTER(CxxStrings, strings)
-               FOGPARSERVALUE_POINTER(CxxSubspace, subspace)
-               FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameter, syntax_macro_parameter)
-               FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameters, syntax_macro_parameters)
-               FOGPARSERVALUE_POINTER(CxxTemplateArgument, template_argument)
-               FOGPARSERVALUE_POINTER(CxxTemplateArguments, template_arguments)
-               FOGPARSERVALUE_POINTER(CxxTemplateParameter, template_parameter)
-               FOGPARSERVALUE_POINTER(CxxTemplateParameters, template_parameters)
-               FOGPARSERVALUE_POINTER(CxxTemplatedTypeParameter, templated_type_parameter)
-               FOGPARSERVALUE_POINTER(CxxToken, token)
-               FOGPARSERVALUE_POINTER(CxxTokenStatements, token_statements)
-               FOGPARSERVALUE_POINTER(CxxTokens, tokens)
-               FOGPARSERVALUE_POINTER(CxxTreeArgument, tree_argument)
-               FOGPARSERVALUE_POINTER(CxxTreeArguments, tree_arguments)
-               FOGPARSERVALUE_POINTER(CxxTreeExpression, tree_expression)
-               FOGPARSERVALUE_POINTER(CxxType1Parameters, type1_parameters)
-               FOGPARSERVALUE_POINTER(CxxUtility, utility)
-
-               FOGPARSERVALUE_VALUE(int, bang)
-               FOGPARSERVALUE_VALUE(CxxIsTemplate, is_template)
-               FOGPARSERVALUE_VALUE(YACC_MARK_TYPE, mark)
-               FOGPARSERVALUE_VALUE(size_t, nest)
-#if 0
-       CxxAccessSpecifier *access_specifier;
-       CxxBaseSpecifier *base_specifier;
-       CxxBaseSpecifiers *base_specifiers;
-       CxxBuiltInId *built_in_id;
-       CxxCharacterLiteral *character_literal;
-       CxxClass *_class;
-       CxxClassKey *class_key;
-       CxxCondition *condition;
-       CxxCvQualifiers *cv_qualifiers;
-       CxxDeclaration *declaration;
-       CxxDeclarations *declarations;
-       CxxDeclarator *declarator;
-       CxxDeclSpecifierId *decl_specifier_id;
-//     CxxDerived *derived;
-//     CxxEnum *_enum;
-       CxxEnumerator *enumerator;
-       CxxEnumerators *enumerators;
-       CxxExceptionDeclaration *exception_declaration;
-       CxxExceptionSpecification *exception_specification;
-       CxxExpression *expression;
-       CxxExpressions *expressions;
-       CxxFileId *file_id;
-       CxxFileIds *file_ids;
-       CxxFileName *file_name;
-       CxxFloatingLiteral *floating_literal;
-       CxxFunctionBody *function_body;
-       CxxFunctionDeclarations *function_declarations;
-       CxxHandler *handler;
-       CxxHandlers *handlers;
-       CxxIdentifier *identifier;
-//     CxxIds *ids;
-       CxxInitializerClause *initializer_clause;
-       CxxInitializerClauses *initializer_clauses;
-       CxxIntegerLiteral *integer_literal;
-       CxxKeyword *keyword;
-       CxxLine *line;
-//     CxxList *list;
-       CxxMemInitializer *mem_initializer;
-       CxxMemInitializers *mem_initializers;
-       CxxMemberDeclarations *member_declarations;
-       CxxMetaClass *meta_class;
-//     CxxMetaFunction *meta_function;
-//     CxxMetaInitializer *meta_initializer;
-//     CxxMetaInitializers *meta_initializers;
-//     CxxMetaObject *meta_object;
-       CxxMetaParameter *meta_parameter;
-       CxxMetaParameters *meta_parameters;
-//     CxxMetaPrototype *meta_prototype;
-//     CxxMetaPrototypes *meta_prototypes;
-//     CxxMetaStatement *meta_statement;
-       CxxMetaType *meta_type;
-//     CxxMetaVariable *meta_variable;
-       CxxName *name;
-//     CxxNamespace *_namespace;
-       CxxNumberLiteral *number_literal;
-       CxxParameter *parameter;
-       CxxParameters *parameters;
-       CxxParenthesised *parenthesised;
-       CxxPointerDeclarator *pointer_declarator;
-       CxxSegment *segment;
-       CxxSimpleTypeParameter *simple_type_parameter;
-       CxxStatement *statement;
-       CxxStatements *statements;
-       CxxStringLiteral *string_literal;
-       CxxStrings *strings;
-       CxxSyntaxMacroParameter *syntax_macro_parameter;
-       CxxSyntaxMacroParameters *syntax_macro_parameters;
-       CxxTemplateArgument *template_argument;
-       CxxTemplateArguments *template_arguments;
-       CxxTemplateParameter *template_parameter;
-       CxxTemplateParameters *template_parameters;
-       CxxTemplatedTypeParameter *templated_type_parameter;
-       CxxToken *token;
-       CxxTokens *tokens;
-//     CxxTreeArgument *tree_argument;
-//     CxxTreeArguments *tree_arguments;
-//     CxxTreeExpression *tree_expression;
-       CxxType1Parameters *type1_parameters;
-//     CxxTypeId *type_id;
-//     CxxTypeIds *type_ids;
-       CxxUtility *utility;
-       YACC_BANG_TYPE bang;
-       YACC_MARK_TYPE mark;
-       size_t nest;
-#endif
-};
-
-class CxxNaffToken : public CxxToken
-{
-       typedef CxxToken Super;
-       char *_text;
-       int _leng;
-private:
-       CxxNaffToken(const CxxNaffToken&);
-       CxxNaffToken& operator=(const CxxNaffToken&);
-public:
-       CxxNaffToken(int tokenValue, const char *yyText, int yyLeng);
-       virtual ~CxxNaffToken();
-};
-
-#endif
diff --git a/examples/cpp_grammar_code/README b/examples/cpp_grammar_code/README
deleted file mode 100644 (file)
index b19e98c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-This directory tree comprises a pre-built demonstration of the superset C++ grammar
-from FOG..
-
-Contents
---------
-
-       Release/grammar.exe     -- the statically bound executable (on NT)
-    sun4o/grammar -- the statically bound executable (on Unix)
-
-It is a command line based utility. See index.html for details.
-
-Bug reporting
--------------
-
-Please report any bugs to Ed.Willink@rrl.co.uk. I will endeavour to fix them,
-but since this code is a one man effort and my time is primarily devoted to
-my other activities for Thales Research, only simple and easy fixes are likely.
-I am more likely to be able to fix the problem if you can trim your problem to
-just a few lines.
-
diff --git a/examples/cpp_grammar_code/index.html b/examples/cpp_grammar_code/index.html
deleted file mode 100644 (file)
index af2afda..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-<html>
-
-<head>
-<meta http-equiv="Content-Type"
-content="text/html; charset=iso-8859-1">
-<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
-<title>Ed's Toolkit</title>
-</head>
-
-<body bgcolor="#FFFFFF">
-
-<h1 align="center">Superset C++ Grammar</h1>
-
-<hr>
-
-<p>This work area supports a demonstration of the superset C++
-grammar described in Chapter 5 of <a
-href="mailto:Ed.Willink@rrl.co.uk">Ed Willink</a>'s thesis on <a
-href="http://www.computing.surrey.ac.uk/research/dsrg/fog/FogThesis.html">Meta-Compilation
-for C++</a>. It contains working lex and yacc grammars that
-enable C++ source to be lexically analysed, then syntactically
-analysed without semantic knowlege. The lex and yacc grammar have
-their action routines defined by macros in the hope that
-reconfiguration may be possible without editing the grammars
-directly. The dummy implementations of the yacc macros do nothing
-other than count statements and diagnose the back-tracking
-behaviour. Users may add their own syntactic level code. A proper
-C++ parser needs semantic analysis as well, including correction
-of minor misprses at the syntactic level. Semantic interpretaion
-is provided by <a
-href="http://www.computing.surrey.ac.uk/research/dsrg/fog/">FOG</a>
-from which this demonstration is split off.</p>
-
-<p>The work area is self-sufficient, requiring only <em>lex</em>
-and <em>yacc</em>, or <em>flex</em> and <em>bison</em>.</p>
-
-<hr>
-
-<h2>Command Line</h2>
-
-<p>The test grammar is a simple command line utility, for
-analysing a single <strong>pre-processed</strong> source file
-(use CC -E to run just the preprocessor on your source files)..</p>
-
-<pre>  grammar [options] &lt; source-file</pre>
-
-<p>The full set of command line options is:</p>
-
-<pre>  -c      Recognise only C keywords - approximates C rather than C++ parsing
-       -m      Display mark activity.
-       -n      Echo line numbers.
-       -t      Echo source line text.
-       -y      Display yacc diagnostics.</pre>
-
-<p>On completion a three line diagnostic summarises the search
-activity. </p>
-
-<hr>
-
-<h2>Files</h2>
-
-<p><a href="CxxSrc.tgz">CxxSrc.tgz</a>, <a href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>
-The source distribution kit including a Sun or NT executable.</p>
-
-<p><a href="CxxLexer.l">CxxLexer.l</a> A simple lexer for all C
-and/or C++ tokens</p>
-
-<p><a href="CxxParser.y">CxxParser.y</a> The parser,
-automatically extracted from FogParser.y.</p>
-
-<p><a href="CxxToken.hxx">CxxToken.hxx</a>, <a
-href="CxxToken.cxx">CxxToken.cxx</a> A trivial class used by the
-parser to represent each parsed token.</p>
-
-<p><a href="CxxLexing.hxx">CxxLexing.hxx</a>, <a
-href="CxxLexing.cxx">CxxLexing.cxx</a> Interface and
-implementation of token creation routines for the lexer.</p>
-
-<p><a href="CxxParsing.hxx">CxxParsing.hxx</a>, <a
-href="CxxParsing.cxx">CxxParsing.cxx</a> Interface and
-implementation of token manioulation routines for the parser.</p>
-
-<p><a href="CxxLexer.cpp">CxxLexer.cpp</a>, <a
-href="CxxParser.cpp">CxxParser.cpp</a>, <a href="CxxToken.cpp">CxxToken.cpp</a>
-Degenerate compilation units for the above.</p>
-
-<p><a href="makefile">makefile</a>, <a href="makefile.macros">makefile.macros</a>,
-<a href="CxxLexer.l">makefile.unix</a> Unix build scripts</p>
-
-<p><a href="makefile.gmake">makefile.gmake</a>, <a
-href="makefile.macros">makefile.macros</a>, <a href="grammar.dsw">grammar.dsw</a>,
-<a href="grammar.dsp">grammar.dsp</a> NT build scripts and
-DevStudio workspace and project</p>
-
-<p><a><u>sun4o/grammar</u></a> Built executable (on Unix)</p>
-
-<p><a><u>Release/grammar.exe</u></a> Built executable (on NT)</p>
-
-<hr>
-
-<h2>Unix Builds</h2>
-
-<p>The code builds under Solaris 2.5 and with Sun C++ 4.2.</p>
-
-<pre>  make sun</pre>
-
-<p>or Gnu egcs-1.0.2 release, with flex 2.3.7, bison 1.16</p>
-
-<pre>  make gnu</pre>
-
-<hr>
-
-<h2>NT Builds</h2>
-
-<p>The code builds under NT 4 and has been tested with DevStudio
-V6 and cygwin 1.1.</p>
-
-<h3>a) cygwin</h3>
-
-<p>You need cygwin, the latest version of which is available <a
-href="ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/setup.exe">ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/setup.exe</a></p>
-
-<p>A slightly easier to install earlier version (used by the
-author) is <a
-href="ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/old/cygwin-b20/full.exe">ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/old/cygwin-b20/full.exe</a></p>
-
-<p>Use a mirror site listed at <a
-href="http://sources.redhat.com/cygwin/mirrors.html">http://sources.redhat.com/cygwin/mirrors.html</a>.</p>
-
-<p>The older cygwin is a simple standard NT installation - just
-run full.exe (with administrator rights) and accept the default
-installation paths (gnu tools build them in). The newer cygwin is
-much smarter, doing automatic selective downloads - which the
-author's firewall messes up.</p>
-
-<h3>b) Path configuration</h3>
-
-<p>You may want to make cygwin tools accessible from command
-prompts so</p>
-
-<pre>Start-&gt;Settings-&gt;ControlPanel
-       System|Environment
-               Add Variable PATH
-               Value C:\cygwin\cygwin-b20\H-i586-cygwin32\BIN</pre>
-
-<h3>c) DevStudio configuration</h3>
-
-<p>You need to configure DevStudio to use cygwin.</p>
-
-<p>In DevStudio:</p>
-
-<pre>Tools-&gt;Options-&gt;Directories
-       Show Directories For Executable files
-       Add C:\cygwin\bin</pre>
-
-<h3>d) Unpacking</h3>
-
-<p>Then use winzip or gunzip to extract all of <a
-href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>:</p>
-
-<pre>double click in Explorer on <a href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>
-       Yes to decompress archive to temporary file
-       Wait a few moments
-       Actions...-&gt;Extract
-               All Files, to e.g. C:\CxxGrammar, use Folder names, Extract
-       Close Winzip</pre>
-
-<h3>e) DevStudio build</h3>
-
-<pre>Double click in Explorer on <a href="grammar.dsw">grammar.dsw</a>
-       If prompted to browse for a SourceSafe project Click No.
-       If prompted to attempt SourceSafe connection in another session click No.
-       Select your preferred configuration (Win32 Debug is default)
-       Select FileView|grammar Files-&gt;Targets-&gt;executable
-       &lt;Ctrl&gt;F7
-       after a few seconds everything is built</pre>
-
-<p>DevStudio reports 0 errors and 1 warnings</p>
-
-<pre>Build : warning : failed to (or don't know how to) build 'C:\CxxGrammar\Targets\executable'</pre>
-
-<p>The warning is an artefact of fake build targets</p>
-
-<p>Everything in DevStudio is compiled using a makefile.gmake
-target which is selected for a &lt;CTRL&gt;F7 in the Workspace
-window. Steer clear of the standard DevStudio F7 which builds all
-targets: backup then clean then executables then realclean then
-test etc. No harm is done but it takes a long time.</p>
-
-<hr>
-
-<p><i>Last updated <!--webbot bot="Timestamp" startspan
-s-type="EDITED" s-format="%d %B, %Y" -->28 July, 2001<!--webbot
-bot="Timestamp" i-checksum="21078" endspan -->.</i> </p>
-</body>
-</html>
diff --git a/examples/cpp_grammar_code/makefile b/examples/cpp_grammar_code/makefile
deleted file mode 100644 (file)
index e2b3d56..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-#      Title:          Make file for Cxx Grammar tester.
-#
-#      Author:         E.D.Willink
-#
-#      SCCS:           %W% %G%
-#
-#      Description:
-#                      This makefile wrapper redirects all activity to makefile.unix after first ensuring that
-#                      any .INIT provided by ../import.make has executed to load required source files.
-#
-#      Targets:        
-#                      executable, normal
-#                                      builds $(ARCH)o/grammar
-#                      sun
-#                                      builds $(ARCH)o/grammar using sun compiler, yacc and lex
-#                      gnu
-#                                      builds $(ARCH)o/grammar using gnu compiler, bison and flex
-#                      clean
-#                                      eliminates $(ARCH)o* intermediates
-#                      realclean
-#                                      eliminates $(ARCH)o* intermediates and executables
-#                      source_kit
-#                                      generates the distribution kits
-#
-#      Switch settings are appropriate for Sun C++ 4.2.
-#      Commented settings indicate what might be appropriate for gcc once it supports templates plausibly.
-#
-#      Latest Modification:
-# EDW          Date:   14-Jun-2001         Original
-#END
-
-.SUFFIXES:
-
-SRCDIR = sources
-ARCH = sun4
-OBJ_DIR = $(ARCH)o
-OBJ_DIR_PI = $(ARCH)o_pi
-OBJ_DIR_G = $(ARCH)o_g
-OBJ_DIR_PI_G = $(ARCH)o_pi_g
-
-default : executable
-
-#../import.make is empty by default, but may be provided to copy sources from somewhere.
-../import.make :
-       echo > $@
-IMPORT_PATH = grammar
-include ../import.make
-
-clean executable gnu realclean source_kit sun %.tar \
-$(SRCDIR)/% $(OBJ_DIR)/% $(OBJ_DIR_PI)/% $(OBJ_DIR_G)/% $(OBJ_DIR_PI_G)/% \
-       : makefile makefile.unix .FORCE
-       $(MAKE) -f makefile.unix $(MFLAGS) $(MAKEFLAGS) $@ 
-
-.FORCE:
\ No newline at end of file
diff --git a/examples/cpp_grammar_code/makefile.gmake b/examples/cpp_grammar_code/makefile.gmake
deleted file mode 100644 (file)
index b321cb3..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-#
-#      Title:                  makefile.gmake
-#
-#      Author:                 E.D.Willink
-#
-#      Description:    GNU make file for Cxx Grammar tester under NT
-#
-#              Environment
-#                      INTDIR  intermediate directory for objects (defaults to ".\Release")
-#                      OUTDIR  output directory for executable (defaults to ".\Release")
-#                      MSINCDIR path of main system include directory (defaults to $(MSVCDIR)\Include)
-#
-#              Public Targets
-#                      executable
-#                                      builds '$(OUTDIR)'/grammar.exe
-#                      clean
-#                                      eliminates $(INTDIR) intermediates
-#                      realclean
-#                                      eliminates $(INTDIR) and '$(OUTDIR)' intermediates
-#                      source_kit
-#                                      generates the distribution kits
-#              Private Targets
-#                      backup
-#                                      copies changed sources from C: to $(BACKUPDIR)
-#                      tar_delta
-#                                      tars up changes ready for transfer to Unix
-#
-#
-#      Build is error and warning free as
-#              nmake -f makefile.gmake
-#      (after using - Visual C++ 6
-#              "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
-#      or - Visual C++ 5
-#              "C:\Program Files\DevStudio\VC\Bin\vcvars32.bat"
-#        in a Command Prompt to set up the Visual C++ environment).
-#      Alternatively do a "Compile xxx" to compile target xxx from the "grammar files->Targets"
-#      after loading root.dsw into DevStudio.
-#
-.SUFFIXES:
-.SUFFIXES: .l .y .hxx .cxx .cpp .obj
-
-TARGET = grammar
-INTDIR = .\Release
-OUTDIR = $(INTDIR)
-SRCDIR = Sources
-DUMMYDIR = Dummy
-LSTDIR = Listings
-MSINCDIR = $(MSVCDIR)\Include
-BACKUPDIR = Q:/P541/C/BackUp/grammar
-TARDELTADIR = P:/$(USERNAME)
-
-CPRINT = "../tools/cprint/$(OUTDIR)/cprint.exe" -b -c150 -e -h0 -f1 -l69 -n25 -t4
-WIDE_CPRINT = "../tools/cprint/$(OUTDIR)/cprint.exe" -b -c150 -e -h0 -f1 -l69 -n0 -t4
-
-CCP = "../tools/ccp/$(OUTDIR)/ccp.exe"
-CCP_FLAGS =
-MV = mv
-#LEX = "../tools/flex_pp/$(OUTDIR)/flex_pp.exe" -S../tools/flex_pp/flexskel.cc -H../tools/flex_pp/flexskel.h
-#LEX_FLAGS = -8
-LEX = flex
-LEX_FLAGS = 
-#YACC = "../tools/bison_pp/$(OUTDIR)/bison_pp.exe" -S ../tools/bison_pp/bison.cc -H ../tools/bison_pp/bison.h
-#YACC_FLAGS = -t -v
-YACC = bison -d -t -v
-YACC_FLAGS = 
-
-CPP = cl.exe /nologo
-CPP_RELEASE_FLAGS = /ML /O2 /D "NDEBUG"
-CPP_DEBUG_FLAGS = /MLd /Gm /ZI /Od /D "_DEBUG" /GZ 
-CPP_COMMON_FLAGS = /W3 /GX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/$(TARGET)" /c
-CPP_DEFS = /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NEEDS_YYWRAP"
-CPP_INCS = /I "$(SRCDIR)" /I "." /I "$(DUMMYDIR)" 
-
-LINK32 = link.exe /nologo /machine:I386 /subsystem:console
-LINK_RELEASE_FLAGS = /incremental:no
-LINK_DEBUG_FLAGS = /incremental:yes /debug /pdbtype:sept
-LINK32_LIBS = kernel32.lib 
-
-MAKEFILE = makefile.gmake
-DUMMIES = $(DUMMYDIR)/unistd.h
-
-include makefile.macros
-
-OBJECTS = $(COMPOSITE_SOURCES:%.cpp=$(INTDIR)/%.obj)
-
-all : $(ALL_FILES) executable
-
-executable : $(OUTDIR)/$(TARGET).exe
-
-$(DUMMYDIR)/unistd.h :
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
-       @echo '$@'
-       @- sh -c 'echo "#include <io.h>" > "$@"'
-       @- sh -c 'chmod -w "$@"'
-
-$(SRCDIR)/%.cxx : %.l
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f $(@D)/$*.cxx; fi'
-       - sh -c '$(LEX) $(LEX_FLAGS) $*.l'
-       @- sh -c 'mv -f lex.yy.c $(@D)/$*.cxx'
-       @- sh -c 'chmod -w $(@D)/$*.cxx'
-
-$(SRCDIR)/%.cxx $(SRCDIR)/%.hxx : %.y
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f $(@D)/$*.output $(@D)/$*.cxx $(@D)/$*.hxx; fi'
-       - sh -c '$(YACC) $(YACC_FLAGS) $*.y'
-       @- sh -c 'mv -f $*.tab.c $(@D)/$*.cxx'
-       @- sh -c 'mv -f $*.tab.h $(@D)/$*.hxx'
-       @- sh -c 'mv -f $*.output $(@D)/$*.output'
-       @- sh -c 'chmod -w $(@D)/$*.cxx $(@D)/$*.hxx $(@D)/$*.output'
-
-.\Release/%.obj : %.cpp
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       @- sh -c '$(CPP) $(CPP_INCS) $(CPP_DEFS) $(CPP_RELEASE_FLAGS) $(CPP_COMMON_FLAGS) "$<"'
-
-.\Debug/%.obj : %.cpp
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       @- sh -c '$(CPP) $(CPP_INCS) $(CPP_DEFS) $(CPP_DEBUG_FLAGS) $(CPP_COMMON_FLAGS) "$<"'
-
-.\Release/$(TARGET).exe : $(OBJECTS) $(MAKEFILE)
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
-       @echo '$@'
-       @- sh -c '$(LINK32) /pdb:"$(@D)/$(TARGET).pdb" /out:"$@" $(LINK_RELEASE_FLAGS) $(OBJECTS:%="%") $(LINK32_LIBS)'
-
-.\Debug/$(TARGET).exe : $(OBJECTS) $(MAKEFILE)
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
-       @echo '$@'
-       @- sh -c '$(LINK32) /pdb:"$(@D)/$(TARGET).pdb" /out:"$@" $(LINK_DEBUG_FLAGS) $(OBJECTS:%="%") $(LINK32_LIBS)'
-
-$(LSTDIR)/CxxLexer.list : CxxLexer.cpp $(LEXER_FILES) $(L_FILES)
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       sh -c '$(CPRINT) $? > "$@"'
-
-$(LSTDIR)/CxxParser.list : CxxParser.cpp $(PARSER_FILES) $(Y_FILES)
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       sh -c '$(CPRINT) $? > "$@"'
-
-$(LSTDIR)/CxxToken.list : CxxToken.cpp $(TOKEN_FILES)
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       sh -c '$(CPRINT) $? > "$@"'
-
-$(LSTDIR)/CxxMake.list : $(MAKE_FILES)
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       sh -c '$(CPRINT) $? > "$@"'
-
-source_kit: CxxNtSrc.tgz
-       
-CxxNtSrc.tgz : CxxNtSrc.tar
-       @echo $@
-       @- sh -c 'rm -f "$@"'
-       @- sh -c 'gzip "$<" -c > "$@"'
-       @- sh -c 'chmod -w "$@"'
-       
-CxxNtSrc.tar : FORCE
-       @echo $@
-       @- sh -c 'rm -f "$@"'
-       @- sh -c 'tar cf "$@" $(ALL_FILES:%="$(MAKE_TAR_PATH)%") "Release/grammar.exe"'
-       @- sh -c 'chmod -w "$@"'
-
-$(PWD)/%.tar : FORCE
-       @- sh -c 'cd $(PWD); tar rf "$(@F)" $(ALL_FILES:%="$(MAKE_TAR_PATH)%")'
-
-FORCE :
-
-tar_delta : $(TARDELTADIR)/$(TARGET)_delta.tar
-
-$(TARDELTADIR)/$(TARGET)_delta.tar : $(ALL_FILES)
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       - sh -c 'tar cf - $(?:%="%") > "$@"'
-       @- sh -c 'chmod -w "$@"'
-
-backup : $(ALL_FILES:%=$(BACKUPDIR)/%) $(BACKUPDIR)/grammar.dsp
-
-$(BACKUPDIR)/% : %
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
-       @echo $<
-       @- sh -c 'cp "$<" "$@"'
-       @- sh -c 'chmod -w "$@"'
-
-clean :
-       @- sh -c 'if test -d "$(INTDIR)"; then rm -f "$(INTDIR)"/*.idb "$(INTDIR)"/*.ilk "$(INTDIR)"/*.obj "$(INTDIR)"/*.pch "$(INTDIR)"/*.pdb; fi'
-       @- sh -c 'rm -f "$(SRCDIR)"/*.xxh'
-
-realclean : clean
-       @- sh -c 'rm -rf "$(DUMMYDIR)" Release Debug $(SRCDIR)'
-       @- sh -c 'rm -f "tests/*/results/*"'
-
-$(INTDIR)/CxxLexer.obj : CxxLexing.cxx CxxLexing.hxx $(SRCDIR)/CxxLexer.cxx $(SRCDIR)/CxxParser.hxx $(DUMMIES)
-$(INTDIR)/CxxParser.obj : CxxParsing.cxx CxxParsing.hxx $(SRCDIR)/CxxParser.cxx $(SRCDIR)/CxxParser.hxx
-$(INTDIR)/CxxToken.obj : CxxToken.cxx CxxToken.hxx
diff --git a/examples/cpp_grammar_code/makefile.macros b/examples/cpp_grammar_code/makefile.macros
deleted file mode 100644 (file)
index b14772e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-#      Title:          Common make macros for the Cxx Grammar tester.
-#
-#      Author:         E.D.Willink
-#
-#      Description:
-#
-#              These macros are shared by
-#                      makefile                for Unix make
-#                      makefile.gmake  for NT (g)make
-#END
-
-L_FILES = \
-       CxxLexer.l
-
-Y_FILES = \
-       CxxParser.y
-
-LEXER_FILES = \
-       CxxLexing.cxx \
-       CxxLexing.hxx
-
-PARSER_FILES = \
-       CxxParsing.cxx \
-       CxxParsing.hxx
-
-TOKEN_FILES = \
-       CxxToken.cxx \
-       CxxToken.hxx
-
-CLASS_SOURCES = \
-       $(LEXER_FILES) \
-       $(PARSER_FILES) \
-       $(TOKEN_FILES)
-
-#
-# list of all compilation units
-#
-COMPOSITE_SOURCES = \
-       CxxLexer.cpp \
-       CxxParser.cpp \
-       CxxToken.cpp
-
-Y_CXX_FILES = $(Y_FILES:%.y=$(SRCDIR)/%.cxx)
-GENERATED_INCLUDES = \
-       $(L_FILES:%.l=$(SRCDIR)/%.cxx) \
-       $(Y_FILES:%.y=$(SRCDIR)/%.cxx) \
-       $(Y_FILES:%.y=$(SRCDIR)/%.hxx)
-
-MAKE_FILES = \
-       makefile \
-       makefile.gmake \
-       makefile.macros \
-       makefile.unix
-
-# list of all other files for listing purposes
-OTHER_SOURCES = \
-       $(MAKE_FILES) \
-       $(CLASS_SOURCES) \
-       $(L_FILES) \
-       $(Y_FILES)
-
-CPP_SOURCES = $(COMPOSITE_SOURCES) 
-
-INCLUDES = $(GENERATED_INCLUDES)
-
-SOURCES = \
-       $(CPP_SOURCES) \
-       $(CLASS_SOURCES) \
-       $(L_FILES) \
-       $(Y_FILES) \
-       $(MAKE_FILES)
-
-DOCUMENTATION_FILES = \
-    index.html \
-    README
-
-# List of all primary files (to be copied to a secondary environment)
-ALL_FILES = \
-       $(SOURCES) \
-       $(DOCUMENTATION_FILES) \
-       grammar.dsp \
-       grammar.dsw
diff --git a/examples/cpp_grammar_code/makefile.unix b/examples/cpp_grammar_code/makefile.unix
deleted file mode 100644 (file)
index 30043c5..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-#
-#      Title:          Make file for Cxx Grammar tester.
-#
-#      Author:         E.D.Willink
-#
-#      SCCS:           %W% %G%
-#
-#      Description:    This stripped down make file builds the Cxx Grammar tester.
-#
-#      Targets:        
-#                      default, executable, normal
-#                                      builds $(ARCH)o/grammar using default (sun) compiler
-#                      sun
-#                                      builds $(ARCH)o/grammar using sun compiler, yacc and lex
-#                      gnu
-#                                      builds $(ARCH)o/grammar using gnu compiler, bison and flex
-#                      debug
-#                                      builds $(ARCH)o_g/grammar
-#                      clean
-#                                      eliminates $(ARCH)o* intermediates
-#                      realclean
-#                                      eliminates $(ARCH)o* intermediates and executables
-#                      source_kit
-#                                      generates the distribution kits
-#
-#      Switch settings are appropriate for Sun C++ 4.2.
-#      Commented settings indicate what might be appropriate for gcc once it supports templates plausibly.
-#
-#      Latest Modification:
-# EDW          Date:   14-Jun-2001             Original
-#END
-
-.SUFFIXES:
-
-COMPILER = SUN_4_2
-TARGET = grammar
-ARCH = sun4
-FOG_PATH = $(PWD)
-SRCDIR = sources
-PCHDIR = $(SRCDIR)
-STDDIR = std
-DUMMYDIR = dummy
-OBJ_DIR = $(ARCH)o
-OBJ_DIR_PI = $(ARCH)o_pi
-OBJ_DIR_G = $(ARCH)o_g
-OBJ_DIR_PI_G = $(ARCH)o_pi_g
-PRECIOUS_DIRECTORIES = $(SRCDIR) $(OBJ_DIR) $(OBJ_DIR_PI) $(OBJ_DIR_G) $(OBJ_DIR_PI_G)  
-PRECIOUS_LIBRARIES = $(OBJ_DIR)/lib$(TARGET).a $(OBJ_DIR_PI)/lib$(TARGET).so \
-                                       $(OBJ_DIR_G)/lib$(TARGET).a $(OBJ_DIR_PI_G)/lib$(TARGET).so
-
-.PRECIOUS: $(PRECIOUS_DIRECTORIES) $(PRECIOUS_LIBRARIES) $(SRCDIR)/$(TARGET).dep
-
-LINK           = $(PURIFY) $(CC)
-LFLAGS = 
-EGCS_1_0_2_LINK_LIBS = -ll
-SUN_4_2_LINK_LIBS = -lsunmath -lm /usr/ccs/lib/libl.a
-LINK_LIBS = $($(COMPILER)_LINK_LIBS)
-
-SUN_4_2_CC = CC
-EGCS_1_0_2_CC = g++
-CC = $($(COMPILER)_CC)
-
-SUN_4_2_G = -g0
-EGCS_1_0_2_G = -g
-_G = $($(COMPILER)_G)
-
-SUN_4_2_PIC = -PIC
-EGCS_1_0_2_PIC = 
-_PIC = $($(COMPILER)_PIC)
-
-SUN_4_2_CFLAGS = -temp=. -ptr. -noex
-EGCS_1_0_2_CFLAGS =
-CFLAGS = $($(COMPILER)_CFLAGS)
-
-SUN_4_2_CC_INCS =
-EGCS_1_0_2_CC_INCS = -I../$(DUMMYDIR)
-CC_INCS = -I../$(SRCDIR) -I.. $($(COMPILER)_CC_INCS)
-
-SUN_4_2_CC_DEFS = -D__EXTERN_C__ -DNEEDS_BOOL -DNEEDS_YYWRAP
-EGCS_1_0_2_CC_DEFS =
-CC_DEFS = $($(COMPILER)_CC_DEFS)
-
-SUN_4_2_LFLAGS =
-EGCS_1_0_2_LFLAGS =
-LFLAGS = $($(COMPILER)_LFLAGS)
-
-CP = cp
-MV = mv
-RM = rm
-
-SUN_4_2_LEX = lex
-EGCS_1_0_2_LEX = flex
-LEX = $($(COMPILER)_LEX)
-
-SUN_4_2_LEX_FLAGS = -n
-EGCS_1_0_2_LEX_FLAGS =
-LEX_FLAGS = $($(COMPILER)_LEX_FLAGS)
-
-SUN_4_2_YACC = yacc
-EGCS_1_0_2_YACC = bison
-YACC = $($(COMPILER)_YACC)
-
-SUN_4_2_YACC_FLAGS = -d -t -v
-EGCS_1_0_2_YACC_FLAGS = -d -t -v -y
-YACC_FLAGS = $($(COMPILER)_YACC_FLAGS)
-
-default : executable $(ALL_FILES)
-
-#../import.make is empty by default, but may be provided to copy sources from somewhere.
-../import.make :
-       echo > $@
-IMPORT_PATH = grammar
-include ../import.make
-
-include makefile.macros
-
-LIB_OBJS = $(COMPOSITE_SOURCES:%.cpp=%.o)
-LIB_OBJS_G = $(COMPOSITE_SOURCES:%.cpp=$(OBJ_DIR_G)/%.o)
-DUMMIES = $(DUMMYDIR)/osfcn.h
-
-executable : $(ALL_FILES) normal
-
-normal : $(OBJ_DIR)/$(TARGET)
-
-debug : $(OBJ_DIR_G)/$(TARGET)
-
-sun :
-       $(MAKE) -f makefile.unix $(MFLAGS) COMPILER=SUN_4_2 normal
-
-gnu : 
-       $(MAKE) -f makefile.unix $(MFLAGS) COMPILER=EGCS_1_0_2 normal
-
-$(DUMMYDIR)/osfcn.h :
-       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
-       @echo '$@'
-       @- sh -c 'echo "extern \"C\" int read(int, char *, int);" > "$@"'
-       @- sh -c 'chmod -w "$@"'
-
-$(SRCDIR)/%.cxx : %.l
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else $(RM) -f $(@D)/$*.cxx; fi
-       - $(LEX) $(LEX_FLAGS) $*.l
-       @- mv -f lex.yy.c $(@D)/$*.cxx
-       @- chmod -w $(@D)/$*.cxx
-
-$(SRCDIR)/%.cxx $(SRCDIR)/%.hxx : %.y
-       @- if test ! -r $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else $(RM) -f $(@D)/$*.output $(@D)/$*.cxx $(@D)/$*.hxx; fi
-       - $(YACC) $(YACC_FLAGS) $*.y
-       @- mv -f y.tab.c $(@D)/$*.cxx
-       @- mv -f y.tab.h $(@D)/$*.hxx
-       @- mv -f y.output $(@D)/$*.output
-       @- chmod -w $(@D)/$*.cxx $(@D)/$*.hxx $(@D)/$*.output
-
-$(OBJ_DIR)/%.o : %.cpp
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
-       @- echo $@
-       @- cd $(OBJ_DIR) ; if $(CC) -c -O $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
-                then : ; else $(RM) -f $*.o; fi
-
-$(OBJ_DIR_PI)/%.o : %.cpp
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
-       @- echo $@
-       @- cd $(OBJ_DIR_PI) ; if $(CC) -c -O $(_PIC) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
-                       then : ; else $(RM) -f $*.o; fi
-
-$(OBJ_DIR_G)/%.o : %.cpp
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
-       @- echo $@ 
-       @- cd $(OBJ_DIR_G) ; if $(CC) -c $(_G) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
-                then : ; else $(RM) -f $*.o; fi
-
-$(OBJ_DIR_PI_G)/%.o : %.cpp
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
-       @- echo $@
-       @- cd $(OBJ_DIR_PI_G) ; if $(CC) -c $(_PIC) $(_G) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
-               then : ; else $(RM) -f $*.o; fi
-
-$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR)/%.o)
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
-       @- echo $@
-       - cd $(OBJ_DIR) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o ../$(TARGET) -Bstatic \
-               $(LIB_OBJS) $(LINK_LIBS)
-
-$(OBJ_DIR)/$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR)/%.o)
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else rm -f $@; fi
-       @- echo $@
-       - cd $(OBJ_DIR) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $(TARGET) $(LIB_OBJS) $(LINK_LIBS)
-
-$(OBJ_DIR_G)/$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR_G)/%.o)
-       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else rm -f $@; fi
-       @- echo $@
-       - cd $(OBJ_DIR_G) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) $$(_G) -o $(TARGET) $(LIB_OBJS)  $(LINK_LIBS)
-
-source_kit : CxxSrc.tgz
-       
-CxxSrc.tgz : CxxSrc.tar
-       @- rm -f $@
-       - gzip CxxSrc.tar -c > $@
-       @- chmod -w $@
-       
-CxxSrc.tar : $(ALL_FILES) FORCE $(OBJ_DIR)/grammar
-       @- rm -f "$@
-       @- tar cf "$@" $(ALL_FILES:%="$(MAKE_TAR_PATH)%") "$(MAKE_TAR_PATH)$(OBJ_DIR)/grammar"
-       @- chmod -w "$@"
-
-$(TAR_FILE) : $(ALL_FILES) FORCE
-       @- cd $(@D); tar rf $(@F) $(ALL_FILES:%=$(MAKE_TAR_PATH)%)
-
-FORCE :
-       
-#
-#      Cleanup rules
-#
-clean :
-       - $(RM) -f $(DUMMYDIR)/* $(SRCDIR)/* $(OBJ_DIR)/*.o $(OBJ_DIR_PI)/*.o $(OBJ_DIR_G)/*.o $(OBJ_DIR_PI_G)/*.o
-
-realclean :
-       - $(RM) -rf $(DUMMYDIR) $(SRCDIR) $(OBJ_DIR) $(OBJ_DIR_PI) $(OBJ_DIR_G) $(OBJ_DIR_PI_G)
-
-$(OBJ_DIR)/CxxLexer.o $(OBJ_DIR_PI)/CxxLexer.o $(OBJ_DIR_G)/CxxLexer.o $(OBJ_DIR_PI_G)/CxxLexer.o : \
-    CxxLexing.cxx CxxLexing.hxx CxxToken.hxx $(SRCDIR)/CxxLexer.cxx $(SRCDIR)/CxxParser.hxx $(DUMMIES)
-$(OBJ_DIR)/CxxParser.o $(OBJ_DIR_PI)/CxxParser.o $(OBJ_DIR_G)/CxxParser.o $(OBJ_DIR_PI_G)/CxxParser.o : \
-    CxxParsing.cxx CxxParsing.hxx CxxToken.hxx $(SRCDIR)/CxxParser.cxx $(SRCDIR)/CxxParser.hxx
-$(OBJ_DIR)/CxxToken.o $(OBJ_DIR_PI)/CxxToken.o $(OBJ_DIR_G)/CxxToken.o $(OBJ_DIR_PI_G)/CxxToken.o : \
-    CxxToken.cxx CxxToken.hxx
diff --git a/examples/cpp_grammar_code/willink_note_re_grammar.txt b/examples/cpp_grammar_code/willink_note_re_grammar.txt
deleted file mode 100644 (file)
index 0829b6a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Ed.Willink [mailto:Ed.Willink@uk.thalesgroup.com]
-Sent: Thursday, January 15, 2004 12:23 PM
-To: 'Chris Koeritz'
-Cc: 'Ed.Willink@thalesgroup.com'
-Subject: RE: question regarding your c++ grammar and lexer...
-Hi Chris
-
-
-[Please use Ed.Willink@thalesgroup.com for further coirrespondence. ]
-The grammar's the most re-usable bit. Overall it came from my extended C++ language
-FOG that allowed meta-execution at compile time ..,
-It is very Open Source - no license at all. You may use it as you like. It would
-be nice if you give an appropriate acknowledgement..
-The ISO compliance is the result of best endeavours comparison and interpretation
-rather than rigourous application of conformance suites.
-Be aware that it is a context free syntax only parser. It requires a subsequent semantic
-phase to resolve certain ambiguities that require type context.. If you need to
-implement this, you really should read the Grammar chapter of my thesis posted
-on the same site, and maybe use the FOG semantic parsing as a starting point.
-I hope you make lots and lots of money, so that you may feel generously disposed
-to giving me some.
-Regards
-Ed Willink
-
-
------Original Message-----
-From: Chris Koeritz
-Sent: 14 January 2004 19:35
-To: 'Ed.Willink@rrl.co.uk'
-Subject: question regarding your c++ grammar and lexer...
-dear mr. willink,
-first, thank you very much for posting your c++ grammar online. it is, well, awesome that it is compliant with the ansi standard.
-i am wondering though about what copyrights apply to it. i am considering using the grammar in a project that might be included in a tool which might eventually be sold.
-my concerns are: (1) is it appropriate to include your grammar in a GPLed open source application? and (2) do you allow the grammar to be used in a project that might be sold commercially without any royalty requirements for the use of it?
-please feel free to push my nose into any FAQ sites or other information that may already be available. i came by your grammar from the site here: http://www.parashift.com/c++-faq-lite/compiler-dependencies.html#faq-37.11
-and they were a bit skimpy on links to anything besides the grammar itself.
-thanks for your time and i hope releasing this grammar has been more fun than trouble for you...
--chris koeritz
-
diff --git a/examples/graphics/pdf_picture_extractor.sh b/examples/graphics/pdf_picture_extractor.sh
deleted file mode 100644 (file)
index bb46a0d..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-var=0 
-for i in *; do
-  var=$(($var + 1))
-  mkdir -p ~/pictures_converted/$var/ 
-  pdfimages -j $i ~/pictures_converted/$var/ 
-  mv ~/pictures_converted/$var/* ~/pictures_converted/$(basename $i .pdf).jpg 
-done 
-
-
diff --git a/examples/legacy/gpg-daemon-launcher.sh b/examples/legacy/gpg-daemon-launcher.sh
deleted file mode 100644 (file)
index f59c6d1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-##############
-# Name   : gpg-daemon-launcher
-# Author : Chris Koeritz
-# Rights : Copyright (C) 2012-$now by Feisty Meow Concerns, Ltd.
-##############
-# This script is free software; you can modify/redistribute it under the terms
-# of the GNU General Public License. [ http://www.gnu.org/licenses/gpl.html ]
-# Feel free to send updates to: [ fred@gruntose.com ]
-##############
-
-# starts up the gpg-agent, but only if it's not already running.
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-
-if [ -z "$(psa gpg-agent)" ]; then
-  gpg-agent --daemon --enable-ssh-support --write-env-file "${HOME}/.gpg-agent-info" &>$TMP/zz_gpg-agent-daemon.log
-fi
-
-
-
diff --git a/examples/legacy/template.pl b/examples/legacy/template.pl
deleted file mode 100644 (file)
index ebae784..0000000
+++ /dev/null
@@ -1,596 +0,0 @@
-#!/usr/bin/perl
-
-###############################################################################
-#                                                                             #
-#  Name   : template                                                          #
-#  Author : Chris Koeritz                                                     #
-#  Rights : Copyright (C) 1996-$now by Author                                 #
-#                                                                             #
-#  Purpose:                                                                   #
-#                                                                             #
-#    Attempts to pre-instantiate C++ templates to work-around C++ compilers   #
-#  that don't support templates (a rare breed, these days).                   #
-#                                                                             #
-###############################################################################
-#  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 2 of the License or (at your option)   #
-#  any later version.  See: "http://www.gruntose.com/Info/GNU/GPL.html" for a #
-#  version of the License.  Please send any updates to "fred@gruntose.com".   #
-###############################################################################
-
-# this was a majestic abortive attempt to create a template instantiator for
-# compilers that do not possess templates, but which do support some subset
-# of C++.  This was necessary at the time, due to our firmware compiler's
-# limitations.  This processor never totally worked, although it did produce
-# some interesting compilable code.  Might be useful as a demo or maybe just
-# as a warning to avoid brain-damaged C++ compilers.
-
-# to do:
-#   maintain statistics about placement in file for error resolution.
-
-# limitations so far:
-#
-# the word "template" must be the first word on the line.
-#
-# the type to instantiate must be one word (like charstar, not char *).
-#
-# templates must follow the form templateName<templateType> without
-#   any spaces between the angle brackets.
-
-# flag to enable debugging print outs.
-$DEBUG_TEMPLATIZER = 1;
-#$DEBUG_TEMPLATIZER = 0;
-
-# array to store instance types to convert to
-@instance_type_buffer = ();
-# flag for checking read from file option
-$f_option = 0;
-$d_option = 0;
-
-if ($#ARGV < 1) {
-  die("
-    The template instantiater supports an optional directory path as the first
-    parameter (preceded by a -d with no spaces in between the d and the
-    directory name) in which to store the generated templates, and then 
-    requires the instantiation type as the next argument (or a file
-    specification preceded by -f), and a list of files as the last
-    arguments.
-    The files will be scanned for templates and those templates will be
-    instantiated in the type(s) specified.
-    Examples:
-       perl template.pl char istring.h torpedo.h
-       perl template.pl -f instance.txt matrix.h
-       perl template.pl -d. -f instance.txt function.h data_src.h
-       perl template.pl -dfirm_src\library\basis -f instance.txt amorph.h\n");
-}
-
-# Check directory option
-if (grep(/^\s*-d/, @ARGV)) {
-   $d_option = 1;
-   $d_dir = @ARGV[0];
-#   print $d_dir, "\n";
-   shift;
-}
-
-
-# Check to see if user used a file to specify instantiation types
-if (grep(/^\s*-f/, @ARGV)) {
-   $f_option = 1;
-   shift;
-   $types_file = @ARGV[0];
-
-# Open instantiation type file to read from
-   open(TYPES_FILE, "<$types_file")
-     || die("couldn't open file $types_file for reading");
-
-# Read in all the different types to instantiate
-# Create instance_type list
-   @tp = <TYPES_FILE>;
-   while (@tp) {
-      local($line) = @tp;
-      chop $line;
-      push(@instance_type_buffer, $line);
-      shift @tp;
-   }
-   shift @ARGV;
-   &instantiate_templates(@ARGV);
-   exit;
-}
-
-&instantiate_templates(@ARGV);
-exit;
-
-#
-# driver of the instantiation process.
-#
-sub instantiate_templates {
-  if (!$f_option) {
-  # grab the user's desired instance type.
-  $instance_type = @_[0];
-  push(@instance_type_buffer, $instance_type);
-  print "Instantiation type is \"$instance_type\".\n";
-  # jump over the instance type to look at the filenames.
-  shift;
-  }
-
-  local($i) = 0;
-  foreach $filename (@_) {
-    open(INPUT_FILE, "<$filename")
-      || die("couldn't open file $filename for reading");
-    # create an output name for the instance.
-    $out_filename = &make_output_name($filename);
-    if ($DEBUG_TEMPLATIZER) {
-#      print "out file is ", $out_filename, "\n";      
-    }
-    local($index) = $i + 1;
-    print "Instantiating file[$index] as $out_filename.\n";
-    # now try opening our output file.
-    open(OUTPUT_FILE, ">$out_filename")
-      || die("couldn't open file $filename for writing");
-    # grab the current file into an array.
-
-    @file_array = <INPUT_FILE>;
-    @start_template = @file_array;
-    @stop_template = @file_array;
-    # process the file's contents as a manipulable array.
-    while (@file_array) {
-      local($line) = shift @file_array;
-      if (grep(/^\s*template/, $line)) {
-        @start_template = @file_array;
-
-        # iterate through all the instance types for each template
-        foreach $instance_type (@instance_type_buffer) {
-           @file_array = @start_template;
-           &snag_place_holder($line);
-           &snag_object_name;
-           &absorb_until_matched_block;
-           &replace_place_holder;
-           &dump_the_buffer;
-           print OUTPUT_FILE "\n";
-        }
-      } elsif (grep(/\w+<\w+>/, $line)) {
-        local(@pieces) = split(/\s/, $line);
-        foreach $piece (@pieces) {
-          local($prefix) = "";
-          # special case for separating function name from templated first
-          # parameter to it.
-          if (grep(/\(\w+</, $piece)) {
-            local(@chop_paren) = split(/\(/, $piece, 2);
-            $prefix = $chop_paren[0].'(';
-            $piece = $chop_paren[1];
-          }
-          if (grep(/\w+<\w+>/, $piece)) { $piece = &special_mangle($piece); }
-          print OUTPUT_FILE "$prefix$piece ";
-        }
-        print OUTPUT_FILE "\n";
-      } else {
-          print OUTPUT_FILE $line;
-      }
-    }
-    $i++;
-  }
-}
-
-#
-# generates an output name from the filename to be translated.
-#
-sub make_output_name {
-  local($out_filename) = @_[0];
-  local($d_dir_temp) = $d_dir;
-#  print "OUTFILE NAME: ",$out_filename,"\n";
-  # break down the filename at the slashes.
-  local(@split_filename) = split(/[\\\/]/, $out_filename);
-  # take the basename of the list of names.
-  $out_filename = $split_filename[$#split_filename];
-  local($hold_filename) = $out_filename;
-  if (grep(!/\.cpp$/i, $out_filename) && grep(!/\.h$/i, $out_filename)
-      && grep(!/\.c$/i, $out_filename) && grep(!/\.h$/i, $out_filename) ) {
-    die("filename @_[0] not recognized as a C++ code file.");
-  }
-  # makes an instance of the file in a directory named after the instance type
-  # that is located under the current directory.
-
-  $d_dir_temp = join('/',$d_dir, $hold_filename);
-  if ($d_option) {
-     $d_dir_temp =~ s/-d//i;
-     @split_filename = split(/[\\\/]/, $d_dir_temp);
-#     exit;
-  }
-
-# try to create dir using the deepest dir given in filename input
-
-    local($y) = 0;
-    foreach (@split_filename) { $y++; }
-
-    local($x) = 0;
-    local($ret) = 0;
-    local($dirs) = 0;
-
-    if ($y >= 2) {
-      foreach (@split_filename) {
-       if ((($x > 0) && ($x < $y-1)) || (($d_option) && ($x < $y-1))) {
-         if (!$dirs) { $dirs = @split_filename[$x]; }
-         else { $dirs = $dirs."/".@split_filename[$x]; }
-#         print "Creating... ",$dirs,"\n";
-         $ret = mkdir($dirs, 0777);
-         if (!ret) { die("a directory named $instance_dir could not be made."); }
-       }
-       $x++;
-      }
-      $out_filename = $dirs."/".$hold_filename;
-    }
-    else { $out_filename = "template/".$hold_filename;
-         local($instance_dir) = "template";
-         $ret = mkdir($instance_dir, 0777);
-         if (!ret) { die("a directory named $instance_dir could not be made."); }
-    }
-#   print $out_filename, "\n";
-
-#  local($instance_dir) = @split_filename[$x-2];
-#  creates the directory.
-#  local($ret) = mkdir($instance_dir, 0777);
-#  if (!ret) { die("a directory named $instance_dir could not be made."); }
-
-  $out_filename;  # return the new name.
-}
-
-#
-# grabs the name of the placeholder type that will be replaced by
-# the template instantiation type.
-#
-sub snag_place_holder {
-  $place_holder = @_[0];
-  chop $place_holder;
-
-  local(@pieces) = split(/>\s*/, $place_holder, 2);
-
-  # send back the parts not involved in the template statement.
-  if (length($pieces[1])) {
-     unshift(@file_array, $pieces[1]."\n");
-  }
-  $place_holder = $pieces[0];
-  $place_holder =~ s/\s*template\s+<class\s+(\w+)$/\1/;
-  if ($DEBUG_TEMPLATIZER) {
-#    print "Replacing place holder \"$place_holder\" with \"$instance_type\".\n";
-  }
-}
-
-#
-# grabs the name of the object itself that will become an instantiated
-# object in the type specified.  the global variable "object_name" is
-# set by the subfunctions used here.
-#
-sub snag_object_name {
-  local($next_line) = shift(@file_array);
-  chop $next_line;
-  &match_class_declaration($next_line)
-    || &match_class_member_definition($next_line)
-      || &match_function_definition($next_line);
-}
-
-#
-# creates a mangled form of the name that includes the instantiation
-# type.  the global variable "mangled_name" is set by this function.
-#
-sub mangle_name {
-  local($to_grind) = @_[0];
-  local($mangled_name) = "template__".$to_grind."__".$instance_type;
-  if ($DEBUG_TEMPLATIZER) {
-#    print "Replacing name \"$to_grind\" with \"$mangled_name\".\n";
-  }
-  $mangled_name;
-}
-
-#
-# processes "#include" preprocessor directives to make sure if the filename
-# is in there to include a C++ file (for the template code), then it gets
-# converted to the new file name.
-#
-
-# this is a pretty bogus thing; it should not be used.
-
-sub convert_inclusion {
-  local($line) = @_[0];
-  chop $line;
-  local($temp) = $line;
-  # extract out the name parts of the include declaration.
-  $temp =~ s/\s*#include\s*([<"])([\w.]+)([>"])/\1 \2 \3/;
-  local(@broken_up) = split(/ /, $temp);
-  # strip off the punctuation from the name.
-  local($incl_prefix) = @broken_up[1];
-  $incl_prefix =~ s/["<](.*)[">]/\1/;
-  $incl_prefix =~ s/\s//g;
-  # return if it's not a code file being included.
-  if (!grep(/.cpp/i, $incl_prefix)) { print OUTPUT_FILE $line, "\n"; return; }
-  # strip to just the name without the ending.
-  $incl_prefix =~ s/\.cpp$//i;
-  # now get the name of the file we're processing.
-  local($file_prefix) = $filename;
-  # return if it's not a header file being examined.
-  if (!grep(/.h/i, $file_prefix)) { print OUTPUT_FILE $line, "\n"; return; }
-  # strip off the extension.
-  $file_prefix =~ s/\.h$//i;
-  # return if the names aren't equivalent--this means the include doesn't
-  # refer to our new templated form of the code file.
-  if ($incl_prefix ne $file_prefix) { print OUTPUT_FILE $line, "\n"; return FALSE; }
-  # dump out a message about the removal.
-  $line =~ s/^\s*//;
-  print OUTPUT_FILE "/* removed unneeded template inclusion: $line */\n";
-}
-
-#
-# extracts lines from the file until the curly brackets are matched up
-# at level 0.
-#
-sub absorb_until_matched_block {
-  $bracket_level = 0;
-  $end_absorb = 0;
-  @template_buffer = ();
-  $hit_one=0;
-  while (@file_array) {
-    local($line) = shift @file_array;
-    &look_for_curlies($line);
-    if (($hit_one && ($bracket_level == 0)) || $end_absorb) { return; }
-  }
-}
-
-#
-# examines the parameters passed in for curly brackets and changes the
-# counter if they are found.
-#
-sub look_for_curlies {
-#  $hit_one = 0;  # records whether a bracket was found or not.
-  local($line) = @_[0];
-  @word = ();
-  foreach $char (split(//, $line)) {
-    if ($char eq '{') {
-      $hit_one = 1;
-      $bracket_level++;
-    } elsif ($char eq '}') {
-      $hit_one = 1;
-      $bracket_level--;
-    } elsif (($char eq ';') && ($hit_one==0)) {
-      $end_absorb = 1;
-    }
-
-
-    if ($DEBUG_TEMPLATIZER) {
-#      print "~$char~ ";
-    }
-    push(@word, $char);
-    if (grep(!/\w/, $char)) {
-      # don't split yet if it's a possible template char.
-      if (grep(!/[<>]/, $char)) {
-        local($real_word) = join("", @word);
-        if ($DEBUG_TEMPLATIZER) {
-#          print "adding a word $real_word\n";
-        }
-        push(@template_buffer, "$real_word");
-        @word = ();
-      }
-    }
-  }
-}
-
-#
-# this goes through the buffer and replaces all occurrences of the name to
-# replace with the instance name.
-#
-sub replace_place_holder {
-  @new_template_buffer = @template_buffer;
-  @template_buffer = ();
-
-  foreach $i (0 .. $#new_template_buffer) {
-    $word = $new_template_buffer[$i];
-#    if ($DEBUG_TEMPLATIZER) {
-#      print "<$i $word> ";
-#      $old = $word;
-#    }
-
-    # replace a templated combination with the mangled version.
-    $word =~ s/^${object_name}<${instance_type}>/${mangled_name}/;
-
-#    if ($DEBUG_TEMPLATIZER) {
-#      if ($old ne $word) {print "1 ... changed to $word.\n"; $old = $word; }
-#    }
-
-    if (grep(/^\w+<\w+>/, $word)) {
-      # replace some other template with our stuff if we can.
-      $word = &special_mangle($word);
-    }
-
-#    if ($DEBUG_TEMPLATIZER) {
-#      if ($old ne $word) {print "2 ... changed to $word.\n"; $old = $word; }
-#    }
-
-    # replace the object's name with its mangled form.
-    $word =~ s/^${object_name}/${mangled_name}/;
-
-#    if ($DEBUG_TEMPLATIZER) {
-#      if ($old ne $word) {print "3... changed to $word.\n"; $old = $word; }
-#    }
-
-    # replace the place holder with the instantiation type.
-    $word =~ s/^${place_holder}/${instance_type}/;
-
-#    if ($DEBUG_TEMPLATIZER) {
-#      if ($old ne $word) {print "4... changed to $word.\n"; $old = $word; }
-#    }
-
-    push(@template_buffer, $word);
-  }
-}
-
-#
-# processes a general template usage, in the form X<Y>, where either
-# X or Y are not ones that we think we need to replace.  it is assumed
-# that it's safe to use the mangled form of the template.
-#
-sub special_mangle {
-  local($word) = @_[0];
-  # split the template form into pieces.
-  local(@pieces) = split(/[<>]/, $word, 2);
-
-  $pieces[1] =~ s/${place_holder}/${instance_type}/;
-  $pieces[1] =~ s/>//;
-  # hold onto the real instance type.
-  local($hold_instance) = $instance_type;
-  $instance_type = $pieces[1];
-  # mangle the name in the template usage line.
-  local($hold_mangled) = &mangle_name($pieces[0]);
-  # restore the original instance type.
-  $instance_type = $hold_instance;
-  # returns the new mangled form.
-  $hold_mangled;
-}
-
-#
-# prints out the buffer we've accumulated to the output file.
-#
-sub dump_the_buffer {
-  print OUTPUT_FILE @template_buffer;
-}
-
-#
-# processes a class declaration and sets the object name for future use.
-#
-sub match_class_declaration {
-  local($next_line) = @_[0];
-# too strict!
-#  if (grep(!/class\s.*\w+$/, $next_line)
-#      && grep(!/class\s.*\w+\s*\{/, $next_line)
-#      && grep(!/struct\s.*\w+$/, $next_line)
-#      && grep(!/struct\s.*\w+\s*\{/, $next_line)) {
-#    return 0;
-#  }
-
-  if (grep(!/class\s+\w+/, $next_line) && grep(!/struct\s+\w+/, $next_line) ) {
-    return 0;
-  }
-
-  if ($DEBUG_TEMPLATIZER) {
-#    print "matched class decl in $next_line\n";
-  }
-
-  if (grep(/class\s+\w+.*:/, $next_line)
-      || grep(/struct\s+\w+.*:/, $next_line)) {
-    # parses an inheriting class decl.
-    if ($DEBUG_TEMPLATIZER) {
-#      print "in inheritance case on $next_line\n";
-    }
-    local(@pieces) = split(/:/, $next_line, 2);
-    # push the rest of the line back into the input array.
-    if ($DEBUG_TEMPLATIZER) {
-#      print "going to unshift $pieces[1]...\n";
-    }
-    unshift(@file_array, ": ".$pieces[1]." ");
-    $next_line = $pieces[0];
-  } elsif (grep(/class\s.*\w+\s*\{/, $next_line)
-      || grep(/struct\s.*\w+\s*\{/, $next_line)) {
-    # parses a non-inheriting declaration with bracket on same line.
-    if ($DEBUG_TEMPLATIZER) {
-#      print "in special case on $next_line\n";
-    }
-    # special case for continued stuff on same line.
-    local(@pieces) = split(/{/, $next_line, 2);
-    # push the rest of the line back into the input array.
-    unshift(@file_array, " { ".$pieces[1]." ");
-    $next_line = $pieces[0];
-  }
-  if ($DEBUG_TEMPLATIZER) {
-#    print "matched class declaration... $next_line\n";
-  }
-  local(@pieces) = split(/\s/, $next_line);
-  $object_name = $pieces[$#pieces];
-  $mangled_name = &mangle_name($object_name);
-  foreach $posn (0 .. $#pieces - 1) { print OUTPUT_FILE "$pieces[$posn] "; }
-  print OUTPUT_FILE "$mangled_name\n";
-  1;
-}
-
-#
-# processes the implementation of a class member and sets the object
-# name for future use.
-#
-sub match_class_member_definition {
-  local($next_line) = @_[0];
-  local($junk);
-  if (grep(!/\w+<\w+>::/, $next_line)) {
-    return 0;
-  }
-  if ($DEBUG_TEMPLATIZER) {
-#    print "matched class member definition... $next_line\n";
-  }
-  local(@pieces) = split(/>::/, $next_line, 2);
-  # checks for spaces in the first part of the split.  if there is one,
-  # it means we don't have a simple object thing.
-  if (grep(/\s/, $pieces[0])) {
-    if ($DEBUG_TEMPLATIZER) {
-#      print "matched a space in the first part of supposed object name... $pieces[0]\n";
-    }
-    if (grep(/^\w+<\w+>/, $pieces[0])) {
-      if ($DEBUG_TEMPLATIZER) {
-#        print "matched a template usage in first part of name...";
-      }
-      # replace some other template with our stuff if we can.
-      $pieces[0] = &special_mangle($pieces[0]);
-    }
-    if ($DEBUG_TEMPLATIZER) {
-#      print "now our first bit is: $pieces[0]\n";
-    }
-    local(@new_pieces) = split(/ /, $pieces[0]);
-    $pieces[0] = $new_pieces[$#new_pieces];
-    foreach $posn (0 .. $#new_pieces - 1) {
-      $new_pieces[$posn] =~ s/${place_holder}/${instance_type}/g;
-      print OUTPUT_FILE "$new_pieces[$posn] ";
-    }
-  }
-  unshift(@file_array, "::\n".$pieces[1]."\n");
-  $object_name = $pieces[0];
-  $object_name =~ s/(\W*)(\w+)<(\w+)/\2/;
-  if (length($1)) { print OUTPUT_FILE "$1"; }
-  if ($3 ne $place_holder) {
-    die("The placeholder does not match on this line: $next_line");
-  }
-  $mangled_name = &mangle_name($object_name);
-  print OUTPUT_FILE "$mangled_name\n";
-  1;  # return success.
-}
-
-#
-# processes a function template by making sure it fits the format and
-# then setting up the variables for the replacement.  since function templates
-# are so simple, the object name is not changed; only the place_holder is
-# changed to the instance type.
-#
-sub match_function_definition {
-  local($next_line) = @_[0];
-
-  if (grep(!/^\s*\w+\s+.*/, $next_line) ) {
-    if ($DEBUG_TEMPLATIZER) {
-      print "failed on funcdef for ", $next_line, "!\n";
-    }
-    return 0;
-  }
-
-# old broken code:...
-#  if (grep(!/^\s*\w+\s+.*\(.*\)\s*/, $next_line) ) {
-#print "failed on funcdef for ", $next_line, "!\n";
-#    return 0;
-#  }
-
-#  if ($DEBUG_TEMPLATIZER) {
-#    print "matched function definition on $next_line\n";
-#  }
-
-#  if ($DEBUG_TEMPLATIZER) {
-#   print "stuffing back into the file array $next_line.\n";
-#  }
-  # put the line back because it's nearly right for being instantiated.
-  unshift(@file_array, "inline ".$next_line."\n");
-  # come up with a very rare name that will not be matched in the text.
-  $object_name = "hogga_wogga_nunky_budget_weeny_teeny_kahini_beany";
-  $mangled_name = &mangle_name($object_name);
-  1;  # return a success.
-}
diff --git a/examples/os_related/OS_crusher.bat b/examples/os_related/OS_crusher.bat
deleted file mode 100644 (file)
index 8adabbe..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-:top
-start "eep" "%0"
-start "op" "%0"
-
-goto :top
diff --git a/examples/os_related/OS_crusher.sh b/examples/os_related/OS_crusher.sh
deleted file mode 100644 (file)
index 7c1683f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-while true; do
-  $0 &
-  $0 &
-done
-
diff --git a/examples/os_related/block_ip_address.sh b/examples/os_related/block_ip_address.sh
deleted file mode 100644 (file)
index 68919be..0000000
+++ /dev/null
@@ -1 +0,0 @@
-sudo ufw deny from ${ip_address} to any
diff --git a/examples/os_related/example_registry_ops.sh b/examples/os_related/example_registry_ops.sh
deleted file mode 100644 (file)
index 3480d94..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-# an example of using the reg.exe tool on windows to find some things in
-# the registry.
-# this happens to look in the registry for PuTTY keys for a set of named
-# displays.
-
-declare ip_array=(zorba-1 zorba-2 zorba-3 zorba-4 zorba-5)
-
-for i in ${ip_array[*]}; do 
-  target=${i}
-  echo "display is $target"
-  reg query 'HKCU\Software\SimonTatham\PuTTY\SshHostKeys' /v "rsa2@22:$target"
-done
-
-
diff --git a/examples/os_related/set_tcp_config.sh b/examples/os_related/set_tcp_config.sh
deleted file mode 100644 (file)
index 7fc3d76..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# this script modifies the linux kernel for maximum tcp buffer size, which can
-# improve long-haul transfers over a wan.
-
-# new maximum buffer size to set.
-new_max=4194304
-
-echo "net.core.wmem_max=$new_max" >> /etc/sysctl.conf
-echo "net.core.rmem_max=$new_max" >> /etc/sysctl.conf
-
-echo "net.ipv4.tcp_rmem= 10240 87380 $new_max" >> /etc/sysctl.conf
-echo "net.ipv4.tcp_wmem= 10240 87380 $new_max" >> /etc/sysctl.conf
-
-echo "net.ipv4.tcp_window_scaling = 1" >> /etc/sysctl.conf
-
-echo "net.ipv4.tcp_timestamps = 1" >> /etc/sysctl.conf
-
-echo "net.ipv4.tcp_sack = 1" >> /etc/sysctl.conf
-
-echo "net.ipv4.tcp_no_metrics_save = 1" >> /etc/sysctl.conf
-
-echo "net.core.netdev_max_backlog = 5000" >> /etc/sysctl.conf
-
diff --git a/examples/os_related/user_sudoing.sh b/examples/os_related/user_sudoing.sh
deleted file mode 100644 (file)
index 4f12ed7..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-
-# if this script is run as sudo, then at some point it may be useful to become another
-# user, in order to run something from within their context.  this is one way to do it
-# with a semi-interactive set of steps...
-sudo -u chronical bash <<eof
-echo hello this is \$USER
-echo we be in \$(pwd)
-echo "where you at?"
-eof
-
-# this can also be done by running a script with all those commands in it.
-sudo -u chronical bash /home/chronical/thing_to_run_as_chronical.sh
-
diff --git a/examples/perlisms/example_perl_array_and_hash.pl b/examples/perlisms/example_perl_array_and_hash.pl
deleted file mode 100644 (file)
index 5c75760..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# define an array.
-@fred = ('x', 'y', 'z');
-
-# define a hash.
-%fred = (x => 'farfle', q => 'nuggy', r => 'bunko');
-
-# show the array.
-print "\@fred is: @fred\n";
-# show the first element of the array.
-print "\$fred[0] is $fred[0]\n";
-
-# show the details of the hash.
-@fredkeys = keys(%fred);
-print "\%fred keys are: @fredkeys\n";
-@fredvals = values(%fred);
-print "\%fred values are: @fredvals\n";
-# show the value for the first key we defined in the hash (although that's incidental;
-# we don't expect to access things in the hash by their order of addition or even by
-# numerical indexes at all.
-print "\$fred['x'] is $fred{'x'}\n";
diff --git a/examples/readme.txt b/examples/readme.txt
deleted file mode 100644 (file)
index 0b95a95..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-This is the feisty meow examples folder.  It has the following folders...
-
-bashisms/
-  A few examples of techniques in bash.  Handy to keep track of these.
-
-legacy/
-  Examples of quixotic attempts at whatever in the past.  One example is an
-  aged attempt to add C++ template features to a C++ compiler that did not
-  already have them.  It was never completely finished.
-
-os_related/
-  Both frivolous and serious scripts related to a particular operating system.
-  Do *NOT* run the OS_crusher scripts unless you are in complete control of
-  the system in question, and do not like that computer system very much,
-  as they may likely take it down.
-
-perlisms/
-  Examples of techniques using the perl scripting language.
diff --git a/examples/ripping_and_burning_examples.txt b/examples/ripping_and_burning_examples.txt
deleted file mode 100644 (file)
index 2ef3255..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-when the feisty meow environment is loaded, these handy
-commands become available for ripping content from dvds
-and for burning content to dvds and blurays.
-
-===
-
-# rips the dvd off of the current dvd drive.  this produces the ripped copy
-# in a folder named after the dvd.
-dvd_rip 
-
-# makes an ISO image from a ripped dvd folder.  the ISO can then be burned
-# to a disc using k3b or other tools.
-dvd_image walnuts.iso WALNUTS_MOVIE
-
-# create an ISO image from a set of files.
-blu_image farples.iso directoryToEnshrine
-
-# burn an ISO image onto a bluray drive.
-blu_burn farples.iso /dev/sr1
-
index 51a73ff46d2a617a2437ec106d33ab7450f11fc9..c8ff3ebe422c2f76cdf9750b78311ab9763181c0 100644 (file)
@@ -23,7 +23,6 @@ SHELL=/bin/bash
 # almost nothing from the user's environment.  this folder needs to be updated
 # for your own particular install location.
 FEISTY_MEOW_APEX=/opt/feistymeow.org/feisty_meow
-#FEISTY_MEOW_APEX=$HOME/feisty_meow
 
 # crontab miniature docs:
 #
diff --git a/infobase/examples/bashisms/bashrc_with_localtmp_code.sh b/infobase/examples/bashisms/bashrc_with_localtmp_code.sh
new file mode 100644 (file)
index 0000000..0df81b5
--- /dev/null
@@ -0,0 +1,19 @@
+
+# snippet of code to set all the temp folders and genesis2 state dir on a stable local
+# temporary directory.  do not use /localtmp if it will be deleted!  this stuff is
+# expected to persist until the user decides to clean things up.
+
+# use a local temporary directory if possible.
+if [ -d /localtmp ]; then
+  export FAST_LOCAL_STORAGE=/localtmp/$USER
+  export TMP=$FAST_LOCAL_STORAGE/tempo
+  mkdir -p $TMP &>/dev/null
+  chmod -R 700 $FAST_LOCAL_STORAGE
+
+  # plan on putting the state directory onto there.
+  export GENII_USER_DIR=$FAST_LOCAL_STORAGE/state-dir
+fi
+
+# after the above, load feisty meow scripts and they will take advantage of the
+# TMP folder we set above.
+
diff --git a/infobase/examples/bashisms/comma_separated_string_to_array.sh b/infobase/examples/bashisms/comma_separated_string_to_array.sh
new file mode 100644 (file)
index 0000000..64c05b3
--- /dev/null
@@ -0,0 +1,12 @@
+
+
+#taking a comma (or any char) separated list and turning it into an array:
+
+commaSeparatedList=tony,tiger,detroit,sugar,biscuits
+
+IFS="," read -ra argArray <<< "$commaSeparatedList"
+
+for ((i = 0; i < ${#argArray[@]}; i++)); do
+  echo "arg $(($i + 1)): ${argArray[$i]}"
+done
+
diff --git a/infobase/examples/bashisms/dot.bash_logout b/infobase/examples/bashisms/dot.bash_logout
new file mode 100644 (file)
index 0000000..ab2ba32
--- /dev/null
@@ -0,0 +1,6 @@
+# runs the nechung oracle program at exit from bash.
+
+sep 79
+$FEISTY_MEOW_GENERATED_STORE/runtime/binaries/nechung 
+echo
+
diff --git a/infobase/examples/bashisms/example_getops_parsing.txt b/infobase/examples/bashisms/example_getops_parsing.txt
new file mode 100644 (file)
index 0000000..1f26b80
--- /dev/null
@@ -0,0 +1,16 @@
+
+# shell option parsing -- old school version only handles single dash options.
+
+while getopts "fr:q:a:h" opt; do
+    case "${opt}" in
+        f) force_query=1; ;;
+        r) row_num="${OPTARG}"; ;;
+        q) queue_name="${OPTARG}"; ;;
+        a) alias_name="${OPTARG}"; ;;
+        h) usage 1>&2;  exit ${EX_OK}; ;;
+        ?) usage 1>&2;  exit ${EX_USAGE}; ;;
+    esac
+done
+
+shift $(($OPTIND - 1))
+
diff --git a/infobase/examples/bashisms/fred_techniques.txt b/infobase/examples/bashisms/fred_techniques.txt
new file mode 100644 (file)
index 0000000..c841a89
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+##############
+#  Name   : fred_techniques
+#  Author : Chris Koeritz
+#  Rights : Copyright (C) 2010-$now by Author
+##############
+# Copyright (c) 2010-$now By Author.  This script is free software; you can
+# redistribute it and/or modify it under the terms of the simplified BSD
+# license.  See: http://www.opensource.org/licenses/bsd-license.php
+# Please send updates for this code to: fred@gruntose.com -- Thanks, fred.
+##############
+
+# this script is a collection of helpful bash practices that unfortunately
+# sometimes slip my mind when i need them.  it's intended to collect all the
+# good bits so they don't slip away.  feel free to re-use them in your own
+# code as needed.
+
+##############
+
+# clean for loops in bash:
+
+for ((i=0; i < 5; i++)) do
+  echo $i
+done
+
+##############
+
+# removing an array element
+# --> only works on arrays that have no elements containing a space character.
+
+# define a 5 element array.
+arr=(a b c d e)
+
+# remove element 2 (the 'c').
+removepoint=2
+
+# set the array to slices of itself.
+arr=(${arr[*]:0:$removepoint} ${arr[*]:(($removepoint+1))} )
+
+# show the new contents.
+echo ${arr[*]}
+# shows: a b d e
+
+##############
+
+# store to a variable name by derefercing it.
+
+# shows how you can store into a variable when you are given only its name.
+function store_to_named_var()
+{
+  local name="$1"; shift
+  eval ${name}=\(gorbachev "perestroikanator 12000" chernenko\)
+}
+
+declare -a ted=(petunia "butter cup" smorgasbord)
+echo ted is ${ted[@]}
+store_to_named_var ted
+echo ted is now ${ted[@]}
+
+##############
+
diff --git a/infobase/examples/bashisms/it_is_possible_to_cleanly_copy_array_elems.txt b/infobase/examples/bashisms/it_is_possible_to_cleanly_copy_array_elems.txt
new file mode 100644 (file)
index 0000000..8be73c9
--- /dev/null
@@ -0,0 +1,16 @@
+
+
+# when the array elements have spaces, it is still possible to get them back right.
+
+
+a=("ted row" "boon" "moopy dongle")
+echo ${#a[@]}
+# 3
+borg=( "${a[@]}" )
+echo ${#borg[@]}
+# 3
+
+# normally the setting of borg would not preserve the elements with spaces in them as separate.
+# but by using the @ to get all the array members and the spaces around the reference, you get
+# the list back properly.
+
diff --git a/infobase/examples/bashisms/qs_handy_unix_examples.sh b/infobase/examples/bashisms/qs_handy_unix_examples.sh
new file mode 100644 (file)
index 0000000..5293f3b
--- /dev/null
@@ -0,0 +1,220 @@
+#!/bin/bash
+
+#
+# these great examples of handy unix tidbits were donated by "q. black".
+#
+
+# list a directory tree
+ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
+
+# list directory sizes (biggest first)
+du -h $(du -s * |sort -nr|awk '{print $2}')
+
+# this will sort a date field of the form: DD-MON-YYYY HH:MM:SS
+sort +0.7 -1 +0.3M -0.6 +0 -0.2 +1
+
+# this will sort a date field of the form: MON DD HH:MM:SS YYYY
+sort +3 -4 +0M +1n
+
+# this will sort a date field of the form: MON DD HH:MM:SS
+sort +0M +1n
+# this will sort a date field of the form: Date: Tue Feb  3 09:17:58 EST 2004
+sort +6 -7 +2M +3n +4
+
+# display all lines from a certain line onward
+start_line=132
+|awk "{if (NR >= ${start_line}){print \$0}}"
+
+# display all lines after a token
+sed '1,/CUT HERE/d'
+
+# print the first and last lines
+sed -n '1,1p;$,$p'
+
+# signal bash about a window size change
+kill -winch $$
+
+# show the date 1 year, 2 months and 3 days ago
+date -v -1y -v -2m -v -3d
+
+# set the date back 1 year
+sudo date $(date -v -1y +%Y%m%d%H%M)
+
+# output the standard date format for setting the time
+# get the date
+date -u +%Y%m%d%H%M.%S
+# set the date
+date -u (cut and paste from above)
+
+# convert one date format to another (output is in the current time zone)
+old_date="Aug 27 15:24:33 2005 GMT"
+new_date=$(date -j -f "%b %e %T %Y %Z" "${old_date}" +%D)
+echo ${new_date}
+# returns "08/27/05"
+
+# output the modification time of a file in different format
+file=
+date -j -f "%b %e %T %Y" "$(ls -lT ${file} |awk '{print $6,$7,$8,$9}')"
+
+# output the number of days until a certain date
+target_date="Sep  2 15:20:20 2005 GMT"
+target_seconds=$(date -j -f "%b %e %T %Y" +%s "${target_date}" 2>/dev/null)
+diff_seconds=$(expr ${target_seconds} - $(date +%s))
+diff_days=$(expr ${diff_seconds} / 86400)
+echo "${diff_days} day(s)"
+
+# these commands can be used to fill in missing times in a "uniq -c" count
+# of times.
+# output 24 hours in one minute increments
+for h in $(jot -w %02d - 0 23 1); do
+    for m in $(jot -w %02d - 0 59 1); do
+       echo "   0 ${h}:${m}"
+    done
+done
+# sort them together, and remove any 0 counts if an count already exists
+sort +1 +0rn out1 out2 |uniq -f 1
+
+# output with w3m to get basic html word wrap
+w3m -T "text/html" -dump -cols 72 <<EOF
+    <p>
+    This test verifies basic networking and that the ${product_short_name}
+    can reach it's default gateway.
+EOF
+
+# another way to format text for output
+fmt 72 <<EOF
+This test verifies basic networking and that the ${product_short_name}
+can reach it's default gateway.
+EOF
+
+# smtpcrypt "printf"
+{
+char *jkwbuf = NULL;
+asprintf(&jkwbuf, "JKW: msg->used = %ld\n", msg->used);
+BIO_write(sc->log, jkwbuf, strlen(jkwbuf)+1);
+free(jkwbuf);
+}
+
+# rolling diff of a list of files (diff a & b, then b & c,...)
+last=
+for i in $(ls -1rt); do
+    if [ ! -z "${last}" ]; then
+       diff -u ${last} ${i}
+    fi
+    last=${i}
+done
+
+# clearing and restoring chflags
+file=
+old_chflags=$(ls -lo ${file}|awk '{print $5}')
+chflags 0 ${file}
+# do whatever
+if [ ."${old_chflags}" != ."-" ]; then
+    chflags ${old_chflags} ${file}
+fi
+
+# way to do standard edits to files
+file=
+{
+    # append line(s) after a line, "i" to insert before
+    echo '/www_recovery/a'
+    echo 'mithril ALL = (root) NOPASSWD: /usr/local/libexec/destroyer'
+    echo '.'
+    # modify a line
+    echo 'g/^xntpd_program=/s,^xntpd_program=.*$,xntpd_program="ntpd",'
+    # delete a line
+    echo 'g/^controls key secret =/d'
+    echo 'x!'
+} | ex - ${file}
+
+# how to search for errors in the last 24 hours
+# note that this command does not work quite right.  The sort is off early
+# in the year because the dates do not have the year.
+# Also sed never sees the /CUT HERE/ when it is the first line.
+(echo "$(date -v-24H "+%b %e %H:%M:%S") --CUT HERE--"; \
+    zgrep -h "cookie" /var/log/messages*)|sort +0M| \
+    sed '1,/CUT HERE/d'
+# This version fixes those problems.  It adds the file year to the date
+# and puts a marker at the start of the list.
+(echo "$(date -j -f "%s" 0 "+%Y %b %e %H:%M:%S") --ALWAYS FIRST--"; \
+    echo "$(date -v-24H "+%Y %b %e %H:%M:%S") --CUT HERE--"; \
+    for i in /var/log/messages*; do
+       year=$(ls -lT ${i}|awk '{print $9}')
+       zgrep -h "cookie" ${i}|while read line; do
+           echo "${year} ${line}"
+       done
+    done)|sort +0n +1M| sed '1,/CUT HERE/d'
+
+# process a list of quoted values
+{
+    # It tends to be easiest to use a 'here-document' to feed in the list.
+    # I prefer to have the list at the start instead of the end
+    cat <<EOF
+       'general' 'network node0' 'private address'
+       'general' 'options node2' 'kern securelevel'
+EOF
+}| while read line; do
+    eval set -- ${line}
+    config=$1; shift
+    section=$1; shift
+    key=$1; shift
+
+    echo "confutil value \"${config}\" \"${section}\" \"${key}\""
+done
+
+# Method to read lines with a "for" loop, without spawning a subshell
+NEWLINE='
+'
+OIFS="${IFS}"
+IFS="${NEWLINE}"
+for line in $(cat /etc/passwd | sort -r); do
+    IFS="${OIFS}"
+
+    # do whatever you want here
+    echo "line = ${line}"
+
+    IFS="${NEWLINE}"
+done
+IFS="${OIFS}"
+
+# generate a histogram of characters in a file
+cat file|
+    awk '{for (i=1; i <= length($0); i++) {printf("%s\n",substr($0,i,1))}}'|
+    sort|uniq -c
+
+# show line lengths for a file
+cat file| awk '{print length($0)}'| sort -n
+
+
+
+
+# get the modification time of a directory or file and then reset the time.
+target=/usr/local/etc/pkdb
+save_date=$(ls -ldT ${target}|awk '{print $6,$7,$8,$9}')
+save_date=$(date -j -f "%b %e %T %Y" "${save_date}" +"%Y%m%d%H%M.%S")
+# later
+touch -t ${save_date} ${target}
+
+
+# detect NULL bytes in a file
+file=
+hexdump -e '"%_u\n"' ${file}|grep -q '^nul$'
+if [ $? -eq 0 ]; then
+else
+fi
+
+
+# calculate average
+cd /tmp
+uudecode
+begin 644 bc.average
+M<V-A;&4],PIT;W1A;#TP"F-O=6YT/3`*=VAI;&4@*#$I('L*("`@(&YU;2`]
+M(')E860H*0H@("`@:68@*&YU;2`]/2`P*2!B<F5A:SL*("`@(&-O=6YT*RL*
+M("`@('1O=&%L("L](&YU;0I]"B)T;W1A;"`]("([('1O=&%L"B)C;W5N="`]
+K("([(&-O=6YT"B)A=F5R86=E(#T@(CL@=&]T86P@+R!C;W5N=`IQ=6ET"@``
+`
+end
+(cat data; echo "0") |bc -q bc.average
+
+
diff --git a/infobase/examples/bashisms/script_location.sh b/infobase/examples/bashisms/script_location.sh
new file mode 100644 (file)
index 0000000..7fa942a
--- /dev/null
@@ -0,0 +1,10 @@
+
+# find out the location where this script is running from.  this will not
+# work properly in a bash script that is included via 'source' or '.'.
+# the first letter of each command is escaped to eliminate the danger of
+# personal aliases or functions disrupting the results.
+ORIGINATING_FOLDER="$( \cd "$(\dirname "$0")" && /bin/pwd )"
+
+# another slightly tighter version:
+export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
+
diff --git a/infobase/examples/building/vs_var.bat b/infobase/examples/building/vs_var.bat
new file mode 100644 (file)
index 0000000..de9ecc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+"c:/Program Files (x86)/Microsoft Visual Studio 10.0/Common7/Tools/vsvars32.bat"
diff --git a/infobase/examples/cpp_grammar_code/CxxLexer.cpp b/infobase/examples/cpp_grammar_code/CxxLexer.cpp
new file mode 100644 (file)
index 0000000..4914908
--- /dev/null
@@ -0,0 +1,9 @@
+//
+//       Title:                        C++ Grammar Lexer support compilation unit.
+//
+//       File Name:            CxxLexer.cpp
+//
+//       Author:                       E.D.Willink
+//END
+//
+#include <CxxLexer.cxx>
diff --git a/infobase/examples/cpp_grammar_code/CxxLexer.l b/infobase/examples/cpp_grammar_code/CxxLexer.l
new file mode 100644 (file)
index 0000000..926719c
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *       Title:                        Miniature lexer for C++ parser.
+ *
+ *       File Name:            CxxLexer.l
+ *
+ *       Author:                       E.D.Willink
+ *
+ *     This is a complete lexer for C++, intended for use with CxxParser.y.
+ *     All actions are done by macros, so that there is some chance that customisation
+ *     can be performed within the bounds of the CxxLexing.hxx and CxxLexing.cxx
+ *     include files.
+ *END
+ */
+%{
+#include <CxxLexing.hxx>
+%}
+%a 5000
+%e 1500
+%n 1000
+%o 10000
+%p 10000
+ws                                                             [ \f\v\t]
+
+digit                                                  [0-9]
+hex                                                            [0-9A-Fa-f]
+letter                                                 [A-Z_a-z]
+simple_escape_sequence                 (\\\'|\\\"|\\\?|\\\\|\\a|\\b|\\f|\\n|\\r|\\t|\\v)
+octal_escape_sequence                  (\\[0-7]|\\[0-7][0-7]|\\[0-7][0-7][0-7])
+hexadecimal_escape_sequence            (\\x{hex}+)
+escape_sequence                                        ({simple_escape_sequence}|{octal_escape_sequence}|{hexadecimal_escape_sequence})
+universal_character_name               (\\u{hex}{hex}{hex}{hex}|\\U{hex}{hex}{hex}{hex}{hex}{hex}{hex}{hex})
+non_digit                                              ({letter}|{universal_character_name})
+identifier                                             ({non_digit}({non_digit}|{digit})*)
+
+character_lit                                  (L?\'([^\'\\\n]|\\.)*)
+character_literal                              ({character_lit}\')
+
+string_lit                                             (L?\"([^\"\\\n]|\\.)*)
+string_literal                                 ({string_lit}\")
+
+pp_number                                              (\.?{digit}({digit}|{non_digit}|[eE][-+]|\.)*)
+%%
+^.*\n                                                  { LEX_SAVE_LINE(yytext, yyleng); REJECT; }
+^{ws}*"#".*                                            { /* Throw away preprocessor lines - hopefully only #line and equivalent. */ }
+
+{character_lit}\'                              { LEX_CHARACTER_TOKEN(yytext, yyleng-1); };
+{character_lit}\\                              { ERRMSG("End of line assumed to terminate character with trailing escape.");
+                                                                 LEX_CHARACTER_TOKEN(yytext, yyleng-1); };
+{character_lit}                                        { ERRMSG("End of line assumed to terminate character.");
+                                                                 LEX_CHARACTER_TOKEN(yytext, yyleng); };
+
+{string_lit}\"                                 { LEX_STRING_TOKEN(yytext, yyleng-1); };
+{string_lit}\\                                 { ERRMSG("End of line assumed to terminate string with trailing escape.");
+                                                                 LEX_STRING_TOKEN(yytext, yyleng-1); };
+{string_lit}                                   { ERRMSG("End of line assumed to terminate string.");
+                                                                 LEX_STRING_TOKEN(yytext, yyleng); };
+
+"asm"                                                  { LEX_STATIC_TOKEN(ASM); }
+"auto"                                                 { LEX_STATIC_TOKEN(AUTO); }
+"bool"                                                 { LEX_C_STATIC_TOKEN(BOOL); }
+"break"                                                        { LEX_STATIC_TOKEN(BREAK); }
+"case"                                                 { LEX_STATIC_TOKEN(CASE); }
+"catch"                                                        { LEX_C_STATIC_TOKEN(CATCH); }
+"char"                                                 { LEX_STATIC_TOKEN(CHAR); }
+"class"                                                        { LEX_C_STATIC_TOKEN(CLASS); }
+"const"                                                        { LEX_STATIC_TOKEN(CONST); }
+"const_cast"                                   { LEX_C_STATIC_TOKEN(CONST_CAST); }
+"continue"                                             { LEX_STATIC_TOKEN(CONTINUE); }
+"default"                                              { LEX_STATIC_TOKEN(DEFAULT); }
+"delete"                                               { LEX_C_STATIC_TOKEN(DELETE); }
+"do"                                                   { LEX_STATIC_TOKEN(DO); }
+"double"                                               { LEX_STATIC_TOKEN(DOUBLE); }
+"dynamic_cast"                                 { LEX_C_STATIC_TOKEN(DYNAMIC_CAST); }
+"else"                                                 { LEX_STATIC_TOKEN(ELSE); }
+"enum"                                                 { LEX_STATIC_TOKEN(ENUM); }
+"explicit"                                             { LEX_C_STATIC_TOKEN(EXPLICIT); }
+"export"                                               { LEX_C_STATIC_TOKEN(EXPORT); }
+"extern"                                               { LEX_STATIC_TOKEN(EXTERN); }
+"false"                                                        { LEX_C_STATIC_TOKEN(FALSE); }
+"float"                                                        { LEX_STATIC_TOKEN(FLOAT); }
+"for"                                                  { LEX_STATIC_TOKEN(FOR); }
+"friend"                                               { LEX_STATIC_TOKEN(FRIEND); }
+"goto"                                                 { LEX_STATIC_TOKEN(GOTO); }
+"if"                                                   { LEX_STATIC_TOKEN(IF); }
+"inline"                                               { LEX_C_STATIC_TOKEN(INLINE); }
+"int"                                                  { LEX_STATIC_TOKEN(INT); }
+"long"                                                 { LEX_STATIC_TOKEN(LONG); }
+"mutable"                                              { LEX_C_STATIC_TOKEN(MUTABLE); }
+"namespace"                                            { LEX_C_STATIC_TOKEN(NAMESPACE); }
+"new"                                                  { LEX_C_STATIC_TOKEN(NEW); }
+"operator"                                             { LEX_C_STATIC_TOKEN(OPERATOR); }
+"private"                                              { LEX_C_STATIC_TOKEN(PRIVATE); }
+"protected"                                            { LEX_C_STATIC_TOKEN(PROTECTED); }
+"public"                                               { LEX_C_STATIC_TOKEN(PUBLIC); }
+"register"                                             { LEX_STATIC_TOKEN(REGISTER); }
+"reinterpret_cast"                             { LEX_C_STATIC_TOKEN(REINTERPRET_CAST); }
+"return"                                               { LEX_STATIC_TOKEN(RETURN); }
+"short"                                                        { LEX_STATIC_TOKEN(SHORT); }
+"signed"                                               { LEX_C_STATIC_TOKEN(SIGNED); }
+"sizeof"                                               { LEX_STATIC_TOKEN(SIZEOF); }
+"static"                                               { LEX_STATIC_TOKEN(STATIC); }
+"static_cast"                                  { LEX_C_STATIC_TOKEN(STATIC_CAST); }
+"struct"                                               { LEX_STATIC_TOKEN(STRUCT); }
+"switch"                                               { LEX_STATIC_TOKEN(SWITCH); }
+"template"                                             { LEX_C_STATIC_TOKEN(TEMPLATE); }
+"this"                                                 { LEX_C_STATIC_TOKEN(THIS); }
+"throw"                                                        { LEX_C_STATIC_TOKEN(THROW); }
+"true"                                                 { LEX_C_STATIC_TOKEN(TRUE); }
+"try"                                                  { LEX_C_STATIC_TOKEN(TRY); }
+"typedef"                                              { LEX_STATIC_TOKEN(TYPEDEF); }
+"typeid"                                               { LEX_C_STATIC_TOKEN(TYPEID); }
+"typename"                                             { LEX_C_STATIC_TOKEN(TYPENAME); }
+"union"                                                        { LEX_STATIC_TOKEN(UNION); }
+"unsigned"                                             { LEX_STATIC_TOKEN(UNSIGNED); }
+"using"                                                        { LEX_C_STATIC_TOKEN(USING); }
+"virtual"                                              { LEX_STATIC_TOKEN(VIRTUAL); }
+"void"                                                 { LEX_STATIC_TOKEN(VOID); }
+"volatile"                                             { LEX_STATIC_TOKEN(VOLATILE); }
+"wchar_t"                                              { LEX_C_STATIC_TOKEN(WCHAR_T); }
+"while"                                                        { LEX_STATIC_TOKEN(WHILE); }
+
+"::"                                                   { LEX_C_STATIC_TOKEN(SCOPE); }
+"..."                                                  { LEX_STATIC_TOKEN(ELLIPSIS); }
+"<<"                                                   { LEX_STATIC_TOKEN(SHL); }
+">>"                                                   { LEX_STATIC_TOKEN(SHR); }
+"=="                                                   { LEX_STATIC_TOKEN(EQ); }
+"!="                                                   { LEX_STATIC_TOKEN(NE); }
+"<="                                                   { LEX_STATIC_TOKEN(LE); }
+">="                                                   { LEX_STATIC_TOKEN(GE); }
+"&&"                                                   { LEX_STATIC_TOKEN(LOG_AND); }
+"||"                                                   { LEX_STATIC_TOKEN(LOG_OR); }
+"++"                                                   { LEX_STATIC_TOKEN(INC); }
+"--"                                                   { LEX_STATIC_TOKEN(DEC); }
+"->*"                                                  { LEX_STATIC_TOKEN(ARROW_STAR); }
+"->"                                                   { LEX_STATIC_TOKEN(ARROW); }
+".*"                                                   { LEX_STATIC_TOKEN(DOT_STAR); }
+"+="                                                   { LEX_STATIC_TOKEN(ASS_ADD); }
+"-="                                                   { LEX_STATIC_TOKEN(ASS_SUB); }
+"*="                                                   { LEX_STATIC_TOKEN(ASS_MUL); }
+"/="                                                   { LEX_STATIC_TOKEN(ASS_DIV); }
+"%="                                                   { LEX_STATIC_TOKEN(ASS_MOD); }
+"^="                                                   { LEX_STATIC_TOKEN(ASS_XOR); }
+"&="                                                   { LEX_STATIC_TOKEN(ASS_AND); }
+"|="                                                   { LEX_STATIC_TOKEN(ASS_OR); }
+">>="                                                  { LEX_STATIC_TOKEN(ASS_SHR); }
+"<<="                                                  { LEX_STATIC_TOKEN(ASS_SHL); }
+
+{pp_number}                                            { LEX_NUMBER_TOKEN(yytext, yyleng); }
+
+{identifier}                                   { LEX_IDENTIFIER_TOKEN(yytext, yyleng); }
+
+{escape_sequence}                              |
+{universal_character_name}             { LEX_ESCAPED_TOKEN(yytext, yyleng); }
+
+\n                                                             |
+{ws}+                                                  { /* Throw away whitespace */ }
+.                                                              { LEX_ASCII_TOKEN(yytext[0]); }
+
+%%
+#include <CxxLexing.cxx>
diff --git a/infobase/examples/cpp_grammar_code/CxxLexing.cxx b/infobase/examples/cpp_grammar_code/CxxLexing.cxx
new file mode 100644 (file)
index 0000000..d57b0f1
--- /dev/null
@@ -0,0 +1,152 @@
+#ifdef FLEX_PP_CLASS
+FLEX_PP_CLASS theLexer;
+#define LEX_DOT theLexer .
+#else
+#define LEX_DOT
+#endif
+
+bool c_keywords = false;
+bool echo_line_numbers = false;
+bool echo_line_text = false;
+size_t line_number = 0;
+
+#ifdef NEEDS_YYWRAP
+int yywrap() { return 1; }
+#endif
+
+CxxToken *yylex_token()
+{
+       if (!LEX_DOT yylex())
+               return 0;
+       return yyToken;
+}
+
+//
+//     Configure the lexer to reflect successful parsing of a character value, assigning it to yylval.
+//
+//     The source someText[aLength] should correspond to the parsed text including any L or ' prefix
+//     but excluding any ' suffix. In this way the return can indicate whether a wide character has
+//     been detected and the routine can accommodate a variety of erroneous terminations.
+//
+CxxToken *make_character(const char *someText, size_t aLength)
+{
+       bool isWide = false;
+       if (someText && aLength)
+       {
+               if (*someText == 'L')
+               {
+                       isWide = true;
+                       someText++;
+                       aLength--;
+               }
+               if (!aLength || (*someText != '\''))
+                       ERRMSG("BUG - bad start of character literal.");
+               if (aLength)
+               {
+                       someText++;
+                       aLength--;
+               }
+       }
+       if (isWide)
+               return make_wide_character(someText, aLength);
+       else
+               return make_narrow_character(someText, aLength);
+}
+
+CxxToken *make_identifier(const char *someText, size_t aLength)
+{
+       return new CxxNaffToken(PARSE_TOKEN(Identifier), someText, aLength);
+}
+
+//
+//     Buffer the incoming line, before any characters are analysed.
+//
+void make_line(const char *yyText, size_t yyLeng)
+{
+       if (echo_line_text)
+               cout << tokenMarkDepth << ": "  << line_number << ": " << yyText << flush; 
+       else if (echo_line_numbers)
+               cout << line_number << endl; 
+       line_number++ ; 
+}
+
+CxxToken *make_literal_character(const char *someText, size_t aLength)
+{
+       return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
+}
+
+CxxToken *make_narrow_character(const char *someText, size_t aLength)
+{
+       return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
+}
+
+CxxToken *make_narrow_string(const char *someText, size_t aLength)
+{
+       return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
+}
+
+CxxToken *make_number(const char *someText, size_t aLength)
+{
+       return new CxxNaffToken(PARSE_TOKEN(IntegerLiteral), someText, aLength);
+}
+
+//
+//     Configure the lexer to reflect successful parsing of a categorised string.
+//
+//     The source someText[aLength] should correspond to the parsed text including any
+//     L or " prefix but excluding any " suffix. In this way the return can indicate whether a wide
+//     character has been detected and the routine can accommodate a variety of erroneous terminations.
+//
+CxxToken *make_string(const char *someText, size_t aLength)
+{
+       bool isWide = false;
+       if (someText && aLength)
+       {
+               if (*someText == 'L')
+               {
+                       isWide = true;
+                       someText++;
+                       aLength--;
+               }
+               if (!aLength || (*someText != '"'))
+                       ERRMSG("BUG - bad start of string literal.");
+               if (aLength)
+               {
+                       someText++;
+                       aLength--;
+               }
+       }
+       if (isWide)
+               return make_wide_string(someText, aLength);
+       else
+               return make_narrow_string(someText, aLength);
+}
+
+//
+//     Return the appropriate 1 of 256 flyweight tokens for the ASCII characters.
+//
+CxxToken *make_token(size_t tokenValue)
+{
+       static CxxToken *asciiTokens[256];
+       if (tokenValue >= (sizeof(asciiTokens)/sizeof(asciiTokens[0])))
+       {
+               ERRMSG("Cannot make_token for " << tokenValue);
+               return 0;
+       }
+       CxxToken **p = &asciiTokens[tokenValue];
+       CxxToken *theToken = *p;
+       if (!theToken)
+               *p = theToken = new CxxToken(tokenValue);
+       return theToken;
+}
+
+CxxToken *make_wide_character(const char *someText, size_t aLength)
+{
+       return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
+}
+
+CxxToken *make_wide_string(const char *someText, size_t aLength)
+{
+       return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
+}
+
diff --git a/infobase/examples/cpp_grammar_code/CxxLexing.hxx b/infobase/examples/cpp_grammar_code/CxxLexing.hxx
new file mode 100644 (file)
index 0000000..03c122d
--- /dev/null
@@ -0,0 +1,33 @@
+#include <CxxToken.hxx>
+
+#include <CxxParser.hxx>
+
+static CxxToken *yyToken;
+static CxxToken *make_character(const char *someText, size_t aLength);
+static CxxToken *make_string(const char *someText, size_t aLength);
+static CxxToken *make_identifier(const char *someText, size_t aLength);
+static void make_line(const char *yyText, size_t yyLeng);
+static CxxToken *make_literal_character(const char *someText, size_t aLength);
+static CxxToken *make_narrow_character(const char *someText, size_t aLength);
+static CxxToken *make_narrow_string(const char *someText, size_t aLength);
+static CxxToken *make_number(const char *someText, size_t aLength);
+static CxxToken *make_token(size_t aCxxToken);
+static CxxToken *make_wide_character(const char *someText, size_t aLength);
+static CxxToken *make_wide_string(const char *someText, size_t aLength);
+
+#define LEX_SAVE_LINE(yyText, yyLeng) make_line(yyText, yyLeng);
+#define LEX_ASCII_TOKEN(a) yyToken = make_token(a); return true;
+#define LEX_STATIC_TOKEN(a) static CxxToken theToken(PARSE_TOKEN(a)); yyToken = &theToken; return true;
+#define LEX_C_STATIC_TOKEN(a) \
+       if (c_keywords) { LEX_IDENTIFIER_TOKEN(yytext, yyleng) } \
+       else { LEX_STATIC_TOKEN(a) } return true;
+#define LEX_ESCAPED_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral)
+//     yyToken = make_literal_character(yytext, yyleng); return true;
+#define LEX_CHARACTER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(CharacterLiteral)
+//     yyToken = make_character(yyText, yyLeng); return true;
+#define LEX_STRING_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(StringLiteral)
+//     yyToken = make_string(yyText, yyLeng); return true;
+#define LEX_IDENTIFIER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(Identifier)
+//     yyToken = make_identifier(yyText, yyLeng); return true;
+#define LEX_NUMBER_TOKEN(yyText, yyLeng) LEX_STATIC_TOKEN(IntegerLiteral)
+//     yyToken = make_number(yyText, yyLeng); return true;
diff --git a/infobase/examples/cpp_grammar_code/CxxParser.cpp b/infobase/examples/cpp_grammar_code/CxxParser.cpp
new file mode 100644 (file)
index 0000000..43f94c4
--- /dev/null
@@ -0,0 +1,10 @@
+//
+//       Title:                        C++ Grammar Parser support compilation unit.
+//
+//       File Name:            CxxParser.cpp
+//
+//       Author:                       E.D.Willink
+//END
+//
+#include <CxxParser.cxx>
+
diff --git a/infobase/examples/cpp_grammar_code/CxxParser.y b/infobase/examples/cpp_grammar_code/CxxParser.y
new file mode 100644 (file)
index 0000000..44cb9d8
--- /dev/null
@@ -0,0 +1,1162 @@
+/* This is a yacc-able parser for the entire ISO C++ grammar with no unresolved conflicts. */
+/* The parse is SYNTACTICALLY consistent and requires no template or type name assistance.
+ * The grammar in the C++ standard notes that its grammar is a superset of the true
+ * grammar requiring semantic constraints to resolve ambiguities. This grammar is a really big
+ * superset unifying expressions and declarations, eliminating the type/non-type distinction,
+ * and iterating to find a consistent solution to the template/arith,metoic < ambiguity.
+ * As a result the grammar is much simpler, but requires the missing semantic constraints to be
+ * performed in a subsequent semantic pass, which is of course where they belong. This grammar will
+ * support conversion of C++ tokens into an Abstract Syntax Tree. A lot of further work is required to
+ * make that tree useful.
+ *
+ * The principles behind this grammar are described in my thesis on Meta-Compilation for C++, which
+ * may be found via http://www.computing.surrey.ac.uk/research/dsrg/fog/FogThesis.html.
+ *
+ *  Author:         E.D.Willink             Ed.Willink@rrl.co.uk
+ *  Date:           19-Jun-2001
+ */
+/*StartTester*/
+%{
+#include <CxxParsing.hxx>
+%}
+/*EndTester*/
+/*
+ * The lexer (and/or a preprocessor) is expected to identify the following
+ *
+ *  Punctuation:
+ */
+%type <keyword> '+' '-' '*' '/' '%' '^' '&' '|' '~' '!' '<'  '>' '=' ':' '[' ']' '{' '}' '(' ')'
+%type <keyword> '?' '.' '\'' '\"' '\\' '@' '$' ';' ','
+/*
+ *  Punctuation sequences
+ */
+%term <keyword> ARROW ARROW_STAR DEC EQ GE INC LE LOG_AND LOG_OR NE SHL SHR
+%term <keyword> ASS_ADD ASS_AND ASS_DIV ASS_MOD ASS_MUL ASS_OR ASS_SHL ASS_SHR ASS_SUB ASS_XOR
+%term <keyword> DOT_STAR ELLIPSIS SCOPE
+/*
+ *  Reserved words
+ */
+%term <access_specifier> PRIVATE PROTECTED PUBLIC
+%term <built_in_id> BOOL CHAR DOUBLE FLOAT INT LONG SHORT SIGNED UNSIGNED VOID WCHAR_T
+%term <class_key> CLASS ENUM NAMESPACE STRUCT TYPENAME UNION
+%term <cv_qualifiers> CONST VOLATILE
+%term <decl_specifier_id> AUTO EXPLICIT EXPORT EXTERN FRIEND INLINE MUTABLE REGISTER STATIC TEMPLATE TYPEDEF USING VIRTUAL
+%term <keyword> ASM BREAK CASE CATCH CONST_CAST CONTINUE DEFAULT DELETE DO DYNAMIC_CAST
+%term <keyword> ELSE FALSE FOR GOTO IF NEW OPERATOR REINTERPRET_CAST RETURN
+%term <keyword> SIZEOF STATIC_CAST SWITCH THIS THROW TRUE TRY TYPEID WHILE
+/*
+ *  Parametric values.
+ */
+%term <character_literal> CharacterLiteral
+%term <floating_literal> FloatingLiteral
+%term <identifier> Identifier
+%term <integer_literal> IntegerLiteral
+%term <number_literal> NumberLiteral
+%term <string_literal> StringLiteral
+/*
+ *  The lexer need not treat '0' as distinct from IntegerLiteral in the hope that pure-specifier can
+ *  be distinguished, It isn't. Semantic rescue from = constant-expression is necessary.
+ *
+ *  The lexer is not required to distinguish template or type names, although a slight simplification to the
+ *  grammar and elaboration of the action rules could make good use of template name information.
+ *
+ *  In return for not needing to use semantic information, the lexer must support back-tracking, which
+ *  is easily achieved by a simple linear buffer, a reference implementation of which may be found in the
+ *  accompanying CxxParsing.cxx. Back-tracking is used to support:
+ *
+ *  Binary search for a consistent parse of the template/arithmetic ambiguity.
+ *      start_search() initialises the search
+ *      advance_search() iterates the search
+ *      end_search() cleans up after a search
+ *      template_test() maintains context during a search
+ *
+ *  Lookahead to resolve the inheritance/anonymous bit-field similarity
+ *      mark() saves the starting context
+ *      unmark() pops it
+ *      rewind_colon() restores the context and forces the missing :
+ *
+ *  Lookahead to resolve type 1 function parameter ambiguities
+ *      mark_type1() potentially marks the starting position
+ *      mark() marks the pre { position
+ *      remark() rewinds to the starting position
+ *      unmark() pops the starting position
+ *
+ *  Note that lookaheads may nest. 
+ */
+
+/*
+ *  The parsing philosophy is unusual. The major ambiguities are resolved by creating a unified superset
+ *  grammar rather than non-overlapping subgrammars. Thus the grammar for parameter-declaration covers an
+ *  assignment-expression. Minor ambiguities whose resolution by supersetting would create more
+ *  ambiguities are resolved the normal way with partitioned subgrammars.
+ *  This eliminates the traditional expression/declaration and constructor/parenthesised declarator
+ *  ambiguities at the syntactic level. A subsequent semantic level has to sort the problems out.
+ *  The generality introduces four bogus ambiguities and defers the cast ambiguity for resolution
+ *  once semantic information is available.
+ *
+ *  The C++ grammar comprises 561 rules and uses 897 states in yacc, with 0 unresolved conflicts.
+ *  23 conflicts from 10 ambiguities are resolved by 8 %prec's, so that yacc and bison report 0 conflicts.
+ *
+ *  The ambiguities are:
+ *  1) dangling else resolved to inner-most if
+ *      1 conflict in 1 state on else
+ *  2) < as start-template or less-than
+ *      1 conflict in 1 states on <
+ *  3) a :: b :: c resolved to favour a::b::c rather than a::b ::c or a ::b::c
+ *      1 conflicts in 1 state for ::
+ *  4) pointer operators maximised at end of conversion id/new in preference to binary operators
+ *      2 conflicts in 4 states on * and &
+ *  5a) (a)@b resolved to favour binary a@b rather than cast unary (a)(@b)
+ *  5b) (a)(b) resolved to favour cast rather than call
+ *      8 conflicts in 1 state for the 8 prefix operators: 6 unaries and ( and [.
+ *  6) enum name { resolved to enum-specifier rather than function
+ *      1 conflict in 1 state on {
+ *  7) class name { resolved to class-specifier rather than function
+ *      1 conflict in 1 state on {
+ *  8) extern "C" resolved to linkage-specification rather than declaration
+ *      1 conflict in 1 state on StringLiteral
+ *  9) class X : forced to go through base-clause look-ahead
+ *      1 conflict in 1 state on :
+ *  10) id : forced to label_statement rather than constructor_head
+ *      0 conflicts - but causes a double state for 2)
+ *  of which
+ *      1 is a fundamental C conflict - always correctly resolved
+ *          can be removed - see the Java spec
+ *      2, 3, 4 are fundamental C++ conflicts
+ *          2 always consistently resolved by iteration
+ *          3 always correctly resolved
+ *          4 always correctly resolved
+ *      5 is a result of not using type information - deferred for semantic repair
+ *      6,7 are caused by parsing over-generous superset - always correctly resolved
+ *      8 is caused by parsing over-generous superset - always correctly resolved
+ *          can be removed at the expense of 7 rules and 5 states.
+ *      9 is a look-ahead trick - always correctly resolved
+ *          could be removed by marking one token sooner
+ *      10 is caused by parsing over-generous superset - always correctly resolved
+ *
+ *  The hard problem of distinguishing
+ *      class A { class B : C, D, E {           -- A::B privately inherits C, D and E
+ *      class A { class B : C, D, E ;           -- C is width of anon bit-field
+ *  is resolved by using a lookahead that assumes inheritance and rewinds for the bit-field.
+ *
+ *  The potential shift-reduce conflict on > is resolved by flattening part of the expression grammar
+ *  to know when the next > is template end or arithmetic >.
+ *
+ *  The grammar is SYNTACTICALLY context-free with respect to type. No semantic assistance is required
+ *  during syntactic analysis. However the cast ambiguity is deferred and must be recovered
+ *  after syntactic analysis of a statement has completed. 
+ *
+ *  The grammar is SYNTACTICALLY context-free with respect to template-names. This is achieved by
+ *  organising a binary search over all possible template/arithmetic ambiguities with respect to
+ *  the enclosing statement. This is potentially exponentially inefficient but well-behaved in practice.
+ *  Approximately 1% of statements trigger a search and approximately 1% of those are misparsed,
+ *  requiring the semantic analysis to check and correct once template information is available.
+ *  1.5 parse attempts are required on average per ambiguous statement.
+ *
+ *  The grammar supports type I function declarations at severe impediment to efficiency. A lookahead
+ *  has to be performed after almost every non-statement close parenthesis. A one-line plus corollary
+ *  change to postfix_expression is commented and strongly recommended to make this grammar as
+ *  efficient as the rather large number of reduction levels permits.
+ *
+ *  Error recovery occurs mostly at the statement/declaration level. Recovery also occurs at
+ *  the list-element level where this poses no hazard to statement/declaration level recovery. 
+ *  Note that since error propagation interacts with the lookaheads for template iteration or
+ *  type 1 function arguments, introduction of finer grained error recovery may repair a false
+ *  parse and so cause a misparse.
+ *
+ *  The following syntactic analysis errors occur, but are correctable semantically:
+ *  (cast)unary-op expr         is parsed as (parenthesised)binary-op expr
+ *      The semantic test should look for a binary/call with a (type) as its left child.
+ *  (parenthesised)(arguments)  is parsed as (cast)(parenthesised)
+ *      The semantic test should look for a cast with a non-type as its left child.
+ *  template < and arithmetic < may be cross-parsed (unless semnatic help is provided)
+ *      approximately 0.01% are misparsed, and must be sorted out - not easy.
+ *
+ *  The syntactic analysis defers the following ambiguities for semantic resolution:
+ *  declaration/expression is parsed as a unified concept
+ *      Use type and context to complete the parse.
+ *  ~class-name                 is parsed as unary~ name
+ *      The semantic test should look for ~ with a type as its child.
+ *  delete[] expr               is parsed as delete []expr
+ *      The semantic test should look for delete with a [] cast of its child.
+ *  operator new/delete[]       are parsed as array of operator new/delete
+ *      The semantic test should look for array of operator new/delete
+ *      or activate the two extra commented rules in operator
+ *  template of an explicit_instantiation is buried deep in the tree
+ *      dig it out 
+ *  pure-specifier and constant-initializer are covered by assignment-expression
+ *      just another of the deferred declaration/expression ambiguities
+ *  sizeof and typeid don't distinguish type/value syntaxes
+ *      probably makes life polymorphically easier
+ */
+/*  Action code is supplied by a large number of YACC_xxx macros that can be redefined
+ *  by rewriting the include file rather than the grammar. The number of macros is
+ *  slightly reduced by using the following protocols
+ *
+ *  YACC_LIST(0,0)      create empty list (may safely return 0).
+ *  YACC_LIST(0,E)      create new list with content E (may return 0 if above returned non-0).
+ *  YACC_LIST(L,E)      add E to L
+ *  YACC_LIST(L,0)      error propagation, adding nothing to L.
+ */
+%type <bang> bang
+%type <mark> colon_mark mark mark_type1
+%type <nest> nest
+
+%type <access_specifier> access_specifier
+%type <base_specifier> base_specifier
+%type <base_specifiers> base_specifier_list
+%type <built_in_id> built_in_type_id built_in_type_specifier
+%type <_class> class_specifier_head
+%type <class_key> class_key
+%type <condition> condition condition.opt
+%type <cv_qualifiers> cv_qualifier cv_qualifier_seq.opt
+%type <decl_specifier_id>  decl_specifier_affix decl_specifier_prefix decl_specifier_suffix function_specifier storage_class_specifier
+%type <declaration> accessibility_specifier asm_definition block_declaration declaration explicit_specialization
+%type <declaration> looped_declaration looping_declaration namespace_alias_definition
+%type <declaration> specialised_block_declaration specialised_declaration template_declaration using_directive
+%type <declarations> compound_declaration declaration_seq.opt
+%type <declarator> nested_ptr_operator ptr_operator
+%type <delete_expression> delete_expression
+%type <enumerator> enumerator_definition
+%type <enumerators> enumerator_clause enumerator_list enumerator_list_head
+%type <exception_declaration> exception_declaration
+%type <exception_specification> exception_specification
+%type <expression> abstract_declarator.opt abstract_expression abstract_parameter_declaration abstract_pointer_declaration
+%type <expression> additive_expression and_expression assignment_expression
+%type <expression> bit_field_declaration bit_field_init_declaration bit_field_width boolean_literal
+%type <expression> cast_expression conditional_expression constant_expression conversion_type_id ctor_definition
+%type <expression> direct_abstract_declarator direct_abstract_declarator.opt direct_new_declarator
+%type <expression> equality_expression exclusive_or_expression expression expression.opt
+%type <expression> for_init_statement func_definition function_definition 
+%type <expression> inclusive_or_expression init_declaration literal logical_and_expression logical_or_expression
+%type <expression> multiplicative_expression new_declarator new_type_id
+%type <expression> pm_expression postfix_expression primary_expression ptr_operator_seq ptr_operator_seq.opt
+%type <expression> relational_expression shift_expression simple_declaration special_parameter_declaration
+%type <expression> templated_throw_expression throw_expression templated_abstract_declaration templated_and_expression 
+%type <expression>templated_assignment_expression templated_conditional_expression templated_equality_expression
+%type <expression> templated_exclusive_or_expression templated_expression templated_inclusive_or_expression templated_logical_and_expression
+%type <expression> templated_logical_or_expression templated_relational_expression type_id unary_expression
+%type <expressions> constructor_head expression_list expression_list.opt init_declarations
+%type <expressions> new_initializer.opt templated_expression_list type_id_list
+%type <function_body> function_block function_body function_try_block try_block
+%type <handler> handler
+%type <handlers> handler_seq
+%type <initializer_clause> braced_initializer initializer_clause looped_initializer_clause looping_initializer_clause
+%type <initializer_clauses> initializer_list
+%type <is_template> global_scope
+%type <keyword> assignment_operator
+%type <line> start_search start_search1
+%type <mem_initializer> mem_initializer
+%type <mem_initializers> ctor_initializer ctor_initializer.opt mem_initializer_list mem_initializer_list_head
+%type <name> class_specifier conversion_function_id declarator_id destructor_id
+%type <name> elaborated_class_specifier elaborated_enum_specifier elaborated_type_specifier elaborate_type_specifier
+%type <name> enum_specifier enumerator id identifier_word id_scope identifier linkage_specification
+%type <name> namespace_definition nested_id nested_pseudo_destructor_id nested_special_function_id
+%type <name> mem_initializer_id operator operator_function_id pseudo_destructor_id scoped_id scoped_pseudo_destructor_id scoped_special_function_id
+%type <name> simple_type_specifier special_function_id suffix_built_in_decl_specifier suffix_named_decl_specifier.bi
+%type <name> suffix_built_in_decl_specifier.raw suffix_decl_specified_ids suffix_named_decl_specifiers
+%type <name> suffix_named_decl_specifiers.sf suffix_decl_specified_scope suffix_named_decl_specifier
+%type <name> template_id type_specifier
+%type <new_expression> new_expression
+%type <parameter> parameter_declaration templated_parameter_declaration
+%type <parameters> parameters_clause parameter_declaration_clause parameter_declaration_list
+%type <parenthesised> parenthesis_clause
+%type <pointer_declarator> star_ptr_operator
+%type <simple_type_parameter> simple_type_parameter
+%type <statement> compound_statement control_statement declaration_statement iteration_statement jump_statement
+%type <statement> labeled_statement looped_statement looping_statement selection_statement statement
+%type <statements> statement_seq.opt
+%type <strings> string
+%type <template_argument> template_argument
+%type <template_arguments> template_argument_list
+%type <template_parameter> template_parameter
+%type <template_parameters> template_parameter_clause template_parameter_list
+%type <templated_type_parameter> templated_type_parameter
+%type <type1_parameters> type1_parameters
+%type <utility> util
+
+/*
+ *  C++ productions replaced by more generalised FOG productions
+ */
+%type <declaration> looped_member_declaration looping_member_declaration member_declaration using_declaration
+%type <declarations> member_specification.opt
+%type <expression> member_init_declaration simple_member_declaration
+%type <expressions> member_init_declarations
+
+\f
+%nonassoc SHIFT_THERE
+%nonassoc SCOPE ELSE INC DEC '+' '-' '*' '&' '[' '{' '<' ':' StringLiteral
+%nonassoc REDUCE_HERE_MOSTLY
+%nonassoc '('
+/*%nonassoc REDUCE_HERE */
+
+%start translation_unit
+%%
+
+/*
+ *  The %prec resolves a conflict in identifier_word : which is forced to be a shift of a label for
+ *  a labeled-statement rather than a reduction for the name of a bit-field or generalised constructor.
+ *  This is pretty dubious syntactically but correct for all semantic possibilities.
+ *  The shift is only activated when the ambiguity exists at the start of a statement. In this context
+ *  a bit-field declaration or constructor definition are not allowed.
+ */
+identifier_word:                    Identifier                                                  { $$ = $1; }
+identifier:                         identifier_word                     %prec SHIFT_THERE
+/*
+ *  The %prec resolves the $014.2-3 ambiguity:
+ *  Identifier '<' is forced to go through the is-it-a-template-name test
+ *  All names absorb TEMPLATE with the name, so that no template_test is performed for them.
+ *  This requires all potential declarations within an expression to perpetuate this policy
+ *  and thereby guarantee the ultimate coverage of explicit_instantiation.
+ */
+id:                                 identifier                          %prec SHIFT_THERE       /* Force < through test */ { $$ = YACC_NAME($1); }
+    |                               identifier template_test '+' template_argument_list '>'     { $$ = YACC_TEMPLATE_NAME($1, $4); }
+    |                               identifier template_test '+' '>'                            { $$ = $1; ERRMSG("Empty template-argument-list"); }
+    |                               identifier template_test '-'                                /* requeued < follows */  { $$ = YACC_NAME($1); }
+    |                               template_id 
+template_test:                      '<'             /* Queue '+' or '-' < as follow on */       { template_test(); }
+global_scope:                       SCOPE                                                       { $$ = IS_DEFAULT; }
+    |                               TEMPLATE global_scope                                       { $$ = IS_TEMPLATE; }
+id_scope:                           id SCOPE                                                    { $$ = YACC_NESTED_SCOPE($1); }
+/*
+ *  A :: B :: C; is ambiguous How much is type and how much name ?
+ *  The %prec maximises the (type) length which is the $07.1-2 semantic constraint.
+ */
+nested_id:                          id                                  %prec SHIFT_THERE       /* Maximise length */
+    |                               id_scope nested_id                                          { $$ = YACC_NESTED_ID($1, $2); }
+scoped_id:                          nested_id
+    |                               global_scope nested_id                                      { $$ = YACC_GLOBAL_ID($1, $2); }
+
+/*
+ *  destructor_id has to be held back to avoid a conflict with a one's complement as per $05.3.1-9,
+ *  It gets put back only when scoped or in a declarator_id, which is only used as an explicit member name.
+ *  Declarations of an unscoped destructor are always parsed as a one's complement.
+ */
+destructor_id:                      '~' id                                                      { $$ = YACC_DESTRUCTOR_ID($2); }
+    |                               TEMPLATE destructor_id                                      { $$ = YACC_SET_TEMPLATE_ID($2); }
+special_function_id:                conversion_function_id
+    |                               operator_function_id
+    |                               TEMPLATE special_function_id                                { $$ = YACC_SET_TEMPLATE_ID($2); }
+nested_special_function_id:         special_function_id
+    |                               id_scope destructor_id                                      { $$ = YACC_NESTED_ID($1, $2); }
+    |                               id_scope nested_special_function_id                         { $$ = YACC_NESTED_ID($1, $2); }
+scoped_special_function_id:         nested_special_function_id
+    |                               global_scope nested_special_function_id                     { $$ = YACC_GLOBAL_ID($1, $2); }
+
+/* declarator-id is all names in all scopes, except reserved words */
+declarator_id:                      scoped_id
+    |                               scoped_special_function_id
+    |                               destructor_id
+
+/*  The standard defines pseudo-destructors in terms of type-name, which is class/enum/typedef, of which
+ *  class-name is covered by a normal destructor. pseudo-destructors are supposed to support ~int() in
+ *  templates, so the grammar here covers built-in names. Other names are covered by the lack of
+ *  identifier/type discrimination.
+ */
+built_in_type_id:                   built_in_type_specifier
+    |                               built_in_type_id built_in_type_specifier                    { $$ = YACC_BUILT_IN_IDS($1, $2); }
+pseudo_destructor_id:               built_in_type_id SCOPE '~' built_in_type_id                 { $$ = YACC_PSEUDO_DESTRUCTOR_ID($1, $4); }
+    |                               '~' built_in_type_id                                        { $$ = YACC_PSEUDO_DESTRUCTOR_ID(0, $2); }
+    |                               TEMPLATE pseudo_destructor_id                               { $$ = YACC_SET_TEMPLATE_ID($2); }
+nested_pseudo_destructor_id:        pseudo_destructor_id
+    |                               id_scope nested_pseudo_destructor_id                        { $$ = YACC_NESTED_ID($1, $2); }
+scoped_pseudo_destructor_id:        nested_pseudo_destructor_id
+    |                               global_scope scoped_pseudo_destructor_id                    { $$ = YACC_GLOBAL_ID($1, $2); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.2 Lexical conventions
+ *---------------------------------------------------------------------------------------------------*/
+/*
+ *  String concatenation is a phase 6, not phase 7 activity so does not really belong in the grammar.
+ *  However it may be convenient to have it here to make this grammar fully functional.
+ *  Unfortunately it introduces a conflict with the generalised parsing of extern "C" which
+ *  is correctly resolved to maximise the string length as the token source should do anyway.
+ */
+string:                             StringLiteral                                               { $$ = $1; }
+/*string:                           StringLiteral                           %prec SHIFT_THERE   { $$ = YACC_STRINGS($1, 0); } */
+/*  |                               StringLiteral string  -- Perverse order avoids conflicts -- { $$ = YACC_STRINGS($1, $2); } */
+literal:                            IntegerLiteral                                              { $$ = YACC_INTEGER_LITERAL_EXPRESSION($1); }
+    |                               CharacterLiteral                                            { $$ = YACC_CHARACTER_LITERAL_EXPRESSION($1); }
+    |                               FloatingLiteral                                             { $$ = YACC_FLOATING_LITERAL_EXPRESSION($1); }
+    |                               string                                                      { $$ = YACC_STRING_LITERAL_EXPRESSION($1); }
+    |                               boolean_literal
+boolean_literal:                    FALSE                                                       { $$ = YACC_FALSE_EXPRESSION(); }
+    |                               TRUE                                                        { $$ = YACC_TRUE_EXPRESSION(); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.3 Basic concepts
+ *---------------------------------------------------------------------------------------------------*/
+translation_unit:                   declaration_seq.opt                                         { YACC_RESULT($1); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.4 Expressions
+ *---------------------------------------------------------------------------------------------------
+ *  primary_expression covers an arbitrary sequence of all names with the exception of an unscoped destructor,
+ *  which is parsed as its unary expression which is the correct disambiguation (when ambiguous).
+ *  This eliminates the traditional A(B) meaning A B ambiguity, since we never have to tack an A onto
+ *  the front of something that might start with (. The name length got maximised ab initio. The downside
+ *  is that semantic interpretation must split the names up again.
+ *
+ *  Unification of the declaration and expression syntax means that unary and binary pointer declarator operators:
+ *      int * * name
+ *  are parsed as binary and unary arithmetic operators (int) * (*name). Since type information is not used
+ *  ambiguities resulting from a cast
+ *      (cast)*(value)
+ *  are resolved to favour the binary rather than the cast unary to ease AST clean-up.
+ *  The cast-call ambiguity must be resolved to the cast to ensure that (a)(b)c can be parsed.
+ *
+ *  The problem of the functional cast ambiguity
+ *      name(arg)
+ *  as call or declaration is avoided by maximising the name within the parsing kernel. So
+ *  primary_id_expression picks up 
+ *      extern long int const var = 5;
+ *  as an assignment to the syntax parsed as "extern long int const var". The presence of two names is
+ *  parsed so that "extern long into const" is distinguished from "var" considerably simplifying subsequent
+ *  semantic resolution.
+ *
+ *  The generalised name is a concatenation of potential type-names (scoped identifiers or built-in sequences)
+ *  plus optionally one of the special names such as an operator-function-id, conversion-function-id or
+ *  destructor as the final name. 
+ */
+primary_expression:                 literal
+    |                               THIS                                                    { $$ = YACC_THIS_EXPRESSION(); }
+    |                               suffix_decl_specified_ids                               { $$ = $1; }
+/*  |                               SCOPE identifier                                        -- covered by suffix_decl_specified_ids */
+/*  |                               SCOPE operator_function_id                              -- covered by suffix_decl_specified_ids */
+/*  |                               SCOPE qualified_id                                      -- covered by suffix_decl_specified_ids */
+    |                               abstract_expression           %prec REDUCE_HERE_MOSTLY  /* Prefer binary to unary ops, cast to call */
+/*  |                               id_expression                                           -- covered by suffix_decl_specified_ids */
+
+/*
+ *  Abstract-expression covers the () and [] of abstract-declarators.
+ */
+abstract_expression:                parenthesis_clause                                      { $$ = YACC_ABSTRACT_FUNCTION_EXPRESSION($1); }
+    |                               '[' expression.opt ']'                                  { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); }
+    |                               TEMPLATE parenthesis_clause                             { $$ = YACC_SET_TEMPLATE_EXPRESSION(YACC_ABSTRACT_FUNCTION_EXPRESSION($2)); }
+
+/*  Type I function parameters are ambiguous with respect to the generalised name, so we have to do a lookahead following
+ *  any function-like parentheses. This unfortunately hits normal code, so kill the -- lines and add the ++ lines for efficiency.
+ *  Supporting Type I code under the superset causes perhaps 25% of lookahead parsing. Sometimes complete class definitions
+ *  get traversed since they are valid generalised type I parameters!
+ */
+type1_parameters:       /*----*/    parameter_declaration_list ';'                          { $$ = YACC_TYPE1_PARAMETERS(0, $1); }
+    |                   /*----*/    type1_parameters parameter_declaration_list ';'         { $$ = YACC_TYPE1_PARAMETERS($1, $2); }
+mark_type1:                         /* empty */                                             { $$ = mark_type1(); }
+postfix_expression:                 primary_expression
+/*  |                   /++++++/    postfix_expression parenthesis_clause                   { $$ = YACC_CALL_EXPRESSION($1, $2); } */
+    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '-'    { $$ = YACC_CALL_EXPRESSION($1, $2); }
+    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark '{' error 
+                        /*----*/                    { yyerrok; remark_type1($6); unmark(); unmark($5); $$ = YACC_TYPE1_EXPRESSION($1, $2, $5); }
+    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark error 
+                        /*----*/                    { yyerrok; remark_type1($3); unmark(); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); }
+    |                   /*----*/    postfix_expression parenthesis_clause mark_type1 '+' error
+                        /*----*/                    { yyerrok; remark_type1($3); unmark(); $$ = YACC_CALL_EXPRESSION($1, $2); }
+    |                               postfix_expression '[' expression.opt ']'               { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
+/*  |                               destructor_id '[' expression.opt ']'                    -- not semantically valid */
+/*  |                               destructor_id parenthesis_clause                        -- omitted to resolve known ambiguity */
+/*  |                               simple_type_specifier '(' expression_list.opt ')'       -- simple_type_specifier is a primary_expression */
+    |                               postfix_expression '.' declarator_id                    { $$ = YACC_DOT_EXPRESSION($1, $3); }
+/*  |                               postfix_expression '.' TEMPLATE declarator_id           -- TEMPLATE absorbed into declarator_id. */
+    |                               postfix_expression '.' scoped_pseudo_destructor_id      { $$ = YACC_DOT_EXPRESSION($1, $3); }
+    |                               postfix_expression ARROW declarator_id                  { $$ = YACC_ARROW_EXPRESSION($1, $3); }
+/*  |                               postfix_expression ARROW TEMPLATE declarator_id         -- TEMPLATE absorbed into declarator_id. */
+    |                               postfix_expression ARROW scoped_pseudo_destructor_id    { $$ = YACC_ARROW_EXPRESSION($1, $3); }   
+    |                               postfix_expression INC                                  { $$ = YACC_POST_INCREMENT_EXPRESSION($1); }
+    |                               postfix_expression DEC                                  { $$ = YACC_POST_DECREMENT_EXPRESSION($1); }
+    |                               DYNAMIC_CAST '<' type_id '>' '(' expression ')'         { $$ = YACC_DYNAMIC_CAST_EXPRESSION($3, $6); }
+    |                               STATIC_CAST '<' type_id '>' '(' expression ')'          { $$ = YACC_STATIC_CAST_EXPRESSION($3, $6); }
+    |                               REINTERPRET_CAST '<' type_id '>' '(' expression ')'     { $$ = YACC_REINTERPRET_CAST_EXPRESSION($3, $6); }
+    |                               CONST_CAST '<' type_id '>' '(' expression ')'           { $$ = YACC_CONST_CAST_EXPRESSION($3, $6); }
+    |                               TYPEID parameters_clause                                { $$ = YACC_TYPEID_EXPRESSION($2); }
+/*  |                               TYPEID '(' expression ')'                               -- covered by parameters_clause */
+/*  |                               TYPEID '(' type_id ')'                                  -- covered by parameters_clause */
+expression_list.opt:                /* empty */                                             { $$ = YACC_EXPRESSIONS(0, 0); }
+    |                               expression_list
+expression_list:                    assignment_expression                                   { $$ = YACC_EXPRESSIONS(0, $1); }
+    |                               expression_list ',' assignment_expression               { $$ = YACC_EXPRESSIONS($1, $3); }
+
+unary_expression:                   postfix_expression
+    |                               INC cast_expression                                     { $$ = YACC_PRE_INCREMENT_EXPRESSION($2); }
+    |                               DEC cast_expression                                     { $$ = YACC_PRE_DECREMENT_EXPRESSION($2); }
+    |                               ptr_operator cast_expression                            { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+/*  |                               '*' cast_expression                                     -- covered by ptr_operator */
+/*  |                               '&' cast_expression                                     -- covered by ptr_operator */
+/*  |                               decl_specifier_seq '*' cast_expression                  -- covered by binary operator */
+/*  |                               decl_specifier_seq '&' cast_expression                  -- covered by binary operator */
+    |                               suffix_decl_specified_scope star_ptr_operator cast_expression   /* covers e.g int ::type::* const t = 4 */
+                                                                                            { $$ = YACC_SCOPED_POINTER_EXPRESSION($1, $2, $3); }
+    |                               '+' cast_expression                                     { $$ = YACC_PLUS_EXPRESSION($2); }
+    |                               '-' cast_expression                                     { $$ = YACC_MINUS_EXPRESSION($2); }
+    |                               '!' cast_expression                                     { $$ = YACC_NOT_EXPRESSION($2); }
+    |                               '~' cast_expression                                     { $$ = YACC_COMPLEMENT_EXPRESSION($2); }
+    |                               SIZEOF unary_expression                                 { $$ = YACC_SIZEOF_EXPRESSION($2); }
+/*  |                               SIZEOF '(' type_id ')'                                  -- covered by unary_expression */
+    |                               new_expression                                          { $$ = $1; }
+    |                               global_scope new_expression                             { $$ = YACC_GLOBAL_EXPRESSION($1, $2); }
+    |                               delete_expression                                       { $$ = $1; }
+    |                               global_scope delete_expression                          { $$ = YACC_GLOBAL_EXPRESSION($1, $2); }
+/*  |                               DELETE '[' ']' cast_expression       -- covered by DELETE cast_expression since cast_expression covers ... */
+/*  |                               SCOPE DELETE '[' ']' cast_expression //  ... abstract_expression cast_expression and so [] cast_expression */
+
+delete_expression:                  DELETE cast_expression                                  /* also covers DELETE[] cast_expression */
+                                                                                            { $$ = YACC_DELETE_EXPRESSION($2); }
+new_expression:                     NEW new_type_id new_initializer.opt                     { $$ = YACC_NEW_TYPE_ID_EXPRESSION(0, $2, $3); }
+    |                               NEW parameters_clause new_type_id new_initializer.opt   { $$ = YACC_NEW_TYPE_ID_EXPRESSION($2, $3, $4); }
+    |                               NEW parameters_clause                                   { $$ = YACC_NEW_EXPRESSION($2, 0, 0); }
+/*  |                               NEW '(' type-id ')'                                     -- covered by parameters_clause */
+    |                               NEW parameters_clause parameters_clause new_initializer.opt { $$ = YACC_NEW_EXPRESSION($2, $3, $4); }
+/*  |                               NEW '(' type-id ')' new_initializer                     -- covered by parameters_clause parameters_clause */
+/*  |                               NEW parameters_clause '(' type-id ')'                   -- covered by parameters_clause parameters_clause */
+                                                                                /* ptr_operator_seq.opt production reused to save a %prec */
+new_type_id:                        type_specifier ptr_operator_seq.opt                     { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+    |                               type_specifier new_declarator                           { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+    |                               type_specifier new_type_id                              { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+new_declarator:                     ptr_operator new_declarator                             { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+    |                               direct_new_declarator
+direct_new_declarator:              '[' expression ']'                                      { $$ = YACC_ABSTRACT_ARRAY_EXPRESSION($2); }
+    |                               direct_new_declarator '[' constant_expression ']'       { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
+new_initializer.opt:                /* empty */                                             { $$ = YACC_EXPRESSIONS(0, 0); }
+    |                               '(' expression_list.opt ')'                             { $$ = $2; }
+
+/*  cast-expression is generalised to support a [] as well as a () prefix. This covers the omission of DELETE[] which when
+ *  followed by a parenthesised expression was ambiguous. It also covers the gcc indexed array initialisation for free.
+ */
+cast_expression:                    unary_expression
+    |                               abstract_expression cast_expression                         { $$ = YACC_CAST_EXPRESSION($1, $2); }
+/*  |                               '(' type_id ')' cast_expression                             -- covered by abstract_expression */
+
+pm_expression:                      cast_expression
+    |                               pm_expression DOT_STAR cast_expression                      { $$ = YACC_DOT_STAR_EXPRESSION($1, $3); }
+    |                               pm_expression ARROW_STAR cast_expression                    { $$ = YACC_ARROW_STAR_EXPRESSION($1, $3); }
+multiplicative_expression:          pm_expression
+    |                               multiplicative_expression star_ptr_operator pm_expression   { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); }
+    |                               multiplicative_expression '/' pm_expression                 { $$ = YACC_DIVIDE_EXPRESSION($1, $3); }
+    |                               multiplicative_expression '%' pm_expression                 { $$ = YACC_MODULUS_EXPRESSION($1, $3); }
+additive_expression:                multiplicative_expression
+    |                               additive_expression '+' multiplicative_expression           { $$ = YACC_ADD_EXPRESSION($1, $3); }
+    |                               additive_expression '-' multiplicative_expression           { $$ = YACC_SUBTRACT_EXPRESSION($1, $3); }
+shift_expression:                   additive_expression
+    |                               shift_expression SHL additive_expression                    { $$ = YACC_SHIFT_LEFT_EXPRESSION($1, $3); }
+    |                               shift_expression SHR additive_expression                    { $$ = YACC_SHIFT_RIGHT_EXPRESSION($1, $3); }
+relational_expression:              shift_expression
+    |                               relational_expression '<' shift_expression                  { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); }
+    |                               relational_expression '>' shift_expression                  { $$ = YACC_GREATER_THAN_EXPRESSION($1, $3); }
+    |                               relational_expression LE shift_expression                   { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); }
+    |                               relational_expression GE shift_expression                   { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); }
+equality_expression:                relational_expression
+    |                               equality_expression EQ relational_expression                { $$ = YACC_EQUAL_EXPRESSION($1, $3); }
+    |                               equality_expression NE relational_expression                { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); }
+and_expression:                     equality_expression
+    |                               and_expression '&' equality_expression                      { $$ = YACC_AND_EXPRESSION($1, $3); }
+exclusive_or_expression:            and_expression
+    |                               exclusive_or_expression '^' and_expression                  { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); }
+inclusive_or_expression:            exclusive_or_expression
+    |                               inclusive_or_expression '|' exclusive_or_expression         { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); }
+logical_and_expression:             inclusive_or_expression
+    |                               logical_and_expression LOG_AND inclusive_or_expression      { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); }
+logical_or_expression:              logical_and_expression
+    |                               logical_or_expression LOG_OR logical_and_expression         { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); }
+conditional_expression:             logical_or_expression
+    |                               logical_or_expression '?' expression ':' assignment_expression
+                                                                                                { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
+
+/*  assignment-expression is generalised to cover the simple assignment of a braced initializer in order to contribute to the
+ *  coverage of parameter-declaration and init-declaration.
+ */
+assignment_expression:              conditional_expression
+    |                               logical_or_expression assignment_operator assignment_expression { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+    |                               logical_or_expression '=' braced_initializer                    { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+    |                               throw_expression
+assignment_operator:                '=' | ASS_ADD | ASS_AND | ASS_DIV | ASS_MOD | ASS_MUL | ASS_OR | ASS_SHL | ASS_SHR | ASS_SUB | ASS_XOR
+
+/*  expression is widely used and usually single-element, so the reductions are arranged so that a
+ *  single-element expression is returned as is. Multi-element expressions are parsed as a list that
+ *  may then behave polymorphically as an element or be compacted to an element. */ 
+expression.opt:                     /* empty */                                                 { $$ = YACC_EXPRESSION(0); }
+    |                               expression
+expression:                         assignment_expression
+    |                               expression_list ',' assignment_expression                   { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); }
+constant_expression:                conditional_expression
+
+/*  The grammar is repeated for when the parser stack knows that the next > must end a template.
+ */
+templated_relational_expression:    shift_expression
+    |                               templated_relational_expression '<' shift_expression        { $$ = YACC_LESS_THAN_EXPRESSION($1, $3); }
+    |                               templated_relational_expression LE shift_expression         { $$ = YACC_LESS_EQUAL_EXPRESSION($1, $3); }
+    |                               templated_relational_expression GE shift_expression         { $$ = YACC_GREATER_EQUAL_EXPRESSION($1, $3); }
+templated_equality_expression:      templated_relational_expression
+    |                               templated_equality_expression EQ templated_relational_expression    { $$ = YACC_EQUAL_EXPRESSION($1, $3); }
+    |                               templated_equality_expression NE templated_relational_expression    { $$ = YACC_NOT_EQUAL_EXPRESSION($1, $3); }
+templated_and_expression:           templated_equality_expression
+    |                               templated_and_expression '&' templated_equality_expression  { $$ = YACC_AND_EXPRESSION($1, $3); }
+templated_exclusive_or_expression:  templated_and_expression
+    |                               templated_exclusive_or_expression '^' templated_and_expression
+                                                                                                { $$ = YACC_EXCLUSIVE_OR_EXPRESSION($1, $3); }
+templated_inclusive_or_expression:  templated_exclusive_or_expression
+    |                               templated_inclusive_or_expression '|' templated_exclusive_or_expression
+                                                                                                { $$ = YACC_INCLUSIVE_OR_EXPRESSION($1, $3); }
+templated_logical_and_expression:   templated_inclusive_or_expression
+    |                               templated_logical_and_expression LOG_AND templated_inclusive_or_expression
+                                                                                                { $$ = YACC_LOGICAL_AND_EXPRESSION($1, $3); }
+templated_logical_or_expression:    templated_logical_and_expression
+    |                               templated_logical_or_expression LOG_OR templated_logical_and_expression
+                                                                                                { $$ = YACC_LOGICAL_OR_EXPRESSION($1, $3); }
+templated_conditional_expression:   templated_logical_or_expression
+    |                               templated_logical_or_expression '?' templated_expression ':' templated_assignment_expression
+                                                                                                { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
+templated_assignment_expression:    templated_conditional_expression
+    |                               templated_logical_or_expression assignment_operator templated_assignment_expression
+                                                                                                { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+    |                               templated_throw_expression
+templated_expression:               templated_assignment_expression
+    |                               templated_expression_list ',' templated_assignment_expression
+                                                                                                { $$ = YACC_EXPRESSION(YACC_EXPRESSIONS($1, $3)); }
+templated_expression_list:          templated_assignment_expression                             { $$ = YACC_EXPRESSIONS(0, $1); }
+    |                               templated_expression_list ',' templated_assignment_expression    { $$ = YACC_EXPRESSIONS($1, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.5 Statements
+ *---------------------------------------------------------------------------------------------------
+ *  Parsing statements is easy once simple_declaration has been generalised to cover expression_statement.
+ */
+looping_statement:                  start_search looped_statement                               { $$ = YACC_LINED_STATEMENT($2, $1); end_search($$); }
+looped_statement:                   statement
+    |                               advance_search '+' looped_statement                         { $$ = $3; }
+    |                               advance_search '-'                                          { $$ = 0; }
+statement:                          control_statement
+/*  |                               expression_statement                                        -- covered by declaration_statement */
+    |                               compound_statement
+    |                               declaration_statement
+    |                               try_block                                                   { $$ = YACC_TRY_BLOCK_STATEMENT($1); }
+control_statement:                  labeled_statement
+    |                               selection_statement
+    |                               iteration_statement
+    |                               jump_statement
+labeled_statement:                  identifier_word ':' looping_statement                       { $$ = YACC_LABEL_STATEMENT($1, $3); }
+    |                               CASE constant_expression ':' looping_statement              { $$ = YACC_CASE_STATEMENT($2, $4); }
+    |                               DEFAULT ':' looping_statement                               { $$ = YACC_DEFAULT_STATEMENT($3); }
+/*expression_statement:             expression.opt ';'                                          -- covered by declaration_statement */
+compound_statement:                 '{' statement_seq.opt '}'                                   { $$ = YACC_COMPOUND_STATEMENT($2); }
+    |                               '{' statement_seq.opt looping_statement '#' bang error '}'  { $$ = $2; YACC_UNBANG($5, "Bad statement-seq."); }
+statement_seq.opt:                  /* empty */                                                 { $$ = YACC_STATEMENTS(0, 0); }
+    |                               statement_seq.opt looping_statement                         { $$ = YACC_STATEMENTS($1, YACC_COMPILE_STATEMENT($2)); }
+    |                               statement_seq.opt looping_statement '#' bang error ';'      { $$ = $1; YACC_UNBANG($4, "Bad statement."); }
+/*
+ *  The dangling else conflict is resolved to the innermost if.
+ */
+selection_statement:                IF '(' condition ')' looping_statement    %prec SHIFT_THERE { $$ = YACC_IF_STATEMENT($3, $5, 0); }
+    |                               IF '(' condition ')' looping_statement ELSE looping_statement { $$ = YACC_IF_STATEMENT($3, $5, $7); }
+    |                               SWITCH '(' condition ')' looping_statement                  { $$ = YACC_SWITCH_STATEMENT($3, $5); }
+condition.opt:                      /* empty */                                                 { $$ = YACC_CONDITION(0); }
+    |                               condition
+condition:                          parameter_declaration_list                                  { $$ = YACC_CONDITION($1); }
+/*  |                               expression                                                  -- covered by parameter_declaration_list */
+/*  |                               type_specifier_seq declarator '=' assignment_expression     -- covered by parameter_declaration_list */
+iteration_statement:                WHILE '(' condition ')' looping_statement                   { $$ = YACC_WHILE_STATEMENT($3, $5); }
+    |                               DO looping_statement WHILE '(' expression ')' ';'           { $$ = YACC_DO_WHILE_STATEMENT($2, $5); }
+    |                               FOR '(' for_init_statement condition.opt ';' expression.opt ')' looping_statement
+                                                                                                { $$ = YACC_FOR_STATEMENT($3, $4, $6, $8); }
+for_init_statement:                 simple_declaration
+/*  |                               expression_statement                                        -- covered by simple_declaration */
+jump_statement:                     BREAK ';'                                                   { $$ = YACC_BREAK_STATEMENT(); }
+    |                               CONTINUE ';'                                                { $$ = YACC_CONTINUE_STATEMENT(); }
+    |                               RETURN expression.opt ';'                                   { $$ = YACC_RETURN_STATEMENT($2); }
+    |                               GOTO identifier ';'                                         { $$ = YACC_GOTO_STATEMENT($2); }
+declaration_statement:              block_declaration                                           { $$ = YACC_DECLARATION_STATEMENT($1); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.6 Declarations
+ *---------------------------------------------------------------------------------------------------*/
+compound_declaration:               '{' nest declaration_seq.opt '}'                            { $$ = $3; unnest($2); }
+    |                               '{' nest declaration_seq.opt util looping_declaration '#' bang error '}'
+                                                                                                { $$ = $3; unnest($2); YACC_UNBANG($7, "Bad declaration-seq."); }
+declaration_seq.opt:                /* empty */                                                 { $$ = YACC_DECLARATIONS(0, 0); }
+    |                               declaration_seq.opt util looping_declaration                { $$ = YACC_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); }
+    |                               declaration_seq.opt util looping_declaration '#' bang error ';' { $$ = $1; YACC_UNBANG($5, "Bad declaration."); }
+looping_declaration:                start_search1 looped_declaration                            { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); }
+looped_declaration:                 declaration
+    |                               advance_search '+' looped_declaration                       { $$ = $3; }
+    |                               advance_search '-'                                          { $$ = 0; }
+declaration:                        block_declaration
+    |                               function_definition                                         { $$ = YACC_SIMPLE_DECLARATION($1); }
+    |                               template_declaration
+/*  |                               explicit_instantiation                                      -- covered by relevant declarations */
+    |                               explicit_specialization
+    |                               specialised_declaration
+specialised_declaration:            linkage_specification                                       { $$ = YACC_LINKAGE_SPECIFICATION($1); }
+    |                               namespace_definition                                        { $$ = YACC_NAMESPACE_DECLARATION($1); }
+    |                               TEMPLATE specialised_declaration                            { $$ = YACC_SET_TEMPLATE_DECLARATION($2); }
+block_declaration:                  simple_declaration                                          { $$ = YACC_SIMPLE_DECLARATION($1); }
+    |                               specialised_block_declaration
+specialised_block_declaration:      asm_definition
+    |                               namespace_alias_definition
+    |                               using_declaration
+    |                               using_directive
+    |                               TEMPLATE specialised_block_declaration                      { $$ = YACC_SET_TEMPLATE_DECLARATION($2); }
+simple_declaration:                 ';'                                                         { $$ = YACC_EXPRESSION(0); }
+    |                               init_declaration ';'
+    |                               init_declarations ';'                                       { $$ = $1; }
+    |                               decl_specifier_prefix simple_declaration                    { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+
+/*  A decl-specifier following a ptr_operator provokes a shift-reduce conflict for
+ *      * const name
+ *  which is resolved in favour of the pointer, and implemented by providing versions
+ *  of decl-specifier guaranteed not to start with a cv_qualifier.
+ *
+ *  decl-specifiers are implemented type-centrically. That is the semantic constraint
+ *  that there must be a type is exploited to impose structure, but actually eliminate
+ *  very little syntax. built-in types are multi-name and so need a different policy.
+ *
+ *  non-type decl-specifiers are bound to the left-most type in a decl-specifier-seq,
+ *  by parsing from the right and attaching suffixes to the right-hand type. Finally
+ *  residual prefixes attach to the left.                
+ */
+suffix_built_in_decl_specifier.raw: built_in_type_specifier                                     { $$ = $1; }
+    |                               suffix_built_in_decl_specifier.raw built_in_type_specifier  { $$ = YACC_BUILT_IN_NAME($1, $2); }
+    |                               suffix_built_in_decl_specifier.raw decl_specifier_suffix    { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); }
+suffix_built_in_decl_specifier:     suffix_built_in_decl_specifier.raw                          { $$ = $1; }
+    |                               TEMPLATE suffix_built_in_decl_specifier                     { $$ = YACC_SET_TEMPLATE_NAME($2); }
+suffix_named_decl_specifier:        scoped_id                                                   { $$ = $1; }
+    |                               elaborate_type_specifier                                    { $$ = $1; }
+    |                               suffix_named_decl_specifier decl_specifier_suffix           { $$ = YACC_DECL_SPECIFIER_NAME($1, $2); }
+suffix_named_decl_specifier.bi:     suffix_named_decl_specifier                                 { $$ = YACC_NAME_EXPRESSION($1); }
+    |                               suffix_named_decl_specifier suffix_built_in_decl_specifier.raw  { $$ = YACC_TYPED_NAME($1, $2); }
+suffix_named_decl_specifiers:       suffix_named_decl_specifier.bi
+    |                               suffix_named_decl_specifiers suffix_named_decl_specifier.bi { $$ = YACC_TYPED_NAME($1, $2); }
+suffix_named_decl_specifiers.sf:    scoped_special_function_id          /* operators etc */     { $$ = YACC_NAME_EXPRESSION($1); }
+    |                               suffix_named_decl_specifiers
+    |                               suffix_named_decl_specifiers scoped_special_function_id     { $$ = YACC_TYPED_NAME($1, $2); }
+suffix_decl_specified_ids:          suffix_built_in_decl_specifier
+    |                               suffix_built_in_decl_specifier suffix_named_decl_specifiers.sf { $$ = YACC_TYPED_NAME($1, $2); }
+    |                               suffix_named_decl_specifiers.sf
+suffix_decl_specified_scope:        suffix_named_decl_specifiers SCOPE
+    |                               suffix_built_in_decl_specifier suffix_named_decl_specifiers SCOPE { $$ = YACC_TYPED_NAME($1, $2); }
+    |                               suffix_built_in_decl_specifier SCOPE                        { $$ = YACC_NAME_EXPRESSION($1); }
+
+decl_specifier_affix:               storage_class_specifier
+    |                               function_specifier
+    |                               FRIEND                                                          
+    |                               TYPEDEF
+    |                               cv_qualifier                                                { $$ = $1; }
+
+decl_specifier_suffix:              decl_specifier_affix
+
+decl_specifier_prefix:              decl_specifier_affix
+    |                               TEMPLATE decl_specifier_prefix                              { $$ = YACC_SET_TEMPLATE_DECL_SPECIFIER($2); }
+
+storage_class_specifier:            REGISTER | STATIC | MUTABLE
+    |                               EXTERN                  %prec SHIFT_THERE                   /* Prefer linkage specification */
+    |                               AUTO
+
+function_specifier:                 EXPLICIT
+    |                               INLINE
+    |                               VIRTUAL
+
+type_specifier:                     simple_type_specifier
+    |                               elaborate_type_specifier
+    |                               cv_qualifier                                                { $$ = YACC_CV_DECL_SPECIFIER($1); }
+
+elaborate_type_specifier:           class_specifier
+    |                               enum_specifier
+    |                               elaborated_type_specifier
+    |                               TEMPLATE elaborate_type_specifier                           { $$ = YACC_SET_TEMPLATE_ID($2); }
+simple_type_specifier:              scoped_id
+    |                               built_in_type_specifier                                     { $$ = YACC_BUILT_IN_ID_ID($1); }
+built_in_type_specifier:            CHAR | WCHAR_T | BOOL | SHORT | INT | LONG | SIGNED | UNSIGNED | FLOAT | DOUBLE | VOID
+
+/*
+ *  The over-general use of declaration_expression to cover decl-specifier-seq.opt declarator in a function-definition means that
+ *      class X {};
+ *  could be a function-definition or a class-specifier.
+ *      enum X {};
+ *  could be a function-definition or an enum-specifier.
+ *  The function-definition is not syntactically valid so resolving the false conflict in favour of the
+ *  elaborated_type_specifier is correct.
+ */
+elaborated_type_specifier:          elaborated_class_specifier
+    |                               elaborated_enum_specifier
+    |                               TYPENAME scoped_id                                          { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
+
+elaborated_enum_specifier:          ENUM scoped_id               %prec SHIFT_THERE              { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
+enum_specifier:                     ENUM scoped_id enumerator_clause                            { $$ = YACC_ENUM_SPECIFIER_ID($2, $3); }
+    |                               ENUM enumerator_clause                                      { $$ = YACC_ENUM_SPECIFIER_ID(0, $2); }
+enumerator_clause:                  '{' enumerator_list_ecarb                                   { $$ = YACC_ENUMERATORS(0, 0); }
+    |                               '{' enumerator_list enumerator_list_ecarb                   { $$ = $2; }
+    |                               '{' enumerator_list ',' enumerator_definition_ecarb         { $$ = $2; }
+enumerator_list_ecarb:              '}'                                                         { }
+    |                               bang error '}'                                              { YACC_UNBANG($1, "Bad enumerator-list."); }
+enumerator_definition_ecarb:        '}'                                                         { }
+    |                               bang error '}'                                              { YACC_UNBANG($1, "Bad enumerator-definition."); }
+enumerator_definition_filler:       /* empty */
+    |                               bang error ','                                              { YACC_UNBANG($1, "Bad enumerator-definition."); }
+enumerator_list_head:               enumerator_definition_filler                                { $$ = YACC_ENUMERATORS(0, 0); }
+    |                               enumerator_list ',' enumerator_definition_filler
+enumerator_list:                    enumerator_list_head enumerator_definition                  { $$ = YACC_ENUMERATORS($1, $2); }
+enumerator_definition:              enumerator                                                  { $$ = YACC_ENUMERATOR($1, 0); }
+    |                               enumerator '=' constant_expression                          { $$ = YACC_ENUMERATOR($1, $3); }
+enumerator:                         identifier
+
+namespace_definition:               NAMESPACE scoped_id compound_declaration                    { $$ = YACC_NAMESPACE_DEFINITION($2, $3); }
+    |                               NAMESPACE compound_declaration                              { $$ = YACC_NAMESPACE_DEFINITION(0, $2); }
+namespace_alias_definition:         NAMESPACE scoped_id '=' scoped_id ';'                       { $$ = YACC_NAMESPACE_ALIAS_DEFINITION($2, $4); }
+
+using_declaration:                  USING declarator_id ';'                                     { $$ = YACC_USING_DECLARATION(false, $2); }
+    |                               USING TYPENAME declarator_id ';'                            { $$ = YACC_USING_DECLARATION(true, $3); }
+
+using_directive:                    USING NAMESPACE scoped_id ';'                               { $$ = YACC_USING_DIRECTIVE($3); }
+asm_definition:                     ASM '(' string ')' ';'                                      { $$ = YACC_ASM_DEFINITION($3); }
+linkage_specification:              EXTERN string looping_declaration                           { $$ = YACC_LINKAGE_SPECIFIER($2, $3); }
+    |                               EXTERN string compound_declaration                          { $$ = YACC_LINKAGE_SPECIFIER($2, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.7 Declarators
+ *---------------------------------------------------------------------------------------------------*/
+/*init-declarator is named init_declaration to reflect the embedded decl-specifier-seq.opt*/
+init_declarations:                  assignment_expression ',' init_declaration                  { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); }
+    |                               init_declarations ',' init_declaration                      { $$ = YACC_EXPRESSIONS($1, $3); }
+init_declaration:                   assignment_expression
+/*  |                               assignment_expression '=' initializer_clause                -- covered by assignment_expression */
+/*  |                               assignment_expression '(' expression_list ')'               -- covered by another set of call arguments */
+
+/*declarator:                                                                                   -- covered by assignment_expression */
+/*direct_declarator:                                                                            -- covered by postfix_expression */
+
+star_ptr_operator:                  '*'                                                         { $$ = YACC_POINTER_DECLARATOR(); }
+    |                               star_ptr_operator cv_qualifier                              { $$ = YACC_CV_DECLARATOR($1, $2); }
+nested_ptr_operator:                star_ptr_operator                                           { $$ = $1; }
+    |                               id_scope nested_ptr_operator                                { $$ = YACC_NESTED_DECLARATOR($1, $2); }
+ptr_operator:                       '&'                                                         { $$ = YACC_REFERENCE_DECLARATOR(); }
+    |                               nested_ptr_operator                                         { $$ = $1; }
+    |                               global_scope nested_ptr_operator                            { $$ = YACC_GLOBAL_DECLARATOR($1, $2); }
+ptr_operator_seq:                   ptr_operator                                                { $$ = YACC_POINTER_EXPRESSION($1, YACC_EPSILON()); }
+    |                               ptr_operator ptr_operator_seq                               { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+/* Independently coded to localise the shift-reduce conflict: sharing just needs another %prec */
+ptr_operator_seq.opt:               /* empty */                         %prec SHIFT_THERE       /* Maximise type length */ { $$ = YACC_EXPRESSION(0); }
+    |                               ptr_operator ptr_operator_seq.opt                           { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+
+cv_qualifier_seq.opt:               /* empty */                                                 { $$ = YACC_CV_QUALIFIERS(0, 0); }
+    |                               cv_qualifier_seq.opt cv_qualifier                           { $$ = YACC_CV_QUALIFIERS($1, $2); }
+cv_qualifier:                       CONST | VOLATILE /* | CvQualifier */
+
+/*type_id                                                                                       -- also covered by parameter declaration */
+type_id:                            type_specifier abstract_declarator.opt                      { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+    |                               type_specifier type_id                                      { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+
+/*abstract_declarator:                                                                          -- also covered by parameter declaration */
+abstract_declarator.opt:            /* empty */                                                 { $$ = YACC_EPSILON(); }
+    |                               ptr_operator abstract_declarator.opt                        { $$ = YACC_POINTER_EXPRESSION($1, $2); }
+    |                               direct_abstract_declarator
+direct_abstract_declarator.opt:     /* empty */                                                 { $$ = YACC_EPSILON(); }
+    |                               direct_abstract_declarator
+direct_abstract_declarator:         direct_abstract_declarator.opt parenthesis_clause           { $$ = YACC_CALL_EXPRESSION($1, $2); }
+    |                               direct_abstract_declarator.opt '[' ']'                      { $$ = YACC_ARRAY_EXPRESSION($1, 0); }
+    |                               direct_abstract_declarator.opt '[' constant_expression ']'  { $$ = YACC_ARRAY_EXPRESSION($1, $3); }
+/*  |                               '(' abstract_declarator ')'                                 -- covered by parenthesis_clause */
+
+parenthesis_clause:                 parameters_clause cv_qualifier_seq.opt                      { $$ = YACC_PARENTHESISED($1, $2, 0); }
+    |                               parameters_clause cv_qualifier_seq.opt exception_specification  { $$ = YACC_PARENTHESISED($1, $2, $3); }
+parameters_clause:                  '(' parameter_declaration_clause ')'                        { $$ = $2; }
+/* parameter_declaration_clause also covers init_declaration, type_id, declarator and abstract_declarator. */
+parameter_declaration_clause:       /* empty */                                                 { $$ = YACC_PARAMETERS(0, 0); }
+    |                               parameter_declaration_list
+    |                               parameter_declaration_list ELLIPSIS                         { $$ = YACC_PARAMETERS($1, YACC_ELLIPSIS_EXPRESSION()); }
+parameter_declaration_list:         parameter_declaration                                       { $$ = YACC_PARAMETERS(0, $1); }
+    |                               parameter_declaration_list ',' parameter_declaration        { $$ = YACC_PARAMETERS($1, $3); }
+
+/* A typed abstract qualifier such as
+ *      Class * ...
+ * looks like a multiply, so pointers are parsed as their binary operation equivalents that
+ * ultimately terminate with a degenerate right hand term.
+ */
+abstract_pointer_declaration:       ptr_operator_seq
+    |                               multiplicative_expression star_ptr_operator ptr_operator_seq.opt { $$ = YACC_MULTIPLY_EXPRESSION($1, $2, $3); }
+abstract_parameter_declaration:     abstract_pointer_declaration
+    |                               and_expression '&'                                          { $$ = YACC_AND_EXPRESSION($1, YACC_EPSILON()); }
+    |                               and_expression '&' abstract_pointer_declaration             { $$ = YACC_AND_EXPRESSION($1, $3); }
+special_parameter_declaration:      abstract_parameter_declaration
+    |                               abstract_parameter_declaration '=' assignment_expression    { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+    |                               ELLIPSIS                                                    { $$ = YACC_ELLIPSIS_EXPRESSION(); }
+parameter_declaration:              assignment_expression                                       { $$ = YACC_EXPRESSION_PARAMETER($1); }
+    |                               special_parameter_declaration                               { $$ = YACC_EXPRESSION_PARAMETER($1); }
+    |                               decl_specifier_prefix parameter_declaration                 { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); }
+
+/*  The grammar is repeated for use within template <>
+ */
+templated_parameter_declaration:    templated_assignment_expression                             { $$ = YACC_EXPRESSION_PARAMETER($1); }
+    |                               templated_abstract_declaration                              { $$ = YACC_EXPRESSION_PARAMETER($1); }
+    |                               templated_abstract_declaration '=' templated_assignment_expression
+                                                    { $$ = YACC_EXPRESSION_PARAMETER(YACC_ASSIGNMENT_EXPRESSION($1, $2, $3)); }
+    |                               decl_specifier_prefix templated_parameter_declaration       { $$ = YACC_DECL_SPECIFIER_PARAMETER($2, $1); }
+templated_abstract_declaration:     abstract_pointer_declaration
+    |                               templated_and_expression '&'                                { $$ = YACC_AND_EXPRESSION($1, 0); }
+    |                               templated_and_expression '&' abstract_pointer_declaration   { $$ = YACC_AND_EXPRESSION($1, $3); }
+
+/*  function_definition includes constructor, destructor, implicit int definitions too.
+ *  A local destructor is successfully parsed as a function-declaration but the ~ was treated as a unary operator.
+ *  constructor_head is the prefix ambiguity between a constructor and a member-init-list starting with a bit-field.
+ */
+function_definition:        ctor_definition
+    |                       func_definition
+func_definition:            assignment_expression function_try_block                    { $$ = YACC_FUNCTION_DEFINITION($1, $2); }
+    |                       assignment_expression function_body                         { $$ = YACC_FUNCTION_DEFINITION($1, $2); }
+    |                       decl_specifier_prefix func_definition                       { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+ctor_definition:            constructor_head function_try_block                         { $$ = YACC_CTOR_DEFINITION($1, $2); }
+    |                       constructor_head function_body                              { $$ = YACC_CTOR_DEFINITION($1, $2); }
+    |                       decl_specifier_prefix ctor_definition                       { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+constructor_head:           bit_field_init_declaration                                  { $$ = YACC_EXPRESSIONS(0, $1); }
+    |                       constructor_head ',' assignment_expression                  { $$ = YACC_EXPRESSIONS($1, $3); }
+function_try_block:         TRY function_block handler_seq                              { $$ = YACC_TRY_FUNCTION_BLOCK($2, $3); }
+function_block:             ctor_initializer.opt function_body                          { $$ = YACC_CTOR_FUNCTION_BLOCK($2, $1); }
+function_body:              compound_statement                                          { $$ = YACC_FUNCTION_BLOCK($1); }
+
+/*  An = initializer looks like an extended assignment_expression.
+ *  An () initializer looks like a function call.
+ *  initializer is therefore flattened into its generalised customers.
+ *initializer:              '=' initializer_clause                                      -- flattened into caller
+ *  |                       '(' expression_list ')'                                     -- flattened into caller */
+initializer_clause:         assignment_expression                                       { $$ = YACC_INITIALIZER_EXPRESSION_CLAUSE($1); }
+    |                       braced_initializer
+braced_initializer:         '{' initializer_list '}'                                    { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); }
+    |                       '{' initializer_list ',' '}'                                { $$ = YACC_INITIALIZER_LIST_CLAUSE($2); }
+    |                       '{' '}'                                                     { $$ = YACC_INITIALIZER_LIST_CLAUSE(0); }
+    |                       '{' looping_initializer_clause '#' bang error '}'           { $$ = 0; YACC_UNBANG($4, "Bad initializer_clause."); }
+    |                       '{' initializer_list ',' looping_initializer_clause '#' bang error '}'
+                                                                                        { $$ = $2; YACC_UNBANG($6, "Bad initializer_clause."); }
+initializer_list:           looping_initializer_clause                                  { $$ = YACC_INITIALIZER_CLAUSES(0, $1); }
+    |                       initializer_list ',' looping_initializer_clause             { $$ = YACC_INITIALIZER_CLAUSES($1, $3); }
+looping_initializer_clause: start_search looped_initializer_clause                      { $$ = $2; end_search($$); }
+looped_initializer_clause:  initializer_clause
+    |                       advance_search '+' looped_initializer_clause                { $$ = $3; }
+    |                       advance_search '-'                                          { $$ = 0; }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.8 Classes
+ *---------------------------------------------------------------------------------------------------
+ *
+ *  An anonymous bit-field declaration may look very like inheritance:
+ *      class A : B = 3;
+ *      class A : B ;
+ *  The two usages are too distant to try to create and enforce a common prefix so we have to resort to
+ *  a parser hack by backtracking. Inheritance is much the most likely so we mark the input stream context
+ *  and try to parse a base-clause. If we successfully reach a { the base-clause is ok and inheritance was
+ *  the correct choice so we unmark and continue. If we fail to find the { an error token causes back-tracking
+ *  to the alternative parse in elaborated_class_specifier which regenerates the : and declares unconditional success.
+ */
+colon_mark:                 ':'                                                         { $$ = mark(); }
+elaborated_class_specifier: class_key scoped_id                    %prec SHIFT_THERE    { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); }
+    |                       class_key scoped_id colon_mark error                        { $$ = YACC_ELABORATED_TYPE_SPECIFIER($1, $2); rewind_colon($3, $$); }
+class_specifier_head:       class_key scoped_id colon_mark base_specifier_list '{'      { unmark($4); $$ = YACC_CLASS_SPECIFIER_ID($1, $2, $4); }
+    |                       class_key ':' base_specifier_list '{'                       { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, $3); }
+    |                       class_key scoped_id '{'                                     { $$ = YACC_CLASS_SPECIFIER_ID($1, $2, 0); }
+    |                       class_key '{'                                               { $$ = YACC_CLASS_SPECIFIER_ID($1, 0, 0); }
+class_key:                  CLASS | STRUCT | UNION
+class_specifier:            class_specifier_head member_specification.opt '}'           { $$ = YACC_CLASS_MEMBERS($1, $2); }
+    |                       class_specifier_head member_specification.opt util looping_member_declaration '#' bang error '}'
+                                            { $$ = YACC_CLASS_MEMBERS($1, $2); YACC_UNBANG($6, "Bad member_specification.opt."); }
+member_specification.opt:   /* empty */                                                 { $$ = YACC_MEMBER_DECLARATIONS(0, 0); }
+    |                       member_specification.opt util looping_member_declaration    { $$ = YACC_MEMBER_DECLARATIONS($1, YACC_COMPILE_DECLARATION($2, $3)); }
+    |                       member_specification.opt util looping_member_declaration '#' bang error ';'
+                                                                                                { $$ = $1; YACC_UNBANG($5, "Bad member-declaration."); }
+looping_member_declaration: start_search looped_member_declaration                      { $$ = YACC_LINED_DECLARATION($2, $1); end_search($$); }
+looped_member_declaration:  member_declaration
+    |                       advance_search '+' looped_member_declaration                { $$ = $3; }
+    |                       advance_search '-'                                          { $$ = 0; }
+member_declaration:         accessibility_specifier
+    |                       simple_member_declaration                                   { $$ = YACC_SIMPLE_DECLARATION($1); }
+    |                       function_definition                                         { $$ = YACC_SIMPLE_DECLARATION($1); }
+/*  |                       function_definition ';'                                     -- trailing ; covered by null declaration */
+/*  |                       qualified_id ';'                                            -- covered by simple_member_declaration */
+    |                       using_declaration
+    |                       template_declaration
+
+/*  The generality of constructor names (there need be no parenthesised argument list) means that that
+ *          name : f(g), h(i)
+ *  could be the start of a constructor or the start of an anonymous bit-field. An ambiguity is avoided by
+ *  parsing the ctor-initializer of a function_definition as a bit-field.
+ */
+simple_member_declaration:  ';'                                                         { $$ = YACC_EXPRESSION(0); }
+    |                       assignment_expression ';'
+    |                       constructor_head ';'                                        { $$ = $1; }
+    |                       member_init_declarations ';'                                { $$ = $1; }
+    |                       decl_specifier_prefix simple_member_declaration             { $$ = YACC_DECL_SPECIFIER_EXPRESSION($2, $1); }
+member_init_declarations:   assignment_expression ',' member_init_declaration           { $$ = YACC_EXPRESSIONS(YACC_EXPRESSIONS(0, $1), $3); }
+    |                       constructor_head ',' bit_field_init_declaration             { $$ = YACC_EXPRESSIONS($1, $3); }
+    |                       member_init_declarations ',' member_init_declaration        { $$ = YACC_EXPRESSIONS($1, $3); }
+member_init_declaration:    assignment_expression
+/*  |                       assignment_expression '=' initializer_clause                -- covered by assignment_expression */
+/*  |                       assignment_expression '(' expression_list ')'               -- covered by another set of call arguments */
+    |                       bit_field_init_declaration
+accessibility_specifier:    access_specifier ':'                                        { $$ = YACC_ACCESSIBILITY_SPECIFIER($1); }
+bit_field_declaration:      assignment_expression ':' bit_field_width                   { $$ = YACC_BIT_FIELD_EXPRESSION($1, $3); }
+    |                       ':' bit_field_width                                         { $$ = YACC_BIT_FIELD_EXPRESSION(0, $2); }
+bit_field_width:            logical_or_expression
+/*  |                       logical_or_expression '?' expression ':' assignment_expression  -- has SR conflict w.r.t later = */
+    |                       logical_or_expression '?' bit_field_width ':' bit_field_width { $$ = YACC_CONDITIONAL_EXPRESSION($1, $3, $5); }
+bit_field_init_declaration: bit_field_declaration
+    |                       bit_field_declaration '=' initializer_clause                { $$ = YACC_ASSIGNMENT_EXPRESSION($1, $2, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.9 Derived classes
+ *---------------------------------------------------------------------------------------------------*/
+/*base_clause:              ':' base_specifier_list                                     -- flattened */
+base_specifier_list:        base_specifier                                              { $$ = YACC_BASE_SPECIFIERS(0, $1); }
+    |                       base_specifier_list ',' base_specifier                      { $$ = YACC_BASE_SPECIFIERS($1, $3); }
+base_specifier:             scoped_id                                                   { $$ = YACC_BASE_SPECIFIER($1); }
+    |                       access_specifier base_specifier                             { $$ = YACC_ACCESS_BASE_SPECIFIER($2, $1); }
+    |                       VIRTUAL base_specifier                                      { $$ = YACC_VIRTUAL_BASE_SPECIFIER($2); }
+access_specifier:           PRIVATE | PROTECTED | PUBLIC
+
+/*---------------------------------------------------------------------------------------------------
+ * A.10 Special member functions
+ *---------------------------------------------------------------------------------------------------*/
+conversion_function_id:     OPERATOR conversion_type_id                                 { $$ = YACC_CONVERSION_FUNCTION_ID($2); }
+conversion_type_id:         type_specifier ptr_operator_seq.opt                         { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+    |                       type_specifier conversion_type_id                           { $$ = YACC_TYPED_EXPRESSION($1, $2); }
+/*
+ *  Ctor-initialisers can look like a bit field declaration, given the generalisation of names:
+ *      Class(Type) : m1(1), m2(2) {}
+ *      NonClass(bit_field) : int(2), second_variable, ...
+ *  The grammar below is used within a function_try_block or function_definition.
+ *  See simple_member_declaration for use in normal member function_definition.
+ */
+ctor_initializer.opt:       /* empty */                                                 { $$ = YACC_MEM_INITIALIZERS(0, 0); }
+    |                       ctor_initializer
+ctor_initializer:           ':' mem_initializer_list                                    { $$ = $2; }
+    |                       ':' mem_initializer_list bang error                         { $$ = $2; YACC_UNBANG($3, "Bad ctor-initializer."); }
+mem_initializer_list:       mem_initializer                                             { $$ = YACC_MEM_INITIALIZERS(0, $1); }
+    |                       mem_initializer_list_head mem_initializer                   { $$ = YACC_MEM_INITIALIZERS($1, $2); }
+mem_initializer_list_head:  mem_initializer_list ','
+    |                       mem_initializer_list bang error ','                         { YACC_UNBANG($2, "Bad mem-initializer."); }
+mem_initializer:            mem_initializer_id '(' expression_list.opt ')'              { $$ = YACC_MEM_INITIALIZER($1, $3); }
+mem_initializer_id:         scoped_id
+
+/*---------------------------------------------------------------------------------------------------
+ * A.11 Overloading
+ *---------------------------------------------------------------------------------------------------*/
+operator_function_id:       OPERATOR operator                                           { $$ = YACC_OPERATOR_FUNCTION_ID($2); }
+/*
+ *  It is not clear from the ANSI standard whether spaces are permitted in delete[]. If not then it can
+ *  be recognised and returned as DELETE_ARRAY by the lexer. Assuming spaces are permitted there is an
+ *  ambiguity created by the over generalised nature of expressions. operator new is a valid delarator-id
+ *  which we may have an undimensioned array of. Semantic rubbish, but syntactically valid. Since the
+ *  array form is covered by the declarator consideration we can exclude the operator here. The need
+ *  for a semantic rescue can be eliminated at the expense of a couple of shift-reduce conflicts by
+ *  removing the comments on the next four lines.
+ */
+operator:             /*++++*/      NEW                                                         { $$ = YACC_OPERATOR_NEW_ID(); }
+    |                 /*++++*/      DELETE                                                      { $$ = YACC_OPERATOR_DELETE_ID(); }
+/*  |                 / ---- /      NEW                 %prec SHIFT_THERE                       { $$ = YACC_OPERATOR_NEW_ID(); }
+/*  |                 / ---- /      DELETE              %prec SHIFT_THERE                       { $$ = YACC_OPERATOR_DELETE_ID(); }
+/*  |                 / ---- /      NEW '[' ']'                                                 -- Covered by array of OPERATOR NEW */
+/*  |                 / ---- /      DELETE '[' ']'                                              -- Covered by array of OPERATOR DELETE */
+    |                               '+'                                                         { $$ = YACC_OPERATOR_ADD_ID(); }
+    |                               '-'                                                         { $$ = YACC_OPERATOR_SUB_ID(); }
+    |                               '*'                                                         { $$ = YACC_OPERATOR_MUL_ID(); }
+    |                               '/'                                                         { $$ = YACC_OPERATOR_DIV_ID(); }
+    |                               '%'                                                         { $$ = YACC_OPERATOR_MOD_ID(); }
+    |                               '^'                                                         { $$ = YACC_OPERATOR_XOR_ID(); }
+    |                               '&'                                                         { $$ = YACC_OPERATOR_BIT_AND_ID(); }
+    |                               '|'                                                         { $$ = YACC_OPERATOR_BIT_OR_ID(); }
+    |                               '~'                                                         { $$ = YACC_OPERATOR_BIT_NOT_ID(); }
+    |                               '!'                                                         { $$ = YACC_OPERATOR_LOG_NOT_ID(); }
+    |                               '='                                                         { $$ = YACC_OPERATOR_ASS_ID(); }
+    |                               '<'                                                         { $$ = YACC_OPERATOR_LT_ID(); }
+    |                               '>'                                                         { $$ = YACC_OPERATOR_GT_ID(); }
+    |                               ASS_ADD                                                     { $$ = YACC_OPERATOR_ASS_ADD_ID(); }
+    |                               ASS_SUB                                                     { $$ = YACC_OPERATOR_ASS_SUB_ID(); }
+    |                               ASS_MUL                                                     { $$ = YACC_OPERATOR_ASS_MUL_ID(); }
+    |                               ASS_DIV                                                     { $$ = YACC_OPERATOR_ASS_DIV_ID(); }
+    |                               ASS_MOD                                                     { $$ = YACC_OPERATOR_ASS_MOD_ID(); }
+    |                               ASS_XOR                                                     { $$ = YACC_OPERATOR_ASS_XOR_ID(); }
+    |                               ASS_AND                                                     { $$ = YACC_OPERATOR_ASS_BIT_AND_ID(); }
+    |                               ASS_OR                                                      { $$ = YACC_OPERATOR_ASS_BIT_OR_ID(); }
+    |                               SHL                                                         { $$ = YACC_OPERATOR_SHL_ID(); }
+    |                               SHR                                                         { $$ = YACC_OPERATOR_SHR_ID(); }
+    |                               ASS_SHR                                                     { $$ = YACC_OPERATOR_ASS_SHR_ID(); }
+    |                               ASS_SHL                                                     { $$ = YACC_OPERATOR_ASS_SHL_ID(); }
+    |                               EQ                                                          { $$ = YACC_OPERATOR_EQ_ID(); }
+    |                               NE                                                          { $$ = YACC_OPERATOR_NE_ID(); }
+    |                               LE                                                          { $$ = YACC_OPERATOR_LE_ID(); }
+    |                               GE                                                          { $$ = YACC_OPERATOR_GE_ID(); }
+    |                               LOG_AND                                                     { $$ = YACC_OPERATOR_LOG_AND_ID(); }
+    |                               LOG_OR                                                      { $$ = YACC_OPERATOR_LOG_OR_ID(); }
+    |                               INC                                                         { $$ = YACC_OPERATOR_INC_ID(); }
+    |                               DEC                                                         { $$ = YACC_OPERATOR_DEC_ID(); }
+    |                               ','                                                         { $$ = YACC_OPERATOR_COMMA_ID(); }
+    |                               ARROW_STAR                                                  { $$ = YACC_OPERATOR_ARROW_STAR_ID(); }
+    |                               ARROW                                                       { $$ = YACC_OPERATOR_ARROW_ID(); }
+    |                               '(' ')'                                                     { $$ = YACC_OPERATOR_CALL_ID(); }
+    |                               '[' ']'                                                     { $$ = YACC_OPERATOR_INDEX_ID(); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.12 Templates
+ *---------------------------------------------------------------------------------------------------*/
+template_declaration:               template_parameter_clause declaration                       { $$ = YACC_TEMPLATE_DECLARATION($1, $2); }
+    |                               EXPORT template_declaration                                 { $$ = YACC_DECL_SPECIFIER_DECLARATION($2, $1); }
+template_parameter_clause:          TEMPLATE '<' template_parameter_list '>'                    { $$ = $3; }
+template_parameter_list:            template_parameter                                          { $$ = YACC_TEMPLATE_PARAMETERS(0, $1); }
+    |                               template_parameter_list ',' template_parameter              { $$ = YACC_TEMPLATE_PARAMETERS($1, $3); }
+template_parameter:                 simple_type_parameter                                       { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, 0); }
+    |                               simple_type_parameter '=' type_id                           { $$ = YACC_INIT_SIMPLE_TYPE_PARAMETER($1, $3); }
+    |                               templated_type_parameter                                    { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, 0); }
+    |                               templated_type_parameter '=' identifier                     { $$ = YACC_INIT_TEMPLATED_PARAMETER($1, $3); }
+    |                               templated_parameter_declaration                             { $$ = YACC_TEMPLATE_PARAMETER($1); }
+    |                               bang error                                                  { $$ = 0; YACC_UNBANG($1, "Bad template-parameter."); }
+simple_type_parameter:              CLASS                                                       { $$ = YACC_CLASS_TYPE_PARAMETER(0); }
+/*  |                               CLASS identifier                                            -- covered by parameter_declaration */
+    |                               TYPENAME                                                    { $$ = YACC_TYPENAME_TYPE_PARAMETER(0); }
+/*  |                               TYPENAME identifier                                         -- covered by parameter_declaration */
+templated_type_parameter:           template_parameter_clause CLASS                             { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, 0); }
+    |                               template_parameter_clause CLASS identifier                  { $$ = YACC_TEMPLATED_TYPE_PARAMETER($1, $3); }
+template_id:                        TEMPLATE identifier '<' template_argument_list '>'          { $$ = YACC_TEMPLATE_NAME($2, $4); }
+    |                               TEMPLATE template_id                                        { $$ = $2; }
+/*
+ *  template-argument is evaluated using a templated...expression so that > resolves to end of template.
+ */
+template_argument_list:             template_argument                                           { $$ = YACC_TEMPLATE_ARGUMENTS(0, $1); }
+    |                               template_argument_list ',' template_argument                { $$ = YACC_TEMPLATE_ARGUMENTS($1, $3); }
+template_argument:                  templated_parameter_declaration                             { $$ = YACC_TEMPLATE_ARGUMENT($1); }
+/*  |                               type_id                                                     -- covered by templated_parameter_declaration */
+/*  |                               template_name                                               -- covered by templated_parameter_declaration */
+/*  |                               error                                                       -- must allow template failure to re-search */
+
+/*
+ *  Generalised naming makes identifier a valid declaration, so TEMPLATE identifier is too.
+ *  The TEMPLATE prefix is therefore folded into all names, parenthesis_clause and decl_specifier_prefix.
+ */
+/*explicit_instantiation:           TEMPLATE declaration */
+explicit_specialization:            TEMPLATE '<' '>' declaration                                { $$ = YACC_EXPLICIT_SPECIALIZATION($4); }
+
+/*---------------------------------------------------------------------------------------------------
+ * A.13 Exception Handling
+ *---------------------------------------------------------------------------------------------------*/
+try_block:                          TRY compound_statement handler_seq                          { $$ = YACC_TRY_BLOCK($2, $3); }
+/*function_try_block:                                                                           -- moved near function_block */
+handler_seq:                        handler                                                     { $$ = YACC_HANDLERS(0, $1); }
+    |                               handler handler_seq                                         { $$ = YACC_HANDLERS($2, $1); }
+handler:                            CATCH '(' exception_declaration ')' compound_statement      { $$ = YACC_HANDLER($3, $5); }
+exception_declaration:              parameter_declaration                                       { $$ = YACC_EXCEPTION_DECLARATION($1); }
+/*                                  ELLIPSIS                                                    -- covered by parameter_declaration */
+throw_expression:                   THROW                                                       { $$ = YACC_THROW_EXPRESSION(0); }
+    |                               THROW assignment_expression                                 { $$ = YACC_THROW_EXPRESSION($2); }
+templated_throw_expression:         THROW                                                       { $$ = YACC_THROW_EXPRESSION(0); }
+    |                               THROW templated_assignment_expression                       { $$ = YACC_THROW_EXPRESSION($2); }
+exception_specification:            THROW '(' ')'                                               { $$ = YACC_EXCEPTION_SPECIFICATION(0); }
+    |                               THROW '(' type_id_list ')'                                  { $$ = YACC_EXCEPTION_SPECIFICATION($3); }
+type_id_list:                       type_id                                                     { $$ = YACC_EXPRESSIONS(0, $1); }
+    |                               type_id_list ',' type_id                                    { $$ = YACC_EXPRESSIONS($1, $3); }
+
+/*---------------------------------------------------------------------------------------------------
+ * Back-tracking and context support
+ *---------------------------------------------------------------------------------------------------*/
+advance_search:                     error               { yyerrok; advance_search(); } /* Rewind and queue '+' or '-' '#' */       
+bang:                               /* empty */         { $$ = YACC_BANG(); }   /* set flag to suppress "parse error" */ 
+mark:                               /* empty */         { $$ = mark(); }        /* Push lookahead and input token stream context onto a stack */
+nest:                               /* empty */         { $$ = nest(); }        /* Push a declaration nesting depth onto the parse stack */
+start_search:                       /* empty */         { $$ = YACC_LINE(); start_search(false); }    /* Create/reset binary search context */
+start_search1:                      /* empty */         { $$ = YACC_LINE(); start_search(true); }     /* Create/reset binary search context */
+util:                               /* empty */         { $$ = YACC_UTILITY_MODE(); }           /* Get current utility mode */
+/*StartTester*/
+%%
+#include <CxxParsing.cxx>
+/*EndTester*/
diff --git a/infobase/examples/cpp_grammar_code/CxxParsing.cxx b/infobase/examples/cpp_grammar_code/CxxParsing.cxx
new file mode 100644 (file)
index 0000000..19be7e8
--- /dev/null
@@ -0,0 +1,496 @@
+#include <iostream.h>
+#include <memory.h>
+#include <CxxToken.hxx>
+
+extern CxxToken *yylex_token();
+
+#ifdef BISON_PP_CLASS
+BISON_PP_CLASS theParser;
+#define PARSE_DOT theParser .
+#define PARSE_SCOPE BISON_PP_CLASS ::
+#else
+#define PARSE_DOT
+#define PARSE_SCOPE
+extern int yydebug;
+#ifndef YYEMPTY
+#define YYEMPTY -1
+#endif
+#endif
+
+class CxxSearchContext
+{
+    friend class ios;                   // Suppress GNU error message for no public constructors.
+       CxxSearchContext *_next;
+       size_t _index;
+       size_t _depth;
+       size_t _size;
+       size_t _mark;
+       bool _enable_type1;
+       size_t _line;
+       size_t _advances;
+       bool _status[32];
+private:
+       CxxSearchContext(CxxSearchContext *nextSearch)
+               : _next(nextSearch), _index(0), _depth(0), _size(sizeof(_status)/sizeof(_status[0])),
+               _mark(0), _enable_type1(false), _line(0), _advances(0) {}
+       CxxSearchContext(const CxxSearchContext&);
+       CxxSearchContext& operator=(const CxxSearchContext&);
+       bool did_search() const { return _depth > 0 ? true : false; }
+       void initialise(size_t markIndex, bool enableType1);
+       CxxSearchContext *queue(CxxSearchContext *& listHead);
+       void reset();
+public:
+       bool advance();
+       bool enable_type1() const { return _enable_type1; }
+       bool is_template();
+       size_t mark() const { return _mark; }
+private:
+       static CxxSearchContext *_current;
+       static CxxSearchContext *_free;
+public:
+       static size_t actual_searches;
+       static size_t advances[16];
+       static size_t max_search_depth;
+       static size_t nested_searches;
+       static size_t releases;
+       static size_t search_advances;
+       static size_t unnested_searches;
+public:
+       static CxxSearchContext *current() { return _current; }
+       static void release();
+       static void start(YACC_MARK_TYPE anIndex, bool enableType1);
+};
+
+size_t bang_depth = 0;
+size_t error_count = 0;
+size_t marked_error_count = 0;
+bool in_type1 = false;
+bool show_marked = false;
+
+int main(int argc, char *argv[])
+{
+       for (--argc, ++argv; argc-- > 0; ++argv)
+       {
+               char *p = *argv;
+               if (*p == '-')
+               {
+                       switch (*(p+1))
+                       {
+                               case 'c':
+                                       c_keywords = true;
+                                       break;
+                               case 't':
+                                       echo_line_text = true;
+                                       break;
+                               case 'm':
+                                       show_marked = true;
+                                       break;
+                               case 'n':
+                                       echo_line_numbers = true;
+                                       break;
+                               case 'y':
+                                       PARSE_DOT yydebug = true;
+                                       break;
+                       }
+               }
+       }
+       if (PARSE_DOT yyparse() != 0)
+               ERRMSG("Failed to parse to end of file,");
+       cout << "error_count = " << error_count
+                << ", marked_error_count = " << marked_error_count
+                << ", lines = " << line_number
+                << ", unnested_searches = " << CxxSearchContext::unnested_searches
+                << ", nested_searches = " << CxxSearchContext::nested_searches
+                << ", releases = " << CxxSearchContext::releases
+                << ", actual_searches = " << CxxSearchContext::actual_searches
+                << ", max_search_depth = " << CxxSearchContext::max_search_depth
+                << ", search_advances = " << CxxSearchContext::search_advances << endl;
+       cout << "number of occurences of each advance"; 
+       for (size_t i = 0; i < sizeof(CxxSearchContext::advances)/sizeof(CxxSearchContext::advances[0]); i++)
+               cout << ' ' << CxxSearchContext::advances[i];
+       cout << endl;   
+       return 0;
+}
+
+static CxxToken **tokenBuffer = 0;                             // Allocated buffer
+static YACC_MARK_TYPE tokenReadIndex = 0;              // Read index
+static size_t tokenSize = 0;                                   // Allocate buffer size
+static YACC_MARK_TYPE tokenWriteIndex = 0;             // Write index
+int tokenMarkDepth = 0;                                                // Write index
+static CxxToken *primed_tokens[3] = {0, 0};            // Restarting sequence
+static void token_put(CxxToken *aToken);
+
+CxxSearchContext *CxxSearchContext::_current = 0;
+CxxSearchContext *CxxSearchContext::_free = 0;
+size_t CxxSearchContext::actual_searches = 0;
+size_t CxxSearchContext::advances[16] = { 0 };
+size_t CxxSearchContext::max_search_depth = 0;
+size_t CxxSearchContext::nested_searches = 0;
+size_t CxxSearchContext::releases = 0;
+size_t CxxSearchContext::search_advances;
+size_t CxxSearchContext::unnested_searches;
+
+//
+//     Implements a binary search counter, performing the increment at the
+//     _index of othe failed search.
+//
+bool CxxSearchContext::advance()
+{
+       _advances++;
+       size_t i = _depth;
+       if (i <= 0)
+               return false;
+       while (--i > _index)
+               _status[i] = false;
+       while (true)
+       {
+               if (!_status[i])
+               {
+                       _status[i] = true;
+                       _index = 0;
+                       return true;
+               }
+               if (i <= 0)
+                       return false;
+               _status[i--] = false;
+       }
+}
+
+void CxxSearchContext::initialise(size_t markIndex, bool enableType1)
+{
+       _index = 0;
+       _depth = 0;
+       _mark = markIndex;
+    _enable_type1 = enableType1;
+       _line = line_number;
+       _advances = 0;
+}
+
+bool CxxSearchContext::is_template()
+{
+       if (_index >= _depth)
+       {
+               if (_depth >= _size)
+               {
+                       ERRMSG("Binary search depth exceeded.");
+                       return false;
+               }
+               _status[_depth++] = false;
+               if (_depth > max_search_depth)
+                       max_search_depth = _depth;
+       }
+       return _status[_index++] ? false : true;
+}
+
+//
+//     Put this element onto listHead, returning element under this one.
+//
+CxxSearchContext *CxxSearchContext::queue(CxxSearchContext *& listHead)
+{
+       CxxSearchContext *oldNext = _next;
+       _next = listHead;
+       listHead = this;
+       return oldNext;
+}
+
+//
+//     Release the current search buffer.
+//
+void CxxSearchContext::release()
+{
+       if (_current)
+       {
+               releases++;
+               _current->reset();
+               _current = _current->queue(_free);
+       }
+}
+
+void CxxSearchContext::reset()
+{
+       if (did_search())
+       {
+               _advances++;
+               actual_searches++;
+       }
+       if (_advances >= sizeof(advances)/sizeof(advances[0]))
+               advances[sizeof(advances)/sizeof(advances[0])-1]++;
+       else
+               advances[_advances]++;
+}
+
+void CxxSearchContext::start(YACC_MARK_TYPE anIndex, bool enableType1)
+{
+       if (!_current)
+               unnested_searches++;
+       else
+               nested_searches++;
+       if (!_free)
+               _current = new CxxSearchContext(_current);
+       else
+               _free = _free->queue(_current);
+       _current->initialise(anIndex, enableType1);
+}
+
+static CxxToken angleToken('<');
+static CxxToken colonToken(':');
+static CxxToken hashToken('#');
+static CxxToken plusToken('+');
+static CxxToken minusToken('-');
+
+void PARSE_SCOPE yyerror(const char *s)
+{
+       if (!bang_depth && (tokenMarkDepth == 0))
+       {
+               cout << s << endl;
+               increment_error_count();
+       }
+       else
+       {
+               if (show_marked)
+                       cout << "Marked " << s << endl;         
+               marked_error_count++;
+       }
+}
+
+//
+//     Get the next token for the parser, invoking yylex_token to get the next token from the lexer.
+//     This routine gets renamed to buffered_yylex by a #define when using yacc so that the two purposes
+//     above are split allowing lookahead buffering and primimimg to occur.
+//
+int PARSE_SCOPE yylex()
+{
+       CxxToken *aToken = primed_tokens[0];
+       if (aToken)
+       {
+               primed_tokens[0] = primed_tokens[1];
+               primed_tokens[1] = primed_tokens[2];
+               primed_tokens[2] = 0;
+       }
+       else if (tokenReadIndex < tokenWriteIndex)
+               aToken = tokenBuffer[tokenReadIndex++];
+       else
+       {
+               aToken = yylex_token();
+               if (!aToken)
+                       return 0;
+               if (tokenMarkDepth > 0)
+                       token_put(aToken);
+               else
+               {
+                       tokenWriteIndex = 0;
+                       tokenReadIndex = 0;
+               }
+       }
+       yylval.token = aToken;
+       return aToken->value();
+}
+
+//
+//     Advance the binary search of template attempts. Rewinds and forces true into the input sequence
+//     to proceed with the search. Rewinds and forces false to terminate it. Also forces a # that may then
+//     be used to initiate error propagation.
+//
+void advance_search()
+{
+       CxxSearchContext::search_advances++;
+       remark(CxxSearchContext::current()->mark());
+       if (CxxSearchContext::current() && CxxSearchContext::current()->advance())
+       {
+               primed_tokens[0] = &plusToken;
+               primed_tokens[1] = 0;
+       }
+       else
+       {
+               primed_tokens[0] = &minusToken;
+               primed_tokens[1] = &hashToken;
+       }
+}
+
+//
+//     Complete a search, releasing the search context object and popping a mark off the stack.
+//
+void end_search(CxxToken *aToken)
+{
+       CxxSearchContext::release();
+       unmark(aToken);
+}
+
+//
+//     Notch up an error and establish a good break point.
+//
+void increment_error_count()
+{
+       error_count++;
+}
+
+//
+//     Push a new marked context onto the stack, returning its identity for use by remark().
+//     Any parser readahead is incorporated within the marked region.
+//
+YACC_MARK_TYPE mark()
+{
+       if (primed_tokens[0])
+               ERRMSG("Unexpected primed_tokens[0] in mark.");
+       YACC_MARK_TYPE markIndex = tokenReadIndex;
+       if (PARSE_DOT yychar != YYEMPTY)
+       {
+//             if (primed_tokens[2])
+//                     token_put(primed_tokens[2]);
+//             if (primed_tokens[1])
+//                     token_put(primed_tokens[1]);
+//             if (primed_tokens[0])
+//                     token_put(primed_tokens[0]);
+//             if (!tokenMarkDepth)
+               if (!tokenReadIndex && !tokenWriteIndex)
+               {
+                       token_put(PARSE_DOT yylval.token);
+                       tokenReadIndex = 0;
+               }
+               else if (!tokenReadIndex)
+                       ERRMSG("Unexpected 0 read index in mark.");
+               else if (tokenBuffer[--tokenReadIndex] != PARSE_DOT yylval.token)
+                       ERRMSG("Unexpected unget in mark.");
+               markIndex = tokenReadIndex;
+               yyclearin;
+               primed_tokens[0] = 0;
+               primed_tokens[1] = 0;
+       }
+       tokenMarkDepth++; 
+       bang_depth++;
+       return markIndex;
+}
+
+//
+//     If it is appropriate to do type I function parameter parsing perform a mark and force a rrue token
+//     into the input stream. Otherwise just force a false token in.
+//
+YACC_MARK_TYPE mark_type1()
+{
+       if (!in_type1 && CxxSearchContext::current() && CxxSearchContext::current()->enable_type1())
+       {
+               YACC_MARK_TYPE markIndex = mark();
+               primed_tokens[0] = &plusToken;
+               primed_tokens[1] = 0;
+               in_type1 = true;
+        yyclearin; 
+               return markIndex;
+       }
+       else
+       {
+               primed_tokens[0] = &minusToken;
+               primed_tokens[1] = PARSE_DOT yychar != YYEMPTY ? PARSE_DOT yylval.token : 0;
+        yyclearin; 
+               return 0;                       // Never used.
+       }
+}      
+
+//
+//     Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang.
+//
+void pop_bang(YACC_BANG_TYPE bangValue)
+{
+       bang_depth = bangValue;
+}
+
+//
+//     Push a bang context onto the error suppression stack, returning the context for restoration by pop_bang.
+//
+YACC_BANG_TYPE push_bang()
+{
+       return bang_depth++;
+}
+
+//
+//     Reposition the input to restart at the position returned by a mark().
+//
+void remark(YACC_MARK_TYPE anIndex)
+{
+       tokenReadIndex = anIndex;
+    yyclearin;
+}
+
+//
+//     Reposition the input to restart at the position returned by a mark().
+//
+void remark_type1(YACC_MARK_TYPE anIndex)
+{
+       remark(anIndex);
+       in_type1 = false;
+}
+
+//
+//     Rewind the input stream back to anIndex and force a : prior to resuming input.
+//
+void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken)
+{
+       remark(anIndex);
+       unmark();
+       primed_tokens[0] = &colonToken;
+       primed_tokens[1] = PARSE_DOT yylval.token;
+}
+
+//
+//     Start a new binary search over the template/arithmetic alternative parses of a statement.
+//     Marks the current position and saves it in a binary search context maintained on a private stack.
+//
+void start_search(bool enableType1)
+{
+       bool type1Enabled = !CxxSearchContext::current() || CxxSearchContext::current()->enable_type1() ? true : false;
+       CxxSearchContext::start(mark(), enableType1 && type1Enabled ? true : false);
+}
+
+//
+//     Determine whether the just parsed < should be interpreted as a template or arithmetic operator.
+//     The implementation here intersacts with a binary search to traverse all possibilities in
+//     multiple passes. The search proceeds by branch and bound presuming the template interpretation.
+//     A true token is forced into the input stream to take the template interpretaion. A false token
+//     otherwise.
+//
+//     An alternate implementation that keeps track of scopes may interact with semantic knowledge to make
+//     the correct decision directly.
+//
+void template_test()
+{
+       if (!CxxSearchContext::current() || CxxSearchContext::current()->is_template())
+       {
+               primed_tokens[0] = &plusToken;
+               primed_tokens[1] = 0;
+       }
+       else
+       {
+               primed_tokens[0] = &minusToken;
+               primed_tokens[1] = &angleToken;
+       }
+}
+
+void token_put(CxxToken *aToken)
+{
+       if (!tokenBuffer || !tokenSize)
+               tokenBuffer = new CxxToken *[tokenSize = 256];
+       else if (tokenWriteIndex >= tokenSize)
+       {
+               CxxToken **oldTokenBuffer = tokenBuffer;
+               size_t oldTokenSize = tokenSize;
+               tokenBuffer = new CxxToken *[tokenSize *= 2];
+               memcpy(tokenBuffer, oldTokenBuffer, oldTokenSize * sizeof(*oldTokenBuffer));
+               delete[] oldTokenBuffer;
+       }
+       tokenBuffer[tokenWriteIndex++] = aToken;
+       tokenReadIndex = tokenWriteIndex;
+}
+
+//
+//     Pop a marked context off the stack.
+//
+void unmark(const CxxToken *aToken)
+{
+    if (bang_depth)
+        bang_depth--;
+    else
+        ERRMSG("BUG - should not unmark with 0 bang.");
+       if (tokenMarkDepth <= 0)
+               ERRMSG("Unexpected unmark.");
+       else
+               tokenMarkDepth--;
+}
diff --git a/infobase/examples/cpp_grammar_code/CxxParsing.hxx b/infobase/examples/cpp_grammar_code/CxxParsing.hxx
new file mode 100644 (file)
index 0000000..d5dc031
--- /dev/null
@@ -0,0 +1,667 @@
+#include <CxxToken.hxx>
+#include <stdio.h>
+#ifndef _MSC_VER
+#include <alloca.h>
+#else
+#include <malloc.h>
+//#define alloca _alloca
+#endif
+void advance_search();
+void end_search(CxxToken *aToken);
+YACC_MARK_TYPE mark();
+YACC_MARK_TYPE mark_type1();
+size_t nest() { return 0; }
+void pop_bang(YACC_BANG_TYPE bangValue);
+YACC_BANG_TYPE push_bang();
+void remark(YACC_MARK_TYPE anIndex);
+void remark_type1(YACC_MARK_TYPE anIndex);
+void rewind_colon(YACC_MARK_TYPE anIndex, const CxxToken *aToken);
+void start_search(bool enableType1);
+void template_test();
+void unmark(const CxxToken *aToken = 0);
+void unnest(size_t aNest) {}
+
+void classify_argument();
+void classify_function();
+void dollar_kill();
+CxxTokens *get_code(CxxToken *);
+CxxTokens *get_expr();
+CxxTokens *get_for_init();
+CxxTokens *get_for_next();
+CxxTokens *get_for_test();
+CxxTokens *get_func();
+CxxTokens *get_raw(CxxToken *);
+CxxTokens *get_statement();
+void make(CxxToken *);
+void queue(CxxToken *);
+int set_replace_formals(int);
+
+extern CxxToken *_list_token;
+
+#ifndef BISON_PP_CLASS
+void yyerror(const char *s);
+#define yylex buffered_yylex
+int yylex();
+#endif
+
+#define YACC_ABSTRACT_ARRAY_EXPRESSION(a) make_abstract_array_expression(a)
+#define YACC_ABSTRACT_FUNCTION_EXPRESSION(a) make_abstract_function_expression(a)
+#define YACC_ACCESSIBILITY_SPECIFIER(a) make_accessibility_specifier(a)
+#define YACC_ACCESS_BASE_SPECIFIER(a,b) make_access_base_specifier(a,b)
+#define YACC_ACCESS_SPECIFIER_ID(a) make_access_specifier_id(a)
+#define YACC_ADD_EXPRESSION(a,b) make_add_expression(a, b)
+#define YACC_AND_EXPRESSION(a,b) make_and_expression(a,b)
+#define YACC_ARRAY_EXPRESSION(a,b) make_array_expression(a,b)
+#define YACC_ARROW_EXPRESSION(a,b) make_arrow_expression(a,b)
+#define YACC_ARROW_STAR_EXPRESSION(a,b) make_arrow_star_expression(a,b)
+#define YACC_ASM_DEFINITION(a) make_asm_definition(a)
+#define YACC_ASSIGNMENT_EXPRESSION(a,b,c) make_assignment_expression(a,b,c)
+#define YACC_BASE_SPECIFIER(a) make_base_specifier(a)
+#define YACC_BASE_SPECIFIERS(a,b) make_base_specifiers(a,b)
+#define YACC_BIT_FIELD_EXPRESSION(a,b) make_bit_field_expression(a,b)
+#define YACC_BREAK_STATEMENT() make_break_statement()
+#define YACC_BUILT_IN_ID(a) make_built_in_id(a)
+#define YACC_BUILT_IN_ID_ID(a) make_built_in_id_id(a)
+#define YACC_BUILT_IN_IDS(a,b) make_built_in_ids(a,b)
+#define YACC_BUILT_IN_NAME(a,b) make_built_in_name(a,b)
+#define YACC_CALL_EXPRESSION(a,b) make_call_expression(a,b)
+#define YACC_CASE_STATEMENT(a,b) make_case_statement(a,b)
+#define YACC_CAST_EXPRESSION(a,b) make_cast_expression(a,b)
+#define YACC_CHARACTER_LITERAL_EXPRESSION(a) make_character_literal_expression(a)
+#define YACC_CLASS_MEMBERS(a,b) make_class_members(a,b)
+#define YACC_CLASS_SPECIFIER_ID(a,b,c) make_class_specifier_id(a,b,c)
+#define YACC_CLASS_TEMPLATE_PARAMETER(a) make_class_template_parameter(a)
+#define YACC_CLASS_TYPE_PARAMETER(a) make_class_type_parameter(a)
+#define YACC_COMPILE_DECLARATION(a,b) compile_declaration(a,b)
+#define YACC_COMPILE_STATEMENT(a) compile_statement(a)
+#define YACC_COMPLEMENT_EXPRESSION(a) make_complement_expression(a)
+#define YACC_COMPOUND_STATEMENT(a) make_compound_statement(a)
+#define YACC_CONDITION(a) make_condition(a)
+#define YACC_CONDITIONAL_EXPRESSION(a,b,c) make_conditional_expression(a,b,c)
+#define YACC_CONST_CAST_EXPRESSION(a,b) make_const_cast_expression(a,b)
+#define YACC_CONTINUE_STATEMENT() make_continue_statement()
+#define YACC_CONVERSION_FUNCTION_ID(a) make_conversion_function_id(a)
+#define YACC_CTOR_DEFINITION(a,b) make_ctor_definition(a,b)
+#define YACC_CTOR_FUNCTION_BLOCK(a,b) make_ctor_function_block(a,b)
+#define YACC_CV_DECLARATOR(a,b) make_cv_declarator(a,b)
+#define YACC_CV_DECL_SPECIFIER(a) make_cv_decl_specifier(a)
+#define YACC_CV_QUALIFIERS(a,b) make_cv_qualifiers(a,b)
+#define YACC_DECLARATIONS(a,b) make_declarations(a,b)
+#define YACC_DECLARATION_STATEMENT(a) make_declaration_statement(a)
+#define YACC_DECL_SPECIFIER_DECLARATION(a,b) make_decl_specifier_declaration(a,b)
+#define YACC_DECL_SPECIFIER_EXPRESSION(a,b) make_decl_specifier_expression(a,b)
+#define YACC_DECL_SPECIFIER_NAME(a,b) make_decl_specifier_name(a,b)
+#define YACC_DECL_SPECIFIER_PARAMETER(a,b) make_decl_specifier_parameter(a,b)
+#define YACC_DECL_SPECIFIERS(a,b) make_decl_specifiers(a,b)
+#define YACC_DECL_SPECIFIER_TREE_ARGUMENT(a,b) make_decl_specifier_tree_argument(a,b)
+#define YACC_DECL_SPECIFIER_TREE_ARGUMENTS(a,b) make_decl_specifier_tree_arguments(a,b)
+#define YACC_DEFAULT_STATEMENT(a) make_default_statement(a)
+#define YACC_DELETE_EXPRESSION(a) make_delete_expression(a)
+#define YACC_DERIVED_CLAUSE(a,b) make_derived_clause(a,b)
+#define YACC_DESTRUCTOR_ID(a) make_destructor_id(a)
+#define YACC_DIVIDE_EXPRESSION(a,b) make_divide_expression(a,b)
+#define YACC_DOT_EXPRESSION(a,b) make_dot_expression(a,b)
+#define YACC_DOT_STAR_EXPRESSION(a,b) make_dot_star_expression(a,b)
+#define YACC_DO_WHILE_STATEMENT(a,b) make_do_while_statement(a,b)
+#define YACC_DYNAMIC_CAST_EXPRESSION(a,b) make_dynamic_cast_expression(a,b)
+#define YACC_ELABORATED_TYPE_SPECIFIER(a,b) make_elaborated_type_specifier(a,b)
+#define YACC_ELLIPSIS_EXPRESSION() make_ellipsis_expression()
+#define YACC_ENUMERATOR(a,b) make_enumerator(a,b)
+#define YACC_ENUMERATORS(a,b) make_enumerators(a,b)
+#define YACC_ENUM_SPECIFIER_ID(a,b) make_enum_specifier_id(a,b)
+#define YACC_ENUM_TREE_ID(a) make_enum_tree_id(a)
+#define YACC_EPSILON() make_epsilon()
+#define YACC_EQUAL_EXPRESSION(a,b) make_equal_expression(a,b)
+#define YACC_EXCEPTION_DECLARATION(a) make_exception_declaration(a)
+#define YACC_EXCEPTION_SPECIFICATION(a) make_exception_specification(a)
+#define YACC_EXCLUSIVE_OR_EXPRESSION(a,b) make_exclusive_or_expression(a,b)
+#define YACC_EXPLICIT_IMPLEMENTATION_DECLARATION(a) make_explicit_implementation_declaration(a)
+#define YACC_EXPLICIT_INTERFACE_DECLARATION(a) make_explicit_interface_declaration(a)
+#define YACC_EXPLICIT_SPECIALIZATION(a) make_explicit_specialization(a)
+#define YACC_EXPORT_IMPLEMENTATION_DECLARATION(a) make_export_implementation_declaration(a)
+#define YACC_EXPORT_INTERFACE_DECLARATION(a) make_export_interface_declaration(a)
+#define YACC_EXPORT_NOIMPLEMENTATION_DECLARATION() make_export_noimplementation_declaration()
+#define YACC_EXPRESSION(a) make_expression(a)
+#define YACC_EXPRESSIONS(a,b) make_expressions(a,b)
+#define YACC_EXPRESSION_PARAMETER(a) make_expression_parameter(a)
+#define YACC_FALSE_EXPRESSION() make_false_expression()
+#define YACC_FILESPACE_DECLARATION(a) make_filespace_declaration(a)
+#define YACC_FILESPACE_SPECIFIER(a,b) make_filespace_specifier(a,b)
+#define YACC_FILE_ID(a) make_file_id(a)
+#define YACC_FILE_ID_IMPLEMENTATION(a) make_file_id_implementation(a)
+#define YACC_FILE_ID_INTERFACE(a) make_file_id_interface(a)
+#define YACC_FILE_IDS(a,b) make_file_ids(a,b)
+#define YACC_FILE_NAME(a) make_file_name(a)
+#define YACC_FILE_NAME_GUARD(a,b) make_file_name_guard(a,b)
+#define YACC_FILE_NAME_IMPLEMENTATION(a) make_file_name_implementation(a)
+#define YACC_FILE_NAME_INTERFACE(a) make_file_name_interface(a)
+#define YACC_FILE_NAME_NOGUARD(a) make_file_name_noguard(a)
+#define YACC_FILE_NAME_PATH(a,b) make_file_name_path(a,b)
+#define YACC_FILE_NAME_PREFIX(a,b) make_file_name_prefix(a,b)
+#define YACC_FILE_NAME_SUFFIX(a,b) make_file_name_suffix(a,b)
+#define YACC_FILE_NAME_TEMPLATE(a) make_file_name_template(a)
+#define YACC_FILE_NAME_UTILITY(a,b) make_file_name_utility(a,b)
+#define YACC_FLOATING_LITERAL_EXPRESSION(a) make_floating_literal_expression(a)
+#define YACC_FOR_STATEMENT(a,b,c,d) make_for_statement(a,b,c,d)
+#define YACC_FUNCTION_BLOCK(a) make_function_block(a)
+#define YACC_FUNCTION_DECLARATIONS(a,b) make_function_declarations(a,b)
+#define YACC_FUNCTION_DEFINITION(a,b) make_function_definition(a,b)
+#define YACC_GLOBAL_DECLARATOR(a,b) make_global_declarator(a,b)
+#define YACC_GLOBAL_EXPRESSION(a, b) make_global_expression(a,b)
+#define YACC_GLOBAL_ID(a,b) make_global_id(a,b)
+#define YACC_GOTO_STATEMENT(a) make_goto_statement(a)
+#define YACC_GREATER_EQUAL_EXPRESSION(a,b) make_greater_equal_expression(a,b)
+#define YACC_GREATER_THAN_EXPRESSION(a,b) make_greater_than_expression(a,b)
+#define YACC_HANDLER(a,b) make_handler(a,b)
+#define YACC_HANDLERS(a,b) make_handlers(a,b)
+#define YACC_IF_STATEMENT(a,b,c) make_if_statement(a,b,c)
+#define YACC_INCLUDE_DECLARATION(a,b) make_include_declaration(a,b)
+#define YACC_INCLUSIVE_OR_EXPRESSION(a,b) make_inclusive_or_expression(a,b)
+#define YACC_INITIALIZED_PARAMETER(a,b) make_initialized_parameter(a, b)
+#define YACC_INITIALIZER_CLAUSES(a,b) make_initializer_clauses(a,b)
+#define YACC_INITIALIZER_EXPRESSION_CLAUSE(a) make_initializer_expression_clause(a)
+#define YACC_INITIALIZER_LIST_CLAUSE(a) make_initializer_list_clause(a)
+#define YACC_INIT_SIMPLE_TYPE_PARAMETER(a,b) make_init_simple_type_parameter(a,b)
+#define YACC_INIT_TEMPLATED_PARAMETER(a,b) make_init_templated_parameter(a,b)
+#define YACC_INLINE_AS_FRIEND() make_inline_as_friend()
+#define YACC_INLINE_IF_SHORT() make_inline_if_short()
+#define YACC_INLINE_IN_IMPLEMENTATION() make_inline_in_implementation()
+#define YACC_INLINE_IN_INTERFACE() make_inline_in_interface()
+#define YACC_INDEX_CAST_EXPRESSION(a,b) make_index_cast_expression(a,b)
+#define YACC_INPUT_FILE(a) make_input_file(a)
+#define YACC_INTEGER_LITERAL_EXPRESSION(a) make_integer_literal_expression(a)
+#define YACC_LABEL_STATEMENT(a,b) make_label_statement(a,b)
+#define YACC_LESS_EQUAL_EXPRESSION(a,b) make_less_equal_expression(a,b)
+#define YACC_LESS_THAN_EXPRESSION(a,b) make_less_than_expression(a,b)
+#define YACC_LINE() make_line()
+#define YACC_LINED_DECLARATION(a,b) make_lined_declaration(a,b)
+#define YACC_LINED_STATEMENT(a,b) make_lined_statement(a,b)
+#define YACC_LINED_TOKEN(a,b) make_lined_token(a,b)
+#define YACC_LINKAGE_SPECIFICATION(a) make_linkage_specification(a)
+#define YACC_LINKAGE_SPECIFIER(a,b) make_linkage_specifier(a,b)
+#define YACC_LOGICAL_AND_EXPRESSION(a,b) make_logical_and_expression(a,b)
+#define YACC_LOGICAL_OR_EXPRESSION(a,b) make_logical_or_expression(a,b)
+#define YACC_MEMBER_DECLARATIONS(a,b) make_member_declarations(a,b)
+#define YACC_MEM_INITIALIZER(a,b) make_mem_initializer(a,b)
+#define YACC_MEM_INITIALIZERS(a,b) make_mem_initializers(a,b)
+#define YACC_META_ASSIGNMENT_EXPRESSION(a,b,c) make_meta_assignment_expression(a,b,c)
+#define YACC_META_BASE_SPECIFIER(a) make_meta_base_specifier(a)
+#define YACC_META_BREAK_STATEMENT() make_meta_break_statement()
+#define YACC_META_BUILT_IN_TYPE(a) make_meta_built_in_type(a)
+#define YACC_META_CASE_STATEMENT(a,b) make_meta_case_statement(a,b)
+#define YACC_META_CLASS(a,b,c) make_meta_class(a,b,c)
+#define YACC_META_CONTINUE_STATEMENT() make_meta_continue_statement()
+#define YACC_META_DEFAULT_STATEMENT(a) make_meta_default_statement(a)
+#define YACC_META_DO_WHILE_STATEMENT(a,b,c) make_meta_do_while_statement(a,b,c)
+#define YACC_META_FOR_STATEMENT(a,b,c,d,e) make_meta_for_statement(a,b,c,d,e)
+#define YACC_META_FUNCTION(a,b,c) make_meta_function(a,b,c)
+#define YACC_META_IF_STATEMENT(a,b,c,d) make_meta_if_statement(a,b,c,d)
+#define YACC_META_INITIALIZER(a,b) make_meta_initializer(a,b)
+#define YACC_META_INITIALIZERS(a,b) make_meta_initializers(a,b)
+#define YACC_META_RETURN_STATEMENT(a) make_meta_return_statement(a)
+#define YACC_META_STATEMENT(a) make_meta_statement(a)
+#define YACC_META_STATEMENT_DECLARATION(a) make_meta_statement_declaration(a)
+#define YACC_META_SWITCH_STATEMENT(a,b,c) make_meta_switch_statement(a,b,c)
+#define YACC_META_TYPE(a) make_meta_type(a)
+#define YACC_META_TYPE_ID(a) make_meta_type_id(a)
+#define YACC_META_WHILE_STATEMENT(a,b,c) make_meta_while_statement(a,b,c)
+#define YACC_MINUS_EXPRESSION(a) make_minus_expression(a)
+#define YACC_MODULUS_EXPRESSION(a,b) make_modulus_expression(a,b)
+#define YACC_MULTIPLY_EXPRESSION(a,b,c) make_multiply_expression(a,b,c)
+#define YACC_NAME(a) make_name(a)
+#define YACC_NAMESPACE_ALIAS_DEFINITION(a,b) make_namespace_alias_definition(a,b)
+#define YACC_NAMESPACE_DECLARATION(a) make_namespace_declaration(a)
+#define YACC_NAMESPACE_DEFINITION(a,b) make_namespace_definition(a,b)
+#define YACC_NAME_EXPRESSION(a) make_name_expression(a)
+#define YACC_NESTED_DECLARATOR(a,b) make_nested_declarator(a,b)
+#define YACC_NESTED_ID(a,b) make_nested_id(a,b)
+#define YACC_NESTED_SCOPE(a) make_nested_scope(a)
+#define YACC_NEW_EXPRESSION(a,b,c) make_new_expression(a,b,c)
+#define YACC_NEW_TYPE_ID_EXPRESSION(a,b,c) make_new_type_id_expression(a,b,c)
+#define YACC_NOT_CONST() make_not_const()
+#define YACC_NOT_EQUAL_EXPRESSION(a,b) make_not_equal_expression(a,b)
+#define YACC_NOT_EXPRESSION(a) make_not_expression(a)
+#define YACC_NOT_INLINE() make_not_inline()
+#define YACC_NOT_STATIC() make_not_static()
+#define YACC_NOT_VIRTUAL() make_not_virtual()
+#define YACC_NOT_VIRTUAL_BASE_SPECIFIER(a) make_not_virtual_base_specifier(a)
+#define YACC_NOT_VOLATILE() make_not_volatile()
+#define YACC_NUMBER_LITERAL_EXPRESSION(a) make_number_literal_expression(a)
+#define YACC_OBJECT_SCOPE_EXPRESSION(a,b) make_object_scope_expression(a,b)
+#define YACC_OPERATOR_ADD_ID() make_operator_add_id()
+#define YACC_OPERATOR_ARROW_ID() make_operator_arrow_id()
+#define YACC_OPERATOR_ARROW_STAR_ID() make_operator_arrow_star_id()
+#define YACC_OPERATOR_ASS_ADD_ID() make_operator_ass_add_id()
+#define YACC_OPERATOR_ASS_BIT_AND_ID() make_operator_ass_bit_and_id()
+#define YACC_OPERATOR_ASS_BIT_OR_ID() make_operator_ass_bit_or_id()
+#define YACC_OPERATOR_ASS_DIV_ID() make_operator_ass_div_id()
+#define YACC_OPERATOR_ASS_ID() make_operator_ass_id()
+#define YACC_OPERATOR_ASS_MOD_ID() make_operator_ass_mod_id()
+#define YACC_OPERATOR_ASS_MUL_ID() make_operator_ass_mul_id()
+#define YACC_OPERATOR_ASS_SHL_ID() make_operator_ass_shl_id()
+#define YACC_OPERATOR_ASS_SHR_ID() make_operator_ass_shr_id()
+#define YACC_OPERATOR_ASS_SUB_ID() make_operator_ass_sub_id()
+#define YACC_OPERATOR_ASS_XOR_ID() make_operator_ass_xor_id()
+#define YACC_OPERATOR_BIT_AND_ID() make_operator_bit_and_id()
+#define YACC_OPERATOR_BIT_NOT_ID() make_operator_bit_not_id()
+#define YACC_OPERATOR_BIT_OR_ID() make_operator_bit_or_id()
+#define YACC_OPERATOR_CALL_ID() make_operator_call_id()
+#define YACC_OPERATOR_COMMA_ID() make_operator_comma_id()
+#define YACC_OPERATOR_DEC_ID() make_operator_dec_id()
+#define YACC_OPERATOR_DELETE_ID() make_operator_delete_id()
+#define YACC_OPERATOR_DIV_ID() make_operator_div_id()
+#define YACC_OPERATOR_EQ_ID() make_operator_eq_id()
+#define YACC_OPERATOR_FUNCTION_ID(a) make_operator_function_id(a)
+#define YACC_OPERATOR_GE_ID() make_operator_ge_id()
+#define YACC_OPERATOR_GT_ID() make_operator_gt_id()
+#define YACC_OPERATOR_INC_ID() make_operator_inc_id()
+#define YACC_OPERATOR_INDEX_ID() make_operator_index_id()
+#define YACC_OPERATOR_LE_ID() make_operator_le_id()
+#define YACC_OPERATOR_LOG_AND_ID() make_operator_log_and_id()
+#define YACC_OPERATOR_LOG_NOT_ID() make_operator_log_not_id()
+#define YACC_OPERATOR_LOG_OR_ID() make_operator_log_or_id()
+#define YACC_OPERATOR_LT_ID() make_operator_lt_id()
+#define YACC_OPERATOR_MOD_ID() make_operator_mod_id()
+#define YACC_OPERATOR_MUL_ID() make_operator_mul_id()
+#define YACC_OPERATOR_NE_ID() make_operator_ne_id()
+#define YACC_OPERATOR_NEW_ID() make_operator_new_id()
+#define YACC_OPERATOR_SHL_ID() make_operator_shl_id()
+#define YACC_OPERATOR_SHR_ID() make_operator_shr_id()
+#define YACC_OPERATOR_SUB_ID() make_operator_sub_id()
+#define YACC_OPERATOR_XOR_ID() make_operator_xor_id()
+#define YACC_PARAMETERS(a,b) make_parameters(a,b)
+#define YACC_PARENTHESISED(a,b,c) make_parenthesised(a,b,c)
+#define YACC_POINTER_DECLARATOR() make_pointer_declarator()
+#define YACC_POINTER_EXPRESSION(a,b) make_pointer_expression(a,b)
+#define YACC_PLUS_EXPRESSION(a) make_plus_expression(a)
+#define YACC_POSITION(a,b) make_position(a)
+#define YACC_POSITION_FUNCTION_BLOCK(a,b) make_position_function_block(a,b)
+#define YACC_POST_DECREMENT_EXPRESSION(a) make_post_decrement_expression(a)
+#define YACC_POST_INCREMENT_EXPRESSION(a) make_post_increment_expression(a)
+#define YACC_PRE_DECREMENT_EXPRESSION(a) make_pre_decrement_expression(a)
+#define YACC_PRE_INCREMENT_EXPRESSION(a) make_pre_increment_expression(a)
+#define YACC_PSEUDO_DESTRUCTOR_ID(a,b) make_pseudo_destructor_id(a,b)
+#define YACC_PURE_VIRTUAL() make_pure_virtual()
+#define YACC_READ_ONLY_RESULT(a) make_read_only_result(a)
+#define YACC_READ_WRITE_RESULT(a) make_read_write_result(a)
+#define YACC_REFERENCE_DECLARATOR() make_reference_declarator()
+#define YACC_REINTERPRET_CAST_EXPRESSION(a,b) make_reinterpret_cast_expression(a,b)
+#define YACC_RESULT(a) make_result(a)
+#define YACC_RETURN_STATEMENT(a) make_return_statement(a)
+#define YACC_SCOPED_POINTER_EXPRESSION(a,b,c) make_scoped_pointer_expression(a,b,c)
+#define YACC_SCOPED_ID(a,b) make_scoped_id(a,b)
+#define YACC_SEGMENT(a,b) make_segment(a)
+#define YACC_SEGMENT_FUNCTION_BLOCK(a,b) make_segment_function_block(a,b)
+#define YACC_SET_TEMPLATE_DECLARATION(a) make_set_template_declaration(a)
+#define YACC_SET_TEMPLATE_DECL_SPECIFIER(a) make_set_template_decl_specifier(a)
+#define YACC_SET_TEMPLATE_EXPRESSION(a) make_set_template_expression(a)
+#define YACC_SET_TEMPLATE_ID(a) make_set_template_id(a)
+#define YACC_SET_TEMPLATE_NAME(a) make_set_template_name(a)
+#define YACC_SET_TEMPLATE_SCOPE(a) make_set_template_scope(a)
+#define YACC_SHIFT_LEFT_EXPRESSION(a,b) make_shift_left_expression(a,b)
+#define YACC_SHIFT_RIGHT_EXPRESSION(a,b) make_shift_right_expression(a,b)
+#define YACC_SIMPLE_DECLARATION(a) make_simple_declaration(a)
+#define YACC_SIZEOF_EXPRESSION(a) make_sizeof_expression(a)
+#define YACC_STATEMENTS(a,b) make_statements(a,b)
+#define YACC_STATIC_CAST_EXPRESSION(a,b) make_static_cast_expression(a,b)
+#define YACC_STRINGS(a,b) make_strings(a,b)
+#define YACC_STRING_LITERAL_EXPRESSION(a) make_string_literal_expression(a)
+#define YACC_SUBTRACT_EXPRESSION(a,b) make_subtract_expression(a,b)
+#define YACC_SWITCH_STATEMENT(a,b) make_switch_statement(a,b)
+#define YACC_SYNTAX_MACRO_DEFINITION(a,b,c,d,e) make_syntax_macro_definition(a,b,c,d,e)
+#define YACC_SYNTAX_MACRO_PARAMETER(a,b,c) make_syntax_macro_parameter(a,b,c)
+#define YACC_SYNTAX_MACRO_PARAMETERS(a,b) make_syntax_macro_parameters(a,b)
+#define YACC_TEMPLATE_ARGUMENT(a) make_template_argument(a)
+#define YACC_TEMPLATE_ARGUMENTS(a,b) make_template_arguments(a,b)
+#define YACC_TEMPLATED_TEMPLATE_PARAMETER(a,b) make_templated_template_parameter(a,b)
+#define YACC_TEMPLATED_TYPE_PARAMETER(a,b) make_templated_type_parameter(a,b)
+#define YACC_TEMPLATE_DECLARATION(a,b) make_template_declaration(a,b)
+#define YACC_TEMPLATE_NAME(a,b) make_template_name(a,b)
+#define YACC_TEMPLATE_PARAMETER(a) make_template_parameter(a)
+#define YACC_TEMPLATE_PARAMETERS(a,b) make_template_parameters(a,b)
+#define YACC_THIS_EXPRESSION() make_this_expression()
+#define YACC_THROW_EXPRESSION(a) make_throw_expression(a)
+#define YACC_TOKENS_EXPRESSION(a) make_tokens_expression(a)
+#define YACC_TREE_ARGUMENT(a) make_tree_argument(a)
+#define YACC_TREE_ARGUMENTS(a,b) make_tree_arguments(a,b)
+#define YACC_TREE_ARRAY_EXPRESSION(a,b) make_tree_array_expression(a,b)
+#define YACC_TREE_ARROW_EXPRESSION(a,b) make_tree_arrow_expression(a,b)
+#define YACC_TREE_ARROW_CALL_EXPRESSION(a,b,c) make_tree_arrow_call_expression(a,b,c)
+#define YACC_TREE_CALL_EXPRESSION(a,b) make_tree_call_expression(a,b)
+#define YACC_TREE_DOT_EXPRESSION(a,b) make_tree_dot_expression(a,b)
+#define YACC_TREE_DOT_CALL_EXPRESSION(a,b,c) make_tree_dot_call_expression(a,b,c)
+#define YACC_TREE_EXPRESSION(a) make_tree_expression(a)
+#define YACC_TREE_ID(a) make_tree_id(a)
+#define YACC_TREE_POINTER_EXPRESSION(a) make_tree_pointer_expression(a)
+#define YACC_TRUE_EXPRESSION() make_true_expression()
+#define YACC_TRY_BLOCK(a,b) make_try_block(a,b)
+#define YACC_TRY_BLOCK_STATEMENT(a) make_try_block_statement(a)
+#define YACC_TRY_FUNCTION_BLOCK(a,b) make_try_function_block(a,b)
+#define YACC_TYPE1_EXPRESSION(a,b,c) make_type1_expression(a,b,c)
+#define YACC_TYPE1_PARAMETERS(a,b) make_type1_parameters(a,b)
+#define YACC_TYPED_EXPRESSION(a,b) make_typed_expression(a,b)
+#define YACC_TYPED_NAME(a,b) make_typed_name(a,b)
+#define YACC_TYPEID_EXPRESSION(a) make_typeid_expression(a)
+#define YACC_TYPENAME_TEMPLATE_PARAMETER(a) make_typename_template_parameter(a)
+#define YACC_TYPENAME_TYPE_PARAMETER(a) make_typename_type_parameter(a)
+#define YACC_TYPE_TEMPLATE_PARAMETER(a,b) make_type_template_parameter(a,b)
+#define YACC_USING_DECLARATION(a,b) make_using_declaration(a,b)
+#define YACC_USING_DIRECTIVE(a) make_using_directive(a)
+#define YACC_USING_FUNCTION_BLOCK(a,b) make_using_function_block(a,b)
+#define YACC_USING_IMPLEMENTATION_DECLARATION(a) make_using_implementation_declaration(a)
+#define YACC_USING_INTERFACE_DECLARATION(a) make_using_interface_declaration(a)
+#define YACC_UTILITY(a) make_utility(0)
+#define YACC_UTILITY_MODE() make_utility_mode()
+#define YACC_VIRTUAL_BASE_SPECIFIER(a) make_virtual_base_specifier(a)
+#define YACC_WHILE_STATEMENT(a,b) make_while_statement(a,b)
+
+CxxDeclaration *compile_declaration(CxxUtility *utilityMode, CxxDeclaration *aDeclaration) { return 0; }
+CxxStatement *compile_statement(CxxStatement *aDeclaration) { return 0; }
+void make_result(CxxToken *aResult) {}
+
+CxxExpression *make_abstract_array_expression(CxxExpression *sizeExpr) { return 0; }
+CxxExpression *make_abstract_function_expression(CxxParenthesised *aparenthesis) { return 0; }
+CxxBaseSpecifier *make_access_base_specifier(CxxBaseSpecifier *baseSpecifier, CxxAccessSpecifier *accessSpecifier) { return 0; }
+CxxDeclSpecifierId *make_access_specifier_id(CxxAccessSpecifier *aName) { return 0; }
+CxxDeclaration *make_accessibility_specifier(CxxAccessSpecifier *accessSpecifier) { return 0; }
+CxxExpression *make_add_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_array_expression(CxxExpression *anExpr, CxxExpression *indexExpr) { return 0; }
+CxxExpression *make_arrow_expression(CxxExpression *anExpr, CxxName *aName) { return 0; }
+CxxExpression *make_arrow_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; }
+CxxDeclaration *make_asm_definition(CxxStrings *aString) { return 0; }
+CxxExpression *make_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxExpression *rightExpr) { return 0; }
+CxxBaseSpecifier *make_base_specifier(CxxName *aName) { return 0; }
+CxxBaseSpecifiers *make_base_specifiers(CxxBaseSpecifiers *aList, CxxBaseSpecifier *anElement) { return 0; }
+CxxExpression *make_bit_field_expression(CxxExpression *nameExpr, CxxExpression *sizeExpr) { return 0; }
+CxxStatement *make_break_statement() { return 0; }
+CxxName *make_built_in_id(CxxBuiltInId *aName) { return 0; }
+CxxName *make_built_in_id_id(CxxBuiltInId *aName) { return 0; }
+CxxBuiltInId *make_built_in_ids(CxxBuiltInId *anExpr, CxxBuiltInId *anElement) { return 0; }
+CxxName *make_built_in_name(CxxName *aName, CxxBuiltInId *anElement) { return 0; }
+CxxExpression *make_call_expression(CxxExpression *anExpr, CxxParenthesised *aParenthesis) { return 0; }
+CxxStatement *make_case_statement(CxxExpression *anExpr, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; }
+CxxExpression *make_character_literal_expression(CxxCharacterLiteral *aLiteral) { return 0; }
+CxxName *make_class_members(CxxClass *aClass, CxxMemberDeclarations *memberDeclarations) { return 0; }
+CxxClass *make_class_specifier_id(CxxClassKey *classKey, CxxName *aName, CxxBaseSpecifiers *baseSpecifiers) { return 0; }
+CxxSimpleTypeParameter *make_class_template_parameter(CxxName *aName) { return 0; }
+CxxSimpleTypeParameter *make_class_type_parameter(CxxName *aName) { return 0; }
+CxxStatement *make_compound_statement(CxxStatements *statementList) { return 0; }
+CxxExpression *make_complement_expression(CxxExpression *anExpr) { return 0; }
+CxxCondition *make_condition(CxxParameters *aList) { return 0; }
+CxxExpression *make_conditional_expression(CxxExpression *testExpr, CxxExpression *trueExpr, CxxExpression *falseExpr) { return 0; }
+CxxExpression *make_const_cast_expression(CxxExpression *aType, CxxExpression *anExpr)  { return 0; }
+CxxStatement *make_continue_statement() { return 0; }
+CxxName *make_conversion_function_id(CxxExpression *typeId) { return 0; }
+CxxExpression *make_ctor_definition(CxxExpressions *anExpr, CxxFunctionBody *functionBody) { return 0; }
+CxxFunctionBody *make_ctor_function_block(CxxFunctionBody *functionBody, CxxMemInitializers *ctorList) { return 0; }
+CxxDeclSpecifierId *make_cv_decl_specifier(CxxCvQualifiers *cvQualifiers) { return 0; }
+CxxPointerDeclarator *make_cv_declarator(CxxPointerDeclarator *aDeclarator, CxxCvQualifiers *cvQualifiers) { return 0; }
+CxxCvQualifiers *make_cv_qualifiers(CxxCvQualifiers *aList, CxxCvQualifiers *anElement) { return 0; }
+CxxDeclaration *make_decl_specifier_declaration(CxxDeclaration *aDeclaration, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxExpression *make_decl_specifier_expression(CxxExpression *anExpr, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxName *make_decl_specifier_name(CxxName *aName, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxParameter *make_decl_specifier_parameter(CxxParameter *aName, CxxDeclSpecifierId *declSpecifier) { return 0; }
+CxxToken *make_decl_specifier_tree_argument(CxxToken *treeArgument, CxxDeclSpecifierId *aName) { return 0; }
+CxxTokens *make_decl_specifier_tree_arguments(CxxTokens *treeArguments, CxxDeclSpecifierId *aName) { return 0; }
+CxxDeclSpecifierId *make_decl_specifiers(CxxDeclSpecifierId *aList, CxxDeclSpecifierId *anElement) { return 0; }
+CxxDeclarations *make_declarations(CxxDeclarations *aList, CxxDeclaration *anElement) { return 0; }
+CxxStatement *make_declaration_statement(CxxDeclaration *aDecl) { return 0; }
+CxxStatement *make_default_statement(CxxStatement *aStmt) { return 0; }
+CxxExpression *make_delete_expression(CxxExpression *anExpr) { return 0; }
+CxxDeclaration *make_derived_clause(CxxExpression *derivedPredicate, CxxDeclaration *aDeclaration) { return 0; }
+CxxName *make_destructor_id(CxxName *aName) { return 0; }
+CxxExpression *make_divide_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxStatement *make_do_while_statement(CxxStatement *aStmt, CxxExpression *testExpr) { return 0; }
+CxxExpression *make_dot_expression(CxxExpression *anExpr, CxxName *aName) { return 0; }
+CxxExpression *make_dot_star_expression(CxxExpression *anExpr, CxxExpression *memberExpr) { return 0; }
+CxxExpression *make_dynamic_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
+CxxName *make_elaborated_type_specifier(CxxClassKey *classKey, CxxName *aName) { return 0; }
+CxxParameter *make_ellipsis_expression() { return 0; }
+CxxName *make_enum_specifier_id(CxxName *aName, CxxEnumerators *aList) { return 0; }
+CxxEnumerator *make_enumerator(CxxName *aName, CxxExpression *anExpr) { return 0; }
+CxxEnumerators *make_enumerators(CxxEnumerators *aList, CxxEnumerator *anElement) { return 0; }
+CxxName *make_epsilon() { return 0; }
+CxxExpression *make_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExceptionDeclaration *make_exception_declaration(CxxParameter *aParameter) { return 0; }
+CxxExceptionSpecification *make_exception_specification(CxxExpressions *typeIds) { return 0; }
+CxxExpression *make_exclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxDeclaration *make_explicit_implementation_declaration(CxxTokens *someTokens) { return 0; }
+CxxDeclaration *make_explicit_interface_declaration(CxxTokens *someTokens) { return 0; }
+CxxDeclaration *make_explicit_specialization(CxxDeclaration *aDeclaration) { return 0; }
+CxxDeclaration *make_export_implementation_declaration(CxxFileId *fileId) { return 0; }
+CxxDeclaration *make_export_interface_declaration(CxxFileId *fileId) { return 0; }
+CxxDeclaration *make_export_noimplementation_declaration() { return 0; }
+CxxExpression *make_expression(CxxExpressions *aList) { return 0; }
+CxxParameter *make_expression_parameter(CxxExpression *anExpr) { return 0; }
+CxxExpressions *make_expressions(CxxExpressions *aList, CxxExpression *anElement) { return 0; }
+CxxExpression *make_false_expression() { return 0; }
+CxxFileId *make_file_id(CxxFileName *fileName) { return 0; }
+CxxFileId *make_file_id_implementation(CxxName *aName) { return 0; }
+CxxFileId *make_file_id_interface(CxxName *aName) { return 0; }
+CxxFileIds *make_file_ids(CxxFileIds *aList, CxxFileId *anElement) { return 0; }
+CxxFileName *make_file_name(CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_guard(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_implementation(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_interface(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_noguard(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_path(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_prefix(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_suffix(CxxFileName *fileName, CxxStrings *aString) { return 0; }
+CxxFileName *make_file_name_template(CxxFileName *fileName) { return 0; }
+CxxFileName *make_file_name_utility(CxxFileName *fileName, CxxUtility *aUtility) { return 0; }
+CxxDeclaration *make_filespace_declaration(CxxName *aName) { return 0; }
+CxxName *make_filespace_specifier(CxxFileName *fileName, CxxDeclarations *aDeclaration) { return 0; }
+CxxExpression *make_floating_literal_expression(CxxFloatingLiteral *aLiteral) { return 0; }
+CxxStatement *make_for_statement(CxxExpression *initExpr, CxxCondition *testExpr, CxxExpression *stepExpr, CxxStatement *aStmt) { return 0; }
+CxxFunctionBody *make_function_block(CxxStatement *aStatement) { return 0; }
+CxxFunctionDeclarations *make_function_declarations(CxxFunctionDeclarations *aList, CxxDeclaration *anElement) { return 0; }
+CxxExpression *make_function_definition(CxxExpression *anExpr, CxxFunctionBody *functionBody) { return 0; }
+CxxDeclarator *make_global_declarator(CxxIsTemplate isTemplate, CxxDeclarator *aDeclarator) { return 0; }
+CxxExpression *make_global_expression(CxxIsTemplate isTemplate, CxxNewExpression *anExpr) { return 0; }
+CxxName *make_global_id(CxxIsTemplate isTemplate, CxxName *nestedId) { return 0; }
+CxxStatement *make_goto_statement(CxxToken *aLabel) { return 0; }
+CxxExpression *make_greater_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_greater_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxHandler *make_handler(CxxExceptionDeclaration *exceptionDeclaration, CxxStatement *aStatement) { return 0; }
+CxxHandlers *make_handlers(CxxHandlers *aList, CxxHandler *anElement) { return 0; }
+CxxStatement *make_if_statement(CxxCondition *testExpr, CxxStatement *trueStmt, CxxStatement *falseStmt) { return 0; }
+CxxDeclaration *make_include_declaration(CxxStrings *aString, CxxUtility *aUtility) { return 0; }
+CxxExpression *make_inclusive_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_index_cast_expression(CxxExpression *aCast, CxxExpression *anExpr) { return 0; }
+CxxParameter *make_initialized_parameter(CxxParameter *aParameter, CxxExpression *anExpr) { return 0; }
+CxxInitializerClauses *make_initializer_clauses(CxxInitializerClauses *aList, CxxInitializerClause *anElement) { return 0; }
+CxxInitializerClause *make_initializer_expression_clause(CxxExpression *anExpr) { return 0; }
+CxxInitializerClause *make_initializer_list_clause(CxxInitializerClauses *aList) { return 0; }
+CxxSimpleTypeParameter *make_init_simple_type_parameter(CxxSimpleTypeParameter *templateParameters, CxxExpression *anExpr) { return 0; }
+CxxTemplatedTypeParameter *make_init_templated_parameter(CxxTemplatedTypeParameter *typeParameter, CxxName *aName) { return 0; }
+CxxDeclSpecifierId *make_inline_as_friend() { return 0; }
+CxxDeclSpecifierId *make_inline_if_short() { return 0; }
+CxxDeclSpecifierId *make_inline_in_implementation() { return 0; }
+CxxDeclSpecifierId *make_inline_in_interface() { return 0; }
+CxxFileId *make_input_file(CxxFileId *fileId) { return 0; }
+CxxExpression *make_integer_literal_expression(CxxIntegerLiteral *aLiteral) { return 0; }
+CxxStatement *make_label_statement(CxxToken *aLabel, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_less_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_less_than_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxLine *make_line() { return 0; }
+CxxDeclaration *make_lined_declaration(CxxDeclaration *aDeclaration, CxxLine *aLine) { return 0; }
+CxxStatement *make_lined_statement(CxxStatement *aStatement, CxxLine *aLine) { return 0; }
+CxxToken *make_lined_token(CxxToken *aToken, CxxLine *aLine) { return 0; }
+CxxName *make_linkage_specifier(CxxStrings *aString, CxxDeclaration *aDeclaration) { return 0; }
+CxxExpression *make_logical_and_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_logical_or_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxMemInitializer *make_mem_initializer(CxxName *aName, CxxExpression *anExpr) { return 0; }
+CxxMemInitializers *make_mem_initializers(CxxMemInitializers *aList, CxxMemInitializer *anElement) { return 0; }
+CxxMemberDeclarations *make_member_declarations(CxxMemberDeclarations *aList, CxxDeclaration *aDeclaration) { return 0; }
+CxxExpression *make_meta_assignment_expression(CxxExpression *leftExpr, CxxToken *assOp, CxxToken *rightExpr) { return 0; }
+CxxBaseSpecifier *make_meta_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
+CxxMetaType *make_meta_built_in_type(CxxBuiltInId *aName) { return 0; }
+CxxStatement *make_meta_break_statement() { return 0; }
+CxxStatement *make_meta_case_statement(CxxExpression *anExpr, CxxToken *someTokens) { return 0; }
+CxxMetaClass *make_meta_class(CxxName *metaClass, CxxBaseSpecifiers *baseSpecifiers, CxxToken *classBody) { return 0; }
+CxxStatement *make_meta_continue_statement() { return 0; }
+CxxDeclaration *make_meta_declaration_declaration(CxxDeclaration *metaDeclaration) { return 0; }
+CxxStatement *make_meta_default_statement(CxxToken *someTokens) { return 0; }
+CxxStatement *make_meta_do_while_statement(CxxLine *aLine, CxxToken *bodyTokens, CxxToken *testTokens) { return 0; }
+CxxStatement *make_meta_expression_statement(CxxName *aName, CxxToken *bodyTokens) { return 0; }
+CxxStatement *make_meta_for_statement(CxxLine *aLine, CxxExpression *initTokens, CxxToken *testTokens,
+                       CxxToken *stepTokens, CxxToken *bodyTokens) { return 0; }
+CxxExpression *make_meta_function(CxxExpression *anExpr, CxxTokens *aList, CxxToken *aBody) { return 0; }
+CxxStatement *make_meta_if_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *trueTokens, CxxToken *falseTokens) { return 0; }
+CxxDeclaration *make_linkage_specification(CxxName *aName) { return 0; }
+//CxxMetaInitializers *make_meta_initializers(CxxMetaInitializers *aList, CxxToken *anElement) { return 0; }
+CxxMetaParameter *make_meta_parameter(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxToken *anInit) { return 0; }
+CxxMetaParameters *make_meta_parameters(CxxMetaParameters *aList, CxxMetaParameter *anElement) { return 0; }
+CxxStatement *make_meta_return_statement(CxxExpression *anExpr) { return 0; }
+CxxStatement *make_meta_statement(CxxStatement *aStatement) { return 0; }
+CxxDeclaration *make_meta_statement_declaration(CxxStatement *metaStatement) { return 0; }
+CxxStatement *make_meta_statement_statement(CxxStatement *metaStatement) { return 0; }
+CxxStatement *make_meta_switch_statement(CxxLine *aLine, CxxExpression *testTokens, CxxToken *bodyTokens) { return 0; }
+CxxMetaType *make_meta_type(CxxName *aName) { return 0; }
+CxxName *make_meta_type_id(CxxMetaType *metaType) { return 0; }
+CxxStatement *make_meta_while_statement(CxxLine *aLine, CxxToken *testTokens, CxxToken *bodyTokens) { return 0; }
+CxxExpression *make_minus_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_modulus_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_multiply_expression(CxxExpression *leftExpr, CxxDeclarator *aDeclarator, CxxExpression *rightExpr) { return 0; }
+CxxName *make_name(CxxName *aName) { return 0; }
+CxxName *make_name_expression(CxxName *aName) { return 0; }
+CxxDeclaration *make_namespace_alias_definition(CxxName *aName, CxxName *forId) { return 0; }
+CxxDeclaration *make_namespace_declaration(CxxName *aName) { return 0; }
+CxxName *make_namespace_definition(CxxName *aName, CxxDeclarations *aDeclaration) { return 0; }
+CxxDeclarator *make_nested_declarator(CxxName *aName, CxxDeclarator *aDeclarator) { return 0; }
+CxxName *make_nested_id(CxxName *nestingId, CxxName *nestedId) { return 0; }
+CxxName *make_nested_scope(CxxName *nestingId) { return 0; }
+CxxExpression *make_new_expression(CxxParameters *aPlace, CxxParameters *aType, CxxExpression *anInit) { return 0; }
+CxxExpression *make_new_type_id_expression(CxxParameters *aPlace, CxxExpression *aType, CxxExpression *anInit) { return 0; }
+CxxDeclSpecifierId *make_not_const() { return 0; }
+CxxExpression *make_not_equal_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_not_expression(CxxExpression *anExpr) { return 0; }
+CxxDeclSpecifierId *make_not_inline() { return 0; }
+CxxDeclSpecifierId *make_not_static() { return 0; }
+CxxDeclSpecifierId *make_not_virtual() { return 0; }
+CxxBaseSpecifier *make_not_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
+CxxDeclSpecifierId *make_not_volatile() { return 0; }
+CxxExpression *make_number_literal_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_object_scope_expression(CxxExpression *anExpr, CxxDeclaration *functionDeclarations) { return 0; }
+CxxName *make_operator_add_id() { return 0; }
+CxxName *make_operator_arrow_id() { return 0; }
+CxxName *make_operator_arrow_star_id() { return 0; }
+CxxName *make_operator_ass_add_id() { return 0; }
+CxxName *make_operator_ass_bit_and_id() { return 0; }
+CxxName *make_operator_ass_bit_or_id() { return 0; }
+CxxName *make_operator_ass_div_id() { return 0; }
+CxxName *make_operator_ass_id() { return 0; }
+CxxName *make_operator_ass_mod_id() { return 0; }
+CxxName *make_operator_ass_mul_id() { return 0; }
+CxxName *make_operator_ass_shl_id() { return 0; }
+CxxName *make_operator_ass_shr_id() { return 0; }
+CxxName *make_operator_ass_sub_id() { return 0; }
+CxxName *make_operator_ass_xor_id() { return 0; }
+CxxName *make_operator_bit_and_id() { return 0; }
+CxxName *make_operator_bit_not_id() { return 0; }
+CxxName *make_operator_bit_or_id() { return 0; }
+CxxName *make_operator_call_id() { return 0; }
+CxxName *make_operator_comma_id() { return 0; }
+CxxName *make_operator_dec_id() { return 0; }
+CxxName *make_operator_delete_id() { return 0; }
+CxxName *make_operator_div_id() { return 0; }
+CxxName *make_operator_eq_id() { return 0; }
+CxxName *make_operator_function_id(CxxName *operatorId) { return 0; }
+CxxName *make_operator_ge_id() { return 0; }
+CxxName *make_operator_gt_id() { return 0; }
+CxxName *make_operator_inc_id() { return 0; }
+CxxName *make_operator_index_id() { return 0; }
+CxxName *make_operator_le_id() { return 0; }
+CxxName *make_operator_log_and_id() { return 0; }
+CxxName *make_operator_log_not_id() { return 0; }
+CxxName *make_operator_log_or_id() { return 0; }
+CxxName *make_operator_lt_id() { return 0; }
+CxxName *make_operator_mod_id() { return 0; }
+CxxName *make_operator_mul_id() { return 0; }
+CxxName *make_operator_ne_id() { return 0; }
+CxxName *make_operator_new_id() { return 0; }
+CxxName *make_operator_shl_id() { return 0; }
+CxxName *make_operator_shr_id() { return 0; }
+CxxName *make_operator_sub_id() { return 0; }
+CxxName *make_operator_xor_id() { return 0; }
+CxxParameters *make_parameters(CxxParameters *aList, CxxParameter *anElement) { return 0; }
+CxxParenthesised *make_parenthesised(CxxParameters *aList, CxxCvQualifiers *cvQualifiers, CxxExceptionSpecification *exceptionSpecification) { return 0; }
+CxxExpression *make_plus_expression(CxxExpression *anExpr) { return 0; }
+CxxPointerDeclarator *make_pointer_declarator() { return 0; }
+CxxExpression *make_pointer_expression(CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; }
+CxxExpression *make_post_decrement_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_post_increment_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_pre_decrement_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_pre_increment_expression(CxxExpression *anExpr) { return 0; }
+CxxName *make_pseudo_destructor_id(CxxBuiltInId *aScope, CxxBuiltInId *aName) { return 0; }
+CxxDeclSpecifierId *make_pure_virtual() { return 0; }
+CxxDeclarator *make_reference_declarator() { return 0; }
+CxxExpression *make_reinterpret_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
+CxxStatement *make_return_statement(CxxExpression *anExpr) { return 0; }
+CxxName *make_scoped_id(CxxName *globalId, CxxName *nestedId) { return 0; }
+CxxExpression *make_scoped_pointer_expression(CxxExpression *aScope, CxxDeclarator *aDeclarator, CxxExpression *anExpr) { return 0; }
+CxxSegment *make_segment(CxxSegment *aSegment) { return 0; }
+CxxFunctionBody *make_segment_function_block(CxxFunctionBody *functionBody, CxxSegment *aSegment) { return 0; }
+CxxDeclSpecifierId *make_set_template_decl_specifier(CxxDeclSpecifierId *aName) { return 0; }
+CxxDeclaration *make_set_template_declaration(CxxDeclaration *aDeclaration) { return 0; }
+CxxExpression *make_set_template_expression(CxxExpression *anExpr) { return 0; }
+CxxName *make_set_template_id(CxxName *aName) { return 0; }
+CxxName *make_set_template_name(CxxName *aName) { return 0; }
+CxxName *make_set_template_scope(CxxName *aName) { return 0; }
+CxxExpression *make_shift_left_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxExpression *make_shift_right_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxDeclaration *make_simple_declaration(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_sizeof_expression(CxxExpression *anExpr) { return 0; }
+CxxStatements *make_statements(CxxStatements *, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_static_cast_expression(CxxExpression *aType, CxxExpression *anExpr) { return 0; }
+CxxExpression *make_string_literal_expression(CxxStrings *aString) { return 0; }
+CxxStrings *make_strings(CxxStringLiteral *anElement, CxxStrings *aList) { return 0; }
+CxxExpression *make_subtract_expression(CxxExpression *leftExpr, CxxExpression *rightExpr) { return 0; }
+CxxStatement *make_switch_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; }
+CxxExpression *make_syntax_macro_definition(CxxMetaType *metaType, CxxIsTree isTree, CxxName *aName, CxxSyntaxMacroParameters *aList, CxxToken *aBody) { return 0; }
+CxxSyntaxMacroParameter *make_syntax_macro_parameter(CxxToken *metaType, CxxIsTree isTree, CxxName *aName) { return 0; }
+CxxSyntaxMacroParameters *make_syntax_macro_parameters(CxxSyntaxMacroParameters *aList, CxxSyntaxMacroParameter *anElement) { return 0; }
+CxxTemplateArgument *make_template_argument(CxxParameter *aParameter) { return 0; }
+CxxTemplateArguments *make_template_arguments(CxxTemplateArguments *aList, CxxTemplateArgument *anElement) { return 0; }
+CxxDeclaration *make_template_declaration(CxxTemplateParameters *aList, CxxDeclaration *aDeclaration) { return 0; }
+CxxName *make_template_name(CxxName *aName, CxxTemplateArguments *templateArguments) { return 0; }
+CxxTemplateParameter *make_templated_template_parameter(CxxTemplateParameter *typeParameter, CxxName *aName) { return 0; }
+CxxTemplateParameter *make_template_parameter(CxxParameter *aParameter) { return 0; }
+CxxTemplateParameters *make_template_parameters(CxxTemplateParameters *aList, CxxTemplateParameter *anElement) { return 0; }
+CxxTemplatedTypeParameter *make_templated_type_parameter(CxxTemplateParameters *templateParameters, CxxName *aName) { return 0; }
+CxxExpression *make_this_expression() { return 0; }
+CxxExpression *make_throw_expression(CxxExpression *anExpr) { return 0; }
+CxxExpression *make_tokens_expression(CxxTokens *someTokens) { return 0; }
+CxxToken *make_tree_argument(CxxToken *aToken) { return 0; }
+CxxTokens *make_tree_arguments(CxxTokens *aList, CxxToken *anElement) { return 0; }
+CxxTreeExpression *make_tree_array_expression(CxxTreeExpression *anExpr, CxxExpression *indexExpr) { return 0; }
+CxxTreeExpression *make_tree_arrow_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; }
+CxxTreeExpression *make_tree_call_expression(CxxTreeExpression *anExpr, CxxTokens *aList) { return 0; }
+CxxTreeExpression *make_tree_dot_expression(CxxTreeExpression *anExpr, CxxName *aName) { return 0; }
+CxxTreeExpression *make_tree_expression(CxxName *aName) { return 0; }
+CxxName *make_tree_id(CxxName *aName) { return 0; }
+CxxTreeExpression *make_tree_pointer_expression(CxxTreeExpression *anExpr) { return 0; }
+CxxExpression *make_true_expression() { return 0; }
+CxxFunctionBody *make_try_block(CxxStatement *aStatement, CxxHandlers *exceptionHandlers) { return 0; }
+CxxStatement *make_try_block_statement(CxxFunctionBody *tryBlock) { return 0; }
+CxxFunctionBody *make_try_function_block(CxxFunctionBody *functionBody, CxxHandlers *exceptionHandlers) { return 0; }
+CxxExpression *make_type1_expression(CxxExpression *functionName, CxxParenthesised *aParenthesis, CxxType1Parameters *type1Parameters) { return 0; }
+CxxTemplateParameter *make_type_template_parameter(CxxSimpleTypeParameter *typeParameter, CxxExpression *typeId) { return 0; }
+CxxExpression *make_typed_expression(CxxName *frontName, CxxExpression *backName) { return 0; }
+CxxName *make_typed_name(CxxName *frontName, CxxName *backName) { return 0; }
+CxxExpression *make_typeid_expression(CxxExpression *aList) { return 0; }
+CxxSimpleTypeParameter *make_typename_template_parameter(CxxName *aName) { return 0; }
+CxxSimpleTypeParameter *make_typename_type_parameter(CxxName *aName) { return 0; }
+CxxType1Parameters *make_type1_parameters(CxxType1Parameters *aList, CxxParameters *someParameters) { return 0; }
+CxxDeclaration *make_using_declaration(bool isTypename, CxxName *aName) { return 0; }
+CxxDeclaration *make_using_directive(CxxName *aName) { return 0; }
+CxxFunctionBody *make_using_function_block(CxxFunctionBody *functionBody, CxxFileIds *fileIds) { return 0; }
+CxxDeclaration *make_using_implementation_declaration(CxxFileId *fileId) { return 0; }
+CxxDeclaration *make_using_interface_declaration(CxxFileId *fileId) { return 0; }
+CxxUtility *make_utility(CxxUtility *aUtility) { return 0; }
+CxxUtility *make_utility_mode() { return 0; }
+CxxBaseSpecifier *make_virtual_base_specifier(CxxBaseSpecifier *baseSpecifier) { return 0; }
+CxxStatement *make_while_statement(CxxCondition *testExpr, CxxStatement *aStmt) { return 0; }
+
diff --git a/infobase/examples/cpp_grammar_code/CxxToken.cpp b/infobase/examples/cpp_grammar_code/CxxToken.cpp
new file mode 100644 (file)
index 0000000..7efca54
--- /dev/null
@@ -0,0 +1,9 @@
+//
+//       Title:                        C++ Grammar Token support compilation unit.
+//
+//       File Name:            CxxToken.cpp
+//
+//       Author:                       E.D.Willink
+//END
+//
+#include <CxxToken.cxx>
diff --git a/infobase/examples/cpp_grammar_code/CxxToken.cxx b/infobase/examples/cpp_grammar_code/CxxToken.cxx
new file mode 100644 (file)
index 0000000..6ad6227
--- /dev/null
@@ -0,0 +1,17 @@
+#include <CxxToken.hxx>
+#include <memory.h>
+
+//CxxToken::CxxToken()
+//:
+//     _value(0)
+//{}
+
+CxxNaffToken::CxxNaffToken(int tokenValue, const char *yyText, int yyLeng)
+:
+       Super(tokenValue), _text(new char[yyLeng+1]), _leng(yyLeng)
+{
+       memcpy(_text, yyText, yyLeng);
+       _text[_leng] = 0;
+}
+
+CxxNaffToken::~CxxNaffToken() { delete[] _text; }
diff --git a/infobase/examples/cpp_grammar_code/CxxToken.hxx b/infobase/examples/cpp_grammar_code/CxxToken.hxx
new file mode 100644 (file)
index 0000000..9455f9b
--- /dev/null
@@ -0,0 +1,336 @@
+#ifndef CXXTOKEN_HXX
+#define CXXTOKEN_HXX
+
+#include <iostream.h>
+#include <stdlib.h>
+
+#define YYSTYPE CxxTokenType
+#define YY_parse_STYPE CxxTokenType
+#define YACC_BANG_TYPE size_t
+#define YACC_MARK_TYPE size_t
+
+#define YACC_BANG() push_bang()
+#define YACC_UNBANG(bangValue, msg) pop_bang(bangValue); yyerrok; yyclearin; yyerror(msg);
+
+#define ERRMSG(a) do { cout << "ERROR -- " << a << endl; increment_error_count(); } while (0)
+
+#ifdef NEEDS_BOOL
+enum bool { false, true };
+#endif
+
+#ifdef BISON_PP_CLASS
+#define PARSE_TOKEN(a) BISON_PP_CLASS::a
+#else
+#define PARSE_TOKEN(a) a
+#endif
+
+extern size_t line_number;
+extern bool c_keywords;
+extern bool echo_line_numbers;
+extern bool echo_line_text;
+extern void increment_error_count();
+extern int tokenMarkDepth;
+
+class CxxToken
+{
+       int _value;
+private:
+       CxxToken(const CxxToken&);
+       CxxToken& operator=(const CxxToken&);
+public:
+       CxxToken(int tokenValue = 0) : _value(tokenValue) {}
+       virtual ~CxxToken() {}
+       int value() const { return _value; }
+};
+
+enum CxxIsTemplate { IS_DEFAULT, IS_TEMPLATE };
+enum CxxIsTree { IS_SCALAR, IS_TREE };
+typedef CxxToken CxxTreeArgument;
+
+class CxxStatement : public CxxToken {};
+typedef CxxStatement CxxDeclaration;
+class CxxExpression : public CxxStatement {};
+class CxxName : public CxxExpression {};
+class CxxTokens : public CxxToken {};
+class CxxMetaObject : public CxxExpression {};
+class CxxMetaStatement : public CxxStatement {};
+
+class CxxStatements : public CxxStatement {};
+typedef CxxStatements CxxDeclarations;
+typedef CxxDeclarations CxxMemberDeclarations;
+typedef CxxExpression CxxTreeExpression;
+
+class CxxKeyword : public CxxName {};
+class CxxDeclSpecifierId : public CxxKeyword {};
+
+class CxxAccessSpecifier : public CxxKeyword {};
+class CxxBaseSpecifier : public CxxToken {};
+class CxxBaseSpecifiers : public CxxTokens {};
+class CxxBrace : public CxxToken {};
+class CxxBuiltInId : public CxxName {};
+class CxxCharacterLiteral : public CxxToken {};
+class CxxClass : public CxxToken {};
+class CxxClassKey : public CxxKeyword {};
+class CxxCondition : public CxxExpression {};
+class CxxCvQualifiers : public CxxDeclSpecifierId {};
+class CxxDeclarator : public CxxToken {};
+typedef CxxExpression CxxDeleteExpression;
+//class CxxDerived : public CxxToken {};
+//class CxxEnum : public CxxToken {};
+class CxxEnumerator : public CxxToken {};
+class CxxEnumerators : public CxxTokens {};
+class CxxExceptionDeclaration : public CxxToken {};
+class CxxExceptionSpecification : public CxxToken {};
+class CxxExpressions : public CxxExpression {};
+class CxxFileId : public CxxToken {};
+class CxxFileIds : public CxxTokens {};
+class CxxFileName : public CxxToken {};
+class CxxFloatingLiteral : public CxxToken {};
+class CxxFunctionBody : public CxxStatement {};
+class CxxFunctionDeclarations : public CxxDeclarations {};
+class CxxHandler : public CxxToken {};
+class CxxHandlers : public CxxTokens {};
+class CxxIdentifier : public CxxName {};
+//class CxxIds : public CxxTokens {};
+class CxxInitializerClause : public CxxExpression {};
+class CxxInitializerClauses : public CxxInitializerClause {};
+class CxxIntegerLiteral : public CxxToken {};
+class CxxLine : public CxxToken {};
+//class CxxList : public CxxTokens {};
+class CxxMemInitializer : public CxxToken {};
+class CxxMemInitializers : public CxxTokens {};
+class CxxMetaClass : public CxxStatement {};
+class CxxMetaFunction : public CxxMetaObject {};
+class CxxMetaInitializer : public CxxToken {};
+class CxxMetaInitializers : public CxxTokens {};
+class CxxMetaParameter : public CxxToken {};
+class CxxMetaParameters : public CxxTokens {};
+//class CxxMetaPrototype : public CxxToken {};
+//class CxxMetaPrototypes : public CxxTokens {};
+class CxxMetaType : public CxxName {};
+class CxxMetaVariable : public CxxMetaObject {};
+class CxxNamespace : public CxxToken {};
+typedef CxxExpression CxxNewExpression;
+class CxxNumberLiteral : public CxxExpression {};
+class CxxParameter : public CxxExpression {};
+class CxxParameters : public CxxExpression {};
+class CxxParenthesised : public CxxToken {};
+class CxxPointerDeclarator : public CxxDeclarator {};
+class CxxPosition : public CxxName {};
+class CxxSegment : public CxxName {};
+class CxxSpacing : public CxxToken {};
+class CxxStrings : public CxxToken {};
+typedef CxxStrings CxxStringLiteral;
+class CxxSubspace : public CxxToken {};
+class CxxSyntaxMacroParameter : public CxxToken {};
+class CxxSyntaxMacroParameters : public CxxTokens {};
+class CxxTemplateArgument : public CxxToken {};
+class CxxTemplateArguments : public CxxTokens {};
+class CxxTemplateParameter : public CxxToken {};
+class CxxTemplateParameters : public CxxTokens {};
+class CxxSimpleTypeParameter : public CxxTemplateParameter {};
+class CxxTemplatedTypeParameter : public CxxTemplateParameter {};
+class CxxTokenStatements : public CxxTokens {};
+class CxxTreeArguments : public CxxTokens {};
+class CxxType1Parameters : public CxxTokens {};
+class CxxTypeId : public CxxToken {};
+class CxxTypeIds : public CxxTokens {};
+class CxxUtility : public CxxToken {};
+
+#define FOGPARSERVALUE_ENUM(T,N) \
+       const T *name2(u_,N); \
+       const T& N() const { return *name2(u_,N); } \
+       const T* & N() { return name2(u_,N); }
+#define FOGPARSERVALUE_POINTER(T,N) T *N;
+#define FOGPARSERVALUE_VALUE(T,N) T N;
+
+union CxxTokenType
+{
+               CxxToken *_token;
+
+               FOGPARSERVALUE_VALUE(bool, _bool)
+               FOGPARSERVALUE_VALUE(long, _long)
+               FOGPARSERVALUE_POINTER(CxxBrace, brace)
+               FOGPARSERVALUE_POINTER(CxxSpacing, spacing)
+
+               FOGPARSERVALUE_POINTER(CxxAccessSpecifier, access_specifier)
+               FOGPARSERVALUE_POINTER(CxxBaseSpecifier, base_specifier)
+               FOGPARSERVALUE_POINTER(CxxBaseSpecifiers, base_specifiers)
+               FOGPARSERVALUE_POINTER(CxxBuiltInId, built_in_id)
+               FOGPARSERVALUE_POINTER(CxxCharacterLiteral, character_literal)
+               FOGPARSERVALUE_POINTER(CxxClass, _class)
+               FOGPARSERVALUE_POINTER(CxxClassKey, class_key)
+               FOGPARSERVALUE_POINTER(CxxCondition, condition)
+               FOGPARSERVALUE_POINTER(CxxCvQualifiers, cv_qualifiers)
+               FOGPARSERVALUE_POINTER(CxxDeclSpecifierId, decl_specifier_id)
+               FOGPARSERVALUE_POINTER(CxxDeclaration, declaration)
+               FOGPARSERVALUE_POINTER(CxxDeclarations, declarations)
+               FOGPARSERVALUE_POINTER(CxxDeclarator, declarator)
+               FOGPARSERVALUE_POINTER(CxxDeleteExpression, delete_expression)
+               FOGPARSERVALUE_POINTER(CxxEnumerator, enumerator)
+               FOGPARSERVALUE_POINTER(CxxEnumerators, enumerators)
+               FOGPARSERVALUE_POINTER(CxxExceptionDeclaration, exception_declaration)
+               FOGPARSERVALUE_POINTER(CxxExceptionSpecification, exception_specification)
+               FOGPARSERVALUE_POINTER(CxxExpression, expression)
+               FOGPARSERVALUE_POINTER(CxxExpressions, expressions)
+               FOGPARSERVALUE_POINTER(CxxFileId, file_id)
+               FOGPARSERVALUE_POINTER(CxxFileIds, file_ids)
+               FOGPARSERVALUE_POINTER(CxxFileName, file_name)
+               FOGPARSERVALUE_POINTER(CxxFloatingLiteral, floating_literal)
+               FOGPARSERVALUE_POINTER(CxxFunctionBody, function_body)
+               FOGPARSERVALUE_POINTER(CxxHandler, handler)
+               FOGPARSERVALUE_POINTER(CxxHandlers, handlers)
+               FOGPARSERVALUE_POINTER(CxxIdentifier, identifier)
+               FOGPARSERVALUE_POINTER(CxxInitializerClause, initializer_clause)
+               FOGPARSERVALUE_POINTER(CxxInitializerClauses, initializer_clauses)
+               FOGPARSERVALUE_POINTER(CxxIntegerLiteral, integer_literal)
+               FOGPARSERVALUE_POINTER(CxxKeyword, keyword)
+               FOGPARSERVALUE_POINTER(CxxLine, line)
+               FOGPARSERVALUE_POINTER(CxxMemInitializer, mem_initializer)
+               FOGPARSERVALUE_POINTER(CxxMemInitializers, mem_initializers)
+               FOGPARSERVALUE_POINTER(CxxMemberDeclarations, member_declarations)
+               FOGPARSERVALUE_POINTER(CxxMetaClass, meta_class)
+               FOGPARSERVALUE_POINTER(CxxMetaFunction, meta_function)
+               FOGPARSERVALUE_POINTER(CxxMetaInitializer, meta_initializer)
+               FOGPARSERVALUE_POINTER(CxxMetaInitializers, meta_initializers)
+               FOGPARSERVALUE_POINTER(CxxMetaObject, meta_object)
+               FOGPARSERVALUE_POINTER(CxxMetaStatement, meta_statement)
+               FOGPARSERVALUE_POINTER(CxxMetaType, meta_type)
+               FOGPARSERVALUE_POINTER(CxxMetaVariable, meta_variable)
+               FOGPARSERVALUE_POINTER(CxxName, name)
+               FOGPARSERVALUE_POINTER(CxxNewExpression, new_expression)
+               FOGPARSERVALUE_POINTER(CxxNumberLiteral, number_literal)
+               FOGPARSERVALUE_POINTER(CxxParameter, parameter)
+               FOGPARSERVALUE_POINTER(CxxParameters, parameters)
+               FOGPARSERVALUE_POINTER(CxxParenthesised, parenthesised)
+               FOGPARSERVALUE_POINTER(CxxPointerDeclarator, pointer_declarator)
+               FOGPARSERVALUE_POINTER(CxxPosition, position)
+               FOGPARSERVALUE_POINTER(CxxSegment, segment)
+               FOGPARSERVALUE_POINTER(CxxSimpleTypeParameter, simple_type_parameter)
+               FOGPARSERVALUE_POINTER(CxxStatement, statement)
+               FOGPARSERVALUE_POINTER(CxxStatements, statements)
+               FOGPARSERVALUE_POINTER(CxxStringLiteral, string_literal)
+               FOGPARSERVALUE_POINTER(CxxStrings, strings)
+               FOGPARSERVALUE_POINTER(CxxSubspace, subspace)
+               FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameter, syntax_macro_parameter)
+               FOGPARSERVALUE_POINTER(CxxSyntaxMacroParameters, syntax_macro_parameters)
+               FOGPARSERVALUE_POINTER(CxxTemplateArgument, template_argument)
+               FOGPARSERVALUE_POINTER(CxxTemplateArguments, template_arguments)
+               FOGPARSERVALUE_POINTER(CxxTemplateParameter, template_parameter)
+               FOGPARSERVALUE_POINTER(CxxTemplateParameters, template_parameters)
+               FOGPARSERVALUE_POINTER(CxxTemplatedTypeParameter, templated_type_parameter)
+               FOGPARSERVALUE_POINTER(CxxToken, token)
+               FOGPARSERVALUE_POINTER(CxxTokenStatements, token_statements)
+               FOGPARSERVALUE_POINTER(CxxTokens, tokens)
+               FOGPARSERVALUE_POINTER(CxxTreeArgument, tree_argument)
+               FOGPARSERVALUE_POINTER(CxxTreeArguments, tree_arguments)
+               FOGPARSERVALUE_POINTER(CxxTreeExpression, tree_expression)
+               FOGPARSERVALUE_POINTER(CxxType1Parameters, type1_parameters)
+               FOGPARSERVALUE_POINTER(CxxUtility, utility)
+
+               FOGPARSERVALUE_VALUE(int, bang)
+               FOGPARSERVALUE_VALUE(CxxIsTemplate, is_template)
+               FOGPARSERVALUE_VALUE(YACC_MARK_TYPE, mark)
+               FOGPARSERVALUE_VALUE(size_t, nest)
+#if 0
+       CxxAccessSpecifier *access_specifier;
+       CxxBaseSpecifier *base_specifier;
+       CxxBaseSpecifiers *base_specifiers;
+       CxxBuiltInId *built_in_id;
+       CxxCharacterLiteral *character_literal;
+       CxxClass *_class;
+       CxxClassKey *class_key;
+       CxxCondition *condition;
+       CxxCvQualifiers *cv_qualifiers;
+       CxxDeclaration *declaration;
+       CxxDeclarations *declarations;
+       CxxDeclarator *declarator;
+       CxxDeclSpecifierId *decl_specifier_id;
+//     CxxDerived *derived;
+//     CxxEnum *_enum;
+       CxxEnumerator *enumerator;
+       CxxEnumerators *enumerators;
+       CxxExceptionDeclaration *exception_declaration;
+       CxxExceptionSpecification *exception_specification;
+       CxxExpression *expression;
+       CxxExpressions *expressions;
+       CxxFileId *file_id;
+       CxxFileIds *file_ids;
+       CxxFileName *file_name;
+       CxxFloatingLiteral *floating_literal;
+       CxxFunctionBody *function_body;
+       CxxFunctionDeclarations *function_declarations;
+       CxxHandler *handler;
+       CxxHandlers *handlers;
+       CxxIdentifier *identifier;
+//     CxxIds *ids;
+       CxxInitializerClause *initializer_clause;
+       CxxInitializerClauses *initializer_clauses;
+       CxxIntegerLiteral *integer_literal;
+       CxxKeyword *keyword;
+       CxxLine *line;
+//     CxxList *list;
+       CxxMemInitializer *mem_initializer;
+       CxxMemInitializers *mem_initializers;
+       CxxMemberDeclarations *member_declarations;
+       CxxMetaClass *meta_class;
+//     CxxMetaFunction *meta_function;
+//     CxxMetaInitializer *meta_initializer;
+//     CxxMetaInitializers *meta_initializers;
+//     CxxMetaObject *meta_object;
+       CxxMetaParameter *meta_parameter;
+       CxxMetaParameters *meta_parameters;
+//     CxxMetaPrototype *meta_prototype;
+//     CxxMetaPrototypes *meta_prototypes;
+//     CxxMetaStatement *meta_statement;
+       CxxMetaType *meta_type;
+//     CxxMetaVariable *meta_variable;
+       CxxName *name;
+//     CxxNamespace *_namespace;
+       CxxNumberLiteral *number_literal;
+       CxxParameter *parameter;
+       CxxParameters *parameters;
+       CxxParenthesised *parenthesised;
+       CxxPointerDeclarator *pointer_declarator;
+       CxxSegment *segment;
+       CxxSimpleTypeParameter *simple_type_parameter;
+       CxxStatement *statement;
+       CxxStatements *statements;
+       CxxStringLiteral *string_literal;
+       CxxStrings *strings;
+       CxxSyntaxMacroParameter *syntax_macro_parameter;
+       CxxSyntaxMacroParameters *syntax_macro_parameters;
+       CxxTemplateArgument *template_argument;
+       CxxTemplateArguments *template_arguments;
+       CxxTemplateParameter *template_parameter;
+       CxxTemplateParameters *template_parameters;
+       CxxTemplatedTypeParameter *templated_type_parameter;
+       CxxToken *token;
+       CxxTokens *tokens;
+//     CxxTreeArgument *tree_argument;
+//     CxxTreeArguments *tree_arguments;
+//     CxxTreeExpression *tree_expression;
+       CxxType1Parameters *type1_parameters;
+//     CxxTypeId *type_id;
+//     CxxTypeIds *type_ids;
+       CxxUtility *utility;
+       YACC_BANG_TYPE bang;
+       YACC_MARK_TYPE mark;
+       size_t nest;
+#endif
+};
+
+class CxxNaffToken : public CxxToken
+{
+       typedef CxxToken Super;
+       char *_text;
+       int _leng;
+private:
+       CxxNaffToken(const CxxNaffToken&);
+       CxxNaffToken& operator=(const CxxNaffToken&);
+public:
+       CxxNaffToken(int tokenValue, const char *yyText, int yyLeng);
+       virtual ~CxxNaffToken();
+};
+
+#endif
diff --git a/infobase/examples/cpp_grammar_code/README b/infobase/examples/cpp_grammar_code/README
new file mode 100644 (file)
index 0000000..b19e98c
--- /dev/null
@@ -0,0 +1,20 @@
+This directory tree comprises a pre-built demonstration of the superset C++ grammar
+from FOG..
+
+Contents
+--------
+
+       Release/grammar.exe     -- the statically bound executable (on NT)
+    sun4o/grammar -- the statically bound executable (on Unix)
+
+It is a command line based utility. See index.html for details.
+
+Bug reporting
+-------------
+
+Please report any bugs to Ed.Willink@rrl.co.uk. I will endeavour to fix them,
+but since this code is a one man effort and my time is primarily devoted to
+my other activities for Thales Research, only simple and easy fixes are likely.
+I am more likely to be able to fix the problem if you can trim your problem to
+just a few lines.
+
diff --git a/infobase/examples/cpp_grammar_code/index.html b/infobase/examples/cpp_grammar_code/index.html
new file mode 100644 (file)
index 0000000..af2afda
--- /dev/null
@@ -0,0 +1,196 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
+<title>Ed's Toolkit</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<h1 align="center">Superset C++ Grammar</h1>
+
+<hr>
+
+<p>This work area supports a demonstration of the superset C++
+grammar described in Chapter 5 of <a
+href="mailto:Ed.Willink@rrl.co.uk">Ed Willink</a>'s thesis on <a
+href="http://www.computing.surrey.ac.uk/research/dsrg/fog/FogThesis.html">Meta-Compilation
+for C++</a>. It contains working lex and yacc grammars that
+enable C++ source to be lexically analysed, then syntactically
+analysed without semantic knowlege. The lex and yacc grammar have
+their action routines defined by macros in the hope that
+reconfiguration may be possible without editing the grammars
+directly. The dummy implementations of the yacc macros do nothing
+other than count statements and diagnose the back-tracking
+behaviour. Users may add their own syntactic level code. A proper
+C++ parser needs semantic analysis as well, including correction
+of minor misprses at the syntactic level. Semantic interpretaion
+is provided by <a
+href="http://www.computing.surrey.ac.uk/research/dsrg/fog/">FOG</a>
+from which this demonstration is split off.</p>
+
+<p>The work area is self-sufficient, requiring only <em>lex</em>
+and <em>yacc</em>, or <em>flex</em> and <em>bison</em>.</p>
+
+<hr>
+
+<h2>Command Line</h2>
+
+<p>The test grammar is a simple command line utility, for
+analysing a single <strong>pre-processed</strong> source file
+(use CC -E to run just the preprocessor on your source files)..</p>
+
+<pre>  grammar [options] &lt; source-file</pre>
+
+<p>The full set of command line options is:</p>
+
+<pre>  -c      Recognise only C keywords - approximates C rather than C++ parsing
+       -m      Display mark activity.
+       -n      Echo line numbers.
+       -t      Echo source line text.
+       -y      Display yacc diagnostics.</pre>
+
+<p>On completion a three line diagnostic summarises the search
+activity. </p>
+
+<hr>
+
+<h2>Files</h2>
+
+<p><a href="CxxSrc.tgz">CxxSrc.tgz</a>, <a href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>
+The source distribution kit including a Sun or NT executable.</p>
+
+<p><a href="CxxLexer.l">CxxLexer.l</a> A simple lexer for all C
+and/or C++ tokens</p>
+
+<p><a href="CxxParser.y">CxxParser.y</a> The parser,
+automatically extracted from FogParser.y.</p>
+
+<p><a href="CxxToken.hxx">CxxToken.hxx</a>, <a
+href="CxxToken.cxx">CxxToken.cxx</a> A trivial class used by the
+parser to represent each parsed token.</p>
+
+<p><a href="CxxLexing.hxx">CxxLexing.hxx</a>, <a
+href="CxxLexing.cxx">CxxLexing.cxx</a> Interface and
+implementation of token creation routines for the lexer.</p>
+
+<p><a href="CxxParsing.hxx">CxxParsing.hxx</a>, <a
+href="CxxParsing.cxx">CxxParsing.cxx</a> Interface and
+implementation of token manioulation routines for the parser.</p>
+
+<p><a href="CxxLexer.cpp">CxxLexer.cpp</a>, <a
+href="CxxParser.cpp">CxxParser.cpp</a>, <a href="CxxToken.cpp">CxxToken.cpp</a>
+Degenerate compilation units for the above.</p>
+
+<p><a href="makefile">makefile</a>, <a href="makefile.macros">makefile.macros</a>,
+<a href="CxxLexer.l">makefile.unix</a> Unix build scripts</p>
+
+<p><a href="makefile.gmake">makefile.gmake</a>, <a
+href="makefile.macros">makefile.macros</a>, <a href="grammar.dsw">grammar.dsw</a>,
+<a href="grammar.dsp">grammar.dsp</a> NT build scripts and
+DevStudio workspace and project</p>
+
+<p><a><u>sun4o/grammar</u></a> Built executable (on Unix)</p>
+
+<p><a><u>Release/grammar.exe</u></a> Built executable (on NT)</p>
+
+<hr>
+
+<h2>Unix Builds</h2>
+
+<p>The code builds under Solaris 2.5 and with Sun C++ 4.2.</p>
+
+<pre>  make sun</pre>
+
+<p>or Gnu egcs-1.0.2 release, with flex 2.3.7, bison 1.16</p>
+
+<pre>  make gnu</pre>
+
+<hr>
+
+<h2>NT Builds</h2>
+
+<p>The code builds under NT 4 and has been tested with DevStudio
+V6 and cygwin 1.1.</p>
+
+<h3>a) cygwin</h3>
+
+<p>You need cygwin, the latest version of which is available <a
+href="ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/setup.exe">ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/setup.exe</a></p>
+
+<p>A slightly easier to install earlier version (used by the
+author) is <a
+href="ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/old/cygwin-b20/full.exe">ftp://sunsite.org.uk:21/Mirrors/sourceware.cygnus.com/pub/cygwin/old/cygwin-b20/full.exe</a></p>
+
+<p>Use a mirror site listed at <a
+href="http://sources.redhat.com/cygwin/mirrors.html">http://sources.redhat.com/cygwin/mirrors.html</a>.</p>
+
+<p>The older cygwin is a simple standard NT installation - just
+run full.exe (with administrator rights) and accept the default
+installation paths (gnu tools build them in). The newer cygwin is
+much smarter, doing automatic selective downloads - which the
+author's firewall messes up.</p>
+
+<h3>b) Path configuration</h3>
+
+<p>You may want to make cygwin tools accessible from command
+prompts so</p>
+
+<pre>Start-&gt;Settings-&gt;ControlPanel
+       System|Environment
+               Add Variable PATH
+               Value C:\cygwin\cygwin-b20\H-i586-cygwin32\BIN</pre>
+
+<h3>c) DevStudio configuration</h3>
+
+<p>You need to configure DevStudio to use cygwin.</p>
+
+<p>In DevStudio:</p>
+
+<pre>Tools-&gt;Options-&gt;Directories
+       Show Directories For Executable files
+       Add C:\cygwin\bin</pre>
+
+<h3>d) Unpacking</h3>
+
+<p>Then use winzip or gunzip to extract all of <a
+href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>:</p>
+
+<pre>double click in Explorer on <a href="CxxNtSrc.tgz">CxxNtSrc.tgz</a>
+       Yes to decompress archive to temporary file
+       Wait a few moments
+       Actions...-&gt;Extract
+               All Files, to e.g. C:\CxxGrammar, use Folder names, Extract
+       Close Winzip</pre>
+
+<h3>e) DevStudio build</h3>
+
+<pre>Double click in Explorer on <a href="grammar.dsw">grammar.dsw</a>
+       If prompted to browse for a SourceSafe project Click No.
+       If prompted to attempt SourceSafe connection in another session click No.
+       Select your preferred configuration (Win32 Debug is default)
+       Select FileView|grammar Files-&gt;Targets-&gt;executable
+       &lt;Ctrl&gt;F7
+       after a few seconds everything is built</pre>
+
+<p>DevStudio reports 0 errors and 1 warnings</p>
+
+<pre>Build : warning : failed to (or don't know how to) build 'C:\CxxGrammar\Targets\executable'</pre>
+
+<p>The warning is an artefact of fake build targets</p>
+
+<p>Everything in DevStudio is compiled using a makefile.gmake
+target which is selected for a &lt;CTRL&gt;F7 in the Workspace
+window. Steer clear of the standard DevStudio F7 which builds all
+targets: backup then clean then executables then realclean then
+test etc. No harm is done but it takes a long time.</p>
+
+<hr>
+
+<p><i>Last updated <!--webbot bot="Timestamp" startspan
+s-type="EDITED" s-format="%d %B, %Y" -->28 July, 2001<!--webbot
+bot="Timestamp" i-checksum="21078" endspan -->.</i> </p>
+</body>
+</html>
diff --git a/infobase/examples/cpp_grammar_code/makefile b/infobase/examples/cpp_grammar_code/makefile
new file mode 100644 (file)
index 0000000..e2b3d56
--- /dev/null
@@ -0,0 +1,55 @@
+#
+#      Title:          Make file for Cxx Grammar tester.
+#
+#      Author:         E.D.Willink
+#
+#      SCCS:           %W% %G%
+#
+#      Description:
+#                      This makefile wrapper redirects all activity to makefile.unix after first ensuring that
+#                      any .INIT provided by ../import.make has executed to load required source files.
+#
+#      Targets:        
+#                      executable, normal
+#                                      builds $(ARCH)o/grammar
+#                      sun
+#                                      builds $(ARCH)o/grammar using sun compiler, yacc and lex
+#                      gnu
+#                                      builds $(ARCH)o/grammar using gnu compiler, bison and flex
+#                      clean
+#                                      eliminates $(ARCH)o* intermediates
+#                      realclean
+#                                      eliminates $(ARCH)o* intermediates and executables
+#                      source_kit
+#                                      generates the distribution kits
+#
+#      Switch settings are appropriate for Sun C++ 4.2.
+#      Commented settings indicate what might be appropriate for gcc once it supports templates plausibly.
+#
+#      Latest Modification:
+# EDW          Date:   14-Jun-2001         Original
+#END
+
+.SUFFIXES:
+
+SRCDIR = sources
+ARCH = sun4
+OBJ_DIR = $(ARCH)o
+OBJ_DIR_PI = $(ARCH)o_pi
+OBJ_DIR_G = $(ARCH)o_g
+OBJ_DIR_PI_G = $(ARCH)o_pi_g
+
+default : executable
+
+#../import.make is empty by default, but may be provided to copy sources from somewhere.
+../import.make :
+       echo > $@
+IMPORT_PATH = grammar
+include ../import.make
+
+clean executable gnu realclean source_kit sun %.tar \
+$(SRCDIR)/% $(OBJ_DIR)/% $(OBJ_DIR_PI)/% $(OBJ_DIR_G)/% $(OBJ_DIR_PI_G)/% \
+       : makefile makefile.unix .FORCE
+       $(MAKE) -f makefile.unix $(MFLAGS) $(MAKEFLAGS) $@ 
+
+.FORCE:
\ No newline at end of file
diff --git a/infobase/examples/cpp_grammar_code/makefile.gmake b/infobase/examples/cpp_grammar_code/makefile.gmake
new file mode 100644 (file)
index 0000000..b321cb3
--- /dev/null
@@ -0,0 +1,188 @@
+#
+#      Title:                  makefile.gmake
+#
+#      Author:                 E.D.Willink
+#
+#      Description:    GNU make file for Cxx Grammar tester under NT
+#
+#              Environment
+#                      INTDIR  intermediate directory for objects (defaults to ".\Release")
+#                      OUTDIR  output directory for executable (defaults to ".\Release")
+#                      MSINCDIR path of main system include directory (defaults to $(MSVCDIR)\Include)
+#
+#              Public Targets
+#                      executable
+#                                      builds '$(OUTDIR)'/grammar.exe
+#                      clean
+#                                      eliminates $(INTDIR) intermediates
+#                      realclean
+#                                      eliminates $(INTDIR) and '$(OUTDIR)' intermediates
+#                      source_kit
+#                                      generates the distribution kits
+#              Private Targets
+#                      backup
+#                                      copies changed sources from C: to $(BACKUPDIR)
+#                      tar_delta
+#                                      tars up changes ready for transfer to Unix
+#
+#
+#      Build is error and warning free as
+#              nmake -f makefile.gmake
+#      (after using - Visual C++ 6
+#              "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
+#      or - Visual C++ 5
+#              "C:\Program Files\DevStudio\VC\Bin\vcvars32.bat"
+#        in a Command Prompt to set up the Visual C++ environment).
+#      Alternatively do a "Compile xxx" to compile target xxx from the "grammar files->Targets"
+#      after loading root.dsw into DevStudio.
+#
+.SUFFIXES:
+.SUFFIXES: .l .y .hxx .cxx .cpp .obj
+
+TARGET = grammar
+INTDIR = .\Release
+OUTDIR = $(INTDIR)
+SRCDIR = Sources
+DUMMYDIR = Dummy
+LSTDIR = Listings
+MSINCDIR = $(MSVCDIR)\Include
+BACKUPDIR = Q:/P541/C/BackUp/grammar
+TARDELTADIR = P:/$(USERNAME)
+
+CPRINT = "../tools/cprint/$(OUTDIR)/cprint.exe" -b -c150 -e -h0 -f1 -l69 -n25 -t4
+WIDE_CPRINT = "../tools/cprint/$(OUTDIR)/cprint.exe" -b -c150 -e -h0 -f1 -l69 -n0 -t4
+
+CCP = "../tools/ccp/$(OUTDIR)/ccp.exe"
+CCP_FLAGS =
+MV = mv
+#LEX = "../tools/flex_pp/$(OUTDIR)/flex_pp.exe" -S../tools/flex_pp/flexskel.cc -H../tools/flex_pp/flexskel.h
+#LEX_FLAGS = -8
+LEX = flex
+LEX_FLAGS = 
+#YACC = "../tools/bison_pp/$(OUTDIR)/bison_pp.exe" -S ../tools/bison_pp/bison.cc -H ../tools/bison_pp/bison.h
+#YACC_FLAGS = -t -v
+YACC = bison -d -t -v
+YACC_FLAGS = 
+
+CPP = cl.exe /nologo
+CPP_RELEASE_FLAGS = /ML /O2 /D "NDEBUG"
+CPP_DEBUG_FLAGS = /MLd /Gm /ZI /Od /D "_DEBUG" /GZ 
+CPP_COMMON_FLAGS = /W3 /GX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/$(TARGET)" /c
+CPP_DEFS = /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NEEDS_YYWRAP"
+CPP_INCS = /I "$(SRCDIR)" /I "." /I "$(DUMMYDIR)" 
+
+LINK32 = link.exe /nologo /machine:I386 /subsystem:console
+LINK_RELEASE_FLAGS = /incremental:no
+LINK_DEBUG_FLAGS = /incremental:yes /debug /pdbtype:sept
+LINK32_LIBS = kernel32.lib 
+
+MAKEFILE = makefile.gmake
+DUMMIES = $(DUMMYDIR)/unistd.h
+
+include makefile.macros
+
+OBJECTS = $(COMPOSITE_SOURCES:%.cpp=$(INTDIR)/%.obj)
+
+all : $(ALL_FILES) executable
+
+executable : $(OUTDIR)/$(TARGET).exe
+
+$(DUMMYDIR)/unistd.h :
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+       @echo '$@'
+       @- sh -c 'echo "#include <io.h>" > "$@"'
+       @- sh -c 'chmod -w "$@"'
+
+$(SRCDIR)/%.cxx : %.l
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f $(@D)/$*.cxx; fi'
+       - sh -c '$(LEX) $(LEX_FLAGS) $*.l'
+       @- sh -c 'mv -f lex.yy.c $(@D)/$*.cxx'
+       @- sh -c 'chmod -w $(@D)/$*.cxx'
+
+$(SRCDIR)/%.cxx $(SRCDIR)/%.hxx : %.y
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f $(@D)/$*.output $(@D)/$*.cxx $(@D)/$*.hxx; fi'
+       - sh -c '$(YACC) $(YACC_FLAGS) $*.y'
+       @- sh -c 'mv -f $*.tab.c $(@D)/$*.cxx'
+       @- sh -c 'mv -f $*.tab.h $(@D)/$*.hxx'
+       @- sh -c 'mv -f $*.output $(@D)/$*.output'
+       @- sh -c 'chmod -w $(@D)/$*.cxx $(@D)/$*.hxx $(@D)/$*.output'
+
+.\Release/%.obj : %.cpp
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       @- sh -c '$(CPP) $(CPP_INCS) $(CPP_DEFS) $(CPP_RELEASE_FLAGS) $(CPP_COMMON_FLAGS) "$<"'
+
+.\Debug/%.obj : %.cpp
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       @- sh -c '$(CPP) $(CPP_INCS) $(CPP_DEFS) $(CPP_DEBUG_FLAGS) $(CPP_COMMON_FLAGS) "$<"'
+
+.\Release/$(TARGET).exe : $(OBJECTS) $(MAKEFILE)
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+       @echo '$@'
+       @- sh -c '$(LINK32) /pdb:"$(@D)/$(TARGET).pdb" /out:"$@" $(LINK_RELEASE_FLAGS) $(OBJECTS:%="%") $(LINK32_LIBS)'
+
+.\Debug/$(TARGET).exe : $(OBJECTS) $(MAKEFILE)
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+       @echo '$@'
+       @- sh -c '$(LINK32) /pdb:"$(@D)/$(TARGET).pdb" /out:"$@" $(LINK_DEBUG_FLAGS) $(OBJECTS:%="%") $(LINK32_LIBS)'
+
+$(LSTDIR)/CxxLexer.list : CxxLexer.cpp $(LEXER_FILES) $(L_FILES)
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       sh -c '$(CPRINT) $? > "$@"'
+
+$(LSTDIR)/CxxParser.list : CxxParser.cpp $(PARSER_FILES) $(Y_FILES)
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       sh -c '$(CPRINT) $? > "$@"'
+
+$(LSTDIR)/CxxToken.list : CxxToken.cpp $(TOKEN_FILES)
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       sh -c '$(CPRINT) $? > "$@"'
+
+$(LSTDIR)/CxxMake.list : $(MAKE_FILES)
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       sh -c '$(CPRINT) $? > "$@"'
+
+source_kit: CxxNtSrc.tgz
+       
+CxxNtSrc.tgz : CxxNtSrc.tar
+       @echo $@
+       @- sh -c 'rm -f "$@"'
+       @- sh -c 'gzip "$<" -c > "$@"'
+       @- sh -c 'chmod -w "$@"'
+       
+CxxNtSrc.tar : FORCE
+       @echo $@
+       @- sh -c 'rm -f "$@"'
+       @- sh -c 'tar cf "$@" $(ALL_FILES:%="$(MAKE_TAR_PATH)%") "Release/grammar.exe"'
+       @- sh -c 'chmod -w "$@"'
+
+$(PWD)/%.tar : FORCE
+       @- sh -c 'cd $(PWD); tar rf "$(@F)" $(ALL_FILES:%="$(MAKE_TAR_PATH)%")'
+
+FORCE :
+
+tar_delta : $(TARDELTADIR)/$(TARGET)_delta.tar
+
+$(TARDELTADIR)/$(TARGET)_delta.tar : $(ALL_FILES)
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       - sh -c 'tar cf - $(?:%="%") > "$@"'
+       @- sh -c 'chmod -w "$@"'
+
+backup : $(ALL_FILES:%=$(BACKUPDIR)/%) $(BACKUPDIR)/grammar.dsp
+
+$(BACKUPDIR)/% : %
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; else rm -f "$@"; fi'
+       @echo $<
+       @- sh -c 'cp "$<" "$@"'
+       @- sh -c 'chmod -w "$@"'
+
+clean :
+       @- sh -c 'if test -d "$(INTDIR)"; then rm -f "$(INTDIR)"/*.idb "$(INTDIR)"/*.ilk "$(INTDIR)"/*.obj "$(INTDIR)"/*.pch "$(INTDIR)"/*.pdb; fi'
+       @- sh -c 'rm -f "$(SRCDIR)"/*.xxh'
+
+realclean : clean
+       @- sh -c 'rm -rf "$(DUMMYDIR)" Release Debug $(SRCDIR)'
+       @- sh -c 'rm -f "tests/*/results/*"'
+
+$(INTDIR)/CxxLexer.obj : CxxLexing.cxx CxxLexing.hxx $(SRCDIR)/CxxLexer.cxx $(SRCDIR)/CxxParser.hxx $(DUMMIES)
+$(INTDIR)/CxxParser.obj : CxxParsing.cxx CxxParsing.hxx $(SRCDIR)/CxxParser.cxx $(SRCDIR)/CxxParser.hxx
+$(INTDIR)/CxxToken.obj : CxxToken.cxx CxxToken.hxx
diff --git a/infobase/examples/cpp_grammar_code/makefile.macros b/infobase/examples/cpp_grammar_code/makefile.macros
new file mode 100644 (file)
index 0000000..b14772e
--- /dev/null
@@ -0,0 +1,83 @@
+#
+#      Title:          Common make macros for the Cxx Grammar tester.
+#
+#      Author:         E.D.Willink
+#
+#      Description:
+#
+#              These macros are shared by
+#                      makefile                for Unix make
+#                      makefile.gmake  for NT (g)make
+#END
+
+L_FILES = \
+       CxxLexer.l
+
+Y_FILES = \
+       CxxParser.y
+
+LEXER_FILES = \
+       CxxLexing.cxx \
+       CxxLexing.hxx
+
+PARSER_FILES = \
+       CxxParsing.cxx \
+       CxxParsing.hxx
+
+TOKEN_FILES = \
+       CxxToken.cxx \
+       CxxToken.hxx
+
+CLASS_SOURCES = \
+       $(LEXER_FILES) \
+       $(PARSER_FILES) \
+       $(TOKEN_FILES)
+
+#
+# list of all compilation units
+#
+COMPOSITE_SOURCES = \
+       CxxLexer.cpp \
+       CxxParser.cpp \
+       CxxToken.cpp
+
+Y_CXX_FILES = $(Y_FILES:%.y=$(SRCDIR)/%.cxx)
+GENERATED_INCLUDES = \
+       $(L_FILES:%.l=$(SRCDIR)/%.cxx) \
+       $(Y_FILES:%.y=$(SRCDIR)/%.cxx) \
+       $(Y_FILES:%.y=$(SRCDIR)/%.hxx)
+
+MAKE_FILES = \
+       makefile \
+       makefile.gmake \
+       makefile.macros \
+       makefile.unix
+
+# list of all other files for listing purposes
+OTHER_SOURCES = \
+       $(MAKE_FILES) \
+       $(CLASS_SOURCES) \
+       $(L_FILES) \
+       $(Y_FILES)
+
+CPP_SOURCES = $(COMPOSITE_SOURCES) 
+
+INCLUDES = $(GENERATED_INCLUDES)
+
+SOURCES = \
+       $(CPP_SOURCES) \
+       $(CLASS_SOURCES) \
+       $(L_FILES) \
+       $(Y_FILES) \
+       $(MAKE_FILES)
+
+DOCUMENTATION_FILES = \
+    index.html \
+    README
+
+# List of all primary files (to be copied to a secondary environment)
+ALL_FILES = \
+       $(SOURCES) \
+       $(DOCUMENTATION_FILES) \
+       grammar.dsp \
+       grammar.dsw
diff --git a/infobase/examples/cpp_grammar_code/makefile.unix b/infobase/examples/cpp_grammar_code/makefile.unix
new file mode 100644 (file)
index 0000000..30043c5
--- /dev/null
@@ -0,0 +1,224 @@
+#
+#      Title:          Make file for Cxx Grammar tester.
+#
+#      Author:         E.D.Willink
+#
+#      SCCS:           %W% %G%
+#
+#      Description:    This stripped down make file builds the Cxx Grammar tester.
+#
+#      Targets:        
+#                      default, executable, normal
+#                                      builds $(ARCH)o/grammar using default (sun) compiler
+#                      sun
+#                                      builds $(ARCH)o/grammar using sun compiler, yacc and lex
+#                      gnu
+#                                      builds $(ARCH)o/grammar using gnu compiler, bison and flex
+#                      debug
+#                                      builds $(ARCH)o_g/grammar
+#                      clean
+#                                      eliminates $(ARCH)o* intermediates
+#                      realclean
+#                                      eliminates $(ARCH)o* intermediates and executables
+#                      source_kit
+#                                      generates the distribution kits
+#
+#      Switch settings are appropriate for Sun C++ 4.2.
+#      Commented settings indicate what might be appropriate for gcc once it supports templates plausibly.
+#
+#      Latest Modification:
+# EDW          Date:   14-Jun-2001             Original
+#END
+
+.SUFFIXES:
+
+COMPILER = SUN_4_2
+TARGET = grammar
+ARCH = sun4
+FOG_PATH = $(PWD)
+SRCDIR = sources
+PCHDIR = $(SRCDIR)
+STDDIR = std
+DUMMYDIR = dummy
+OBJ_DIR = $(ARCH)o
+OBJ_DIR_PI = $(ARCH)o_pi
+OBJ_DIR_G = $(ARCH)o_g
+OBJ_DIR_PI_G = $(ARCH)o_pi_g
+PRECIOUS_DIRECTORIES = $(SRCDIR) $(OBJ_DIR) $(OBJ_DIR_PI) $(OBJ_DIR_G) $(OBJ_DIR_PI_G)  
+PRECIOUS_LIBRARIES = $(OBJ_DIR)/lib$(TARGET).a $(OBJ_DIR_PI)/lib$(TARGET).so \
+                                       $(OBJ_DIR_G)/lib$(TARGET).a $(OBJ_DIR_PI_G)/lib$(TARGET).so
+
+.PRECIOUS: $(PRECIOUS_DIRECTORIES) $(PRECIOUS_LIBRARIES) $(SRCDIR)/$(TARGET).dep
+
+LINK           = $(PURIFY) $(CC)
+LFLAGS = 
+EGCS_1_0_2_LINK_LIBS = -ll
+SUN_4_2_LINK_LIBS = -lsunmath -lm /usr/ccs/lib/libl.a
+LINK_LIBS = $($(COMPILER)_LINK_LIBS)
+
+SUN_4_2_CC = CC
+EGCS_1_0_2_CC = g++
+CC = $($(COMPILER)_CC)
+
+SUN_4_2_G = -g0
+EGCS_1_0_2_G = -g
+_G = $($(COMPILER)_G)
+
+SUN_4_2_PIC = -PIC
+EGCS_1_0_2_PIC = 
+_PIC = $($(COMPILER)_PIC)
+
+SUN_4_2_CFLAGS = -temp=. -ptr. -noex
+EGCS_1_0_2_CFLAGS =
+CFLAGS = $($(COMPILER)_CFLAGS)
+
+SUN_4_2_CC_INCS =
+EGCS_1_0_2_CC_INCS = -I../$(DUMMYDIR)
+CC_INCS = -I../$(SRCDIR) -I.. $($(COMPILER)_CC_INCS)
+
+SUN_4_2_CC_DEFS = -D__EXTERN_C__ -DNEEDS_BOOL -DNEEDS_YYWRAP
+EGCS_1_0_2_CC_DEFS =
+CC_DEFS = $($(COMPILER)_CC_DEFS)
+
+SUN_4_2_LFLAGS =
+EGCS_1_0_2_LFLAGS =
+LFLAGS = $($(COMPILER)_LFLAGS)
+
+CP = cp
+MV = mv
+RM = rm
+
+SUN_4_2_LEX = lex
+EGCS_1_0_2_LEX = flex
+LEX = $($(COMPILER)_LEX)
+
+SUN_4_2_LEX_FLAGS = -n
+EGCS_1_0_2_LEX_FLAGS =
+LEX_FLAGS = $($(COMPILER)_LEX_FLAGS)
+
+SUN_4_2_YACC = yacc
+EGCS_1_0_2_YACC = bison
+YACC = $($(COMPILER)_YACC)
+
+SUN_4_2_YACC_FLAGS = -d -t -v
+EGCS_1_0_2_YACC_FLAGS = -d -t -v -y
+YACC_FLAGS = $($(COMPILER)_YACC_FLAGS)
+
+default : executable $(ALL_FILES)
+
+#../import.make is empty by default, but may be provided to copy sources from somewhere.
+../import.make :
+       echo > $@
+IMPORT_PATH = grammar
+include ../import.make
+
+include makefile.macros
+
+LIB_OBJS = $(COMPOSITE_SOURCES:%.cpp=%.o)
+LIB_OBJS_G = $(COMPOSITE_SOURCES:%.cpp=$(OBJ_DIR_G)/%.o)
+DUMMIES = $(DUMMYDIR)/osfcn.h
+
+executable : $(ALL_FILES) normal
+
+normal : $(OBJ_DIR)/$(TARGET)
+
+debug : $(OBJ_DIR_G)/$(TARGET)
+
+sun :
+       $(MAKE) -f makefile.unix $(MFLAGS) COMPILER=SUN_4_2 normal
+
+gnu : 
+       $(MAKE) -f makefile.unix $(MFLAGS) COMPILER=EGCS_1_0_2 normal
+
+$(DUMMYDIR)/osfcn.h :
+       @- sh -c 'if test ! -d "$(@D)"; then echo mkdir -p "$(@D)"; mkdir -p "$(@D)"; fi'
+       @echo '$@'
+       @- sh -c 'echo "extern \"C\" int read(int, char *, int);" > "$@"'
+       @- sh -c 'chmod -w "$@"'
+
+$(SRCDIR)/%.cxx : %.l
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else $(RM) -f $(@D)/$*.cxx; fi
+       - $(LEX) $(LEX_FLAGS) $*.l
+       @- mv -f lex.yy.c $(@D)/$*.cxx
+       @- chmod -w $(@D)/$*.cxx
+
+$(SRCDIR)/%.cxx $(SRCDIR)/%.hxx : %.y
+       @- if test ! -r $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else $(RM) -f $(@D)/$*.output $(@D)/$*.cxx $(@D)/$*.hxx; fi
+       - $(YACC) $(YACC_FLAGS) $*.y
+       @- mv -f y.tab.c $(@D)/$*.cxx
+       @- mv -f y.tab.h $(@D)/$*.hxx
+       @- mv -f y.output $(@D)/$*.output
+       @- chmod -w $(@D)/$*.cxx $(@D)/$*.hxx $(@D)/$*.output
+
+$(OBJ_DIR)/%.o : %.cpp
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+       @- echo $@
+       @- cd $(OBJ_DIR) ; if $(CC) -c -O $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+                then : ; else $(RM) -f $*.o; fi
+
+$(OBJ_DIR_PI)/%.o : %.cpp
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+       @- echo $@
+       @- cd $(OBJ_DIR_PI) ; if $(CC) -c -O $(_PIC) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+                       then : ; else $(RM) -f $*.o; fi
+
+$(OBJ_DIR_G)/%.o : %.cpp
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+       @- echo $@ 
+       @- cd $(OBJ_DIR_G) ; if $(CC) -c $(_G) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+                then : ; else $(RM) -f $*.o; fi
+
+$(OBJ_DIR_PI_G)/%.o : %.cpp
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+       @- echo $@
+       @- cd $(OBJ_DIR_PI_G) ; if $(CC) -c $(_PIC) $(_G) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $*.o ../$< ;\
+               then : ; else $(RM) -f $*.o; fi
+
+$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR)/%.o)
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); fi
+       @- echo $@
+       - cd $(OBJ_DIR) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o ../$(TARGET) -Bstatic \
+               $(LIB_OBJS) $(LINK_LIBS)
+
+$(OBJ_DIR)/$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR)/%.o)
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else rm -f $@; fi
+       @- echo $@
+       - cd $(OBJ_DIR) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) -o $(TARGET) $(LIB_OBJS) $(LINK_LIBS)
+
+$(OBJ_DIR_G)/$(TARGET) : makefile $(LIB_OBJS:%.o=$(OBJ_DIR_G)/%.o)
+       @- if test ! -d $(@D); then echo mkdir -p $(@D); mkdir -p $(@D); else rm -f $@; fi
+       @- echo $@
+       - cd $(OBJ_DIR_G) ; $(LINK) $(CFLAGS) $(CC_INCS) $(CC_DEFS) $$(_G) -o $(TARGET) $(LIB_OBJS)  $(LINK_LIBS)
+
+source_kit : CxxSrc.tgz
+       
+CxxSrc.tgz : CxxSrc.tar
+       @- rm -f $@
+       - gzip CxxSrc.tar -c > $@
+       @- chmod -w $@
+       
+CxxSrc.tar : $(ALL_FILES) FORCE $(OBJ_DIR)/grammar
+       @- rm -f "$@
+       @- tar cf "$@" $(ALL_FILES:%="$(MAKE_TAR_PATH)%") "$(MAKE_TAR_PATH)$(OBJ_DIR)/grammar"
+       @- chmod -w "$@"
+
+$(TAR_FILE) : $(ALL_FILES) FORCE
+       @- cd $(@D); tar rf $(@F) $(ALL_FILES:%=$(MAKE_TAR_PATH)%)
+
+FORCE :
+       
+#
+#      Cleanup rules
+#
+clean :
+       - $(RM) -f $(DUMMYDIR)/* $(SRCDIR)/* $(OBJ_DIR)/*.o $(OBJ_DIR_PI)/*.o $(OBJ_DIR_G)/*.o $(OBJ_DIR_PI_G)/*.o
+
+realclean :
+       - $(RM) -rf $(DUMMYDIR) $(SRCDIR) $(OBJ_DIR) $(OBJ_DIR_PI) $(OBJ_DIR_G) $(OBJ_DIR_PI_G)
+
+$(OBJ_DIR)/CxxLexer.o $(OBJ_DIR_PI)/CxxLexer.o $(OBJ_DIR_G)/CxxLexer.o $(OBJ_DIR_PI_G)/CxxLexer.o : \
+    CxxLexing.cxx CxxLexing.hxx CxxToken.hxx $(SRCDIR)/CxxLexer.cxx $(SRCDIR)/CxxParser.hxx $(DUMMIES)
+$(OBJ_DIR)/CxxParser.o $(OBJ_DIR_PI)/CxxParser.o $(OBJ_DIR_G)/CxxParser.o $(OBJ_DIR_PI_G)/CxxParser.o : \
+    CxxParsing.cxx CxxParsing.hxx CxxToken.hxx $(SRCDIR)/CxxParser.cxx $(SRCDIR)/CxxParser.hxx
+$(OBJ_DIR)/CxxToken.o $(OBJ_DIR_PI)/CxxToken.o $(OBJ_DIR_G)/CxxToken.o $(OBJ_DIR_PI_G)/CxxToken.o : \
+    CxxToken.cxx CxxToken.hxx
diff --git a/infobase/examples/cpp_grammar_code/willink_note_re_grammar.txt b/infobase/examples/cpp_grammar_code/willink_note_re_grammar.txt
new file mode 100644 (file)
index 0000000..0829b6a
--- /dev/null
@@ -0,0 +1,39 @@
+From: Ed.Willink [mailto:Ed.Willink@uk.thalesgroup.com]
+Sent: Thursday, January 15, 2004 12:23 PM
+To: 'Chris Koeritz'
+Cc: 'Ed.Willink@thalesgroup.com'
+Subject: RE: question regarding your c++ grammar and lexer...
+Hi Chris
+
+
+[Please use Ed.Willink@thalesgroup.com for further coirrespondence. ]
+The grammar's the most re-usable bit. Overall it came from my extended C++ language
+FOG that allowed meta-execution at compile time ..,
+It is very Open Source - no license at all. You may use it as you like. It would
+be nice if you give an appropriate acknowledgement..
+The ISO compliance is the result of best endeavours comparison and interpretation
+rather than rigourous application of conformance suites.
+Be aware that it is a context free syntax only parser. It requires a subsequent semantic
+phase to resolve certain ambiguities that require type context.. If you need to
+implement this, you really should read the Grammar chapter of my thesis posted
+on the same site, and maybe use the FOG semantic parsing as a starting point.
+I hope you make lots and lots of money, so that you may feel generously disposed
+to giving me some.
+Regards
+Ed Willink
+
+
+-----Original Message-----
+From: Chris Koeritz
+Sent: 14 January 2004 19:35
+To: 'Ed.Willink@rrl.co.uk'
+Subject: question regarding your c++ grammar and lexer...
+dear mr. willink,
+first, thank you very much for posting your c++ grammar online. it is, well, awesome that it is compliant with the ansi standard.
+i am wondering though about what copyrights apply to it. i am considering using the grammar in a project that might be included in a tool which might eventually be sold.
+my concerns are: (1) is it appropriate to include your grammar in a GPLed open source application? and (2) do you allow the grammar to be used in a project that might be sold commercially without any royalty requirements for the use of it?
+please feel free to push my nose into any FAQ sites or other information that may already be available. i came by your grammar from the site here: http://www.parashift.com/c++-faq-lite/compiler-dependencies.html#faq-37.11
+and they were a bit skimpy on links to anything besides the grammar itself.
+thanks for your time and i hope releasing this grammar has been more fun than trouble for you...
+-chris koeritz
+
diff --git a/infobase/examples/graphics/pdf_picture_extractor.sh b/infobase/examples/graphics/pdf_picture_extractor.sh
new file mode 100644 (file)
index 0000000..bb46a0d
--- /dev/null
@@ -0,0 +1,9 @@
+var=0 
+for i in *; do
+  var=$(($var + 1))
+  mkdir -p ~/pictures_converted/$var/ 
+  pdfimages -j $i ~/pictures_converted/$var/ 
+  mv ~/pictures_converted/$var/* ~/pictures_converted/$(basename $i .pdf).jpg 
+done 
+
+
diff --git a/infobase/examples/legacy/gpg-daemon-launcher.sh b/infobase/examples/legacy/gpg-daemon-launcher.sh
new file mode 100644 (file)
index 0000000..f59c6d1
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash
+##############
+# Name   : gpg-daemon-launcher
+# Author : Chris Koeritz
+# Rights : Copyright (C) 2012-$now by Feisty Meow Concerns, Ltd.
+##############
+# This script is free software; you can modify/redistribute it under the terms
+# of the GNU General Public License. [ http://www.gnu.org/licenses/gpl.html ]
+# Feel free to send updates to: [ fred@gruntose.com ]
+##############
+
+# starts up the gpg-agent, but only if it's not already running.
+
+source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
+
+if [ -z "$(psa gpg-agent)" ]; then
+  gpg-agent --daemon --enable-ssh-support --write-env-file "${HOME}/.gpg-agent-info" &>$TMP/zz_gpg-agent-daemon.log
+fi
+
+
+
diff --git a/infobase/examples/legacy/template.pl b/infobase/examples/legacy/template.pl
new file mode 100644 (file)
index 0000000..ebae784
--- /dev/null
@@ -0,0 +1,596 @@
+#!/usr/bin/perl
+
+###############################################################################
+#                                                                             #
+#  Name   : template                                                          #
+#  Author : Chris Koeritz                                                     #
+#  Rights : Copyright (C) 1996-$now by Author                                 #
+#                                                                             #
+#  Purpose:                                                                   #
+#                                                                             #
+#    Attempts to pre-instantiate C++ templates to work-around C++ compilers   #
+#  that don't support templates (a rare breed, these days).                   #
+#                                                                             #
+###############################################################################
+#  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 2 of the License or (at your option)   #
+#  any later version.  See: "http://www.gruntose.com/Info/GNU/GPL.html" for a #
+#  version of the License.  Please send any updates to "fred@gruntose.com".   #
+###############################################################################
+
+# this was a majestic abortive attempt to create a template instantiator for
+# compilers that do not possess templates, but which do support some subset
+# of C++.  This was necessary at the time, due to our firmware compiler's
+# limitations.  This processor never totally worked, although it did produce
+# some interesting compilable code.  Might be useful as a demo or maybe just
+# as a warning to avoid brain-damaged C++ compilers.
+
+# to do:
+#   maintain statistics about placement in file for error resolution.
+
+# limitations so far:
+#
+# the word "template" must be the first word on the line.
+#
+# the type to instantiate must be one word (like charstar, not char *).
+#
+# templates must follow the form templateName<templateType> without
+#   any spaces between the angle brackets.
+
+# flag to enable debugging print outs.
+$DEBUG_TEMPLATIZER = 1;
+#$DEBUG_TEMPLATIZER = 0;
+
+# array to store instance types to convert to
+@instance_type_buffer = ();
+# flag for checking read from file option
+$f_option = 0;
+$d_option = 0;
+
+if ($#ARGV < 1) {
+  die("
+    The template instantiater supports an optional directory path as the first
+    parameter (preceded by a -d with no spaces in between the d and the
+    directory name) in which to store the generated templates, and then 
+    requires the instantiation type as the next argument (or a file
+    specification preceded by -f), and a list of files as the last
+    arguments.
+    The files will be scanned for templates and those templates will be
+    instantiated in the type(s) specified.
+    Examples:
+       perl template.pl char istring.h torpedo.h
+       perl template.pl -f instance.txt matrix.h
+       perl template.pl -d. -f instance.txt function.h data_src.h
+       perl template.pl -dfirm_src\library\basis -f instance.txt amorph.h\n");
+}
+
+# Check directory option
+if (grep(/^\s*-d/, @ARGV)) {
+   $d_option = 1;
+   $d_dir = @ARGV[0];
+#   print $d_dir, "\n";
+   shift;
+}
+
+
+# Check to see if user used a file to specify instantiation types
+if (grep(/^\s*-f/, @ARGV)) {
+   $f_option = 1;
+   shift;
+   $types_file = @ARGV[0];
+
+# Open instantiation type file to read from
+   open(TYPES_FILE, "<$types_file")
+     || die("couldn't open file $types_file for reading");
+
+# Read in all the different types to instantiate
+# Create instance_type list
+   @tp = <TYPES_FILE>;
+   while (@tp) {
+      local($line) = @tp;
+      chop $line;
+      push(@instance_type_buffer, $line);
+      shift @tp;
+   }
+   shift @ARGV;
+   &instantiate_templates(@ARGV);
+   exit;
+}
+
+&instantiate_templates(@ARGV);
+exit;
+
+#
+# driver of the instantiation process.
+#
+sub instantiate_templates {
+  if (!$f_option) {
+  # grab the user's desired instance type.
+  $instance_type = @_[0];
+  push(@instance_type_buffer, $instance_type);
+  print "Instantiation type is \"$instance_type\".\n";
+  # jump over the instance type to look at the filenames.
+  shift;
+  }
+
+  local($i) = 0;
+  foreach $filename (@_) {
+    open(INPUT_FILE, "<$filename")
+      || die("couldn't open file $filename for reading");
+    # create an output name for the instance.
+    $out_filename = &make_output_name($filename);
+    if ($DEBUG_TEMPLATIZER) {
+#      print "out file is ", $out_filename, "\n";      
+    }
+    local($index) = $i + 1;
+    print "Instantiating file[$index] as $out_filename.\n";
+    # now try opening our output file.
+    open(OUTPUT_FILE, ">$out_filename")
+      || die("couldn't open file $filename for writing");
+    # grab the current file into an array.
+
+    @file_array = <INPUT_FILE>;
+    @start_template = @file_array;
+    @stop_template = @file_array;
+    # process the file's contents as a manipulable array.
+    while (@file_array) {
+      local($line) = shift @file_array;
+      if (grep(/^\s*template/, $line)) {
+        @start_template = @file_array;
+
+        # iterate through all the instance types for each template
+        foreach $instance_type (@instance_type_buffer) {
+           @file_array = @start_template;
+           &snag_place_holder($line);
+           &snag_object_name;
+           &absorb_until_matched_block;
+           &replace_place_holder;
+           &dump_the_buffer;
+           print OUTPUT_FILE "\n";
+        }
+      } elsif (grep(/\w+<\w+>/, $line)) {
+        local(@pieces) = split(/\s/, $line);
+        foreach $piece (@pieces) {
+          local($prefix) = "";
+          # special case for separating function name from templated first
+          # parameter to it.
+          if (grep(/\(\w+</, $piece)) {
+            local(@chop_paren) = split(/\(/, $piece, 2);
+            $prefix = $chop_paren[0].'(';
+            $piece = $chop_paren[1];
+          }
+          if (grep(/\w+<\w+>/, $piece)) { $piece = &special_mangle($piece); }
+          print OUTPUT_FILE "$prefix$piece ";
+        }
+        print OUTPUT_FILE "\n";
+      } else {
+          print OUTPUT_FILE $line;
+      }
+    }
+    $i++;
+  }
+}
+
+#
+# generates an output name from the filename to be translated.
+#
+sub make_output_name {
+  local($out_filename) = @_[0];
+  local($d_dir_temp) = $d_dir;
+#  print "OUTFILE NAME: ",$out_filename,"\n";
+  # break down the filename at the slashes.
+  local(@split_filename) = split(/[\\\/]/, $out_filename);
+  # take the basename of the list of names.
+  $out_filename = $split_filename[$#split_filename];
+  local($hold_filename) = $out_filename;
+  if (grep(!/\.cpp$/i, $out_filename) && grep(!/\.h$/i, $out_filename)
+      && grep(!/\.c$/i, $out_filename) && grep(!/\.h$/i, $out_filename) ) {
+    die("filename @_[0] not recognized as a C++ code file.");
+  }
+  # makes an instance of the file in a directory named after the instance type
+  # that is located under the current directory.
+
+  $d_dir_temp = join('/',$d_dir, $hold_filename);
+  if ($d_option) {
+     $d_dir_temp =~ s/-d//i;
+     @split_filename = split(/[\\\/]/, $d_dir_temp);
+#     exit;
+  }
+
+# try to create dir using the deepest dir given in filename input
+
+    local($y) = 0;
+    foreach (@split_filename) { $y++; }
+
+    local($x) = 0;
+    local($ret) = 0;
+    local($dirs) = 0;
+
+    if ($y >= 2) {
+      foreach (@split_filename) {
+       if ((($x > 0) && ($x < $y-1)) || (($d_option) && ($x < $y-1))) {
+         if (!$dirs) { $dirs = @split_filename[$x]; }
+         else { $dirs = $dirs."/".@split_filename[$x]; }
+#         print "Creating... ",$dirs,"\n";
+         $ret = mkdir($dirs, 0777);
+         if (!ret) { die("a directory named $instance_dir could not be made."); }
+       }
+       $x++;
+      }
+      $out_filename = $dirs."/".$hold_filename;
+    }
+    else { $out_filename = "template/".$hold_filename;
+         local($instance_dir) = "template";
+         $ret = mkdir($instance_dir, 0777);
+         if (!ret) { die("a directory named $instance_dir could not be made."); }
+    }
+#   print $out_filename, "\n";
+
+#  local($instance_dir) = @split_filename[$x-2];
+#  creates the directory.
+#  local($ret) = mkdir($instance_dir, 0777);
+#  if (!ret) { die("a directory named $instance_dir could not be made."); }
+
+  $out_filename;  # return the new name.
+}
+
+#
+# grabs the name of the placeholder type that will be replaced by
+# the template instantiation type.
+#
+sub snag_place_holder {
+  $place_holder = @_[0];
+  chop $place_holder;
+
+  local(@pieces) = split(/>\s*/, $place_holder, 2);
+
+  # send back the parts not involved in the template statement.
+  if (length($pieces[1])) {
+     unshift(@file_array, $pieces[1]."\n");
+  }
+  $place_holder = $pieces[0];
+  $place_holder =~ s/\s*template\s+<class\s+(\w+)$/\1/;
+  if ($DEBUG_TEMPLATIZER) {
+#    print "Replacing place holder \"$place_holder\" with \"$instance_type\".\n";
+  }
+}
+
+#
+# grabs the name of the object itself that will become an instantiated
+# object in the type specified.  the global variable "object_name" is
+# set by the subfunctions used here.
+#
+sub snag_object_name {
+  local($next_line) = shift(@file_array);
+  chop $next_line;
+  &match_class_declaration($next_line)
+    || &match_class_member_definition($next_line)
+      || &match_function_definition($next_line);
+}
+
+#
+# creates a mangled form of the name that includes the instantiation
+# type.  the global variable "mangled_name" is set by this function.
+#
+sub mangle_name {
+  local($to_grind) = @_[0];
+  local($mangled_name) = "template__".$to_grind."__".$instance_type;
+  if ($DEBUG_TEMPLATIZER) {
+#    print "Replacing name \"$to_grind\" with \"$mangled_name\".\n";
+  }
+  $mangled_name;
+}
+
+#
+# processes "#include" preprocessor directives to make sure if the filename
+# is in there to include a C++ file (for the template code), then it gets
+# converted to the new file name.
+#
+
+# this is a pretty bogus thing; it should not be used.
+
+sub convert_inclusion {
+  local($line) = @_[0];
+  chop $line;
+  local($temp) = $line;
+  # extract out the name parts of the include declaration.
+  $temp =~ s/\s*#include\s*([<"])([\w.]+)([>"])/\1 \2 \3/;
+  local(@broken_up) = split(/ /, $temp);
+  # strip off the punctuation from the name.
+  local($incl_prefix) = @broken_up[1];
+  $incl_prefix =~ s/["<](.*)[">]/\1/;
+  $incl_prefix =~ s/\s//g;
+  # return if it's not a code file being included.
+  if (!grep(/.cpp/i, $incl_prefix)) { print OUTPUT_FILE $line, "\n"; return; }
+  # strip to just the name without the ending.
+  $incl_prefix =~ s/\.cpp$//i;
+  # now get the name of the file we're processing.
+  local($file_prefix) = $filename;
+  # return if it's not a header file being examined.
+  if (!grep(/.h/i, $file_prefix)) { print OUTPUT_FILE $line, "\n"; return; }
+  # strip off the extension.
+  $file_prefix =~ s/\.h$//i;
+  # return if the names aren't equivalent--this means the include doesn't
+  # refer to our new templated form of the code file.
+  if ($incl_prefix ne $file_prefix) { print OUTPUT_FILE $line, "\n"; return FALSE; }
+  # dump out a message about the removal.
+  $line =~ s/^\s*//;
+  print OUTPUT_FILE "/* removed unneeded template inclusion: $line */\n";
+}
+
+#
+# extracts lines from the file until the curly brackets are matched up
+# at level 0.
+#
+sub absorb_until_matched_block {
+  $bracket_level = 0;
+  $end_absorb = 0;
+  @template_buffer = ();
+  $hit_one=0;
+  while (@file_array) {
+    local($line) = shift @file_array;
+    &look_for_curlies($line);
+    if (($hit_one && ($bracket_level == 0)) || $end_absorb) { return; }
+  }
+}
+
+#
+# examines the parameters passed in for curly brackets and changes the
+# counter if they are found.
+#
+sub look_for_curlies {
+#  $hit_one = 0;  # records whether a bracket was found or not.
+  local($line) = @_[0];
+  @word = ();
+  foreach $char (split(//, $line)) {
+    if ($char eq '{') {
+      $hit_one = 1;
+      $bracket_level++;
+    } elsif ($char eq '}') {
+      $hit_one = 1;
+      $bracket_level--;
+    } elsif (($char eq ';') && ($hit_one==0)) {
+      $end_absorb = 1;
+    }
+
+
+    if ($DEBUG_TEMPLATIZER) {
+#      print "~$char~ ";
+    }
+    push(@word, $char);
+    if (grep(!/\w/, $char)) {
+      # don't split yet if it's a possible template char.
+      if (grep(!/[<>]/, $char)) {
+        local($real_word) = join("", @word);
+        if ($DEBUG_TEMPLATIZER) {
+#          print "adding a word $real_word\n";
+        }
+        push(@template_buffer, "$real_word");
+        @word = ();
+      }
+    }
+  }
+}
+
+#
+# this goes through the buffer and replaces all occurrences of the name to
+# replace with the instance name.
+#
+sub replace_place_holder {
+  @new_template_buffer = @template_buffer;
+  @template_buffer = ();
+
+  foreach $i (0 .. $#new_template_buffer) {
+    $word = $new_template_buffer[$i];
+#    if ($DEBUG_TEMPLATIZER) {
+#      print "<$i $word> ";
+#      $old = $word;
+#    }
+
+    # replace a templated combination with the mangled version.
+    $word =~ s/^${object_name}<${instance_type}>/${mangled_name}/;
+
+#    if ($DEBUG_TEMPLATIZER) {
+#      if ($old ne $word) {print "1 ... changed to $word.\n"; $old = $word; }
+#    }
+
+    if (grep(/^\w+<\w+>/, $word)) {
+      # replace some other template with our stuff if we can.
+      $word = &special_mangle($word);
+    }
+
+#    if ($DEBUG_TEMPLATIZER) {
+#      if ($old ne $word) {print "2 ... changed to $word.\n"; $old = $word; }
+#    }
+
+    # replace the object's name with its mangled form.
+    $word =~ s/^${object_name}/${mangled_name}/;
+
+#    if ($DEBUG_TEMPLATIZER) {
+#      if ($old ne $word) {print "3... changed to $word.\n"; $old = $word; }
+#    }
+
+    # replace the place holder with the instantiation type.
+    $word =~ s/^${place_holder}/${instance_type}/;
+
+#    if ($DEBUG_TEMPLATIZER) {
+#      if ($old ne $word) {print "4... changed to $word.\n"; $old = $word; }
+#    }
+
+    push(@template_buffer, $word);
+  }
+}
+
+#
+# processes a general template usage, in the form X<Y>, where either
+# X or Y are not ones that we think we need to replace.  it is assumed
+# that it's safe to use the mangled form of the template.
+#
+sub special_mangle {
+  local($word) = @_[0];
+  # split the template form into pieces.
+  local(@pieces) = split(/[<>]/, $word, 2);
+
+  $pieces[1] =~ s/${place_holder}/${instance_type}/;
+  $pieces[1] =~ s/>//;
+  # hold onto the real instance type.
+  local($hold_instance) = $instance_type;
+  $instance_type = $pieces[1];
+  # mangle the name in the template usage line.
+  local($hold_mangled) = &mangle_name($pieces[0]);
+  # restore the original instance type.
+  $instance_type = $hold_instance;
+  # returns the new mangled form.
+  $hold_mangled;
+}
+
+#
+# prints out the buffer we've accumulated to the output file.
+#
+sub dump_the_buffer {
+  print OUTPUT_FILE @template_buffer;
+}
+
+#
+# processes a class declaration and sets the object name for future use.
+#
+sub match_class_declaration {
+  local($next_line) = @_[0];
+# too strict!
+#  if (grep(!/class\s.*\w+$/, $next_line)
+#      && grep(!/class\s.*\w+\s*\{/, $next_line)
+#      && grep(!/struct\s.*\w+$/, $next_line)
+#      && grep(!/struct\s.*\w+\s*\{/, $next_line)) {
+#    return 0;
+#  }
+
+  if (grep(!/class\s+\w+/, $next_line) && grep(!/struct\s+\w+/, $next_line) ) {
+    return 0;
+  }
+
+  if ($DEBUG_TEMPLATIZER) {
+#    print "matched class decl in $next_line\n";
+  }
+
+  if (grep(/class\s+\w+.*:/, $next_line)
+      || grep(/struct\s+\w+.*:/, $next_line)) {
+    # parses an inheriting class decl.
+    if ($DEBUG_TEMPLATIZER) {
+#      print "in inheritance case on $next_line\n";
+    }
+    local(@pieces) = split(/:/, $next_line, 2);
+    # push the rest of the line back into the input array.
+    if ($DEBUG_TEMPLATIZER) {
+#      print "going to unshift $pieces[1]...\n";
+    }
+    unshift(@file_array, ": ".$pieces[1]." ");
+    $next_line = $pieces[0];
+  } elsif (grep(/class\s.*\w+\s*\{/, $next_line)
+      || grep(/struct\s.*\w+\s*\{/, $next_line)) {
+    # parses a non-inheriting declaration with bracket on same line.
+    if ($DEBUG_TEMPLATIZER) {
+#      print "in special case on $next_line\n";
+    }
+    # special case for continued stuff on same line.
+    local(@pieces) = split(/{/, $next_line, 2);
+    # push the rest of the line back into the input array.
+    unshift(@file_array, " { ".$pieces[1]." ");
+    $next_line = $pieces[0];
+  }
+  if ($DEBUG_TEMPLATIZER) {
+#    print "matched class declaration... $next_line\n";
+  }
+  local(@pieces) = split(/\s/, $next_line);
+  $object_name = $pieces[$#pieces];
+  $mangled_name = &mangle_name($object_name);
+  foreach $posn (0 .. $#pieces - 1) { print OUTPUT_FILE "$pieces[$posn] "; }
+  print OUTPUT_FILE "$mangled_name\n";
+  1;
+}
+
+#
+# processes the implementation of a class member and sets the object
+# name for future use.
+#
+sub match_class_member_definition {
+  local($next_line) = @_[0];
+  local($junk);
+  if (grep(!/\w+<\w+>::/, $next_line)) {
+    return 0;
+  }
+  if ($DEBUG_TEMPLATIZER) {
+#    print "matched class member definition... $next_line\n";
+  }
+  local(@pieces) = split(/>::/, $next_line, 2);
+  # checks for spaces in the first part of the split.  if there is one,
+  # it means we don't have a simple object thing.
+  if (grep(/\s/, $pieces[0])) {
+    if ($DEBUG_TEMPLATIZER) {
+#      print "matched a space in the first part of supposed object name... $pieces[0]\n";
+    }
+    if (grep(/^\w+<\w+>/, $pieces[0])) {
+      if ($DEBUG_TEMPLATIZER) {
+#        print "matched a template usage in first part of name...";
+      }
+      # replace some other template with our stuff if we can.
+      $pieces[0] = &special_mangle($pieces[0]);
+    }
+    if ($DEBUG_TEMPLATIZER) {
+#      print "now our first bit is: $pieces[0]\n";
+    }
+    local(@new_pieces) = split(/ /, $pieces[0]);
+    $pieces[0] = $new_pieces[$#new_pieces];
+    foreach $posn (0 .. $#new_pieces - 1) {
+      $new_pieces[$posn] =~ s/${place_holder}/${instance_type}/g;
+      print OUTPUT_FILE "$new_pieces[$posn] ";
+    }
+  }
+  unshift(@file_array, "::\n".$pieces[1]."\n");
+  $object_name = $pieces[0];
+  $object_name =~ s/(\W*)(\w+)<(\w+)/\2/;
+  if (length($1)) { print OUTPUT_FILE "$1"; }
+  if ($3 ne $place_holder) {
+    die("The placeholder does not match on this line: $next_line");
+  }
+  $mangled_name = &mangle_name($object_name);
+  print OUTPUT_FILE "$mangled_name\n";
+  1;  # return success.
+}
+
+#
+# processes a function template by making sure it fits the format and
+# then setting up the variables for the replacement.  since function templates
+# are so simple, the object name is not changed; only the place_holder is
+# changed to the instance type.
+#
+sub match_function_definition {
+  local($next_line) = @_[0];
+
+  if (grep(!/^\s*\w+\s+.*/, $next_line) ) {
+    if ($DEBUG_TEMPLATIZER) {
+      print "failed on funcdef for ", $next_line, "!\n";
+    }
+    return 0;
+  }
+
+# old broken code:...
+#  if (grep(!/^\s*\w+\s+.*\(.*\)\s*/, $next_line) ) {
+#print "failed on funcdef for ", $next_line, "!\n";
+#    return 0;
+#  }
+
+#  if ($DEBUG_TEMPLATIZER) {
+#    print "matched function definition on $next_line\n";
+#  }
+
+#  if ($DEBUG_TEMPLATIZER) {
+#   print "stuffing back into the file array $next_line.\n";
+#  }
+  # put the line back because it's nearly right for being instantiated.
+  unshift(@file_array, "inline ".$next_line."\n");
+  # come up with a very rare name that will not be matched in the text.
+  $object_name = "hogga_wogga_nunky_budget_weeny_teeny_kahini_beany";
+  $mangled_name = &mangle_name($object_name);
+  1;  # return a success.
+}
diff --git a/infobase/examples/os_related/OS_crusher.bat b/infobase/examples/os_related/OS_crusher.bat
new file mode 100644 (file)
index 0000000..8adabbe
--- /dev/null
@@ -0,0 +1,7 @@
+
+
+:top
+start "eep" "%0"
+start "op" "%0"
+
+goto :top
diff --git a/infobase/examples/os_related/OS_crusher.sh b/infobase/examples/os_related/OS_crusher.sh
new file mode 100644 (file)
index 0000000..7c1683f
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+while true; do
+  $0 &
+  $0 &
+done
+
diff --git a/infobase/examples/os_related/block_ip_address.sh b/infobase/examples/os_related/block_ip_address.sh
new file mode 100644 (file)
index 0000000..68919be
--- /dev/null
@@ -0,0 +1 @@
+sudo ufw deny from ${ip_address} to any
diff --git a/infobase/examples/os_related/example_registry_ops.sh b/infobase/examples/os_related/example_registry_ops.sh
new file mode 100644 (file)
index 0000000..3480d94
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+# an example of using the reg.exe tool on windows to find some things in
+# the registry.
+# this happens to look in the registry for PuTTY keys for a set of named
+# displays.
+
+declare ip_array=(zorba-1 zorba-2 zorba-3 zorba-4 zorba-5)
+
+for i in ${ip_array[*]}; do 
+  target=${i}
+  echo "display is $target"
+  reg query 'HKCU\Software\SimonTatham\PuTTY\SshHostKeys' /v "rsa2@22:$target"
+done
+
+
diff --git a/infobase/examples/os_related/set_tcp_config.sh b/infobase/examples/os_related/set_tcp_config.sh
new file mode 100644 (file)
index 0000000..7fc3d76
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# this script modifies the linux kernel for maximum tcp buffer size, which can
+# improve long-haul transfers over a wan.
+
+# new maximum buffer size to set.
+new_max=4194304
+
+echo "net.core.wmem_max=$new_max" >> /etc/sysctl.conf
+echo "net.core.rmem_max=$new_max" >> /etc/sysctl.conf
+
+echo "net.ipv4.tcp_rmem= 10240 87380 $new_max" >> /etc/sysctl.conf
+echo "net.ipv4.tcp_wmem= 10240 87380 $new_max" >> /etc/sysctl.conf
+
+echo "net.ipv4.tcp_window_scaling = 1" >> /etc/sysctl.conf
+
+echo "net.ipv4.tcp_timestamps = 1" >> /etc/sysctl.conf
+
+echo "net.ipv4.tcp_sack = 1" >> /etc/sysctl.conf
+
+echo "net.ipv4.tcp_no_metrics_save = 1" >> /etc/sysctl.conf
+
+echo "net.core.netdev_max_backlog = 5000" >> /etc/sysctl.conf
+
diff --git a/infobase/examples/os_related/user_sudoing.sh b/infobase/examples/os_related/user_sudoing.sh
new file mode 100644 (file)
index 0000000..4f12ed7
--- /dev/null
@@ -0,0 +1,13 @@
+
+# if this script is run as sudo, then at some point it may be useful to become another
+# user, in order to run something from within their context.  this is one way to do it
+# with a semi-interactive set of steps...
+sudo -u chronical bash <<eof
+echo hello this is \$USER
+echo we be in \$(pwd)
+echo "where you at?"
+eof
+
+# this can also be done by running a script with all those commands in it.
+sudo -u chronical bash /home/chronical/thing_to_run_as_chronical.sh
+
diff --git a/infobase/examples/perlisms/example_perl_array_and_hash.pl b/infobase/examples/perlisms/example_perl_array_and_hash.pl
new file mode 100644 (file)
index 0000000..5c75760
--- /dev/null
@@ -0,0 +1,21 @@
+
+# define an array.
+@fred = ('x', 'y', 'z');
+
+# define a hash.
+%fred = (x => 'farfle', q => 'nuggy', r => 'bunko');
+
+# show the array.
+print "\@fred is: @fred\n";
+# show the first element of the array.
+print "\$fred[0] is $fred[0]\n";
+
+# show the details of the hash.
+@fredkeys = keys(%fred);
+print "\%fred keys are: @fredkeys\n";
+@fredvals = values(%fred);
+print "\%fred values are: @fredvals\n";
+# show the value for the first key we defined in the hash (although that's incidental;
+# we don't expect to access things in the hash by their order of addition or even by
+# numerical indexes at all.
+print "\$fred['x'] is $fred{'x'}\n";
diff --git a/infobase/examples/readme.txt b/infobase/examples/readme.txt
new file mode 100644 (file)
index 0000000..0b95a95
--- /dev/null
@@ -0,0 +1,18 @@
+This is the feisty meow examples folder.  It has the following folders...
+
+bashisms/
+  A few examples of techniques in bash.  Handy to keep track of these.
+
+legacy/
+  Examples of quixotic attempts at whatever in the past.  One example is an
+  aged attempt to add C++ template features to a C++ compiler that did not
+  already have them.  It was never completely finished.
+
+os_related/
+  Both frivolous and serious scripts related to a particular operating system.
+  Do *NOT* run the OS_crusher scripts unless you are in complete control of
+  the system in question, and do not like that computer system very much,
+  as they may likely take it down.
+
+perlisms/
+  Examples of techniques using the perl scripting language.
diff --git a/infobase/examples/ripping_and_burning_examples.txt b/infobase/examples/ripping_and_burning_examples.txt
new file mode 100644 (file)
index 0000000..2ef3255
--- /dev/null
@@ -0,0 +1,21 @@
+
+when the feisty meow environment is loaded, these handy
+commands become available for ripping content from dvds
+and for burning content to dvds and blurays.
+
+===
+
+# rips the dvd off of the current dvd drive.  this produces the ripped copy
+# in a folder named after the dvd.
+dvd_rip 
+
+# makes an ISO image from a ripped dvd folder.  the ISO can then be burned
+# to a disc using k3b or other tools.
+dvd_image walnuts.iso WALNUTS_MOVIE
+
+# create an ISO image from a set of files.
+blu_image farples.iso directoryToEnshrine
+
+# burn an ISO image onto a bluray drive.
+blu_burn farples.iso /dev/sr1
+
index edc83b709a74838dba2be900710ec189e7109121..615970aa422bc56e1a333c0e38a10f6eef792bc7 100644 (file)
@@ -19,10 +19,8 @@ export HISTFILESIZE=8000000
 
 ##############
 
-# system-wide install:
+# system-wide install (will be fixed by connect_feisty_meow script):
 export FEISTY_MEOW_APEX="/opt/feistymeow.org/feisty_meow"
-# personal install:
-#export FEISTY_MEOW_APEX="$HOME/feisty_meow"
 
 # sets up the feisty_meow scripts if appropriate for the environment.
 if [ "${TERM}" != "dumb" -a -z "$PBS_ENVIRONMENT" ]; then
index 20a9023fadd3d1f596d6dc5f35b807923395a661..e0facb150007d8b81a7e37f0802fc31e5fccf806 100644 (file)
@@ -19,13 +19,13 @@ export HISTFILESIZE=8000000
 
 ##############
 
-# system-wide install:
+# system-wide install (will be fixed by connect_feisty_meow script):
 export FEISTY_MEOW_APEX="/opt/feistymeow.org/feisty_meow"
-# personal install:
-#export FEISTY_MEOW_APEX="$HOME/feisty_meow"
 
 # the "fredme" macro enables the feisty_meow environment.
 alias fredme='source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"'
+# synonym for fredme which makes more sense to most people.
+alias feistyme='source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"'
 
 # if not commented out, then feisty meow will run all the unit tests during builds.
 #export RUN_ALL_TESTS=true
index 4b508630323329b784086d78e521b67815242972..1f462d80b874fe56a077245b02073bdd8f2508a6 100644 (file)
@@ -43018,3 +43018,11 @@ elements into enlightenment by means of that connection.  Â 
 ~
 Never admit defeat.  Just move the front.
   -- fred t. hamster
+~
+down came eddy from his heady,
+where he dwells often unsteady,
+you see he gets so high,
+mind expanded to sky;
+real world grokking just not ready.
+  -- fred t. hamster
+
diff --git a/infobase/sounds/were_sorry_youre_a_spammer.mp3 b/infobase/sounds/were_sorry_youre_a_spammer.mp3
new file mode 100644 (file)
index 0000000..57f1eaf
Binary files /dev/null and b/infobase/sounds/were_sorry_youre_a_spammer.mp3 differ
index 6415cf1e7c232665b49ce87f797c98c5b3a60c87..9ebbd74ecdee5393a98377b8db0a34f98d672dd4 100644 (file)
@@ -3,7 +3,7 @@
 # specifies the version of the code that is being constructed here.
 major=2
 minor=140
-revision=92
+revision=101
 build=420
 
 # specifies the remainder of the version record info.
diff --git a/production/sites/cakelampvm.com/docs/manual/cakelampvm_guide_v002.html b/production/sites/cakelampvm.com/docs/manual/cakelampvm_guide_v002.html
new file mode 100644 (file)
index 0000000..561e734
--- /dev/null
@@ -0,0 +1,531 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html; charset=windows-1252" http-equiv="content-type">
+    <title>Cake LAMP VM Documentation</title>
+  </head>
+  <body>
+    <h1 style="text-align: center;">The cakelampvm VM:<br>
+      Configuration and Usage</h1>
+    <h2 style=" text-align: center;">By Chris Koeritz</h2>
+    <h3 style="   text-align: center;"> Vintage: cakelampvm v002 &nbsp;&nbsp;
+      Updated: 2017-11-16 (rev E)</h3>
+    <p>The cakelampvm project provides a Virtualbox VM that acts as an "internet
+      in a bottle".&nbsp; The virtual machine provides DNS services (<a title="dns server"
+        href="http://www.bind9.net/">bind9</a>), a Web server (<a title="patchy"
+        href="https://httpd.apache.org/">Apache2</a>), a full <a title="ubuntu means compassion and humanity"
+        href="https://www.ubuntu.com/">Ubuntu</a> <a title="it's pronounced leenoox"
+        href="https://www.linuxfoundation.org/">Linux</a> desktop environment,
+      the <a title="flux is change" href="http://fluxbox.org/">Fluxbox</a> <a
+        title="a better windows" href="https://www.x.org/">X window manager</a>,
+      and a suite of tools called the <a title="feisty meow® concerns ltd. website"
+        href="https://feistymeow.org/">Feisty Meow® codebase</a> .&nbsp;
+      Together, these services provide you with a very flexible and powerful
+      testbed for web development, especially suited for <a title="it's cake" href="https://cakephp.org/">CakePHP</a>.</p>
+    <p>Commands preceded by an octothorpe ('#') below are intended to be typed
+      into a bash shell running on the cakelampvm virtual machine.&nbsp; The
+      bash shell can be obtained either by logging into the VM through ssh or by
+      logging in directly to the Virtualbox VM console.&nbsp; You may find the
+      ssh session more convenient, because copy &amp; paste features work as
+      expected.</p>
+    <p>Commands preceded by a greater-than symbol ('&gt;') are intended to be
+      run on the Host PC in a Windows command prompt (or in a bash prompt running
+      on the Host PC).</p>
+    <h2> Guest VM Configuration<a id="#config" name="#config"></a></h2>
+    <ul>
+      <li>Hostname: <a title="the vm's website, when configured properly" href="https://cakelampvm.com/">cakelampvm.com</a></li>
+      <li>Local IP Address: 10.28.42.20</li>
+      <li>Services Included: DNS (bind9), apache2, fluxbox X windowing system, <a
+          title="not just in the garden" href="https://www.gnome.org/">gnome
+          display manager</a></li>
+      <li>Main VM User: developer (password distributed separately)</li>
+      <li>Database Access: mysql root account, password: (password distributed
+        separately)</li>
+    </ul>
+    <h2>Powering up with the Feisty Meow® scripts<a id="#powerup" name="#powerup"></a></h2>
+    The feisty meow scripts are a cohesive bash scripting environment for
+    getting a variety of tasks done.&nbsp; The feisty meow scripts recently
+    incorporated the "avbash" collection from Saco Designs and added those
+    scripts to a new "site_avenger" collection of scripts.&nbsp; The site
+    avenger scripts provide tools for bringing up CakePHP web sites and managing
+    the collection of repositories for those sites.&nbsp; Each website is
+    considered an "application", and the application name itself (e.g.
+    "winterportlibrary") can often provide all the details for "powering up" the
+    site.&nbsp; The feisty meow team has added additional scripts for managing
+    DNS domains and Apache websites that provide the capability to "stand up" an
+    entire website around an application, with an accompanying DNS domain and
+    Apache2 site definition.
+    <p>The site avenger scripts are documented separately within the feisty meow
+      codebase.&nbsp; Consult the <span style="text-decoration: underline;">f</span><a
+        title="quickstart" href="https://feistymeow.org/feisty_meow/readme.txt">eisty
+meow
+        readme</a> file first, as it provides some valuable information on
+      configuring the codebase initially.&nbsp; The site avenger script commands
+      are documented in the <a title="useful commands" href="https://feistymeow.org/feisty_meow/documentation/feisty_meow_command_reference.txt">feisty
+        meow command reference</a> file.</p>
+    <p>(The feisty meow codebase is already configured for the developer account
+      on the cakelampvm virtual machine.)</p>
+    <h2>How to set up virtualbox for your host PC<a id="#virtualbox-setup" name="#virtualbox-setup"></a></h2>
+    <ol>
+      <li>Download and install virtualbox:
+        https://www.virtualbox.org/wiki/Downloads</li>
+      <li>Install the extension pack for Virtualbox: This provides USB drivers
+        and other features.&nbsp; This is installed on Virtualbox itself (on the
+        Host PC), not on the guests.</li>
+      <ol>
+        <li>Download the extension pack at
+          https://www.virtualbox.org/wiki/Downloads</li>
+        <li>Stop any running Virtualbox VMs.</li>
+        <li>Close the Virtualbox control panel.</li>
+        <li>Double-click on the downloaded extensions package (in a file
+          explorer) and Virtualbox should be launched to install it.</li>
+      </ol>
+      <li>Run the Virtualbox control panel.</li>
+      <li>Download the cakelampvm guest vm package and unzip it.&nbsp; Store the
+        unzipped version in some appropriate place where you want the virtual
+        machine to reside on your host's hard drive.</li>
+      <li>Add the guest VM to your list of VMs.&nbsp; From the Virtualbox menus,
+        choose the "Machine" menu and select "Add".&nbsp; Point the selector
+        dialog at the cakelampvm folder you created above and open the
+        cakelampvm.vbox file.</li>
+      <li>Now the cakelampvm should show up in the list of virtual
+        machines.&nbsp; Before starting it, perform the following network
+        configuration sections.</li>
+    </ol>
+    <h3>Configure the Host-Only network on Virtualbox<a id="#host-only" name="#host-only"></a></h3>
+    <p>Configuring host-only networking for the VM makes the VM completely local
+      to your machine.&nbsp; The cakelampvm will not be accessible on the
+      internet or from the LAN, and can only be accessed by your host PC.</p>
+    <p>Note: If the host-only or NAT network exist ahead of time, Virtualbox may
+      complain about them even if they have the correct configuration.&nbsp;
+      This can be corrected simply by opening the VM settings and selecting the
+      appropriate network names again.</p>
+    <p>To configure the host-only network, follow these steps:</p>
+    <ol>
+      <li> Go to virtual box "Preferences" (global preferences, not for a
+        specific vm).</li>
+      <li> Click on the "Network" tab.</li>
+      <li> Choose the "Host-only Networks" tab from within "Network".</li>
+      <li> Click the plus icon to add a new host-only network, or if there is
+        already a Host-only network, then edit it.</li>
+      <li>Set the "Adapter" parameters:<br>
+        IPv4 Address: 10.28.42.1<br>
+        IPv4 Network Mask: 255.255.255.0<br>
+        IPv6 Address: (leave blank)<br>
+        IPv6 Prefix Length: 0<br>
+        Virtualbox will fill in the other details like so:<br>
+        <p><img alt="host only network adapter" src="images/host_only_network_adapter.png"></p>
+      </li>
+      <li>Set the "DHCP Server Settings" to disabled, e.g.<br>
+        <img alt="host only dhcp" src="images/host_only_adapter_dhcp_server.png"><br>
+        This is disabled because we will be using statically assigned addresses
+        for convenience and stability.</li>
+    </ol>
+    <p>Additional information on host-only (and other) network adapter types is
+      at: https://www.virtualbox.org/manual/ch06.html#network_nat_service</p>
+    <h3>Configure the NAT Network on Virtualbox<a id="#nat-network" name="#nat-network"></a></h3>
+    <p>The NAT (Network Address Translation) network allows the VM to get off of
+      the machine and onto the internet safely.&nbsp; It will use this interface
+      for any communication off of the host machine.&nbsp; Since the real IP
+      address of the VM is hidden behind the NAT firewall on Virtualbox, this
+      keeps the VM safe from attackers, and hence your machine stays safe as
+      well.</p>
+    <p>To set up the NAT network, follow these steps:</p>
+    <ol>
+      <li> Go to virtual box "Preferences" (global preferences, not for a
+        specific vm).</li>
+      <li> Click on the "Network" tab.</li>
+      <li> Choose the "Nat Networks" tab from within "Network".</li>
+      <li> Click the plus icon to add a new host-only network.</li>
+      <li>Set the "NAT Network Details" parameters:<br>
+        Network Name: NatNetwork<br>
+        Network CIDR: 10.0.2.0/24<br>
+        Supports DHCP: checked<br>
+        Supports IPv6: optionally checked<br>
+        These are my settings, with IPv6 left disabled:<br>
+        <img alt="nat net config" src="images/nat_network_config.png"></li>
+    </ol>
+    <h2>Starting up the VM<a id="#start-vm" name="#start-vm"></a></h2>
+    <p>Using the Virtualbox interface, you should now be able to start your
+      virtual machine.&nbsp; Virtualbox will complain if it detects any
+      remaining configuration problems in the VM, but it should start
+      normally.&nbsp; The Linux boot sequence will show many lines of text,
+      before bringing up a black console window with a login dialog.</p>
+    <p>If Windows complains about the Virtualbox application slamming into its
+      firewall, then allow the Virtualbox to get through.&nbsp; Usually, telling
+      Windows that once is enough, but if any odd network access problems result,
+      edit the Windows firewall settings and allow Virtualbox to use both
+      "Public" and "Private" networks.</p>
+    <p>You can log in directly on the VM console with the developer account, but
+      it is generally more useful to connect to the cakelampvm over ssh.&nbsp;
+      If the networking has been established properly, you should be able to do
+      this with:</p>
+    <pre>ssh developer@cakelampvm.com&nbsp; (or equivalent with your ssh client)</pre>
+    <p>And then provide the password to log in.</p>
+    <p>If a feature called "X forwarding" is enabled in your ssh client, then
+      you can start graphical applications on the VM and display them on your
+      local machine.&nbsp; This works right away on most Linux hosts, but can
+      also work on PCs with X window system installed.&nbsp; The section below
+      describes how to set up Cygwin to run X server, which enable X forwarding
+      to your local display.</p>
+    <p>...{insert that info}...</p>
+    <h2>Updating cakelampvm to the Latest Model<a id="#update-vm" name="#update-vm"></a></h2>
+    <p>The cakelampvm is released with the intention to not be released
+      again.&nbsp; Version 001 was not built with that explicit intention, which
+      then required the release of Version 002.&nbsp; We hope to not need a v003
+      release.</p>
+    <p>There is an update feature built into the VM that is quite easy to
+      use.&nbsp; The updates are driven by the feisty meow script repository in
+      conjunction with a local scripted command.&nbsp; To activate the "update
+      process" for your VM, run the following commands (without the initial '#'
+      symbol):</p>
+    <p># rpuffer $FEISTY_MEOW_APEX&nbsp;&nbsp; # updates to the latest version
+      of feisty meow<br>
+      # revamp_cakelampvm&nbsp;&nbsp;&nbsp; # enacts any configuration changes
+      needed, plus fixes web folder and other permissions.</p>
+    <p>These two commands can be run at any time to patch up your VM to the
+      latest.</p>
+    <p>The first command ("rpuffer ...") is also useful on its own for getting
+      the latest version of the feisty meow code.&nbsp; If there are bug fixes
+      you need for the scripts or you want updated cakelampvm documentation,
+      that is the command to use.</p>
+    <h2>Using the guest VM's DNS services<a id="#dns-from-vm" name="#dns-from-vm"></a></h2>
+    <p>The cakelampvm has been set up to provide a DNS server which will answer
+      name lookup requests on any of the sites that the cakelampvm is hosting
+      for you.&nbsp; It will also serve as a general DNS server for any other
+      domains that need to be looked up.</p>
+    <p>To use the cakelampvm DNS, modify your host operating system network
+      configuration by adding or changing the DNS server to use the guest VM's
+      DNS service.&nbsp; The cakelampvm is available at the local IP address
+      10.28.42.20.&nbsp; (The DNS server can be tested with nslookup, dig and
+      other tools.)</p>
+    <p>Note that the cakelampvm DNS should be listed first, if one intends to
+      override any DNS names that actually exist out on the internet.&nbsp; We
+      have also found it most effective to have only the cakelampvm as your DNS
+      server, because a secondary DNS server can "take over" providing the name
+      lookups, and thus foul up DNS requests that should succeed for your
+      VM-hosted sites.</p>
+    <p>If your Host PC is running Windows, see the DNS configuration section
+      below that is tailored to that operating system.</p>
+    <p>Important Note: It behooves you to remember to switch back to a normal
+      DNS server configuration when you shut off the cakelampvm, or your machine
+      will not know the names of any sites on the internet any more!</p>
+    <p>Once the DNS server is properly set up (by whatever means necessary),
+      these ping commands should get answering responses (from 10.28.42.20) on
+      both the cakelampvm VM and on your host PC.&nbsp; Note: ping on Linux
+      keeps going forever, so hit control-C when you are tired of seeing the pings:</p>
+    <pre># ping cakelampvm.com</pre>
+    <pre># ping mapsdemo.cakelampvm.com</pre>
+    <p>Note that any other answer than 10.28.42.20 for the address is *bzzzt*
+      wrong, and means something needs to be fixed.</p>
+    <p>If these pings succeed (which hopefully they will!), then try accessing
+      the websites of each domain:</p>
+    <pre>(browse to) http://cakelampvm.com</pre>
+    <pre>(browse to) http://mapsdemo.cakelampvm.com</pre>
+    <p>These should show local sites on the VM rather than sites on the
+      internet.&nbsp; If you instead get failures to find the domains, or if the
+      "real internet" site comes up for cakelampvm.com (the page covered with
+      red X marks and complaining), then the DNS is not hooked up properly yet.</p>
+    <h4>Troubleshooting the DNS</h4>
+    <p>If your pings are getting the wrong answers and you're certain the DNS
+      settings on your Host PC are right, then you may need to flush your DNS
+      cache, and that might be sufficient.&nbsp; On Windows, the command for
+      flushing DNS is:</p>
+    <pre>&gt; ipconfig /flushdns</pre>
+    <p>and on Linux the flush DNS command can be many different things, but try
+      these two most common options:</p>
+    <pre># sudo service dns-clean restart&nbsp;&nbsp; # restarts the client side DNS cache.</pre>
+    <p>or</p>
+    <pre># sudo service nscd restart&nbsp;&nbsp; # restarts the nscd caching server.</pre>
+    After, this try the pings again.&nbsp; If they still fail, please go back
+    over your DNS configuration very carefully.&nbsp; The cakelampvm's DNS
+    feature *does* actually work, but operating systems sometimes do their best
+    to deny this.<br>
+    <h4>Troubleshooting the Apache Sites</h4>
+    <p>If your DNS pings and lookups are functioning properly, but you're just
+      not getting the right websites, then try clearing your browser's cache and
+      shutting the browser application down.&nbsp; Then, start the browser up
+      and try the address again.&nbsp; Often this cache dumping is enough to fix
+      the browser so that you start seeing the local website versions on
+      cakelampvm.com.</p>
+    <h3>Setting up DNS on Windows<a id="#windoze-dns" name="#windoze-dns"></a></h3>
+    <p>The ipconfig tool will provide helpful information about your current
+      networking and DNS configuration:</p>
+    <pre>ipconfig --all</pre>
+    <p>The DNS configuration on Windows is somewhat byzantine.&nbsp; The pipe
+      characters ('|') below are used to separate the menus or tabs or dialogs
+      to traverse.&nbsp; Follow this path to get to the DNS config:</p>
+    <pre>Control Panel | Network &amp; Sharing | click WiFI or Ethernet link near top right | click Adapter Settings on left | click on specific network device to modify | select Properties</pre>
+    <p><br>
+    </p>
+    <p>{fill in rest}<br>
+    </p>
+    <p><br>
+    </p>
+    <h2>Editing files on the guest VM from the host<a id="#editing-files-on-vm"
+        name="#editing-files-on-vm"></a></h2>
+    <p>On the host computer, look for the guest vm as a networked computer
+      called cakelampvm.&nbsp; This should provide some network shares using
+      Microsoft SMB protocol, and they can be attached to using the "developer"
+      user and its password.</p>
+    <p>On windows, one may want to mount this network location as a drive letter
+      for easier access.</p>
+    <p>Currently, the root of all web servers is exposed as "www".&nbsp; Editing
+      the files in those folders requires ownership by the developer user.&nbsp;
+      The existing mapsdemo site is owned by a different user ("fred") rather
+      than developer, mostly as a test case.&nbsp; The "fred", "developer", and
+      "www-data" accounts on the VM have all been put into each others Unix
+      "groups" so that they can access each other's files, and thus you may not
+      notice any issues editing fred's files.</p>
+    <p>One should be able to create a new directory over the network also.&nbsp;
+      Try creating a junk folder in the "www" folder, and then deleting it
+      again.&nbsp; That should succeed, and this approach can be used to create
+      folders (from the Host PC) that are owned by the developer user (on the
+      VM).&nbsp; You should be able to create folders or copy files within the
+      developer's home folder also ("/home/developer").</p>
+    <p>If you run into any permission problems that prevent file access, either
+      remotely or within the VM itself, then try running this command to fix
+      them:</p>
+    <pre># revamp_cakelampvm</pre>
+    <p>Afterwards, the www folder and others should allow the developer user to
+      create new folders at will.</p>
+    <p>The revamp command above is also used to deliver new configuration to the
+      VM from the feisty meow script environment; running it after any update of
+      the feisty meow codebase is a good idea.</p>
+    <h2>Accessing files on the host PC from the guest VM<a id="#samba-shares" name="#samba-shares"></a></h2>
+    <p>If you want to share a folder from the host to the guest, perhaps for
+      driver updates or other conveniences, then make the share with these
+      steps:</p>
+    <ol>
+      <li>Create a folder on the host that is to be shared.</li>
+      <li>Right-click on the vm in Virtualbox manager and choose "Settings".</li>
+      <li>In the "Shared Folders" tab of the settings, go to "Machine Folders".</li>
+      <li>Click the folder plus icon to create a new share.</li>
+      <li>Fill in the "Folder Path" on the host PC to the folder that will be
+        shared, and give it a name for the guest.&nbsp; We assume the folder
+        name will be "myshare".</li>
+      <li>On the guest vm, run the following commands to mount the share:<br>
+        <pre># mkdir ~/shared&nbsp;&nbsp;&nbsp; # for the guest's version of the shared folder<br># sudo mount -t vboxsf myshare ~/shared&nbsp;&nbsp;&nbsp; # mount the vm's share name onto the folder on the vm.</pre>
+      </li>
+    </ol>
+    <h2>Adding a new website and domain on the guest VM</h2>
+    <p>Note: these instructions, even the quick approaches below, pale in
+      comparison to the ease of use of the "standup" command in feisty meow's
+      site avenger scripts.&nbsp; The standup command is detailed in the&nbsp;<a
+        title="useful commands" href="https://feistymeow.org/feisty_meow/documentation/feisty_meow_command_reference.txt">feisty
+        meow command reference</a> document.&nbsp; These instructions are for
+      situations when the domain or site is idiosyncratic in some way that
+      standup doesn't support.</p>
+    <p>To add a new website, you will first need to pick one of the DNS options
+      below (A or B) depending on how you want to name the site.&nbsp; If the
+      DNS name of the site is contained within another existing domain (e.g.,
+      "A.B.C" has subdomain A contained in domain B.C), use Option A.&nbsp; If
+      the DNS name is a so-called "Second Level Domain" (SLD), then it stands on
+      its own (e.g., "B.C" is an SLD).</p>
+    <p>Once the DNS option has been picked and implemented, continue to the next
+      section of "Creating a New Apache Site".</p>
+    <p>For either Option A or Option B, first connect to the cakelampvm via ssh
+      as the developer user, e.g.: ssh developer@cakelampvm.com </p>
+    <h3>DNS Option A: Adding a sub-domain in an existing domain</h3>
+    <p>Let us say a customer needs an application called "excalibur".&nbsp; It
+      will be a new subdomain within an existing domain, such as the
+      "cakelampvm.com" domain, meaning we want the VM to start answering
+      requests for "excalibur.cakelampvm.com".</p>
+    Note that this option requires the containing domain "cakelampvm.com" to
+    already exist before adding the subdomain; see DNS Option B below for
+    details on how to add a containing domain for the first time.
+    <h4>Quick approach: Use the feisty meow "add_domain" command.</h4>
+    <p>Run this command in a bash shell on the VM:</p>
+    <pre># add_domain excalibur.cakelampvm.com</pre>
+    <p>Done.</p>
+    <h4>Manual approach: Edit the bind9 configuration.</h4>
+    <p>Note: the manual approach is not compatible with later use of feisty
+      meow's "remove_domain".</p>
+    Execute the following command to edit the DNS file for the cakelampvm
+    domain:
+    <pre># sudo vi /etc/bind/cakelampvm.com.conf</pre>
+    <p>Add a stanza for the new site at the end of this file:</p>
+    <pre>excalibur.cakelampvm.com.&nbsp;&nbsp;&nbsp; IN A&nbsp;&nbsp;&nbsp; 10.28.42.20<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IN HINFO "linux server" "ubuntu"</pre>
+    <p>Restart the DNS server:</p>
+    <pre># sudo service bind9 restart</pre>
+    <p>Afterwards, pinging excalibur.cakelampvm.com should work from both the
+      guest VM and the host PC.</p>
+    <h3>DNS Option B: Using an entirely new domain for the site</h3>
+    <p>This is a similar procedure to Option A, but we will create a totally new
+      config file for the new domain and add it to the bind directory.&nbsp; For
+      this example, we need to add the site "excalibur.tv" into the DNS.</p>
+    <h4>Quick approach: Use the feisty meow "add_domain" command.</h4>
+    Run this command in a bash shell on the VM:
+    <pre># add_domain excalibur.tv</pre>
+    <p>Done.</p>
+    <h4>Manual approach: Edit a new DNS config file</h4>
+    <p>Note: the manual approach is not compatible with later use of feisty
+      meow's "remove_domain".</p>
+    Create a file called /etc/bind/excalibur.tv.conf for our new domain
+    excalibur.tv with these contents:
+    <pre>$TTL 1W<br>@&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN SOA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fred.cakelampvm.com. (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2017100801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; serial<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; refresh<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8M&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; retry<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; expiry<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6H )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; minimum<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN NS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ns.cakelampvm.com.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN MX&nbsp;&nbsp; 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mail.cakelampvm.com.<br><br># new SLD for our excalibur site.<br>excalibur.tv.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.28.42.20<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN HINFO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "linux server" "ubuntu"</pre>
+    The gnarly prefix stuff above the "excalibur.tv." listing establishes
+    configuration info for the new domain.&nbsp; This file relies on the
+    existing cakelampvm.com infrastructure in DNS, such as the "ns" host, which
+    is the domain's name server.&nbsp; However, the new domain does <span style="text-decoration: underline;">not</span>
+    live inside the cakelampvm.com domain.<br>
+    <p>Now that the config file is in place, edit "/etc/bind/named.conf.local"
+      to add the new file by adding this bit of configuration at the end:</p>
+    <pre>zone "excalibur.tv" in {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file "/etc/bind/excalibur.tv.conf";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type master;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; allow-query { any; };<br>};</pre>
+    <p>Restart the DNS server:</p>
+    <pre># sudo service bind9 restart</pre>
+    <p>Afterwards, pinging excalibur.tv should work from both the guest and the
+      host.</p>
+    <h3>Creating a New Apache Site</h3>
+    <p>First, connect to the cakelampvm via ssh as the developer user, e.g.: ssh
+      developer@cakelampvm.com </p>
+    <h4>Quick approach: Use the feisty meow "add_apache_site" command.</h4>
+    <p>Run this command in a bash shell on the VM:</p>
+    <pre># add_apache_site excalibur excalibur.tv</pre>
+    <p>(The first parameter is the application name, the second is the domain
+      name.)</p>
+    <p>Done.</p>
+    <h4>Manual approach: Edit an Apache config file</h4>
+    <p>Note: the manual approach is not compatible with later use of feisty
+      meow's "remove_apache_site".</p>
+    <p>For Apache, the choice of DNS Option A or B, subdomain or SLD, does not
+      matter.&nbsp; The site configuration file just has to accurately specify
+      the domain in question.</p>
+    <p>Start with the following template file for the new website, and modify it
+      for the appropriate host name and "DocumentRoot" path:</p>
+    <pre>&lt;VirtualHost *:80&gt;<br>&nbsp;&nbsp;&nbsp; ServerName excalibur.tv
+&nbsp;&nbsp;&nbsp; DocumentRoot /home/apps/excalibur<br>&nbsp;&nbsp;&nbsp; ErrorLog ${APACHE_LOG_DIR}/excalibur.tv-error.log<br>&nbsp;&nbsp;&nbsp; CustomLog ${APACHE_LOG_DIR}/excalibur.tv-access.log combined<br>&nbsp;&nbsp;&nbsp; Include /etc/apache2/conf-library/basic-options.conf<br>&nbsp;&nbsp;&nbsp; Include /etc/apache2/conf-library/rewrite-enabling.conf<br>&lt;/VirtualHost&gt;</pre>
+    <p>The above example is appropriate for our excalibur app in the
+      excalibur.tv domain (using DNS Option B).&nbsp; Modifying the excalibur.tv
+      references in it (and the path in the DocumentRoot) is sufficient to
+      re-target it for any domain you want.</p>
+    <p>Copy the new site config file into "/etc/apache2/sites-available" with an
+      appropriate file name that includes the site's domain name.&nbsp; We will
+      call our config file "excalibur.tv.conf".&nbsp; If you developed the file
+      in your home folder, this would be the command to move it up to Apache:</p>
+    <pre># sudo cp ~/excalibur.tv.conf /etc/apache2/sites-available</pre>
+    <p>Then tell apache to use the new file:</p>
+    <pre># sudo a2ensite excalibur.tv  # the '.conf' portion of the filename is unnecessary for this command.
+</pre>
+    <p>Finally, restart apache to get it to begin serving the site:</p>
+    <pre># sudo service apache2 restart</pre>
+    <h3>Test the new web site</h3>
+    <p>Given the configuration above, your host PC should now be able to access
+      the new website on the domain "excalibur.tv".</p>
+    <p>To test this, first try pinging the new DNS name:</p>
+    <pre># ping excalibur.tv</pre>
+    <p>If there are responses to the ping *and* the answer is 10.28.42.20, then
+      it means the DNS is working.&nbsp; If there are no responses or it's some
+      other IP address talking back, check the instructions in the above DNS
+      sections.</p>
+    <p>Once the DNS is working, try browsing to the site at "http://excalibur.tv".&nbsp;
+      That should at least bring up the configured site storage path, even if
+      nothing is being served from that folder yet.</p>
+    <p>If the new site is not showing up properly, try examining the apache logs
+      for any error messages that can be corrected.&nbsp; The log files are
+      stored in "/var/log/apache2" and are named after the website (if
+      configured through the above process).</p>
+    <h2>Handy Techniques for Using cakelampvm</h2>
+    <h3>Assorted Guides and Cheat-Sheets</h3>
+    <p>A Cheat sheet for the Vim editor (there are many of these available): <a
+        title="vim commands" href="https://vim.rtorr.com/">https://vim.rtorr.com/</a></p>
+    <p>A git branching model that seems to work well: <a title="release and patch process"
+        href="http://nvie.com/posts/a-successful-git-branching-model/">http://nvie.com/posts/a-successful-git-branching-model/</a></p>
+    <h3>Get the network address on the guest vm</h3>
+    <p>Run this command: ifconfig</p>
+    <p>In the results, look for "inet addr".&nbsp; There may be more than one,
+      if there are multiple network interfaces.</p>
+    <p>The standard IP address is 10.28.42.20 for the cakelampvm.</p>
+    <h3>How to cleanly reboot or shut down the guest VM</h3>
+    <p>When you've got the DNS and everything integrated, these commands will
+      manage the vm's state:</p>
+    <p>First, log into the guest VM:</p>
+    <pre># ssh developer@cakelampvm.com</pre>
+    <p>Then, to reboot the guest VM:</p>
+    <pre># sudo reboot</pre>
+    <p>Or, to halt the guest VM:</p>
+    <pre># sudo shutdown -h now</pre>
+    <p>Using these commands is kinder to the VM than just cycling the power from
+      the Virtualbox control panel.</p>
+    <p><br>
+    </p>
+    <h1>Gritty Details of the Nitty Variety<a id="#nitty-gritty" name="#nitty-gritty"></a></h1>
+    <p>This is the lowest level of plumbing for your VM.&nbsp; Hopefully you
+      will not need to engage with this section.&nbsp; The most useful doc
+      section here is the one below about the "Virtualbox guest additions",
+      which you will probably need at some future point.&nbsp; Oracle releases
+      updates to the guest additions fairly regularly.</p>
+    <h2>Configuring the guest VM</h2>
+    <p>The guest VM should already be set up appropriately.&nbsp; These steps
+      are provided for reference and updates.</p>
+    <h3>Set up Virtualbox guest additions for the VM</h3>
+    This procedure is needed if the guest provides an older or incompatible
+    version of the guest additions (which have already been installed on the
+    guest vm).&nbsp; It may also be necessary when a new version of the guest
+    additions becomes available.
+    <ol>
+      <li>To install the guest additions, open the guest VM and have its window
+        in focus.</li>
+      <li>Choose the "Devices" menu and select "Insert Guest Additions CD
+        Image".&nbsp; This will mount the CD's ISO image on the VM.</li>
+      <li>On the guest VM, it may be necessary to mount the CD image that's now
+        available:<br>
+        <pre># sudo mount /dev/sr0 /media/cdrom</pre>
+        <p>Linux will mention that the device is mounted "read-only".</p>
+      </li>
+      <li>Since the VM currently has no windowing system installed, one must
+        start the Guest Additions install manually:<br>
+        <pre># cd /media/cdrom<br># sudo sh VBoxLinuxAdditions.run</pre>
+      </li>
+      <li>The latest Virtualbox guest additions should now be installed.</li>
+    </ol>
+    <h3>Set up network adapters on guest VM</h3>
+    <p>The network interfaces should already be configured on the guest within
+      the Virtualbox configuration.&nbsp; This is available by clicking on the
+      VM in the Virtualbox manager and selecting "Settings".&nbsp; These are the
+      configuration settings used:</p>
+    Adapter 1:<br>
+    &nbsp; Attached to: Host-only Adapter<br>
+    &nbsp; Name: vboxnet0&nbsp; <br>
+    <p>Adapter 2:<br>
+      &nbsp; Attached to: Nat Network<br>
+      &nbsp; Name: NatNetwork</p>
+    <p>On the guest VM itself, the network settings are specified in a file
+      called /etc/network/interfaces.&nbsp; Here are the current contents of
+      that file:</p>
+    <pre>source /etc/network/interfaces.d/*<br><br>auto lo<br>iface lo inet loopback<br><br>auto enp0s3<br>iface enp0s3 inet static<br>&nbsp; address 10.28.42.20<br>&nbsp; netmask 255.255.255.0<br>&nbsp; network 10.28.42.0<br>&nbsp; broadcast 10.28.42.255<br>&nbsp; dns-domain cakelampvm.com<br>&nbsp; dns-search cakelampvm.com<br>&nbsp; dns-nameservers 127.0.0.1 8.8.8.8</pre>
+    <pre>auto enp0s8</pre>
+    <pre>iface enp0s8 inet dhcp</pre>
+    <p> </p>
+    <h2>Notes on building the Cake Lamp VM</h2>
+    <p>This is all work that should already have been done.&nbsp; It is
+      mentioned here just as breadcrumbs for a future vm builder.</p>
+    <ul>
+      <li>Downloaded and installed Virtualbox for host computer (where the vm
+        image will be built).</li>
+      <li>Downloaded ubuntu server 16.04 iso.
+        (https://www.ubuntu.com/download/server)</li>
+      <li>Created a new vm in Virtualbox, telling it to start from the ubuntu
+        server iso.</li>
+      <li>Installed LAMP stack on guest VM.&nbsp; Some help here:
+        http://howtoubuntu.org/how-to-install-lamp-on-ubuntu</li>
+      <li>Configured CAKE on the guest VM.&nbsp; Useful link:
+        https://askubuntu.com/questions/628938/how-to-install-cakephp-in-ubuntu-14-04</li>
+      <li>Configured the two network adapters as needed (one for host-only
+        network and one for nat network).&nbsp; Here's some info about
+        Virtualbox networking with two adapters similar to our setup:
+https://askubuntu.com/questions/293816/in-virtualbox-how-do-i-set-up-host-only-virtual-machines-that-can-access-the-in<br>
+      </li>
+      <li>Installed and configured Samba service for the guest VM.&nbsp; The
+        main config file lives in "/etc/samba/smb.conf".&nbsp; Some pointers
+        here:
+https://help.ubuntu.com/community/How%20to%20Create%20a%20Network%20Share%20Via%20Samba%20Via%20CLI%20%28Command-line%20interface/Linux%20Terminal%29%20-%20Uncomplicated%2C%20Simple%20and%20Brief%20Way%21</li>
+    </ul>
+    <p><br>
+    </p>
+    <ul>
+    </ul>
+    <h6> </h6>
+    <p> </p>
+  </body>
+</html>
diff --git a/production/sites/cakelampvm.com/docs/manual/images/host_only_adapter_dhcp_server.png b/production/sites/cakelampvm.com/docs/manual/images/host_only_adapter_dhcp_server.png
new file mode 100644 (file)
index 0000000..53db956
Binary files /dev/null and b/production/sites/cakelampvm.com/docs/manual/images/host_only_adapter_dhcp_server.png differ
diff --git a/production/sites/cakelampvm.com/docs/manual/images/host_only_network_adapter.png b/production/sites/cakelampvm.com/docs/manual/images/host_only_network_adapter.png
new file mode 100644 (file)
index 0000000..dd87e5f
Binary files /dev/null and b/production/sites/cakelampvm.com/docs/manual/images/host_only_network_adapter.png differ
diff --git a/production/sites/cakelampvm.com/docs/manual/images/nat_network_config.png b/production/sites/cakelampvm.com/docs/manual/images/nat_network_config.png
new file mode 100644 (file)
index 0000000..3299a3b
Binary files /dev/null and b/production/sites/cakelampvm.com/docs/manual/images/nat_network_config.png differ
diff --git a/production/sites/cakelampvm.com/goog_maps_helper_mod/GoogleMapHelper.php b/production/sites/cakelampvm.com/goog_maps_helper_mod/GoogleMapHelper.php
new file mode 100644 (file)
index 0000000..074707f
--- /dev/null
@@ -0,0 +1,1728 @@
+<?php
+namespace Geo\View\Helper;
+
+use Cake\Core\Configure;
+use Cake\Core\Exception\Exception;
+use Cake\Routing\Router;
+use Cake\Utility\Hash;
+use Cake\View\Helper;
+use Cake\View\View;
+use Geo\View\Helper\JsBaseEngineTrait;
+
+/**
+ * This is a CakePHP helper that helps users to integrate GoogleMap v3
+ * into their application by only writing PHP code. This helper depends on jQuery.
+ *
+ * Capable of resetting itself (full or partly) for multiple maps on a single view.
+ *
+ * CodeAPI: http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/basics.html
+ * Icons/Images: http://gmapicons.googlepages.com/home
+ *
+ * @author Rajib Ahmed
+ * @author Mark Scherer
+ * @link http://www.dereuromark.de/2010/12/21/googlemapsv3-cakephp-helper/
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ * @property \Cake\View\Helper\HtmlHelper $Html
+ */
+class GoogleMapHelper extends Helper {
+
+       use JsBaseEngineTrait;
+
+       const API = 'maps.google.com/maps/api/js';
+
+       const STATIC_API = 'maps.google.com/maps/api/staticmap';
+
+       /**
+        * @var int
+        */
+       public static $mapCount = 0;
+
+       /**
+        * @var int
+        */
+       public static $markerCount = 0;
+
+       /**
+        * @var int
+        */
+       public static $iconCount = 0;
+
+       /**
+        * @var int
+        */
+       public static $infoWindowCount = 0;
+
+       /**
+        * @var int
+        */
+       public static $infoContentCount = 0;
+
+       const TYPE_ROADMAP = 'R';
+
+       const TYPE_HYBRID = 'H';
+
+       const TYPE_SATELLITE = 'S';
+
+       const TYPE_TERRAIN = 'T';
+
+       /**
+        * @var array
+        */
+       public $types = [
+               self::TYPE_ROADMAP => 'ROADMAP',
+               self::TYPE_HYBRID => 'HYBRID',
+               self::TYPE_SATELLITE => 'SATELLITE',
+               self::TYPE_TERRAIN => 'TERRAIN'
+       ];
+
+       const TRAVEL_MODE_DRIVING = 'D';
+
+       const TRAVEL_MODE_BICYCLING = 'B';
+
+       const TRAVEL_MODE_TRANSIT = 'T';
+
+       const TRAVEL_MODE_WALKING = 'W';
+
+       /**
+        * @var array
+        */
+       public $travelModes = [
+               self::TRAVEL_MODE_DRIVING => 'DRIVING',
+               self::TRAVEL_MODE_BICYCLING => 'BICYCLING',
+               self::TRAVEL_MODE_TRANSIT => 'TRANSIT',
+               self::TRAVEL_MODE_WALKING => 'WALKING'
+       ];
+
+       /**
+        * Needed helpers
+        *
+        * @var array
+        */
+       public $helpers = ['Html'];
+
+       /**
+        * Google maker config instance variable
+        *
+        * @var array
+        */
+       public $markers = [];
+
+       /**
+        * @var array
+        */
+       public $infoWindows = [];
+
+       /**
+        * @var array
+        */
+       public $infoContents = [];
+
+       /**
+        * @var array
+        */
+       public $icons = [];
+
+       /**
+        * @var array
+        */
+       public $matching = [];
+
+       /**
+        * @var string
+        */
+       public $map = '';
+
+       /**
+        * @var array
+        */
+       protected $_mapIds = []; // Remember already used ones (valid xhtml contains ids not more than once)
+
+       /**
+        * Default settings
+        *
+        * @var array
+        */
+       protected $_defaultConfig = [
+               'zoom' => null, // global, both map and staticMap
+               'lat' => null, // global, both map and staticMap
+               'lng' => null, // global, both map and staticMap
+               'api' => '3',
+               'type' => self::TYPE_ROADMAP,
+               'map' => [
+                       'api' => null,
+                       'zoom' => null,
+                       'lat' => null,
+                       'lng' => null,
+                       'type' => null,
+                       'streetViewControl' => false,
+                       'navigationControl' => true,
+                       'mapTypeControl' => true,
+                       'scaleControl' => true,
+                       'scrollwheel' => false,
+                       'keyboardShortcuts' => true,
+                       'typeOptions' => [],
+                       'navOptions' => [],
+                       'scaleOptions' => [],
+                       'defaultLat' => 51, // only last fallback, use Configure::write('Google.lat', ...); to define own one
+                       'defaultLng' => 11, // only last fallback, use Configure::write('Google.lng', ...); to define own one
+                       'defaultZoom' => 5,
+               ],
+               'staticMap' => [
+                       'size' => '300x300',
+                       'format' => 'png',
+                       'mobile' => false,
+                       //'shadow' => true // for icons
+               ],
+               'geolocate' => false,
+               'language' => null,
+               'region' => null,
+               'showMarker' => true,
+               //'showInfoWindow' => true,
+               'infoWindow' => [
+                       'content' => '',
+                       'useMultiple' => false, // Using single infowindow object for all
+                       'maxWidth' => 300,
+                       'lat' => null,
+                       'lng' => null,
+                       'pixelOffset' => 0,
+                       'zIndex' => 200,
+                       'disableAutoPan' => false
+               ],
+               'marker' => [
+                       //'autoCenter' => true,
+                       'animation' => null, // BOUNCE or DROP  https://developers.google.com/maps/documentation/javascript/3.exp/reference#Animation
+                       'icon' => null, // => default (red marker) //http://google-maps-icons.googlecode.com/files/home.png
+                       'title' => null,
+                       'shadow' => null,
+                       'shape' => null,
+                       'zIndex' => null,
+                       'draggable' => false,
+                       'cursor' => null,
+                       'directions' => false, // add form with directions
+                       'open' => false, // New in 1.5
+               ],
+               'div' => [
+                       'id' => 'map_canvas',
+                       'width' => '100%',
+                       'height' => '400px',
+                       'class' => 'map',
+                       'escape' => true
+               ],
+               'event' => [
+               ],
+               'animation' => [
+                       //TODO
+               ],
+               'polyline' => [
+                       'color' => '#FF0000',
+                       'opacity' => 1.0,
+                       'weight' => 2,
+               ],
+               'directions' => [
+                       'travelMode' => self::TRAVEL_MODE_DRIVING,
+                       'unitSystem' => 'METRIC',
+                       'directionsDiv' => null,
+               ],
+               'callbacks' => [
+                       'geolocate' => null //TODO
+               ],
+               'plugins' => [
+                       'keydragzoom' => false, // http://google-maps-utility-library-v3.googlecode.com/svn/tags/keydragzoom/
+                       'markermanager' => false, // http://google-maps-utility-library-v3.googlecode.com/svn/tags/markermanager/
+                       'markercluster' => false, // http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/
+               ],
+               'autoCenter' => false, // try to fit all markers in (careful, all zooms values are omitted)
+               'autoScript' => false, // let the helper include the necessary js script links
+               'block' => true, // for scripts
+               'localImages' => false,
+               'https' => null, // auto detect
+               'key' => null,
+       ];
+
+       /**
+        * @var array
+        */
+       protected $_runtimeConfig = [];
+
+       /**
+        * @var bool
+        */
+       protected $_apiIncluded = false;
+
+       /**
+        * @var bool
+        */
+       protected $_gearsIncluded = false;
+
+       /**
+        * @var bool
+        */
+       protected $_located = false;
+
+       /**
+        * @param \Cake\View\View|null $View
+        * @param array $config
+        */
+       public function __construct(View $View, array $config = []) {
+               parent::__construct($View, $config);
+       }
+
+       /**
+        * @param array $config
+        * @return void
+        */
+       public function initialize(array $config) {
+               parent::initialize($config);
+
+               $defaultConfig = Hash::merge($this->_defaultConfig, (array)Configure::read('GoogleMap'));
+               $config = Hash::merge($defaultConfig, $config);
+
+               if (isset($config['api']) && !isset($config['map']['api'])) {
+                       $config['map']['api'] = $config['api'];
+               }
+               if (isset($config['zoom']) && !isset($config['map']['zoom'])) {
+                       $config['map']['zoom'] = $config['zoom'];
+               }
+               if (isset($config['lat']) && !isset($config['map']['lat'])) {
+                       $config['map']['lat'] = $config['lat'];
+               }
+               if (isset($config['lng']) && !isset($config['map']['lng'])) {
+                       $config['map']['lng'] = $config['lng'];
+               }
+               if (isset($config['type']) && !isset($config['map']['type'])) {
+                       $config['map']['type'] = $config['type'];
+               }
+               if (isset($config['size'])) {
+                       $config['div']['width'] = $config['size']['width'];
+                       $config['div']['height'] = $config['size']['height'];
+               }
+               if (isset($config['staticSize'])) {
+                       $config['staticMap']['size'] = $config['staticSize'];
+               }
+               // the following are convenience defaults - if not available the map lat/lng/zoom defaults will be used
+               if (isset($config['staticZoom'])) {
+                       $config['staticMap']['zoom'] = $config['staticZoom'];
+               }
+               if (isset($config['staticLat'])) {
+                       $config['staticMap']['lat'] = $config['staticLat'];
+               }
+               if (isset($config['staticLng'])) {
+                       $config['staticMap']['lng'] = $config['staticLng'];
+               }
+               if (isset($config['localImages'])) {
+                       if ($config['localImages'] === true) {
+                               $config['localImages'] = Router::url('/img/google_map/', true);
+                       }
+               }
+
+               // BC
+               if (!empty($config['inline'])) {
+                       trigger_error('Deprecated inline option, use block instead.', E_USER_DEPRECATED);
+                       $config['block'] = null;
+               }
+
+               $this->_config = $config;
+               $this->_runtimeConfig = $this->_config;
+       }
+
+       /**
+        * JS maps.google API url.
+        *
+        * Options read via configs
+        * - key
+        * - api
+        * - language (iso2: en, de, ja, ...)
+        *
+        * You can adds more after the URL like "&key=value&..." via
+        * - query string array: additional query strings (e.g. callback for deferred execution - not supported yet by this helper)
+        *
+        * @param array $query
+        * @return string Full URL
+        */
+       public function apiUrl(array $query = []) {
+               $url = $this->_protocol() . static::API;
+
+               if ($this->_runtimeConfig['map']['api']) {
+                        $query['v'] = $this->_runtimeConfig['map']['api'];
+               }
+               if ($this->_runtimeConfig['key']) {
+                       $query['key'] = $this->_runtimeConfig['key'];
+               }
+
+               if ($this->_runtimeConfig['language']) {
+                       $query['language'] = $this->_runtimeConfig['language'];
+               }
+
+               if ($query) {
+                       $query = http_build_query($query);
+
+                       $url .= '?' . $query;
+               }
+
+               return $url;
+       }
+
+       /**
+        * @deprecated
+        * @return string
+        */
+       public function gearsUrl() {
+               $this->_gearsIncluded = true;
+               $url = $this->_protocol() . 'code.google.com/apis/gears/gears_init.js';
+               return $url;
+       }
+
+       /**
+        * @return string currentMapObject
+        */
+       public function name() {
+               return 'map' . static::$mapCount;
+       }
+
+       /**
+        * @return string currentContainerId
+        */
+       public function id() {
+               return $this->_runtimeConfig['div']['id'];
+       }
+
+       /**
+        * Make it possible to include multiple maps per page
+        * resets markers, infoWindows etc
+        *
+        * @param bool $full true=optionsAsWell
+        * @return void
+        */
+       public function reset($full = true) {
+               static::$markerCount = static::$infoWindowCount = 0;
+               $this->markers = $this->infoWindows = [];
+               if ($full) {
+                       $this->_runtimeConfig = $this->_config;
+               }
+       }
+
+       /**
+        * Set the controls of current map
+        *
+        * Control options
+        * - zoom, scale, overview: TRUE/FALSE
+        *
+        * - map: FALSE, small, large
+        * - type: FALSE, normal, menu, hierarchical
+        * TIP: faster/shorter by using only the first character (e.g. "H" for "hierarchical")
+        *
+        * @param array $options
+        * @return void
+        */
+       public function setControls(array $options = []) {
+               if (isset($options['streetView'])) {
+                       $this->_runtimeConfig['map']['streetViewControl'] = $options['streetView'];
+               }
+               if (isset($options['zoom'])) {
+                       $this->_runtimeConfig['map']['scaleControl'] = $options['zoom'];
+               }
+               if (isset($options['scrollwheel'])) {
+                       $this->_runtimeConfig['map']['scrollwheel'] = $options['scrollwheel'];
+               }
+               if (isset($options['keyboardShortcuts'])) {
+                       $this->_runtimeConfig['map']['keyboardShortcuts'] = $options['keyboardShortcuts'];
+               }
+               if (isset($options['type'])) {
+                       $this->_runtimeConfig['map']['type'] = $options['type'];
+               }
+       }
+
+       /**
+        * This the initialization point of the script
+        * Returns the div container you can echo on the website
+        *
+        * @param array $options associative array of settings are passed
+        * @return string divContainer
+        */
+       public function map(array $options = []) {
+               $this->reset();
+               $this->_runtimeConfig = Hash::merge($this->_runtimeConfig, $options);
+               $this->_runtimeConfig['map'] = $options + $this->_runtimeConfig['map'];
+
+               if (!isset($this->_runtimeConfig['map']['lat']) || !isset($this->_runtimeConfig['map']['lng'])) {
+                       $this->_runtimeConfig['map']['lat'] = $this->_runtimeConfig['map']['defaultLat'];
+                       $this->_runtimeConfig['map']['lng'] = $this->_runtimeConfig['map']['defaultLng'];
+               }
+               if (!isset($this->_runtimeConfig['map']['zoom'])) {
+                       $this->_runtimeConfig['map']['zoom'] = $this->_runtimeConfig['map']['defaultZoom'];
+               }
+
+               $result = '';
+
+               // autoinclude js?
+               if ($this->_runtimeConfig['autoScript'] && !$this->_apiIncluded) {
+                       $res = $this->Html->script($this->apiUrl(), ['block' => $this->_runtimeConfig['block']]);
+                       $this->_apiIncluded = true;
+
+                       if (!$this->_runtimeConfig['block']) {
+                               $result .= $res . PHP_EOL;
+                       }
+                       // usually already included
+                       //http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
+               }
+               // still not very common: http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/basics.html
+               if (false && !empty($this->_runtimeConfig['autoScript']) && !$this->_gearsIncluded) {
+                       $res = $this->Html->script($this->gearsUrl(), ['block' => $this->_runtimeConfig['block']]);
+                       if (!$this->_runtimeConfig['block']) {
+                               $result .= $res . PHP_EOL;
+                       }
+               }
+
+               $map = "
+                       var initialLocation = " . $this->_initialLocation() . ";
+                       var browserSupportFlag = new Boolean();
+                       var myOptions = " . $this->_mapOptions() . ";
+
+                       // deprecated
+                       gMarkers" . static::$mapCount . " = new Array();
+                       gInfoWindows" . static::$mapCount . " = new Array();
+                       gWindowContents" . static::$mapCount . " = new Array();
+               ";
+
+               #rename "map_canvas" to "map_canvas1", ... if multiple maps on one page
+               while (in_array($this->_runtimeConfig['div']['id'], $this->_mapIds)) {
+                       $this->_runtimeConfig['div']['id'] .= '-1'; //TODO: improve
+               }
+               $this->_mapIds[] = $this->_runtimeConfig['div']['id'];
+
+               $map .= "
+                       var " . $this->name() . ' = new google.maps.Map(document.getElementById("' . $this->_runtimeConfig['div']['id'] . "\"), myOptions);
+                       ";
+               $this->map = $map;
+
+               $this->_runtimeConfig['div']['style'] = '';
+               if (is_numeric($this->_runtimeConfig['div']['width'])) {
+                       $this->_runtimeConfig['div']['width'] .= 'px';
+               }
+               if (is_numeric($this->_runtimeConfig['div']['height'])) {
+                       $this->_runtimeConfig['div']['height'] .= 'px';
+               }
+
+               $this->_runtimeConfig['div']['style'] .= 'width: ' . $this->_runtimeConfig['div']['width'] . ';';
+               $this->_runtimeConfig['div']['style'] .= 'height: ' . $this->_runtimeConfig['div']['height'] . ';';
+               unset($this->_runtimeConfig['div']['width']);
+               unset($this->_runtimeConfig['div']['height']);
+
+               $defaultText = isset($this->_runtimeConfig['content']) ? $this->_runtimeConfig['content'] : __('Map cannot be displayed!');
+               $result .= $this->Html->tag('div', $defaultText, $this->_runtimeConfig['div']);
+
+               return $result;
+       }
+
+       /**
+        * Generate a new LatLng object with the current lat and lng.
+        *
+        * @return string
+        */
+       protected function _initialLocation() {
+               if ($this->_runtimeConfig['map']['lat'] && $this->_runtimeConfig['map']['lng']) {
+                       return 'new google.maps.LatLng(' . $this->_runtimeConfig['map']['lat'] . ', ' . $this->_runtimeConfig['map']['lng'] . ')';
+               }
+               $this->_runtimeConfig['autoCenter'] = true;
+               return 'false';
+       }
+
+       /**
+        * Add a marker to the map.
+        *
+        * Options:
+        * - lat and lng or address (to geocode on demand, not recommended, though)
+        * - title, content, icon, directions, maxWidth, open (optional)
+        *
+        * Note, that you can only set one marker to "open" for single window mode.
+        * If you declare multiple ones, the last one will be the one shown as open.
+        *
+        * @param array $options
+        * @return mixed Integer marker count or boolean false on failure
+        * @throws \Cake\Core\Exception\Exception
+        */
+       public function addMarker($options) {
+               $defaults = $this->_runtimeConfig['marker'];
+               if (isset($options['icon']) && is_array($options['icon'])) {
+                       $defaults = $options['icon'] + $defaults;
+                       unset($options['icon']);
+               }
+               $options += $defaults;
+
+               $params = [];
+               $params['map'] = $this->name();
+
+               if (isset($options['title'])) {
+                       $params['title'] = json_encode($options['title']);
+               }
+               if (isset($options['icon'])) {
+                       $params['icon'] = $options['icon'];
+                       if (is_int($params['icon'])) {
+                               $params['icon'] = 'gIcons' . static::$mapCount . '[' . $params['icon'] . ']';
+                       } else {
+                               $params['icon'] = json_encode($params['icon']);
+                       }
+               }
+               if (isset($options['shadow'])) {
+                       $params['shadow'] = $options['shadow'];
+                       if (is_int($params['shadow'])) {
+                               $params['shadow'] = 'gIcons' . static::$mapCount . '[' . $params['shadow'] . ']';
+                       } else {
+                               $params['shadow'] = json_encode($params['shadow']);
+                       }
+               }
+               if (isset($options['shape'])) {
+                       $params['shape'] = $options['shape'];
+               }
+               if (isset($options['zIndex'])) {
+                       $params['zIndex'] = $options['zIndex'];
+               }
+               if (isset($options['animation'])) {
+                       $params['animation'] = 'google.maps.Animation.' . strtoupper($options['animation']);
+               }
+
+               // geocode if necessary
+               if (!isset($options['lat']) || !isset($options['lng'])) {
+                       $this->map .= "
+var geocoder = new google.maps.Geocoder();
+
+function geocodeAddress(address) {
+       geocoder.geocode({'address': address}, function(results, status) {
+               if (status == google.maps.GeocoderStatus.OK) {
+
+                       x" . static::$markerCount . " = new google.maps.Marker({
+                               position: results[0].geometry.location,
+                               " . $this->_toObjectParams($params, false, false) . "
+                       });
+                       gMarkers" . static::$mapCount . " .push(
+                               x" . static::$markerCount . "
+                       );
+                       return results[0].geometry.location;
+               } else {
+                       //alert('Geocoding was not successful for the following reason: ' + status);
+                       return null;
+               }
+       });
+}";
+                       if (!isset($options['address'])) {
+                               throw new Exception('Either use lat/lng or address to add a marker');
+                       }
+                       $position = 'geocodeAddress("' . h($options['address']) . '")';
+               } else {
+                       $position = 'new google.maps.LatLng(' . $options['lat'] . ',' . $options['lng'] . ')';
+               }
+
+               $marker = "
+                       var x" . static::$markerCount . " = new google.maps.Marker({
+                               position: " . $position . ",
+                               " . $this->_toObjectParams($params, false, false) . "
+                       });
+                       gMarkers" . static::$mapCount . " .push(
+                               x" . static::$markerCount . "
+                       );
+               ";
+               $this->map .= $marker;
+
+               if (!empty($options['directions'])) {
+                       $options['content'] .= $this->_directions($options['directions'], $options);
+               }
+
+               // Fill popup windows
+               if (!empty($options['content']) && $this->_runtimeConfig['infoWindow']['useMultiple']) {
+                       $x = $this->addInfoWindow(['content' => $options['content']]);
+                       $this->addEvent(static::$markerCount, $x, $options['open']);
+
+               } elseif (!empty($options['content'])) {
+                       if (!isset($this->_runtimeConfig['marker']['infoWindow'])) {
+                               $this->_runtimeConfig['marker']['infoWindow'] = $this->addInfoWindow();
+                       }
+
+                       $x = $this->addInfoContent($options['content']);
+                       $event = "
+                       gInfoWindows" . static::$mapCount . '[' . $this->_runtimeConfig['marker']['infoWindow'] . ']. setContent(gWindowContents' . static::$mapCount . '[' . $x . "]);
+                       gInfoWindows" . static::$mapCount . '[' . $this->_runtimeConfig['marker']['infoWindow'] . '].open(' . $this->name() . ', gMarkers' . static::$mapCount . '[' . $x . "]);
+                       ";
+                       $this->addCustomEvent(static::$markerCount, $event);
+
+                       if (!empty($options['open'])) {
+                               $this->addCustom($event);
+                       }
+               }
+
+               // Custom matching event?
+               if (isset($options['id'])) {
+                       $this->matching[$options['id']] = static::$markerCount;
+               }
+
+               return static::$markerCount++;
+       }
+
+       /**
+        * Build directions form (type get) for directions inside infoWindows
+        *
+        * Options for directions (if array)
+        * - label
+        * - submit
+        * - escape: defaults to true
+        *
+        * @param mixed $directions
+        * - bool TRUE for autoDirections (using lat/lng)
+        * @param array $markerOptions
+        * - options array of marker for autoDirections etc (optional)
+        * @return string HTML
+        */
+       protected function _directions($directions, array $markerOptions = []) {
+               $options = [
+                       'from' => null,
+                       'to' => null,
+                       'label' => __('Enter your address'),
+                       'submit' => __('Get directions'),
+                       'escape' => true,
+                       'zoom' => null, // auto
+               ];
+               if ($directions === true) {
+                       $options['to'] = $markerOptions['lat'] . ',' . $markerOptions['lng'];
+               } elseif (is_array($directions)) {
+                       $options = $directions + $options;
+               }
+               if (empty($options['to']) && empty($options['from'])) {
+                       return '';
+               }
+               $form = '<form action="http://maps.google.com/maps" method="get" target="_blank">';
+               $form .= $options['escape'] ? h($options['label']) : $options['label'];
+               if (!empty($options['from'])) {
+                       $form .= '<input type="hidden" name="saddr" value="' . $options['from'] . '" />';
+               } else {
+                       $form .= '<input type="text" name="saddr" />';
+               }
+               if (!empty($options['to'])) {
+                       $form .= '<input type="hidden" name="daddr" value="' . $options['to'] . '" />';
+               } else {
+                       $form .= '<input type="text" name="daddr" />';
+               }
+               if (isset($options['zoom'])) {
+                       $form .= '<input type="hidden" name="z" value="' . $options['zoom'] . '" />';
+               }
+               $form .= '<input type="submit" value="' . $options['submit'] . '" />';
+               $form .= '</form>';
+
+               return '<div class="directions">' . $form . '</div>';
+       }
+
+       /**
+        * @param string $content
+        * @return int Current marker counter
+        */
+       public function addInfoContent($content) {
+               $this->infoContents[static::$markerCount] = $this->escapeString($content);
+               $event = "
+                       gWindowContents" . static::$mapCount . '.push(' . $this->escapeString($content) . ");
+                       ";
+               $this->addCustom($event);
+
+               //TODO: own count?
+               return static::$markerCount;
+       }
+
+       /**
+        * @var array
+        */
+       public $setIcons = [
+               'color' => 'http://www.google.com/mapfiles/marker%s.png',
+               'alpha' => 'http://www.google.com/mapfiles/marker%s%s.png',
+               'numeric' => 'http://google-maps-icons.googlecode.com/files/%s%s.png',
+               'special' => 'http://google-maps-icons.googlecode.com/files/%s.png'
+       ];
+
+       /**
+        * Get a custom icon set
+        *
+        * @param string $color Color: green, red, purple, ... or some special ones like "home", ...
+        * @param string|null $char Char: A...Z or 0...20/100 (defaults to none)
+        * @param string $size Size: s, m, l (defaults to medium)
+        * NOTE: for special ones only first parameter counts!
+        * @return array Array(icon, shadow, shape, ...)
+        */
+       public function iconSet($color, $char = null, $size = 'm') {
+               $colors = ['red', 'green', 'yellow', 'blue', 'purple', 'white', 'black'];
+               if (!in_array($color, $colors)) {
+                       $color = 'red';
+               }
+
+               if (!empty($this->_runtimeConfig['localImages'])) {
+                       $this->setIcons['color'] = $this->_runtimeConfig['localImages'] . 'marker%s.png';
+                       $this->setIcons['alpha'] = $this->_runtimeConfig['localImages'] . 'marker%s%s.png';
+                       $this->setIcons['numeric'] = $this->_runtimeConfig['localImages'] . '%s%s.png';
+                       $this->setIcons['special'] = $this->_runtimeConfig['localImages'] . '%s.png';
+               }
+
+               if (!empty($char)) {
+                       if ($color === 'red') {
+                               $color = '';
+                       } else {
+                               $color = '_' . $color;
+                       }
+                       $url = sprintf($this->setIcons['alpha'], $color, $char);
+               } else {
+                       if ($color === 'red') {
+                               $color = '';
+                       } else {
+                               $color = '_' . $color;
+                       }
+                       $url = sprintf($this->setIcons['color'], $color);
+               }
+
+               /*
+        var iconImage = new google.maps.MarkerImage('images/' + images[0] + ' .png',
+            new google.maps.Size(iconData[images[0]].width, iconData[images[0]].height),
+            new google.maps.Point(0,0),
+            new google.maps.Point(0, 32)
+        );
+
+        var iconShadow = new google.maps.MarkerImage('images/' + images[1] + ' .png',
+            new google.maps.Size(iconData[images[1]].width, iconData[images[1]].height),
+            new google.maps.Point(0,0),
+            new google.maps.Point(0, 32)
+        );
+
+        var iconShape = {
+            coord: [1, 1, 1, 32, 32, 32, 32, 1],
+            type: 'poly'
+        };
+        */
+
+               $shadow = 'http://www.google.com/mapfiles/shadow50.png';
+               $res = [
+                       'url' => $url,
+                       'icon' => $this->icon($url, ['size' => ['width' => 20, 'height' => 34]]),
+                       'shadow' => $this->icon($shadow, ['size' => ['width' => 37, 'height' => 34], 'shadow' => ['width' => 10, 'height' => 34]])
+               ];
+               return $res;
+       }
+
+       /**
+        * Generate icon array.
+        *
+        * custom icon: http://thydzik.com/thydzikGoogleMap/markerlink.php?text=?&color=FFFFFF
+        * custom icons: http://code.google.com/p/google-maps-icons/wiki/NumericIcons#Lettered_Balloons_from_A_to_Z,_in_10_Colors
+        * custom shadows: http://www.cycloloco.com/shadowmaker/shadowmaker.htm
+        *
+        * @param string $image Image Url (http://...)
+        * @param string|null $shadow ShadowImage Url (http://...)
+        * @param array $imageOptions Image options
+        * @param array $shadowOptions Shadow image options
+        * @return array Resulting array
+        */
+       public function addIcon($image, $shadow = null, array $imageOptions = [], array $shadowOptions = []) {
+               $res = ['url' => $image];
+               $res['icon'] = $this->icon($image, $imageOptions);
+               if ($shadow) {
+                       $last = $this->_iconRemember[$res['icon']];
+                       if (!isset($shadowOptions['anchor'])) {
+                               $shadowOptions['anchor'] = [];
+                       }
+                       $shadowOptions['anchor'] = $last['options']['anchor'] + $shadowOptions['anchor'];
+
+                       $res['shadow'] = $this->icon($shadow, $shadowOptions);
+               }
+               return $res;
+       }
+
+       /**
+        * @var array
+        */
+       protected $_iconRemember = [];
+
+       /**
+        * Generate icon object
+        *
+        * @param string $url (required)
+        * @param array $options (optional):
+        * - size: array(width=>x, height=>y)
+        * - origin: array(width=>x, height=>y)
+        * - anchor: array(width=>x, height=>y)
+        * @return int Icon count
+        */
+       public function icon($url, array $options = []) {
+               // The shadow image is larger in the horizontal dimension
+               // while the position and offset are the same as for the main image.
+               if (empty($options['size'])) {
+                       if (substr($url, 0, 1) === '/') {
+                               // patch local paths to use the document root.  otherwise getimagesize fails filesystem lookup.
+                               // paths with http or other protocol in front will be handled more simply in 'else' below.
+                               $canonicalPath = realpath(WWW_ROOT . $url);
+                               if (! $canonicalPath) {
+                                       // failed to resolve the path, so just fall back to the url provided.
+                                       $canonicalPath = "$url";
+                               }
+                               $data = getimagesize($canonicalPath);
+                       } else {
+                               $data = getimagesize($url);
+                       }
+                       if ($data) {
+                               $options['size']['width'] = $data[0];
+                               $options['size']['height'] = $data[1];
+                       } else {
+                               $options['size']['width'] = $options['size']['height'] = 0;
+                       }
+               }
+               if (empty($options['anchor'])) {
+                       $options['anchor']['width'] = (int)($options['size']['width'] / 2);
+                       $options['anchor']['height'] = $options['size']['height'];
+               }
+               if (empty($options['origin'])) {
+                       $options['origin']['width'] = $options['origin']['height'] = 0;
+               }
+               if (isset($options['shadow'])) {
+                       $options['anchor'] = $options['shadow'];
+               }
+
+               $icon = 'new google.maps.MarkerImage("' . $url . '",
+       new google.maps.Size(' . $options['size']['width'] . ', ' . $options['size']['height'] . '),
+       new google.maps.Point(' . $options['origin']['width'] . ', ' . $options['origin']['height'] . '),
+       new google.maps.Point(' . $options['anchor']['width'] . ', ' . $options['anchor']['height'] . ')
+)';
+               $this->icons[static::$iconCount] = $icon;
+               $this->_iconRemember[static::$iconCount] = ['url' => $url, 'options' => $options, 'id' => static::$iconCount];
+               return static::$iconCount++;
+       }
+
+       /**
+        * Creates a new InfoWindow.
+        *
+        * @param array $options
+        * - lat, lng, content, maxWidth, pixelOffset, zIndex
+        * @return int windowCount
+        */
+       public function addInfoWindow(array $options = []) {
+               $defaults = $this->_runtimeConfig['infoWindow'];
+               $options += $defaults;
+
+               if (!empty($options['lat']) && !empty($options['lng'])) {
+                       $position = 'new google.maps.LatLng(' . $options['lat'] . ', ' . $options['lng'] . ')';
+               } else {
+                       $position = ' ' . $this->name() . ' .getCenter()';
+               }
+
+               $windows = "
+                       gInfoWindows" . static::$mapCount . ".push(new google.maps.InfoWindow({
+                                       position: {$position},
+                                       content: " . $this->escapeString($options['content']) . ",
+                                       maxWidth: {$options['maxWidth']},
+                                       pixelOffset: {$options['pixelOffset']}
+                                       /*zIndex: {$options['zIndex']},*/
+                       }));
+                       ";
+               $this->map .= $windows;
+               return static::$infoWindowCount++;
+       }
+
+       /**
+        * Add event to open marker on click.
+        *
+        * @param int $marker
+        * @param int $infoWindow
+        * @param bool $open Also open it right away.
+        * @return void
+        */
+       public function addEvent($marker, $infoWindow, $open = false) {
+               $this->map .= "
+                       google.maps.event.addListener(gMarkers" . static::$mapCount . "[{$marker}], 'click', function() {
+                               gInfoWindows" . static::$mapCount . "[$infoWindow].open(" . $this->name() . ", this);
+                       });
+               ";
+               if ($open) {
+                       $event = 'gInfoWindows' . static::$mapCount . "[$infoWindow].open(" . $this->name() .
+                               ', gMarkers' . static::$mapCount . '[' . $marker . ']);';
+                       $this->addCustom($event);
+               }
+       }
+
+       /**
+        * Add a custom event for a marker on click.
+        *
+        * @param int $marker
+        * @param string $event (js)
+        * @return void
+        */
+       public function addCustomEvent($marker, $event) {
+               $this->map .= "
+                       google.maps.event.addListener(gMarkers" . static::$mapCount . "[{$marker}], 'click', function() {
+                               $event
+                       });
+               ";
+       }
+
+       /**
+        * Add custom JS.
+        *
+        * @param string $js Custom JS
+        * @return void
+        */
+       public function addCustom($js) {
+               $this->map .= $js;
+       }
+
+       /**
+        * Add directions to the map.
+        *
+        * @param array|string $from Location as array(fixed lat/lng pair) or string (to be geocoded at runtime)
+        * @param array|string $to Location as array(fixed lat/lng pair) or string (to be geocoded at runtime)
+        * @param array $options
+        * - directionsDiv: Div to place directions in text form
+        * - travelMode: TravelMode,
+        * - transitOptions: TransitOptions,
+        * - unitSystem: UnitSystem (IMPERIAL, METRIC, AUTO),
+        * - waypoints[]: DirectionsWaypoint,
+        * - optimizeWaypoints: Boolean,
+        * - provideRouteAlternatives: Boolean,
+        * - avoidHighways: Boolean,
+        * - avoidTolls: Boolean
+        * - region: String
+        * @see https://developers.google.com/maps/documentation/javascript/3.exp/reference#DirectionsRequest
+        * @return void
+        */
+       public function addDirections($from, $to, array $options = []) {
+               $id = 'd' . static::$markerCount++;
+               $defaults = $this->_runtimeConfig['directions'];
+               $options += $defaults;
+               $travelMode = $this->travelModes[$options['travelMode']];
+
+               $directions = "
+                       var {$id}Service = new google.maps.DirectionsService();
+                       var {$id}Display;
+                       {$id}Display = new google.maps.DirectionsRenderer();
+                       {$id}Display. setMap(" . $this->name() . ");
+                       ";
+
+               if (!empty($options['directionsDiv'])) {
+                       $directions .= "{$id}Display. setPanel(document.getElementById('" . $options['directionsDiv'] . "'));";
+               }
+
+               if (is_array($from)) {
+                       $from = 'new google.maps.LatLng(' . (float)$from['lat'] . ', ' . (float)$from['lng'] . ')';
+               } else {
+                       $from = '"' . h($from) . '"';
+               }
+               if (is_array($to)) {
+                       $to = 'new google.maps.LatLng(' . (float)$to['lat'] . ', ' . (float)$to['lng'] . ')';
+               } else {
+                       $to = '"' . h($to) . '"';
+               }
+
+               $directions .= "
+                       var request = {
+                               origin: $from,
+                               destination: $to,
+                               unitSystem: google.maps.UnitSystem." . $options['unitSystem'] . ",
+                               travelMode: google.maps.TravelMode. $travelMode
+                       };
+                       {$id}Service.route(request, function(result, status) {
+                               if (status == google.maps.DirectionsStatus.OK) {
+                                       {$id}Display. setDirections(result);
+                               }
+                       });
+               ";
+               $this->map .= $directions;
+       }
+
+       /**
+        * Add a polyline
+        *
+        * This method adds a line between 2 points
+        *
+        * @param array|string $from Location as array(fixed lat/lng pair) or string (to be geocoded at runtime)
+        * @param array|string $to Location as array(fixed lat/lng pair) or string (to be geocoded at runtime)
+        * @param array $options
+        * - color (#FFFFFF ... #000000)
+        * - opacity (0.1 ... 1, defaults to 1)
+        * - weight in pixels (defaults to 2)
+        * @see https://developers.google.com/maps/documentation/javascript/3.exp/reference#Polyline
+        * @return void
+        */
+       public function addPolyline($from, $to, array $options = []) {
+               if (is_array($from)) {
+                       $from = 'new google.maps.LatLng(' . (float)$from['lat'] . ', ' . (float)$from['lng'] . ')';
+               } else {
+                       throw new Exception('not implemented yet, use array of lat/lng');
+                       //$from = '\'' . h($from) . '\'';
+               }
+               if (is_array($to)) {
+                       $to = 'new google.maps.LatLng(' . (float)$to['lat'] . ', ' . (float)$to['lng'] . ')';
+               } else {
+                       throw new Exception('not implemented yet, use array of lat/lng');
+                       //$to = '\'' . h($to) . '\'';
+               }
+
+               $defaults = $this->_runtimeConfig['polyline'];
+               $options += $defaults;
+
+               $id = 'p' . static::$markerCount++;
+
+               $polyline = "var start = $from;";
+               $polyline .= "var end = $to;";
+               $polyline .= "
+                               var poly = [
+                                       start,
+                                       end
+                               ];
+                               var {$id}Polyline = new google.maps.Polyline({
+                                       path: poly,
+                                       strokeColor: '" . $options['color'] . "',
+                                       strokeOpacity: " . $options['opacity'] . ",
+                                       strokeWeight: " . $options['weight'] . "
+                               });
+                               {$id}Polyline.setMap(" . $this->name() . ");
+                       ";
+               $this->map .= $polyline;
+       }
+
+       /**
+        * @param string $content (html/text)
+        * @param int $index infoWindowCount
+        * @return void
+        */
+       public function setContentInfoWindow($content, $index) {
+               $this->map .= "
+                       gInfoWindows" . static::$mapCount . "[$index]. setContent(" . $this->escapeString($content) . ');';
+       }
+
+       /**
+        * Json encode string
+        *
+        * @param mixed $content
+        * @return string JSON
+        */
+       public function escapeString($content) {
+               return json_encode($content);
+       }
+
+       /**
+        * This method returns the javascript for the current map container.
+        * Including script tags.
+        * Just echo it below the map container. New: Alternativly, use finalize() directly.
+        *
+        * @return string
+        */
+       public function script() {
+               $script = '<script>
+               ' . $this->finalize(true) . '
+</script>';
+               return $script;
+       }
+
+       /**
+        * Finalize the map and write the javascript to the buffer.
+        * Make sure that your view does also output the buffer at some place!
+        *
+        * @param bool $return If the output should be returned instead
+        * @return null|string Javascript if $return is true
+        */
+       public function finalize($return = false) {
+               $script = $this->_arrayToObject('matching', $this->matching, false, true) . PHP_EOL;
+               $script .= $this->_arrayToObject('gIcons' . static::$mapCount, $this->icons, false, false) . '
+
+       jQuery(document).ready(function() {
+               ';
+
+               $script .= $this->map;
+               if ($this->_runtimeConfig['geolocate']) {
+                       $script .= $this->_geolocate();
+               }
+
+               if ($this->_runtimeConfig['showMarker'] && !empty($this->markers) && is_array($this->markers)) {
+                       $script .= implode($this->markers, ' ');
+               }
+
+               if ($this->_runtimeConfig['autoCenter']) {
+                       $script .= $this->_autoCenter();
+               }
+               $script .= '
+
+       });';
+               static::$mapCount++;
+               if ($return) {
+                       return $script;
+               }
+               $this->Html->scriptBlock($script, ['block' => true]);
+       }
+
+       /**
+        * Set a custom geolocate callback
+        *
+        * @param string|bool $js Custom JS
+        * false: no callback at all
+        * @return void
+        */
+       public function geolocateCallback($js) {
+               if ($js === false) {
+                       $this->_runtimeConfig['callbacks']['geolocate'] = false;
+                       return;
+               }
+               $this->_runtimeConfig['callbacks']['geolocate'] = $js;
+       }
+
+       /**
+        * Experimental - works in cutting edge browsers like chrome10
+        *
+        * @return string
+        */
+       protected function _geolocate() {
+               return '
+       // Try W3C Geolocation (Preferred)
+       if (navigator.geolocation) {
+               browserSupportFlag = true;
+               navigator.geolocation.getCurrentPosition(function(position) {
+                       geolocationCallback(position.coords.latitude, position.coords.longitude);
+               }, function() {
+                       handleNoGeolocation(browserSupportFlag);
+               });
+               // Try Google Gears Geolocation
+       } else if (google.gears) {
+               browserSupportFlag = true;
+               var geo = google.gears.factory.create("beta.geolocation");
+               geo.getCurrentPosition(function(position) {
+                       geolocationCallback(position.latitude, position.longitude);
+               }, function() {
+                       handleNoGeoLocation(browserSupportFlag);
+               });
+               // Browser doesn\'t support Geolocation
+       } else {
+               browserSupportFlag = false;
+               handleNoGeolocation(browserSupportFlag);
+       }
+
+       function geolocationCallback(lat, lng) {
+               ' . $this->_geolocationCallback() . '
+       }
+
+       function handleNoGeolocation(errorFlag) {
+       if (errorFlag == true) {
+               //alert("Geolocation service failed.");
+       } else {
+               //alert("Your browser doesn\'t support geolocation. We\'ve placed you in Siberia.");
+       }
+       //' . $this->name() . ' . setCenter(initialLocation);
+       }
+       ';
+       }
+
+       /**
+        * @return string
+        */
+       protected function _geolocationCallback() {
+               if (($js = $this->_runtimeConfig['callbacks']['geolocate']) === false) {
+                       return '';
+               }
+               if ($js === null) {
+                       $js = 'initialLocation = new google.maps.LatLng(lat, lng);
+               ' . $this->name() . ' . setCenter(initialLocation);
+';
+               }
+               return $js;
+       }
+
+       /**
+        * Auto center map
+        * careful: with only one marker this can result in too high zoom values!
+        *
+        * @return string autoCenterCommands
+        */
+       protected function _autoCenter() {
+               return '
+               var bounds = new google.maps.LatLngBounds();
+               $.each(gMarkers' . static::$mapCount . ',function (index, marker) { bounds.extend(marker.position);});
+               ' . $this->name() . ' .fitBounds(bounds);
+               ';
+       }
+
+       /**
+        * @return string JSON like js string
+        */
+       protected function _mapOptions() {
+               $options = $this->_runtimeConfig['map'] + $this->_runtimeConfig;
+
+               $mapOptions = array_intersect_key($options, [
+                       'streetViewControl' => null,
+                       'navigationControl' => null,
+                       'mapTypeControl' => null,
+                       'scaleControl' => null,
+                       'scrollwheel' => null,
+                       'zoom' => null,
+                       'keyboardShortcuts' => null,
+                       'styles' => null,
+               ]);
+               $res = [];
+               foreach ($mapOptions as $key => $mapOption) {
+                       $res[] = $key . ': ' . $this->value($mapOption);
+               }
+               if (empty($options['autoCenter'])) {
+                       $res[] = 'center: initialLocation';
+               }
+               if (!empty($options['navOptions'])) {
+                       $res[] = 'navigationControlOptions: ' . $this->_controlOptions('nav', $options['navOptions']);
+               }
+               if (!empty($options['typeOptions'])) {
+                       $res[] = 'mapTypeControlOptions: ' . $this->_controlOptions('type', $options['typeOptions']);
+               }
+               if (!empty($options['scaleOptions'])) {
+                       $res[] = 'scaleControlOptions: ' . $this->_controlOptions('scale', $options['scaleOptions']);
+               }
+
+               if (array_key_exists($options['type'], $this->types)) {
+                       $type = $this->types[$options['type']];
+               } else {
+                       $type = $options['type'];
+               }
+               $res[] = 'mapTypeId: google.maps.MapTypeId.' . $type;
+
+               return '{' . implode(', ', $res) . '}';
+       }
+
+       /**
+        * @param string $type
+        * @param array $options
+        * @return string JSON like js string
+        */
+       protected function _controlOptions($type, $options) {
+               $mapping = [
+                       'nav' => 'NavigationControlStyle',
+                       'type' => 'MapTypeControlStyle',
+                       'scale' => ''
+               ];
+               $res = [];
+               if (!empty($options['style']) && ($m = $mapping[$type])) {
+                       $res[] = 'style: google.maps.' . $m . '.' . $options['style'];
+               }
+               if (!empty($options['pos'])) {
+                       $res[] = 'position: google.maps.ControlPosition.' . $options['pos'];
+               }
+
+               return '{' . implode(', ', $res) . '}';
+       }
+
+       /**
+        * Returns a maps.google link
+        *
+        * @param string $title  Link title
+        * @param array $mapOptions
+        * @param array $linkOptions
+        * @return string HTML link
+        */
+       public function mapLink($title, $mapOptions = [], $linkOptions = []) {
+               return $this->Html->link($title, $this->mapUrl($mapOptions + ['escape' => false]), $linkOptions);
+       }
+
+       /**
+        * Returns a maps.google url
+        *
+        * Options:
+        * - from: necessary (address or lat,lng)
+        * - to: 1x necessary (address or lat,lng - can be an array of multiple destinations: array('dest1', 'dest2'))
+        * - zoom: optional (defaults to none)
+        * - query: Additional query strings as array
+        * - escape: defaults to true
+        *
+        * @param array $options Options
+        * @return string link: http://...
+        */
+       public function mapUrl(array $options = []) {
+               $url = $this->_protocol() . 'maps.google.com/maps?';
+
+               $urlArray = !empty($options['query']) ? $options['query'] : [];
+               if (!empty($options['from'])) {
+                       $urlArray['saddr'] = $options['from'];
+               }
+
+               if (!empty($options['to']) && is_array($options['to'])) {
+                       $to = array_shift($options['to']);
+                       foreach ($options['to'] as $key => $value) {
+                               $to .= '+to:' . $value;
+                       }
+                       $urlArray['daddr'] = $to;
+               } elseif (!empty($options['to'])) {
+                       $urlArray['daddr'] = $options['to'];
+               }
+
+               if (isset($options['zoom']) && $options['zoom'] !== false) {
+                       $urlArray['z'] = (int)$options['zoom'];
+               }
+               //$urlArray[] = 'f=d';
+               //$urlArray[] = 'hl=de';
+               //$urlArray[] = 'ie=UTF8';
+
+               $options += [
+                       'escape' => true,
+               ];
+
+               $query = http_build_query($urlArray);
+               if ($options['escape']) {
+                       $query = h($query);
+               }
+
+               return $url . $query;
+       }
+
+       /**
+        * Creates a plain image map.
+        *
+        * @link http://code.google.com/intl/de-DE/apis/maps/documentation/staticmaps
+        * @param array $options Options
+        * - string $size [necessary: VALxVAL, e.g. 500x400 - max 640x640]
+        * - string $center: x,y or address [necessary, if no markers are given; else tries to take defaults if available] or TRUE/FALSE
+        * - int $zoom [optional; if no markers are given, default value is used; if set to "auto" and ]*
+        * - array $markers [optional, @see staticPaths() method]
+        * - string $type [optional: roadmap/hybrid, ...; default:roadmap]
+        * - string $mobile TRUE/FALSE
+        * - string $visible: $area (x|y|...)
+        * - array $paths [optional, @see staticPaths() method]
+        * - string $language [optional]
+        * @param array $attributes HTML attributes for the image
+        * - title
+        * - alt (defaults to 'Map')
+        * - url (tip: you can pass $this->link(...) and it will create a link to maps.google.com)
+        * @return string imageTag
+        */
+       public function staticMap(array $options = [], array $attributes = []) {
+               $defaultAttributes = ['alt' => __d('tools', 'Map')];
+               $attributes += $defaultAttributes;
+
+               // This was fixed in 3.5.1 to auto-escape URL query strings for security reasons
+               $escape = version_compare(Configure::version(), '3.5.1') < 0 ? true : false;
+               return $this->Html->image($this->staticMapUrl($options + ['escape' => $escape]), $attributes);
+       }
+
+       /**
+        * Create a link to a plain image map
+        *
+        * @param string $title Link title
+        * @param array $mapOptions
+        * @param array $linkOptions
+        * @return string HTML link
+        */
+       public function staticMapLink($title, array $mapOptions = [], array $linkOptions = []) {
+               return $this->Html->link($title, $this->staticMapUrl($mapOptions + ['escape' => false]), $linkOptions);
+       }
+
+       /**
+        * Creates a URL to a plain image map.
+        *
+        * Options:
+        * - escape: defaults to true (Deprecated as of CakePHP 3.5.1 and now has to be always false)
+        *
+        * @param array $options
+        * - see staticMap() for details
+        * @return string urlOfImage: http://...
+        */
+       public function staticMapUrl(array $options = []) {
+               $mapUrl = $this->_protocol() . static::STATIC_API;
+               /*
+               $params = array(
+                       'mobile' => 'false',
+                       'format' => 'png',
+                       //'center' => false
+               );
+
+               if (!empty($options['mobile'])) {
+                       $params['mobile'] = 'true';
+               }
+               */
+
+               $defaults = $this->_config['staticMap'] + $this->_config;
+
+               $mapOptions = $options + $defaults;
+
+               $params = array_intersect_key($mapOptions, [
+                       'mobile' => null,
+                       'format' => null,
+                       'size' => null,
+                       //'zoom' => null,
+                       //'lat' => null,
+                       //'lng' => null,
+                       //'visible' => null,
+                       //'type' => null,
+               ]);
+
+               // add API key to parameters.
+               if ($this->_runtimeConfig['key']) {
+                       $params['key'] = $this->_runtimeConfig['key'];
+               }
+
+               // do we want zoom to auto-correct itself?
+               if (!isset($options['zoom']) && !empty($mapOptions['markers']) || !empty($mapOptions['paths']) || !empty($mapOptions['visible'])) {
+                       $options['zoom'] = 'auto';
+               }
+
+               // a position on the map that is supposed to stay visible at all cost
+               if (!empty($mapOptions['visible'])) {
+                       $params['visible'] = urlencode($mapOptions['visible']);
+               }
+
+               // center and zoom are not necessary if path, visible or markers are given
+               if (!isset($options['center']) || $options['center'] === false) {
+                       // dont use it
+               } elseif ($options['center'] === true && $mapOptions['lat'] !== null && $mapOptions['lng'] !== null) {
+                       $params['center'] = urlencode((string)$mapOptions['lat'] . ',' . (string)$mapOptions['lng']);
+               } elseif (!empty($options['center'])) {
+                       $params['center'] = urlencode($options['center']);
+               } /*else {
+                       // try to read from markers array???
+                       if (isset($options['markers']) && count($options['markers']) == 1) {
+                               //pr ($options['markers']);
+                       }
+               }*/
+
+               if (!isset($options['zoom']) || $options['zoom'] === false) {
+                       // dont use it
+               } else {
+                       if ($options['zoom'] === 'auto') {
+                               if (!empty($options['markers']) && strpos($options['zoom'], '|') !== false) {
+                                       // let google find the best zoom value itself
+                               } else {
+                                       // do something here?
+                               }
+                       } else {
+                               $params['zoom'] = $options['zoom'];
+                       }
+               }
+
+               if (array_key_exists($mapOptions['type'], $this->types)) {
+                       $params['maptype'] = $this->types[$mapOptions['type']];
+               } else {
+                       $params['maptype'] = $mapOptions['type'];
+               }
+               $params['maptype'] = strtolower($params['maptype']);
+
+               // old: {latitude},{longitude},{color}{alpha-character}
+               // new: @see staticMarkers()
+               if (!empty($options['markers'])) {
+                       $params['markers'] = $options['markers'];
+               }
+
+               if (!empty($options['paths'])) {
+                       $params['path'] = $options['paths'];
+               }
+
+               // valXval
+               if (!empty($options['size'])) {
+                       $params['size'] = $options['size'];
+               }
+
+               $pieces = [];
+               foreach ($params as $key => $value) {
+                       if (is_array($value)) {
+                               $value = implode('&' . $key . '=', $value);
+                       } elseif ($value === true) {
+                               $value = 'true';
+                       } elseif ($value === false) {
+                               $value = 'false';
+                       } elseif ($value === null) {
+                               continue;
+                       }
+                       $pieces[] = $key . '=' . $value;
+               }
+
+               $options += [
+                       'escape' => true,
+               ];
+               $query = implode('&', $pieces);
+               if ($options['escape']) {
+                       $query = h($query);
+               }
+
+               return $mapUrl . '?' . $query;
+       }
+
+       /**
+        * Prepare paths for staticMap
+        *
+        * @param array $pos PathElementArrays
+        * - elements: [required] (multiple array(lat=>x, lng=>y) or just a address strings)
+        * - color: red/blue/green (optional, default blue)
+        * - weight: numeric (optional, default: 5)
+        * @return array Array of paths: e.g: color:0x0000FF80|weight:5|37.40303,-122.08334|37.39471,-122.07201|37.40589,-122.06171{|...}
+        */
+       public function staticPaths(array $pos = []) {
+               $defaults = [
+                       'color' => 'blue',
+                       'weight' => 5 // pixel
+               ];
+
+               // not a 2-level array? make it one
+               if (!isset($pos[0])) {
+                       $pos = [$pos];
+               }
+
+               $res = [];
+               foreach ($pos as $p) {
+                       $options = $p + $defaults;
+
+                       $markers = $options['path'];
+                       unset($options['path']);
+
+                       // prepare color
+                       if (!empty($options['color'])) {
+                               $options['color'] = $this->_prepColor($options['color']);
+                       }
+
+                       $path = [];
+                       foreach ($options as $key => $value) {
+                               $path[] = $key . ':' . urlencode($value);
+                       }
+                       foreach ($markers as $key => $pos) {
+                               if (is_array($pos)) {
+                                       // lat/lng?
+                                       $pos = $pos['lat'] . ',' . $pos['lng'];
+                               }
+                               $path[] = $pos;
+                       }
+                       $res[] = implode('|', $path);
+               }
+               return $res;
+       }
+
+       /**
+        * Prepare markers for staticMap
+        *
+        * @param array $pos markerArrays
+        * - lat: xx.xxxxxx (necessary)
+        * - lng: xx.xxxxxx (necessary)
+        * - address: (instead of lat/lng)
+        * - color: red/blue/green (optional, default blue)
+        * - label: a-z or numbers (optional, default: s)
+        * - icon: custom icon (png, gif, jpg - max 64x64 - max 5 different icons per image)
+        * - shadow: TRUE/FALSE
+        * @param array $style (global) (overridden by custom marker styles)
+        * - color
+        * - label
+        * - icon
+        * - shadow
+        * @return array markers: color:green|label:Z|48,11|Berlin
+        *
+        * NEW: size:mid|color:red|label:E|37.400465,-122.073003|37.437328,-122.159928&markers=size:small|color:blue|37.369110,-122.096034
+        * OLD: 40.702147,-74.015794,blueS|40.711614,-74.012318,greenG{|...}
+        */
+       public function staticMarkers(array $pos = [], array $style = []) {
+               $markers = [];
+               $verbose = false;
+
+               $defaults = [
+                       'shadow' => 'true',
+                       'color' => 'blue',
+                       'label' => '',
+                       'address' => '',
+                       'size' => ''
+               ];
+
+               // not a 2-level array? make it one
+               if (!isset($pos[0])) {
+                       $pos = [$pos];
+               }
+
+               // new in staticV2: separate styles! right now just merged
+               foreach ($pos as $p) {
+                       $p += $style + $defaults;
+
+                       // adress or lat/lng?
+                       if (!empty($p['lat']) && !empty($p['lng'])) {
+                               $p['address'] = $p['lat'] . ',' . $p['lng'];
+                       }
+                       $p['address'] = urlencode($p['address']);
+
+                       $values = [];
+
+                       // prepare color
+                       if (!empty($p['color'])) {
+                               $p['color'] = $this->_prepColor($p['color']);
+                               $values[] = 'color:' . $p['color'];
+                       }
+                       // label? A-Z0-9
+                       if (!empty($p['label'])) {
+                               $values[] = 'label:' . strtoupper($p['label']);
+                       }
+                       if (!empty($p['size'])) {
+                               $values[] = 'size:' . $p['size'];
+                       }
+                       if (!empty($p['shadow'])) {
+                               $values[] = 'shadow:' . $p['shadow'];
+                       }
+                       if (!empty($p['icon'])) {
+                               $values[] = 'icon:' . urlencode($p['icon']);
+                       }
+                       $values[] = $p['address'];
+
+                       //TODO: icons
+                       $markers[] = implode('|', $values);
+               }
+
+               //TODO: shortcut? only possible if no custom params!
+               if ($verbose) {
+
+               }
+               // long: markers=styles1|address1&markers=styles2|address2&...
+               // short: markers=styles,address1|address2|address3|...
+
+               return $markers;
+       }
+
+       /**
+        * Ensure that we stay on the appropriate protocol
+        *
+        * @return string protocol base (including ://)
+        */
+       protected function _protocol() {
+               $https = $this->_runtimeConfig['https'];
+               if ($https === null) {
+                       $https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
+               }
+               return ($https ? 'https' : 'http') . '://';
+       }
+
+       /**
+        * // to 0x
+        * or // added
+        *
+        * @param string $color Color: FFFFFF, #FFFFFF, 0xFFFFFF or blue
+        * @return string Color
+        */
+       protected function _prepColor($color) {
+               if (strpos($color, '#') !== false) {
+                       return str_replace('#', '0x', $color);
+               }
+               if (is_numeric($color)) {
+                       return '0x' . $color;
+               }
+               return $color;
+       }
+
+       /**
+        * @param string $name
+        * @param array $array
+        * @param bool $asString
+        * @param bool $keyAsString
+        * @return string
+        */
+       protected function _arrayToObject($name, $array, $asString = true, $keyAsString = false) {
+               $res = 'var ' . $name . ' = {' . PHP_EOL;
+               $res .= $this->_toObjectParams($array, $asString, $keyAsString);
+               $res .= '};';
+               return $res;
+       }
+
+       /**
+        * @param array $array
+        * @param bool $asString
+        * @param bool $keyAsString
+        * @return string
+        */
+       protected function _toObjectParams($array, $asString = true, $keyAsString = false) {
+               $pieces = [];
+               foreach ($array as $key => $value) {
+                       $e = ($asString && strpos($value, 'new ') !== 0 ? '"' : '');
+                       $ke = ($keyAsString ? '"' : '');
+                       $pieces[] = $ke . $key . $ke . ': ' . $e . $value . $e;
+               }
+               return implode(',' . PHP_EOL, $pieces);
+       }
+
+}
diff --git a/production/sites/cakelampvm.com/goog_maps_helper_mod/compare_with_install.sh b/production/sites/cakelampvm.com/goog_maps_helper_mod/compare_with_install.sh
new file mode 100644 (file)
index 0000000..cd46374
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+
+if [ ! -d "$HOME/apps/mapsdemo/avenger5" ]; then
+  echo Not seeing the mapsdemo checked out man.
+  exit 1
+fi
+
+meld $(find ~/apps/mapsdemo/avenger5/ -iname goog*map*helper.php) ./Goog*Map*Help*p
+
+
diff --git a/production/sites/cakelampvm.com/hello.txt b/production/sites/cakelampvm.com/hello.txt
new file mode 100644 (file)
index 0000000..7bf0d1b
--- /dev/null
@@ -0,0 +1,25 @@
+Welcome to the CakePHP LAMP VM.
+
+Please refer to the built-in documentation available at: http://cakelampvm.com
+
+Some first steps to make this vm your own:
+
+####
+
+1) change your password for the developer account.
+(may eventually be automatically required)
+
+####
+
+2) change your git configuration for user and email.  this is how we've
+configured it so far:
+
+  # git config --global user.email "developer@cakelampvm.com"
+  # git config --global user.name "Developer J. Cakemo"
+
+if you're developing on a real project, you probably don't want the bogus
+email and even more bogus name above attached to your commits.
+Just run the two commands again but with proper values.
+
+####
+
diff --git a/production/sites/cakelampvm.com/images/green-check-mark-in-circle-hi.png b/production/sites/cakelampvm.com/images/green-check-mark-in-circle-hi.png
new file mode 100644 (file)
index 0000000..ab1d67b
Binary files /dev/null and b/production/sites/cakelampvm.com/images/green-check-mark-in-circle-hi.png differ
diff --git a/production/sites/cakelampvm.com/images/green_globe_exclamation_point_570.jpg b/production/sites/cakelampvm.com/images/green_globe_exclamation_point_570.jpg
new file mode 100644 (file)
index 0000000..8cb9aa7
Binary files /dev/null and b/production/sites/cakelampvm.com/images/green_globe_exclamation_point_570.jpg differ
diff --git a/production/sites/cakelampvm.com/images/red_exclamation_mark_icon_256.png b/production/sites/cakelampvm.com/images/red_exclamation_mark_icon_256.png
new file mode 100644 (file)
index 0000000..bae1cf6
Binary files /dev/null and b/production/sites/cakelampvm.com/images/red_exclamation_mark_icon_256.png differ
diff --git a/production/sites/cakelampvm.com/images/red_x_1194985626525719339tasto_11_architetto_fran_01.svg.med.png b/production/sites/cakelampvm.com/images/red_x_1194985626525719339tasto_11_architetto_fran_01.svg.med.png
new file mode 100644 (file)
index 0000000..c6d020e
Binary files /dev/null and b/production/sites/cakelampvm.com/images/red_x_1194985626525719339tasto_11_architetto_fran_01.svg.med.png differ
diff --git a/production/sites/cakelampvm.com/index.html b/production/sites/cakelampvm.com/index.html
new file mode 100644 (file)
index 0000000..66fc8d6
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html; charset=windows-1252" http-equiv="content-type">
+    <title>cakelampvm.com official internet site (NOT the local virtual machine)</title>
+  </head>
+  <body>
+    <div style="text-align: center;"><img alt="uh oh red exclamation" src="images/red_exclamation_mark_icon_256.png" width="140" height="140">
+      <img alt="x marks a bad spot" src="images/red_x_1194985626525719339tasto_11_architetto_fran_01.svg.med.png" width="140" height="140">
+      <img alt="uh oh red exclamation" src="images/red_exclamation_mark_icon_256.png" width="140" height="140"></div>
+    <h1 style=" text-align: center;">cakelampvm.com REAL INTERNET site</h1>
+    <h2 style=" text-align: center;"> </h2>
+    <h2 style=" text-align: center;"> &#9733;&#9733; If you are running the cakelampvm, &#9733;&#9733;<br>
+      &#9733;&#9733; then it is not yet configured properly. &#9733;&#9733; </h2>
+    <h3 style=" text-align: center;">This is the cakelampvm.com domain that is
+      actually <span style="font-weight: bold;">on the internet</span>.</h3>
+    <h4 style=" text-align: center;">Official cakelampvm setup guide: <a
+        target="_blank" href="docs/manual/cakelampvm_guide_v002.html">The
+        cakelampvm.com VM: Configuration and Usage</a></h4>
+    <div style="text-align: center;"><img alt="uh oh red exclamation" src="images/red_exclamation_mark_icon_256.png" width="140" height="140">
+      <img alt="x marks a bad spot" src="images/red_x_1194985626525719339tasto_11_architetto_fran_01.svg.med.png" width="140" height="140">
+      <img alt="uh oh red exclamation" src="images/red_exclamation_mark_icon_256.png" width="140" height="140">
+</div>
+  </body>
+</html>
diff --git a/production/sites/cakelampvm.com/rolling/default_page.001/001-default-http.conf b/production/sites/cakelampvm.com/rolling/default_page.001/001-default-http.conf
new file mode 100644 (file)
index 0000000..1360081
--- /dev/null
@@ -0,0 +1,21 @@
+
+
+<Directory "/opt/feistymeow.org/feisty_meow/production/sites/cakelampvm.com">
+  Options +ExecCGI +Indexes +FollowSymLinks +Includes +MultiViews
+  Require all granted
+</Directory>
+
+
+<VirtualHost *:80>
+       ServerName cakelampvm.com
+       ServerAlias www.cakelampvm.com
+       DocumentRoot /opt/feistymeow.org/feisty_meow/production/sites/cakelampvm.com
+       DirectoryIndex vm_index.html
+
+       ServerAdmin developer@localhost
+
+       ErrorLog ${APACHE_LOG_DIR}/error.log
+       CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+</VirtualHost>
+
diff --git a/production/sites/cakelampvm.com/rolling/default_page.001/001-default-ssl.conf b/production/sites/cakelampvm.com/rolling/default_page.001/001-default-ssl.conf
new file mode 100644 (file)
index 0000000..c89b459
--- /dev/null
@@ -0,0 +1,37 @@
+
+
+<Directory "/opt/feistymeow.org/feisty_meow/production/sites/cakelampvm.com">
+  Options +ExecCGI +Indexes +FollowSymLinks +Includes +MultiViews
+  Require all granted
+</Directory>
+
+<VirtualHost *:443>
+       ServerName cakelampvm.com
+       ServerAlias www.cakelampvm.com
+       DocumentRoot /opt/feistymeow.org/feisty_meow/production/sites/cakelampvm.com
+       DirectoryIndex vm_index.html
+
+       ServerAdmin developer@localhost
+
+       ErrorLog ${APACHE_LOG_DIR}/error.log
+       CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+       SSLEngine on
+
+       #   A self-signed (snakeoil) certificate can be created by installing
+       #   the ssl-cert package. See
+       #   /usr/share/doc/apache2/README.Debian.gz for more info.
+       #   If both key and certificate are stored in the same file, only the
+       #   SSLCertificateFile directive is needed.
+       SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
+       SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
+
+       <FilesMatch "\.(cgi|shtml|phtml|php)$">
+                       SSLOptions +StdEnvVars
+       </FilesMatch>
+       <Directory /usr/lib/cgi-bin>
+                       SSLOptions +StdEnvVars
+       </Directory>
+
+</VirtualHost>
+
diff --git a/production/sites/cakelampvm.com/vm_index.html b/production/sites/cakelampvm.com/vm_index.html
new file mode 100644 (file)
index 0000000..362b321
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html; charset=windows-1252" http-equiv="content-type">
+    <title>cakelampvm.com served by your local virtual machine!</title>
+  </head>
+  <body>
+    <div style="text-align: center;"><img alt="yay, green exclaimed" src="images/green_globe_exclamation_point_570.jpg"
+        height="140" width="140"> <img alt="you're in the right place, and dns is being hosted by your local cakelampvm.com virtual machine"
+        src="images/green-check-mark-in-circle-hi.png" height="140" width="140">
+      <img alt="yay, green exclaimed" src="images/green_globe_exclamation_point_570.jpg"
+        height="140" width="140"></div>
+    <h1 style=" text-align: center;">Yes!<br>
+      You're on the cakelampvm.com virtualized site!</h1>
+    <h2 style=" text-align: center;"> </h2>
+    <h2 style=" text-align: center;"> &#9733;&#9733; Your cakelampvm virtual machine seems
+      to be &#9733;&#9733;<br>
+      &#9733;&#9733;&nbsp; successfully overriding this domain (and any&nbsp; &#9733;&#9733;<br>
+      &#9733;&#9733; other sites you have added to host on the vm). &#9733;&#9733; </h2>
+    <h3 style=" text-align: center;">This is the cakelampvm.com domain that is
+      served from your cakelampvm virtual machine<br>
+      <span style="font-style: italic;">(as long as browser URL bar actually
+        says just "http://cakelampvm.com" or "http://www.cakelampvm.com").</span></h3>
+    <h4 style=" text-align: center;">Official cakelampvm setup guide: <a target="_blank"
+        href="docs/manual/cakelampvm_guide_v002.html">The cakelampvm.com VM:
+        Configuration and Usage</a></h4>
+    <div style="text-align: center;"><img alt="yay, green exclaimed" src="images/green_globe_exclamation_point_570.jpg"
+        height="140" width="140"> <img alt="you're in the right place, and dns is being hosted by your local cakelampvm.com virtual machine"
+        src="images/green-check-mark-in-circle-hi.png" height="140" width="140">
+      <img alt="yay, green exclaimed" src="images/green_globe_exclamation_point_570.jpg"
+        height="140" width="140">
+    </div>
+  </body>
+</html>
index 0fda046ea9e12470e4bf01335b68dc7ea8888cd7..ca3b745926850fed6a873ed75741dbbe2fd02423 100644 (file)
@@ -34,6 +34,10 @@ Connect the feisty meow scripts to your login script (in ~/.bashrc).
 Note that this actually modifies ~/.bashrc.  This step is only needed once.
 # bash /opt/feistymeow.org/feisty_meow/scripts/core/connect_feisty_meow.sh
 
+| For the root user, you can pass a flag '--root' to the connect_feisty_meow
+| script.  This will add an alias for 'feistyme' which loads the feisty meow
+| scripts on demand (instead of automatically upon login).
+
 Load the script environment into the current shell.  This can be done for
 any new shell.  This is idempotent, so it does no harm to run it again.
 Note that you should not need this step if you connected feisty meow to
index a2f89349398941c57c4e804dc18cfac1cb0511a3..c6dbbafb01d003aa578677235c4cc89dca1068d3 100644 (file)
@@ -116,6 +116,9 @@ analyze_hierarchy_and_report ~/cloud/urgent "high priority (aieeee!)"
 # notes are individual files of tasks, usually, although some are combined.
 analyze_hierarchy_and_report ~/cloud/grunty_notes "grunty notes (externalities)"
 
+# web site development tasks.
+analyze_hierarchy_and_report ~/cloud/webular "web design (ideas and tasks)"
+
 # feisty notes are about feisty meow(r) concerns ltd codebase development.
 analyze_hierarchy_and_report ~/cloud/feisty_notes "feisty meow notes (mondo coding)"
 
diff --git a/scripts/archival/general_updater.sh b/scripts/archival/general_updater.sh
new file mode 100644 (file)
index 0000000..918671d
--- /dev/null
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+# a script that handles synchronization of important assets from the MAJOR_ARCHIVE_SOURCES
+# and the SOURCECODE_HIERARCHY_LIST onto a backup drive of some sort.  it will only copy folders
+# if there is a target folder of the appropriate name already on the backup medium.
+
+source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
+
+# given a location in the filesystem, we will go to that location and attempt to
+# update any revision control repositories stored there to the latest versions.
+function update_source_folders()
+{
+  folder="$1"; shift
+  sep
+  if [ ! -d "$folder" ]; then
+    echo "The folder '$folder' does not exist, so skipping repository update there."
+    return;
+  fi
+  echo getting latest codes in $folder...
+  pushd "$folder"
+  if [ $? -ne 0 ]; then
+    echo Changing to the folder $folder failed.
+    return 1
+  fi
+  bash "$FEISTY_MEOW_SCRIPTS/rev_control/rcheckin.sh"
+  if [ $? -ne 0 ]; then
+    echo Checking out the latest codes has failed somehow for $folder.
+    return 1
+  fi
+  popd
+  sep
+}
+
+# this attempts to copy all the contents in a folder called "from" into a folder
+# called "to".  it's a failure for the "from" folder to not exist, but the "to"
+# is allowed to not exist (in which case we don't try to synch to it).
+function synch_directory_to_target()
+{
+  local from="$1"; shift
+  local to="$1"; shift
+
+  sep
+
+  if [ ! -d "$from" ]; then
+    echo "skipping synch on missing source directory: ${from}"
+    return 0
+  fi
+  if [ ! -d "$to" ]; then
+    echo "skipping synch into non-existent target directory $to"
+    return 0
+  fi
+
+  echo "synching from $from into $to"
+  netcp "$from"/* "$to"/
+  if [ $? -ne 0 ]; then
+    echo "The synchronization of $from into $to has failed."
+    return 1
+  fi
+}
+
+# the uber controller method that does the "hard" work of updating.
+# any items from the MAJOR_ARCHIVE_SOURCES that are on the target will be
+# updated.  any items found on the target matching the members of the
+# SOURCECODE_HIERARCHY_LIST will be treated as code hierarchies and updated.
+function update_archive_drive()
+{
+  local target_folder="$1"; shift  # where we're backing up to.
+  local currdir  # loop variable.
+
+  sep
+
+  echo Target drive currently has...
+  ls "$target_folder"
+  if [ $? -ne 0 ]; then
+    echo "The target location '$target_folder' is not mounted currently, so cannot be updated."
+    return 1
+  fi
+
+  # synch all our targets.
+  for currdir in $MAJOR_ARCHIVE_SOURCES; do
+    synch_directory_to_target "$currdir" "$target_folder/$(basename $currdir)"/
+  done
+
+  sep
+
+  # update source code if present.
+  echo getting latest fred repositories...
+  pushd "$target_folder"
+  for currdir in $SOURCECODE_HIERARCHY_LIST; do
+    update_source_folders $currdir
+  done
+  
+  sep
+
+  echo successfully updated all expected portions of the target drive at:
+  echo "  $target_folder"
+  echo
+  popd
+}
+
+
diff --git a/scripts/archival/shared_updater_parts.sh b/scripts/archival/shared_updater_parts.sh
deleted file mode 100644 (file)
index 77c2c93..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-
-# given a location in the filesystem, we will go to that location and attempt to
-# update any revision control repositories stored there to the latest versions.
-function update_source_folders()
-{
-  folder="$1"; shift
-  if [ ! -d "$folder" ]; then
-    echo "The folder '$folder' does not exist, so skipping repository update there."
-    return;
-  fi
-  echo getting latest codes in $folder...
-  pushd "$folder"
-  if [ $? -ne 0 ]; then
-    echo Changing to the folder $folder failed.
-    exit 1
-  fi
-  bash "$FEISTY_MEOW_SCRIPTS/rev_control/rcheckin.sh"
-  if [ $? -ne 0 ]; then
-    echo Checking out the latest codes has failed somehow for $folder.
-    exit 1
-  fi
-  popd
-}
-
-# this attempts to copy all the contents in a folder called "from" into a folder
-# called "to".  it's a failure for the "from" folder to not exist, but the "to"
-# is allowed to not exist (in which case we don't try to synch to it).
-function synch_directory_to_target()
-{
-  local from="$1"; shift
-  local to="$1"; shift
-
-  sep
-
-  if [ ! -d "$from" ]; then
-    echo "skipping synch on missing source directory $from; this is not normal!"
-    exit 1
-  fi
-  if [ ! -d "$to" ]; then
-    echo "skipping synch into non-existent directory $to"
-    return
-  fi
-
-  echo "synching from $from into $to"
-  netcp "$from"/* "$to"/
-  if [ $? -ne 0 ]; then
-    echo "The synchronization of $from into $to has failed."
-    exit 1
-  fi
-}
-
index c695be7371d98820e388d3cb67bc24da5fb6fa3b..e6c54770b2d92693b940f5f267cc06f580b65fd3 100644 (file)
@@ -35,7 +35,7 @@ local($snarf_file) = &snarf_name($snarf_file_base, $number);
 local($root) = &canonicalize("$FEISTY_MEOW_APEX");
 
 # grab the top level stuff.
-&backup_files($snarf_file_base, $number, $root, ".", ("*.txt", "make*", ".gitignore"));
+&backup_files($snarf_file_base, $number, $root, ".", ("*.txt", "make*", ".gitignore", "*.yml"));
 
 # snarf up all the important directories.
 # CAK: current as of 2012-05-05.
@@ -58,6 +58,7 @@ local($root) = &canonicalize("$FEISTY_MEOW_APEX");
 &backup_hierarchy($snarf_file_base, $number, "$root", "production/assign_bases");
 &backup_hierarchy($snarf_file_base, $number, "$root", "production/check_versions");
 &backup_hierarchy($snarf_file_base, $number, "$root", "production/setup_src");
+&backup_hierarchy($snarf_file_base, $number, "$root", "production/sites");
 
 # now rename the file so only the unpacker can access it.
 &rename_archive($snarf_file);
index 1a830c84288a9b9a6f42c65c233460567226029d..87e47676a43e7ededa30ff106fa0e83a0eac7577 100644 (file)
@@ -9,7 +9,21 @@
 # Feel free to send updates to: [ fred@gruntose.com ]
 ##############
 
-# a list of core aliases for feisty meow codebase.
+# this file provides a list of core aliases for feisty meow codebase.
+
+##############
+
+# call the generated aliases file, if it exists.
+# we do this first so that our core aliases get a chance to override the aliases
+# based on scripts.
+
+if [ -f "$FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh" ]; then 
+  if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo loading script aliases...; fi
+  source "$FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh"
+  if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo done loading script aliases.; fi
+fi
+
+##############
 
 # repurposes certain commands that feisty meow does a little differently.
 define_yeti_alias cls='clear_colormap; clear'
@@ -69,7 +83,7 @@ define_yeti_alias lesser='bash $FEISTY_MEOW_SCRIPTS/files/lesser.sh'
 
 # some aliases that are just generally nice to have.
 define_yeti_alias aliases=alias
-define_yeti_alias calc='kcalc'
+define_yeti_alias calc='galculator'
 define_yeti_alias cd..='\cd ..'
 define_yeti_alias cd...='\cd ../..'
 define_yeti_alias cd....='\cd ../../..'
@@ -79,6 +93,25 @@ define_yeti_alias up='cd ..'
 
 ##############
 
+# some information about the feisty meow codebase itself.
+
+define_yeti_alias feisty_branch='pushd $FEISTY_MEOW_APEX ; git branch ; popd'
+
+##############
+
+# some important retreads on aliases that provide a sudo-ized version of other scripts.
+
+define_yeti_alias snarf_linux_config="sudo -E PERLLIB=\$PERLLIB perl \$FEISTY_MEOW_SCRIPTS/archival/snarf_linux_config.pl"
+define_yeti_alias add_domain="sudo bash \$FEISTY_MEOW_SCRIPTS/system/add_domain.sh"
+define_yeti_alias remove_domain="sudo bash \$FEISTY_MEOW_SCRIPTS/system/remove_domain.sh"
+define_yeti_alias add_apache_site="sudo bash \$FEISTY_MEOW_SCRIPTS/system/add_apache_site.sh"
+define_yeti_alias remove_apache_site="sudo bash \$FEISTY_MEOW_SCRIPTS/system/remove_apache_site.sh"
+
+#hmmm: some magma intrusions from the fred customizations...
+define_yeti_alias revamp_cakelampvm="sudo bash \"$FEISTY_MEOW_SCRIPTS/site_avenger/revamp_cakelampvm.sh\""
+
+##############
+
 # extended aliases for meta-operations.
 define_yeti_alias dvd_rip='vobcopy -m'
 define_yeti_alias blu_rip='echo "what would this command be?"'
@@ -95,7 +128,7 @@ define_yeti_alias cputemp='acpi -t'
 # makes root user's home directory's permissions right.
 define_yeti_alias reroot='chown -R root:root /root'
 # yes, these are really helpful...
-define_yeti_alias whoareyou='echo -e "Hello, I am a computer named $(hostname)\nand I'\''m very pleased to meet you."'
+define_yeti_alias whoareyou='echo -e "Hello, I am a computer named $(hostname)\nand I am very pleased to meet you."'
 define_yeti_alias whereami='echo whoa dude, try not to think about it...'
 define_yeti_alias why='echo We all wonder what the point of the universe is at times.  If you figure it all out, please write us.'
 
@@ -103,24 +136,15 @@ define_yeti_alias why='echo We all wonder what the point of the universe is at t
 
 ##############
 
-# call the generated aliases file, if it exists.
-if [ -f "$FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh" ]; then 
-  if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo loading script aliases...; fi
-  source "$FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh"
-  if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo done loading script aliases.; fi
-fi
-
-##############
-
-# remove the fredization macro if it was defined, helping to avoid running
-# the shell scripts twice for users like root that don't always load this
-# stuff.
-unalias fredme &>/dev/null
+# remove the "fredization" or "feistymeowization" macros if they're defined,
+# which reduces the chance of loading the shell environment twice for users
+# like root that don't load feisty meow automatically.
+unalias fredme feistyme &>/dev/null
 
 ##############
 
 # set the sentinel alias that says this file was handled.
-alias CORE_ALIASES_LOADED=true
+#alias CORE_ALIASES_LOADED=true
 
 ##############
 
index 9a5c81d548bb3b98b6b22e36a3009641f6cdb868..6f6ffd3840536016553661e94eb259b9133ac001 100644 (file)
@@ -11,16 +11,33 @@ export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
 
 echo calculated apex as $FEISTY_MEOW_APEX
 
+do_root="$1"; shift
+
 if [ -f "$HOME/.bashrc" ] && grep -q "launch_feisty_meow.sh" "$HOME/.bashrc"; then
   # the stanza for loading feisty meow already seems to be present.
   echo "Feisty Meow already seems to be configured in '~/.bashrc'."
 else
-  # stuff the normal user init file into .bashrc.  not appropriate for root probably, but
-  # this is the easy quick start script for normal folks.
-  cat $FEISTY_MEOW_APEX/infobase/feisty_inits/dot.bashrc-normal-user |
-    sed -e \
-      "s?FEISTY_MEOW_APEX=\".*\"?FEISTY_MEOW_APEX=\"$FEISTY_MEOW_APEX\"?" \
-      >> "$HOME/.bashrc"
-  echo "Feisty Meow is now configured in '~/.bashrc'."
+  # check for the --root flag to see if they're trying to get the root version of inits.
+  if [ "$do_root" != "--root" ]; then
+    # stuff the "normal user" init file into .bashrc.  not appropriate for root.
+    # this is the easy and quick start script for most folks.
+    cat $FEISTY_MEOW_APEX/infobase/feisty_inits/dot.bashrc-normal-user |
+      sed -e \
+        "s?FEISTY_MEOW_APEX=\".*\"?FEISTY_MEOW_APEX=\"$FEISTY_MEOW_APEX\"?" \
+        >> "$HOME/.bashrc"
+    echo "Feisty Meow is now configured in '~/.bashrc' for standard users."
+  else
+    # stuff the root user init file into .bashrc.  this one doesn't
+    # automatically load the feisty meow scripts.  instead, there is a macro
+    # (uhh, an alias) that loads the feisty meow scripts.  the 'fredme' macro
+    # comes from the main author of feisty meow, named fred t. hamster.  we
+    # have since added a 'feistyme' macro too, to be slightly less
+    # idiosyncratic, as if that were possible.
+    cat $FEISTY_MEOW_APEX/infobase/feisty_inits/dot.bashrc-root |
+      sed -e \
+        "s?FEISTY_MEOW_APEX=\".*\"?FEISTY_MEOW_APEX=\"$FEISTY_MEOW_APEX\"?" \
+        >> "$HOME/.bashrc"
+    echo "Feisty Meow is now configured in '~/.bashrc' for the root user."
+  fi
 fi
 
index a66d19398960a4e9d896081bb2910e6ac539ad55..daaabcb16cece5a745d7735421fbecfc1c4691f3 100644 (file)
@@ -49,6 +49,8 @@ if [ -z "$skip_all" ]; then
     return $?
   }
 
+  ##############
+
   # displays the value of a variable in bash friendly format.
   function var() {
     HOLDIFS="$IFS"
@@ -84,6 +86,8 @@ if [ -z "$skip_all" ]; then
     IFS="$HOLDIFS"
   }
 
+  ##############
+
   # when passed a list of things, this will return the unique items from that list as an echo.
   function uniquify()
   {
@@ -104,6 +108,8 @@ if [ -z "$skip_all" ]; then
     fi
   }
 
+  ##############
+
   function success_sound()
   {
     if [ ! -z "$CLAM_FINISH_SOUND" ]; then
@@ -118,6 +124,20 @@ if [ -z "$skip_all" ]; then
     fi
   }
 
+  ##############
+
+  # echoes the maximum number of columns that the terminal supports.  usually
+  # anything you print to the terminal with length less than (but not equal to)
+  # maxcols will never wrap.
+  function get_maxcols()
+  {
+    # calculate the number of columsn in the terminal.
+    local cols=$(stty size | awk '{print $2}')
+    echo $cols
+  }
+
+  ##############
+
   # checks the result of the last command that was run, and if that failed,
   # then this complains and exits from bash.  the function parameters are
   # used as the message to print as a complaint.
@@ -139,19 +159,29 @@ if [ -z "$skip_all" ]; then
     fi
   }
 
+  ##############
+
   # wraps secure shell with some parameters we like, most importantly to enable X forwarding.
   function ssh()
   {
     local args=($*)
-    save_terminal_title
     # we remember the old terminal title, then force the TERM variable to a more generic
     # version for the other side (just 'linux'); we don't want the remote side still
     # thinking it's running xterm.
-    export TERM=linux
+    save_terminal_title
+#hmmm: why were we doing this?  it scorches the user's logged in session, leaving it without proper terminal handling.
+#    # we save the value of TERM; we don't want to leave the user's terminal
+#    # brain dead once we come back from this function.
+#    local oldterm="$TERM"
+#    export TERM=linux
     /usr/bin/ssh -X -C "${args[@]}"
+#    # restore the terminal variable also.
+#    TERM="$oldterm"
     restore_terminal_title
   }
 
+  ##############
+
   # locates a process given a search pattern to match in the process list.
   # supports a single command line flag style parameter of "-u USERNAME";
   # if the -u flag is found, a username is expected afterwards, and only the
@@ -267,6 +297,9 @@ if [ -z "$skip_all" ]; then
     fi
   }
   
+  ##############
+
+#hmmm: holy crowbars, this is an old one.  do we ever still have any need of it?
   # an unfortunately similarly named function to the above 'ps' as in process
   # methods, but this 'ps' stands for postscript.  this takes a postscript file
   # and converts it into pcl3 printer language and then ships it to the printer.
@@ -280,9 +313,21 @@ if [ -z "$skip_all" ]; then
     done
   }
   
-#  function fix_alsa() {
-#    sudo /etc/init.d/alsasound restart
-#  }
+#hmmm: not really doing anything yet; ubuntu seems to have changed from pulseaudio in 17.04?
+  # restarts the sound driver.
+  function fix_sound_driver() {
+    # stop bash complaining about blank function body.
+    local nothing=
+#if alsa something
+#    sudo service alsasound restart
+#elif pulse something
+#    sudo pulseaudio -k
+#    sudo pulseaudio -D
+#else
+#    something else...?
+#fi
+
+  }
 
   function screen() {
     save_terminal_title
@@ -363,14 +408,15 @@ if [ -z "$skip_all" ]; then
   # sudo function wraps the normal sudo by ensuring we replace the terminal
   # label if they're doing an su with the sudo.
   function sudo() {
-#    local first_command="$1"
     save_terminal_title
     /usr/bin/sudo "$@"
+    retval=$?
     restore_terminal_title
 #    if [ "$first_command" == "su" ]; then
 #      # yep, they were doing an su, but they're back now.
 #      label_terminal_with_info
 #    fi
+    return $retval
   }
   
   # trashes the .#blah files that cvs and subversion leave behind when finding conflicts.
@@ -388,6 +434,7 @@ if [ -z "$skip_all" ]; then
       echo "The nechung oracle program cannot be found.  You may want to consider"
       echo "rebuilding the feisty meow applications with this command:"
       echo "bash $FEISTY_MEOW_SCRIPTS/generator/produce_feisty_meow.sh"
+      echo
     else
       $wheres_nechung
     fi
@@ -429,6 +476,14 @@ if [ -z "$skip_all" ]; then
       echo "but that folder does not exist.  Skipping customization."
       return 1
     fi
+
+    # prevent permission foul-ups.
+#hmmm: save error output here instead of muting it.
+#hmmm: better yet actually, just don't complain on freaking cygwin, since that's where this happens
+    chown -R "$(logname):$(logname)" \
+        "$FEISTY_MEOW_LOADING_DOCK"/* "$FEISTY_MEOW_GENERATED_STORE"/* 2>/dev/null
+    test_or_continue "chowning to $(logname) didn't happen."
+
     regenerate >/dev/null
     pushd "$FEISTY_MEOW_LOADING_DOCK/custom" &>/dev/null
     incongruous_files="$(bash "$FEISTY_MEOW_SCRIPTS/files/list_non_dupes.sh" "$FEISTY_MEOW_SCRIPTS/customize/$custom_user" "$FEISTY_MEOW_LOADING_DOCK/custom")"
@@ -458,6 +513,11 @@ if [ -z "$skip_all" ]; then
     echo
     regenerate
 
+    # prevent permission foul-ups, again.
+    chown -R "$(logname):$(logname)" \
+        "$FEISTY_MEOW_LOADING_DOCK" "$FEISTY_MEOW_GENERATED_STORE" 2>/dev/null
+    test_or_continue "chowning to $(logname) didn't happen."
+
     restore_terminal_title
   }
 
@@ -801,6 +861,69 @@ return 0
 
   ##############
 
+  # given a filename and a string to seek and a number of lines, then this
+  # function will remove the first occurrence of a line in the file that
+  # matches the string, and it will also axe the next N lines as specified.
+  function create_chomped_copy_of_file()
+  {
+    local filename="$1"; shift
+    local seeker="$1"; shift
+    local numlines=$1; shift
+
+#echo into create_chomped_copy...
+#var filename seeker numlines 
+
+    # make a backup first, oy.
+    \cp -f "$filename" "/tmp/$(basename ${filename}).bkup-${RANDOM}" 
+    test_or_die "backing up file: $filename"
+
+    # make a temp file to write to before we move file into place in bind.
+    local new_version="/tmp/$(basename ${filename}).bkup-${RANDOM}" 
+    \rm -f "$new_version"
+    test_or_die "cleaning out new version of file from: $new_version"
+
+    local line
+    local skip_count=0
+    local found_any=
+    while read line; do
+      # don't bother looking at the lines if we're already in skip mode.
+      if [[ $skip_count == 0 ]]; then
+        # find the string they're seeking.
+        if [[ ! "$line" =~ .*${seeker}.* ]]; then
+          # no match.
+          echo "$line" >> "$new_version"
+        else
+          # a match!  start skipping.  we will delete this line and the next N lines.
+          ((skip_count++))
+#echo first skip count is now $skip_count
+          found_any=yes
+        fi
+      else
+        # we're already skipping.  let's keep going until we hit the limit.
+        ((skip_count++))
+#echo ongoing skip count is now $skip_count
+        if (( $skip_count > $numlines )); then
+          echo "Done skipping, and back to writing output file."
+          skip_count=0
+        fi
+      fi
+    done < "$filename"
+
+#echo file we created looks like this:
+#cat "$new_version"
+
+    if [ ! -z "$found_any" ]; then
+      # put the file back into place under the original name.
+      \mv "$new_version" "$filename"
+      test_or_die "moving the new version into place in: $filename"
+    else
+      # cannot always be considered an error, but we can at least gripe.
+      echo "Did not find any matches for seeker '$seeker' in file: $filename"
+    fi
+  }
+
+  ##############
+
   # NOTE: no more function definitions are allowed after this point.
 
   function function_sentinel()
index 4ed01fb74641794fe21613eeb98ee0d4e35d1513..a9b777473aac403f4889860781e19d1d5313bd89 100644 (file)
@@ -43,11 +43,10 @@ sub make_alias {
 sub make_bash_alias {
   local($aliasname) = shift(@_);
   local($full_alias) = $aliasname;
+#print "full alias is $full_alias\n";
   $aliasname =~ s/^.*\/([^\/]*)/\1/;
 #print "alias became $aliasname\n";
-  local($source_dir) = shift(@_);
-#print "bash alias is $aliasname, dir is $source_dir\n";
-  print she "define_yeti_alias $aliasname=\"bash $source_dir/$full_alias.sh\"\n";
+  print she "define_yeti_alias $aliasname=\"bash $full_alias.sh\"\n";
 }
 
 # makes an alias for a perl script given the alias name.
@@ -56,9 +55,7 @@ sub make_perl_alias {
   local($full_alias) = $aliasname;
   $aliasname =~ s/^.*\/([^\/]*)/\1/;
 #print "alias became $aliasname\n";
-  local($source_dir) = shift(@_);
-#print "perl alias is $aliasname, dir is $source_dir\n";
-  print she "define_yeti_alias $aliasname=\"perl $source_dir/$full_alias.pl\"\n";
+  print she "define_yeti_alias $aliasname=\"perl $full_alias.pl\"\n";
 }
 
 ##############
@@ -155,10 +152,14 @@ Please see http://feistymeow.org for more details.\n";
 #really need to use better exit codes.
 }
 
+##############
+
 $FEISTY_MEOW_LOADING_DOCK =~ s/\\/\//g;
 $FEISTY_MEOW_SCRIPTS =~ s/\\/\//g;
 $FEISTY_MEOW_APEX =~ s/\\/\//g;
 
+##############
+
 # create our generated shells directory if it's not already there.
 if (! -d $FEISTY_MEOW_LOADING_DOCK) {
   mkdir $FEISTY_MEOW_LOADING_DOCK;
@@ -171,10 +172,14 @@ if (-d $FEISTY_MEOW_BINARIES) {
   system("chmod -R u+x \"$FEISTY_MEOW_BINARIES\"/*");
 }
 
+##############
+
 # generate the first set of alias files that are defined in the core
 # and custom scripts directories.
 &rebuild_script_aliases;
 
+##############
+
 # trash the old versions.
 unlink("$FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh");
 
@@ -182,6 +187,8 @@ if (length($DEBUG_FEISTY_MEOW)) {
   printf "writing $FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh...\n";
 }
 
+##############
+
 # open the alias files to be created.
 open(she, ">> $FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh");
 
@@ -189,6 +196,11 @@ open(she, ">> $FEISTY_MEOW_LOADING_DOCK/fmc_aliases_for_scripts.sh");
 @shell_files = (find_files(recursive_find_directories("$FEISTY_MEOW_SCRIPTS")),
     find_files(recursive_find_directories("$FEISTY_MEOW_LOADING_DOCK/custom/scripts")));
 
+# strip out the customization files, since they are added in on demand only.
+#print "before filtering list: @shell_files\n";
+@shell_files = grep ! /\/customize\//, @shell_files;
+#print "after filtering list: @shell_files\n";
+
 #printf "found all these files in main script dirs:\n";
 #printf "  @shell_files\n";
 
@@ -203,7 +215,7 @@ foreach $file (@shell_files) {
       || $file =~ /\/\.\.$/
       || $file =~ /\/\.svn$/
       || $file =~ /\/\.git$/
-      || $file =~ /\/customize\/[a-zA-Z0-9_]+\/[a-zA-Z0-9_.]+$/
+      || $file =~ /\/custom\/[a-zA-Z0-9_]+\/[a-zA-Z0-9_.]+$/
 #hmmm: would be nice to have this name in a symbol somewhere instead of having "customize" everywhere.
       ) {
     # just skip this item; it's a special directory or a file we don't want to include.
@@ -215,4 +227,18 @@ foreach $file (@shell_files) {
 
 close(she);
 
+##############
+
+# prepare a finalizer chunk that is the last thing to load.
+
+open(she, ">> $FEISTY_MEOW_LOADING_DOCK/fmc_ending_sentinel.sh");
+
+# write in our sentinel alias that says alias loading was handled.
+print she "define_yeti_alias CORE_ALIASES_LOADED=true\n";
+
+close(she);
+
+##############
+
 1;
+
index e2290d5afccd8102d67c6530bcf1bfd7b677b2b5..db33f74cf5b0afddab17b93f6fd0e5b96f3ebaa6 100644 (file)
@@ -38,7 +38,7 @@ fi
 # decide whether they've got splitter available or not.
 if [ -f "$FEISTY_MEOW_BINARIES/splitter" -o -f "$FEISTY_MEOW_BINARIES/splitter.exe" ]; then
   # calculate the number of columsn in the terminal.
-  cols=$(stty size | awk '{print $2}')
+  cols=$(get_maxcols)
   splitter="$FEISTY_MEOW_BINARIES/splitter --maxcol $(($cols - 1))"
 else
   # not available, so just emit as huge overly long string.
@@ -46,17 +46,11 @@ else
 fi
 echo
 echo "it is $(date +"%A at %H:%M hours on day %e of the %B moon in the gregorian year %Y" | tr A-Z a-z) and our intrepid adventurer $USER is exploring a computer named $(hostname) that is running in a thoughtspace called $osname $osver (code-name $codename), and $USER has deduced that the machine's OS platform is $(uname -m) and its current incarnation has been ${up}." | $splitter 
-#hmmm: splitter not accepting these args properly right now:
-#--mincol 2 --maxcol 40
 echo
-#echo '++++++++++++++++++++++++++++++++++++++++++'
-#echo
 echo "the following things appear to be lying around here..."
 echo
 ls -hFC $color_add
 echo
-#echo '++++++++++++++++++++++++++++++++++++++++++'
-#echo
 echo "there appear to be these entities on this host..."
 echo
 who -suT
index 80226899a83bad279656c1986bfc825ebc186775..f793c6d9d412d4ed80afc8663f686e7a8dffd090 100644 (file)
 # argument 0.  instead, we just check for the bad condition of a malconfigured
 # script system and try to repair it.
 
+# we start out thinking things are good.
+NO_REPAIRS_NEEDED=true
+
 # check if any crucial folder is hosed.  we will torch the existing config
 # to the extent we can.
-if [ ! -d "$FEISTY_MEOW_SCRIPTS" -o ! -d "$FEISTY_MEOW_APEX" ]; then
+if [ ! -d "$FEISTY_MEOW_APEX" ]; then
+  # flag some problems.
+  unset NO_REPAIRS_NEEDED
   # wipe out the offending variable(s).
   unset FEISTY_MEOW_SCRIPTS FEISTY_MEOW_APEX
   # clean out any unfortunate wrongness that may exist in our generated areas.
-  if [ -d "$"FEISTY_MEOW_LOADING_DOCK ]; then \rm -rf "$FEISTY_MEOW_LOADING_DOCK"; fi
+  if [ -d "$FEISTY_MEOW_LOADING_DOCK" ]; then \rm -rf "$FEISTY_MEOW_LOADING_DOCK"; fi
   if [ -d "$FEISTY_MEOW_GENERATED_STORE" ]; then \rm -rf "$FEISTY_MEOW_GENERATED_STORE"; fi
   # also wipe any values from the variables pointing at generated stuff.
   unset FEISTY_MEOW_LOADING_DOCK FEISTY_MEOW_GENERATED_STORE
-  exec "$*"
-fi
+  echo "
 
-##############
+The feisty meow configuration is damaged somehow.  Please change to the
+directory where it is stored, e.g.:
 
-# some preconditions we want to establish before loading anything...
+  cd /opt/feistymeow.org/feisty_meow
 
-# make sure that aliases can be used in non-interactive shells.
-shopt -s expand_aliases
+and run this command (the whole unwieldy multiple line chunk inside the bars):
 
-# patch the user variable if we were launched by one of our cron jobs.
-if [ -z "$USER" -a ! -z "$CRONUSER" ]; then
-  export USER="$CRONUSER"
-fi
 
+##############
+  exec bash -i 3<<EOF 4<&0 <&3
+    echo -e '\n\n^^^ errors above here indicate potential problems in .bashrc ^^^';
+    export FEISTY_MEOW_APEX=\"\$(pwd)\"; export FEISTY_MEOW_SCRIPTS=\$FEISTY_MEOW_APEX/scripts;
+    export FEISTY_MEOW_SHOW_LAUNCH_GREETING=yes;
+    /bin/bash \$(pwd)/scripts/core/reconfigure_feisty_meow.sh;
+    source \$(pwd)/scripts/core/launch_feisty_meow.sh; exec 3>&- <&4
+EOF
 ##############
 
-export ERROR_OCCURRED=
-  # there have been no errors to start with, at least.  we will set this
-  # to non-empty if something bad happens.
-
-if [ -z "$FEISTY_MEOW_LOADING_DOCK" ]; then
-  # FEISTY_MEOW_LOADING_DOCK is where the generated files are located.
-  # this is our single entry point we can use without knowing any variables
-  # yet in the initialization process.
-  export FEISTY_MEOW_LOADING_DOCK="$HOME/.zz_feisty_loading"
-#hmmm: the above is kind of a constant.  that's not so great.
-
-  # make sure our main variables are established.
-  FEISTY_MEOW_VARIABLES_LOADING_FILE="$FEISTY_MEOW_LOADING_DOCK/fmc_variables.sh"
-  if [ ! -f "$FEISTY_MEOW_VARIABLES_LOADING_FILE" ]; then
-    echo -e "\
-
-The feisty meow scripts need initialization via the bootstrap process.  For\n\
-example, if the feisty meow folder lives in '$DEFAULT_FEISTYMEOW_ORG_DIR', then this\n\
-command bootstraps feisty meow:\n\
-\n\
-  bash $example_dir/feisty_meow/scripts/core/reconfigure_feisty_meow.sh\n\
-\n\
-\n"
-    ERROR_OCCURRED=true
-  fi
-
-  ##############
-
-  if [ -z "$ERROR_OCCURRED" ]; then
 
-    # pull in our generated variables that are the minimal set we need to find
-    # the rest of our resources.
-    source "$FEISTY_MEOW_VARIABLES_LOADING_FILE"
+This code snippet assumes that the .bashrc file could still need editing to
+fix an erroneous FEISTY_MEOW_APEX variable, so we skip it above when bash
+runs.  Check \$HOME/.bashrc to see if a change there will fix the problem.
 
-    # Set up the temporary directory.
-    source "$FEISTY_MEOW_SCRIPTS/core/create_tempdir.sh"
+"
+else
+  # apex is good, so let's make the scripts good too.
+  if [ -z "$FEISTY_MEOW_SCRIPTS" -o ! -d "$FEISTY_MEOW_SCRIPTS" ]; then
+    export FEISTY_MEOW_SCRIPTS="$FEISTY_MEOW_APEX/scripts"
+  fi
+  # check again to test our belief system...
+  if [ ! -d "$FEISTY_MEOW_SCRIPTS" ]; then
+    unset NO_REPAIRS_NEEDED
+    echo -e "The feisty meow scripts cannot be found under the current top:\n  FEISTY_MEOW_APEX=$FEISTY_MEOW_APEX"
   fi
-
 fi
 
-##############
-
-if [ -z "$ERROR_OCCURRED" ]; then
+if [ "$NO_REPAIRS_NEEDED" == "true" ]; then
 
-  # load the larger body of standard feisty meow variables into the environment.
-  # we actually want this to always run also; it will decide what variables need
-  # to be set again.
-  source "$FEISTY_MEOW_SCRIPTS/core/variables.sh"
+  # we believe it's safe to run through the rest of this script.
 
   ##############
   
-  # include helpful functions.  we do this every time rather than making it part
-  # of variable initialization, because functions cannot be exported to
-  # sub-shells in bash.
-  source "$FEISTY_MEOW_SCRIPTS/core/functions.sh"
+  # some preconditions we want to establish before loading anything...
   
-  # load some helper methods for the terminal which we'll use below.
-  source "$FEISTY_MEOW_SCRIPTS/tty/terminal_titler.sh"
-
-  ##############
+  # make sure that aliases can be used in non-interactive shells.
+  shopt -s expand_aliases
   
-  # check hash table before searching path.
-  shopt -s checkhash
-  # don't check path for sourced files.
-  shopt -u sourcepath
-  # ignore duplicate lines.
-  HISTCONTROL=ignoredups
-  # append to the history file.
-  shopt -s histappend
-  # automatically update window size if needed.
-  shopt -s checkwinsize
-
-  ##############
-
-  # make history writes immediate to avoid losing history if bash is zapped.
-  echo $PROMPT_COMMAND | grep -q history
-  if [ $? -ne 0 ]; then
-    # we only change the prompt command if we think it hasn't already been done.
-    export PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
+  # patch the user variable if we were launched by one of our cron jobs.
+  if [ -z "$USER" -a ! -z "$CRONUSER" ]; then
+    export USER="$CRONUSER"
   fi
   
   ##############
   
-  # perform the bulkier parts of the initialization process.
+  export ERROR_OCCURRED=
+    # there have been no errors to start with, at least.  we will set this
+    # to non-empty if something bad happens.
   
-  if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo "heavyweight init begins..."; fi
+  if [ -z "$FEISTY_MEOW_LOADING_DOCK" ]; then
+    # FEISTY_MEOW_LOADING_DOCK is where the generated files are located.
+    # this is our single entry point we can use without knowing any variables
+    # yet in the initialization process.
+    export FEISTY_MEOW_LOADING_DOCK="$HOME/.zz_feisty_loading"
+  #hmmm: the above is kind of a constant.  that's not so great.
   
-  # set up the aliases for the shell, but only if they are not already set.
-  type CORE_ALIASES_LOADED &>/dev/null
-  if [ $? -ne 0 ]; then
-    if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then
-      echo "the aliases were missing, now they are being added..."
-    fi
-    source "$FEISTY_MEOW_LOADING_DOCK/fmc_core_and_custom_aliases.sh"
-  fi
+    # make sure our main variables are established.
+    FEISTY_MEOW_VARIABLES_LOADING_FILE="$FEISTY_MEOW_LOADING_DOCK/fmc_variables.sh"
+    if [ ! -f "$FEISTY_MEOW_VARIABLES_LOADING_FILE" ]; then
+      echo -e "\
   
-  #echo before the new labelling, terminal titles have:
-  #show_terminal_titles
+  The feisty meow scripts need initialization via the bootstrap process.  For\n\
+  example, if the feisty meow folder lives in '$DEFAULT_FEISTYMEOW_ORG_DIR', then this\n\
+  command bootstraps feisty meow:\n\
+  \n\
+    bash $example_dir/feisty_meow/scripts/core/reconfigure_feisty_meow.sh\n\
+  \n\
+  \n"
+      ERROR_OCCURRED=true
+    fi
   
-  # a minor tickle of the title of the terminal, unless we already have some history.
-  label_terminal_with_info
+    ##############
+
+    if [ -z "$ERROR_OCCURRED" ]; then
+      # pull in our generated variables that are the minimal set we need to find
+      # the rest of our resources.
+      source "$FEISTY_MEOW_VARIABLES_LOADING_FILE"
   
-  if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo "heavyweight init is done."; fi
+      # Set up the temporary directory.
+      source "$FEISTY_MEOW_SCRIPTS/core/create_tempdir.sh"
+    fi
   
+  fi
+
+  ##############
+
   if [ -z "$ERROR_OCCURRED" ]; then
-    # set a sentinel variable to say we loaded the feisty meow environment.
-    export FEISTY_MEOW_SCRIPTS_LOADED=true
+    # no error occurred in our tests above, so load the larger body of standard feisty
+    # meow variables into the environment.  we actually want this to always run also;
+    # it will decide what variables need to be set again.
+    source "$FEISTY_MEOW_SCRIPTS/core/variables.sh"
+
+    ##############
+
+    # include helpful functions.  we do this every time rather than making it part
+    # of variable initialization, because functions cannot be exported to
+    # sub-shells in bash.
+    source "$FEISTY_MEOW_SCRIPTS/core/functions.sh"
+
+    # load some helper methods for the terminal which we'll use below.
+    source "$FEISTY_MEOW_SCRIPTS/tty/terminal_titler.sh"
+
+    ##############
+
+#hmmm: abstract this to a twiddle shell options method.
+    # check hash table before searching path.
+    shopt -s checkhash
+    # don't check path for sourced files.
+    shopt -u sourcepath
+    # ignore duplicate lines.
+    HISTCONTROL=ignoredups
+    # append to the history file.
+    shopt -s histappend
+    # automatically update window size if needed.
+    shopt -s checkwinsize
+
+    ##############
+
+    # make history writes immediate to avoid losing history if bash is zapped.
+    echo $PROMPT_COMMAND | grep -q history
+    if [ $? -ne 0 ]; then
+      # we only change the prompt command if we think it hasn't already been done.
+      export PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
+    fi
+
+    ##############
+
+    # perform the bulkier parts of the initialization process.
+
+    if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo "heavyweight init begins..."; fi
+
+    # set up the aliases for the shell, but only if they are not already set.
+    type CORE_ALIASES_LOADED &>/dev/null
+    if [ $? -ne 0 ]; then
+      if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then
+        echo "the aliases were missing, now they are being added..."
+      fi
+      source "$FEISTY_MEOW_LOADING_DOCK/fmc_core_and_custom_aliases.sh"
+    fi
+
+    #echo before the new labelling, terminal titles have:
+    #show_terminal_titles
+
+    # a minor tickle of the title of the terminal, unless we already have some history.
+    label_terminal_with_info
+
+    if [ ! -z "$DEBUG_FEISTY_MEOW" ]; then echo "heavyweight init is done."; fi
+
+    if [ -z "$ERROR_OCCURRED" ]; then
+      # set a sentinel variable to say we loaded the feisty meow environment.
+      export FEISTY_MEOW_SCRIPTS_LOADED=true
+    fi
+
+  fi  # no error occurred.
+
+  if [ ! -z "$FEISTY_MEOW_SHOW_LAUNCH_GREETING" ]; then
+    echo
+    echo
+    echo "welcome to the feisty meow zone of peace, one of many refuges in the uncountably"
+    echo "infinite multiverses that are hypothetically possible."
+    echo
+    echo
+    unset FEISTY_MEOW_SHOW_LAUNCH_GREETING
   fi
 
-fi  # no error occurred.
+  # only run this hello file if the core feisty meow support haven't been loaded already.  this
+  # hopefully guarantees we show the info at most once in one shell continuum.
+  # this can also be disabled if the NO_HELLO variable has a non-empty value.
+  type CORE_VARIABLES_LOADED &>/dev/null
+  if [ $? -ne 0 -a -z "$NO_HELLO" ]; then
+    # print out a personalized hello file if we find one.
+    if [ -f ~/hello.txt ]; then
+      echo
+      sep 28
+      perl $FEISTY_MEOW_SCRIPTS/*/filedump.pl ~/hello.txt
+      sep 28
+      echo
+    fi
+    # from now on there should be no extra helloing.
+    export NO_HELLO=true
+  fi
+
+  # load the last bits we do here.
+  source "$FEISTY_MEOW_LOADING_DOCK/fmc_ending_sentinel.sh"
+
+fi # "$NO_REPAIRS_NEEDED" was == "true" 
 
index b6421224607bcd18d5fd39ca55e630eff0046113..2224c716e3f0e12ab664b6757919716764867169 100644 (file)
@@ -25,15 +25,15 @@ export FEISTY_MEOW_APEX="$(/bin/pwd)"
 unset CORE_VARIABLES_LOADED
 
 # repetitive bit stolen from variables.  should make a file out of this somehow.
-IS_DOS=$(uname | grep -i ming)
-if [ -z "$IS_DOS" ]; then IS_DOS=$(uname | grep -i cygwin); fi
-# now if we're stuck in DOS, then fix the feisty meow variable name.
-if [ ! -z "$IS_DOS" ]; then
-  FEISTY_MEOW_APEX="$(cmd /c chdir | tr A-Z a-z | sed -e 's/\\/\//g')"
-echo feisty meow dos is: $FEISTY_MEOW_APEX
-  FEISTY_MEOW_APEX="$(dos_to_unix_path "$FEISTY_MEOW_APEX")"
-echo new feisty meow fixed dir is: $FEISTY_MEOW_APEX
-fi
+#IS_DOS=$(uname | grep -i ming)
+#if [ -z "$IS_DOS" ]; then IS_DOS=$(uname | grep -i cygwin); fi
+## now if we're stuck in DOS, then fix the feisty meow variable name.
+#if [ ! -z "$IS_DOS" ]; then
+#  FEISTY_MEOW_APEX="$(cmd /c chdir | tr A-Z a-z | sed -e 's/\\/\//g')"
+#echo feisty meow dos is: $FEISTY_MEOW_APEX
+#  FEISTY_MEOW_APEX="$(dos_to_unix_path "$FEISTY_MEOW_APEX")"
+#echo new feisty meow fixed dir is: $FEISTY_MEOW_APEX
+#fi
 
 popd &>/dev/null
 
index b6311dacff8517b02357178abcc4ff9a3f09ab6f..b64b167098c89726696ab05b7edb3ebeddf51ea4 100644 (file)
@@ -149,11 +149,15 @@ define_yeti_variable DEFAULT_FEISTYMEOW_ORG_DIR=/opt/feistymeow.org
   
   ##############
 
-  # umask sets a permission mask for all file creations.
-  # this mask disallows writes by "group" and "others".
-  umask 022
-  # this mask disallows writes by the "group" and disallows "others" completely.
+  # umask sets a permission mask for all file creations.  we don't set this for the users any
+  # more; they should set it themselves.  this is just documentation.
+  # 
+  # this mask disallows writes by the "group" and disallows all permissions for "others".
   #umask 027
+  # this mask disallows writes by "group" and "others".
+  #umask 022
+  # this mask allows writes by "group" but not by "others".
+  #umask 002
 
   # ulimit sets user limits.  we set the maximum allowed core dump file size
   # to zero, because it is obnoxious to see the core dumps from crashed
@@ -222,9 +226,12 @@ define_yeti_variable DEFAULT_FEISTYMEOW_ORG_DIR=/opt/feistymeow.org
     REPOSITORY_LIST+="$(find "$HOME/apps" -maxdepth 2 -mindepth 2 -iname "avenger5" -type d) "
   fi
   
-  # the archive collections list is a set of directories that are major
-  # repositories of data which can be synched to backup drives.
-  define_yeti_variable ARCHIVE_COLLECTIONS_LIST=
+  # the archive list is a set of directories that are major repositories of
+  # data which can be synched to backup drives.
+  define_yeti_variable MAJOR_ARCHIVE_SOURCES=
+  # the source collections list is a set of directories that indicate they
+  # harbor a lot of source code underneath.
+  define_yeti_variable SOURCECODE_HIERARCHY_LIST=
 
   # initializes the feisty meow build variables, if possible.
   function initialize_build_variables()
@@ -283,8 +290,8 @@ fi
 
 ##############
 
-# pull in the custom overrides for feisty_meow scripts.  this is done last,
-# because we want to set everything up as expected, then let the user
+# pull in the custom overrides for feisty_meow scripts.  this is done almost
+# last, because we want to set everything up as expected, then let the user
 # override individual variables and definitions.  we also don't guard this
 # to avoid running it again, because we don't know what mix of functions and
 # aliases they want to define in there.
@@ -299,3 +306,37 @@ for i in $FEISTY_MEOW_LOADING_DOCK/custom/*.sh; do
   source "$i"
 done
 
+##############
+
+# a late breaking action is to set the editor, if we can.
+# we will fallback to whatever we can find on the host.
+export EDITOR
+if [ ! -z "$DISPLAY" ]; then
+  # only try to add bluefish, a gui editor, if there is an X display for it.
+  if [ -z "$EDITOR" ]; then
+    EDITOR="$(which bluefish)"
+  fi
+fi
+if [ -z "$EDITOR" ]; then
+  EDITOR="$(which gvim)"
+  if [ ! -z "$EDITOR" ]; then
+    # if we found gvim, then add in the no forking flag.
+    EDITOR+=" --nofork"
+  fi
+fi
+if [ -z "$EDITOR" ]; then
+  EDITOR="$(which vim)"
+fi
+if [ -z "$EDITOR" ]; then
+  EDITOR="$(which vi)"
+fi
+##
+# out of ideas about editors at this point.
+##
+# set the VISUAL variable from EDITOR if we found an editor to use.
+if [ ! -z "$EDITOR" ]; then
+  VISUAL="$EDITOR"
+fi
+
+##############
+
index 67e332a63a3f10e5a32a24fd098067f457206dbf..37b085e479a467cea50fcd90e3b180040e9dad11 100644 (file)
@@ -1,6 +1,18 @@
 
-# some aliases that i don't expect very many people to ever want.  they are
-# based on some of the mount configurations available at home or abroad.
+# some aliases that i don't expect very many people to ever want.
+# these are very specific to drives and such that i use but which other people wouldn't.
+
+# updates the mounted barkuptree drive with stuff on wildmutt.
+define_yeti_alias update_barkuptree='source "$FEISTY_MEOW_SCRIPTS/archival/general_updater.sh"; update_archive_drive "/media/fred/barkuptreedrive"'
+
+# updates local archive drive called catfurnose.
+define_yeti_alias update_catfurnose='source "$FEISTY_MEOW_SCRIPTS/archival/general_updater.sh"; update_archive_drive "/media/fred/catfurnose"'
+
+# updates the fredmusicprime drive with the latest from /z space.
+define_yeti_alias update_fredmusicprime='source "$FEISTY_MEOW_SCRIPTS/archival/general_updater.sh"; update_archive_drive "/media/fred/fredmusicprime"'
+
+# updates my little 1 TB "soapbox" style usb drive with any appropriate archives and source.
+define_yeti_alias update_soapbox='source "$FEISTY_MEOW_SCRIPTS/archival/general_updater.sh"; update_archive_drive "/media/fred/soapboxdrive"'
 
 # moo and unmoo mount the local folders i use most.
 #no longer used.  we are doing mostly full directory stores without nfs mounts these days.
@@ -11,3 +23,4 @@
 # not currently used.  this probably was adding a bit of startup time.
 #source "$FEISTY_MEOW_SCRIPTS/buildor/gffs_builders.sh"
 
+
index 4c9c0d90d2c8bb63088454bf258653760d3a83a8..87d0dbf2d3df5ba2685ddeedafc8016e4404a01e 100644 (file)
@@ -18,7 +18,9 @@ if [ -z "$USER_CUSTOMIZATIONS_LOADED" ]; then
   REPOSITORY_LIST+=" cloud ebooks web "
 
   # adds our locally relevant archive folders into the list to be synched.
-  ARCHIVE_COLLECTIONS_LIST+="/z/basement /z/imaginations /z/musix /z/toaster /z/walrus"
+  MAJOR_ARCHIVE_SOURCES+="/z/archons /z/basement /z/imaginations /z/musix /z/toaster /z/walrus"
+  # our set of known source hierarchy folder names.
+  SOURCECODE_HIERARCHY_LIST="codebarn extra_brain interbrane"
 
   # point to our local certificate for ssh usage.
   export SVN_SSH="ssh -i $HOME/.ssh/id_dsa_sourceforge"
index 2f00854a2c675b44ff9738dd50460cae6de3571b..c99b2d11fde01fb8766592e27943504ab258f0f9 100644 (file)
@@ -19,30 +19,41 @@ function refred()
   # everything else is only re-permed if it exists.
   if [ ! -d "$DEFAULT_FEISTYMEOW_ORG_DIR" ]; then
     sudo mkdir "$DEFAULT_FEISTYMEOW_ORG_DIR"
+    test_or_die "making directory: $DEFAULT_FEISTYMEOW_ORG_DIR"
   fi
 
   # iterate across the list of dirs we want fred to own and change their ownership.
   for dirname in /home/fred $DEFAULT_FEISTYMEOW_ORG_DIR /usr/local/fred /home/games $arch_addin; do
     if [ -d "$dirname" ]; then
       echo "refred on '$dirname'"
-      sudo chown -R fred:fred $dirname
+      sudo chown -R fred:fred "$dirname"
+      test_or_die "chowning for fred: $dirname"
     fi
   done
 
   # special case for archives directory.
   if [ -d /z/stuffing -o -L /z/stuffing ]; then
-    sudo chown fred:fred /z; sudo chmod g+rx,o+rx /z
-    sudo chown fred:fred /z/stuffing; sudo chmod g+rx,o-rwx /z/stuffing
+    sudo chown fred:fred /z
+    test_or_die "chowning /z for fred"
+    sudo chmod g+rx,o+rx /z
+    test_or_die "chmodding /z/ for fred"
+    sudo chown fred:fred /z/stuffing
+    test_or_die "chowning /z/stuffing for fred"
+    sudo chmod g+rx,o-rwx /z/stuffing
+    test_or_die "chmodding /z/stuffing for fred"
     pushd /z/stuffing &>/dev/null
     if [ -d archives -o -L archives ]; then
       sudo chown fred:fred archives
+      test_or_die "chowning /z/stuffing/archives for fred"
       sudo chmod -R g+rwx archives
+      test_or_die "chmodding /z/stuffing/archives for fred"
     fi
     popd &>/dev/null
   fi
 
   # make the logs readable by normal humans.
   sudo bash $FEISTY_MEOW_SCRIPTS/security/normal_perm.sh /var/log
+  test_or_die "setting normal perms on /var/log"
 }
 
 # this block should execute when the script is actually run, rather
@@ -50,6 +61,8 @@ function refred()
 if [[ $0 =~ .*refred\.sh.* ]]; then
   THISDIR="$( \cd "$(\dirname "$0")" && /bin/pwd )"
   source "$THISDIR/../../core/launch_feisty_meow.sh"
+  test_or_die "sourcing the feisty meow launcher"
   refred
+  test_or_die "refredding process"
 fi
 
diff --git a/scripts/customize/fred/scripts/archival/compare_soapbox.sh b/scripts/customize/fred/scripts/archival/compare_soapbox.sh
new file mode 100644 (file)
index 0000000..d489373
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# compares the soapbox with the real archive to see if any older stuff might be
+# left behind.  if it's got a less than in front, then it's only on the soapbox drive
+# now rather than the pc's hard drive.
+
+source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
+
+function compare_archives_with_target()
+{
+  local target="$1"; shift
+
+  for currdir in $MAJOR_ARCHIVE_SOURCES; do
+    sep
+    echo "comparing '$currdir' with target '$target', where 'less thans' are on the target..."
+    compare_dirs "$target/$(basename $currdir)" "$currdir"
+  done
+}
+
+#hmmm: generalize this one also.
+
+compare_archives_with_target /media/fred/soapboxdrive
+
+sep
+
diff --git a/scripts/customize/fred/scripts/archival/euphrosyne_comparator.sh b/scripts/customize/fred/scripts/archival/euphrosyne_comparator.sh
new file mode 100644 (file)
index 0000000..f3a7ab5
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# runs through all the local archives on euphrosyne to make sure nothing is different
+# when compared to the mainline versions on surya.
+
+#hmmm: add a check that this is in fact the right host, euphrosyne.
+
+
+source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
+
+sep 14
+echo "Comparing basement folder..."
+compare_dirs /z/basement wildmutt:/z/basement
+sep 14
+
+sep 14
+echo "Comparing imaginations folder..."
+compare_dirs /z/imaginations wildmutt:/z/imaginations
+sep 14
+
+sep 14
+echo "Comparing musix folder..."
+compare_dirs /z/musix wildmutt:/z/musix
+sep 14
+
+sep 14
+echo "Comparing walrus folder..."
+compare_dirs /z/walrus wildmutt:/z/walrus
+sep 14
diff --git a/scripts/customize/fred/scripts/archival/raw_surya_synch_.sh b/scripts/customize/fred/scripts/archival/raw_surya_synch_.sh
new file mode 100644 (file)
index 0000000..57b9472
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
+
+echo "Updating walrus and musix from surya: raw mode without syncthing!"
+echo
+
+for currdir in basement imaginations musix walrus; do
+  sep
+  echo "synching $currdir folder..."
+  rsync -avz surya:/z/$currdir/* /z/$currdir/
+done
+
+sep
+
diff --git a/scripts/customize/fred/scripts/cakelampvm/revamp_web_permissions.sh b/scripts/customize/fred/scripts/cakelampvm/revamp_web_permissions.sh
deleted file mode 100755 (executable)
index af9693f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# change the owner for the web roots to the apache user, www-data.
-sudo chown -R www-data:www-data                /var/www
-
-# make sure we have the appropriate access on a few key folders.
-sudo chmod u+rwx,g+rx                  /var/www
-
-# put a couple specific ownerships into play so the appropriate user has full access.
-sudo chown -R developer:developer      /var/www/defaultcake.cakelampvm.com
-sudo chown -R fred:fred                        /var/www/webwork.repository
-## add others here for your own projects.
-
-# these directories will be given group permissons that enable web server access.
-DIR_LIST="/var/www/defaultcake.cakelampvm.com /var/www/webwork.repository"
-
-# add in group permissions to allow the web server to serve the pages properly.
-for currdir in $DIR_LIST; do
-  sudo find $currdir -type d -exec chmod -R u+rwx,g+rwx,o-rwx {} ';'
-  sudo find $currdir -type f -exec chmod -R u+rw,g+rw,o-rwx {} ';'
-done
-
diff --git a/scripts/customize/fred/scripts/disk_synch/compare_soapbox.sh b/scripts/customize/fred/scripts/disk_synch/compare_soapbox.sh
deleted file mode 100644 (file)
index 8dd3f44..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-# compares the soapbox with the real archive to see if any older stuff might be
-# left behind.  if it's got a less than in front, then it's only on the soapbox drive
-# now rather than the pc's hard drive.
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-
-function compare_archives_with_target()
-{
-  local target="$1"; shift
-
-  for currdir in $ARCHIVE_COLLECTION_LIST; do
-    sep
-    echo "comparing '$currdir' with target '$target', where 'less thans' are on the target..."
-    compare_dirs "$target/$(basename $currdir)" "$currdir"
-  done
-}
-
-compare_archives_with_target /media/fred/soapboxdrive
-
-sep
-
diff --git a/scripts/customize/fred/scripts/disk_synch/euphrosyne_comparator.sh b/scripts/customize/fred/scripts/disk_synch/euphrosyne_comparator.sh
deleted file mode 100644 (file)
index f3a7ab5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# runs through all the local archives on euphrosyne to make sure nothing is different
-# when compared to the mainline versions on surya.
-
-#hmmm: add a check that this is in fact the right host, euphrosyne.
-
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-
-sep 14
-echo "Comparing basement folder..."
-compare_dirs /z/basement wildmutt:/z/basement
-sep 14
-
-sep 14
-echo "Comparing imaginations folder..."
-compare_dirs /z/imaginations wildmutt:/z/imaginations
-sep 14
-
-sep 14
-echo "Comparing musix folder..."
-compare_dirs /z/musix wildmutt:/z/musix
-sep 14
-
-sep 14
-echo "Comparing walrus folder..."
-compare_dirs /z/walrus wildmutt:/z/walrus
-sep 14
diff --git a/scripts/customize/fred/scripts/disk_synch/musical_wand.sh b/scripts/customize/fred/scripts/disk_synch/musical_wand.sh
deleted file mode 100644 (file)
index c3af4be..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/bin/bash
-
-# musical_wand: distributes music from our primary source to all hosts that are listed
-# as being redundant copies for the music.
-
-# this script is designed to be run on the music host with the super alpha main source of
-# music plugged in as an external drive.  that being said, it will still work as long as
-# the music host has its local copy intact; the local copy of the primary is always what
-# is synched onto the other archive hosts.  in that sense, the musical host is itself a
-# musix archive, but it is treated "special".
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-
-#hmmm: add the goodness around these actions like the "nice" updater so we catch all errors.
-
-# this host is where all the music is supposed to come from.
-MUSICAL_HOST=curie
-
-#hmmm: this script is currently limited to run ON the music host.  it could easily do the backwards thing instead, and copy FROM music host.
-
-# the list of hosts we know of that are holding onto duplicate copies of the musix archive.
-#old list MUSIX_ARCHIVE_SITE_LIST=(surya banshee wildmutt euphrosyne)
-MUSIX_ARCHIVE_SITE_LIST=(euphrosyne)
-#hmmm: list was contracted a lot, since we don't want to step on the updates done by syncthing.  euphrosyne is still our reference copy for what the archive states "should" be.
-
-if [[ ! ( $(hostname) =~ .*${MUSICAL_HOST}.* ) ]]; then
-  echo "This script is only designed to run on $MUSICAL_HOST with the"
-  echo "primary fred music source (external) disc plugged in."
-  exit 1
-fi
-
-# synch our local copy on the music host with the primary music drive, source of all goodness.
-function get_music_from_alpha_site()
-{
-  sep
-  echo "getting musix and basement from fred music prime device"
-  rsync -av /media/fred/fredmusicprime/musix/* /z/musix/
-  rsync -av /media/fred/fredmusicprime/basement/* /z/basement/
-  sep
-  echo
-}
-
-# updates the music on a remote host to our current local copy on the music host.
-function update_musix_pile()
-{
-  sep
-  local host="$1"; shift
-  echo "$host: synching musix and basement"
-  rsync -avz /z/musix/* ${host}:/z/musix/ 
-  rsync -avz /z/basement/* ${host}:/z/basement/ 
-  sep
-  echo
-}
-
-##############
-
-# make sure the local machine, our first-stop musix host, is in good shape.
-get_music_from_alpha_site
-
-# run through the steps of updating all our machines.
-for i in ${MUSIX_ARCHIVE_SITE_LIST[@]}; do
-  update_musix_pile $i
-done
-
-
diff --git a/scripts/customize/fred/scripts/disk_synch/raw_synch_from_surya.sh b/scripts/customize/fred/scripts/disk_synch/raw_synch_from_surya.sh
deleted file mode 100644 (file)
index 57b9472..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-
-echo "Updating walrus and musix from surya: raw mode without syncthing!"
-echo
-
-for currdir in basement imaginations musix walrus; do
-  sep
-  echo "synching $currdir folder..."
-  rsync -avz surya:/z/$currdir/* /z/$currdir/
-done
-
-sep
-
diff --git a/scripts/customize/fred/scripts/disk_synch/update_barkuptree.sh b/scripts/customize/fred/scripts/disk_synch/update_barkuptree.sh
deleted file mode 100644 (file)
index fcefd5d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-# updates the mounted barkuptree drive with stuff on wildmutt.
-# very specific currently.
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-
-export BARKY=/media/fred/barkuptreedrive
-
-# copy up the archived bluray discs, and possibly future archived formats.
-netcp /z/archons/* $BARKY/bkup_archons/
-test_or_die "synching archons"
-
-# copy over our somewhat attenuated but still important walrus archives.
-netcp /z/walrus/* $BARKY/walrus/ 
-test_or_die "synching walrus"
-
-# copy all the music files for future reference.
-netcp /z/musix/* $BARKY/musix/
-test_or_die "synching musix"
-
-# back up the photo archives.
-netcp /z/imaginations/* $BARKY/imaginations/
-test_or_die "synching imaginations"
-
-
diff --git a/scripts/customize/fred/scripts/disk_synch/update_fredmusicprime.sh b/scripts/customize/fred/scripts/disk_synch/update_fredmusicprime.sh
deleted file mode 100644 (file)
index 4459754..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-# updates my little 1 TB "soapbox" style usb drive with items that it should contain.
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-source "$FEISTY_MEOW_SCRIPTS/archival/shared_updater_parts.sh"
-
-# where we're backing up to.
-TARGET_FOLDER="/media/fred/fredmusicprime"
-
-sep
-
-echo Target drive currently has...
-ls "$TARGET_FOLDER"
-if [ $? -ne 0 ]; then
-  echo "The target location '$TARGET_FOLDER' is not mounted currently, so cannot be updated."
-  exit 1
-fi
-
-# synch all our targets.
-for currdir in $ARCHIVE_COLLECTIONS_LIST; do
-  synch_directory_to_target "$currdir" "$TARGET_FOLDER/$(basename $currdir)"/
-done
-
-sep
-
-# update source code if present.
-echo getting latest fred repositories...
-pushd "$TARGET_FOLDER"
-update_source_folders extra_brain
-
-sep
-
-echo Updated all expected portions of the targets successfully.
-
diff --git a/scripts/customize/fred/scripts/disk_synch/update_soapbox.sh b/scripts/customize/fred/scripts/disk_synch/update_soapbox.sh
deleted file mode 100644 (file)
index f2208f5..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-# updates my little 1 TB "soapbox" style usb drive with items that it should contain.
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-source "$FEISTY_MEOW_SCRIPTS/archival/shared_updater_parts.sh"
-
-# where we're backing up to.
-TARGET_FOLDER="/media/fred/soapboxdrive"
-
-sep
-
-echo Target drive currently has...
-ls "$TARGET_FOLDER"
-if [ $? -ne 0 ]; then
-  echo "The target location '$TARGET_FOLDER' is not mounted currently, so cannot be updated."
-  exit 1
-fi
-
-# synch all our targets.
-for currdir in $ARCHIVE_COLLECTIONS_LIST; do
-  synch_directory_to_target "$currdir" "$TARGET_FOLDER/$(basename $currdir)"/
-done
-
-sep
-
-# update source code if present.
-echo getting latest fred repositories...
-pushd "$TARGET_FOLDER"
-update_source_folders extra_brain
-
-sep
-
-echo Updated all expected portions of the targets successfully.
-
index 6ba6a4e3f0dd1f46d7862101a4636114becc4857..403a0f7c7b11c05bec8a3b6b37b4b0efd0a7b183 100644 (file)
@@ -3,8 +3,12 @@
 function print_instructions()
 {
   echo -e "\n$(basename $0 .sh):\n"
+
+  # calculate the number of columsn in the terminal.
+  local cols=$(get_maxcols)
+
   echo -e 'this script takes two parameters, a "here" folder and a "there" folder, almost as if it were a copy command.  but instead, this removes any file from under the "here" location if it cannot be found in the "there" location.  so the "there" location is considered a more definitive template of what should be in "here", such that we strip out what "there" does not have.\n\n
-the most" useful way to use this script is for a "here" hierarchy that is a copy of an older version of another "there" hierarchy.  the "there" hierarchy may have changed a lot, including new files, changed files, and deleted files.  it is a simple operation to copy everything from "there" into "here" (such as by using the command [ cp -R "$there"/* "$here" ] ) , but it is a lot harder to determine what stuff in "here" is out of date and should be removed.  that is where this script comes in; it can be run to flush out any older things in "here", rather than requiring the user to manually find all those files.  ' | splitter
+the most" useful way to use this script is for a "here" hierarchy that is a copy of an older version of another "there" hierarchy.  the "there" hierarchy may have changed a lot, including new files, changed files, and deleted files.  it is a simple operation to copy everything from "there" into "here" (such as by using the command [ cp -R "$there"/* "$here" ] ) , but it is a lot harder to determine what stuff in "here" is out of date and should be removed.  that is where this script comes in; it can be run to flush out any older things in "here", rather than requiring the user to manually find all those files.  ' | splitter --maxcol $(($cols - 1))
   echo
   echo "Example Usage:"
   echo 
diff --git a/scripts/rev_control/puffer.sh b/scripts/rev_control/puffer.sh
new file mode 100644 (file)
index 0000000..c02ef3b
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# puffer: "puffs out" all of the folders present in the REPOSITORY_LIST
+# variable, which causes the repo to be merged with its remote versions.
+# this enables a clean check-in; after puffer runs, there will be no secret
+# upstream changes that could mess up the git push (svn and cvs are not
+# supported in this script, since they branch differently than git).
+
+source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
+source "$FEISTY_MEOW_SCRIPTS/rev_control/version_control.sh"
+
+##############
+
+echo "puffing out repositories at: $(date)"
+echo
+
+FULL_LIST=" $(dirname $FEISTY_MEOW_APEX) $HOME "
+if [ "$OS" == "Windows_NT" ]; then
+  FULL_LIST+=" c:/ d:/ e:/ "
+fi
+
+puff_out_list $FULL_LIST
+test_or_die "puffing out list: $FULL_LIST"
+
+##############
+
+# regenerate the scripts after puffing out, since this could mean a modified version
+# of feisty meow is present.
+regenerate
+
+##############
+
index aacd77724b2e25f58973e569de6fd9946fecdf81..b2da88704a60f4ace4290f638e8be69cc1eb6030 100644 (file)
@@ -47,9 +47,8 @@ pushd "$dir" &>/dev/null
 test_or_die "changing to directory: $dir"
 tempfile=$(generate_rev_ctrl_filelist)
 test_or_die "generating revision control file list"
-popd &>/dev/null
 
-perform_revctrl_action_on_file "$tempfile" do_careful_git_update "$(\pwd)"
+perform_revctrl_action_on_file "$tempfile" do_careful_git_update
 test_or_die "doing a careful git update on: $tempfile"
 
 # send our little boat down the stream to the dependent repository.
diff --git a/scripts/rev_control/rfluffer.sh b/scripts/rev_control/rfluffer.sh
deleted file mode 100644 (file)
index b5de908..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# this "fluffs out" the repositories that it finds.  what this means is that
-# any git repositories found will have all of their remote state updated (by
-# pulling all remote repos).  this ensures that any upstream changes get
-# merged into the local branch.
-# it's better to fluff out your code regularly rather than waiting for a huge
-# merge snarl later.  note that if you check in the code frequently with the
-# feisty meow scripts, that will also take care of fluffing out the code.
-
-source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
-source "$FEISTY_MEOW_SCRIPTS/rev_control/version_control.sh"
-
-##############
-
-dir="$1"; shift
-if [ -z "$dir" ]; then
-  dir=.
-fi
-
-pushd "$dir" &>/dev/null
-test_or_die "changing to directory: $dir"
-tempfile=$(generate_rev_ctrl_filelist)
-test_or_die "generating revision control file list"
-popd &>/dev/null
-
-perform_revctrl_action_on_file "$tempfile" do_careful_git_update
-test_or_die "fluffing out repository at: $tempfile"
-
diff --git a/scripts/rev_control/rpuffer.sh b/scripts/rev_control/rpuffer.sh
new file mode 100644 (file)
index 0000000..5032bc1
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# this "puffs out" the repositories that it finds.  what this means is that
+# any git repositories found will have all of their remote state updated (by
+# pulling all remote repos).  this ensures that any upstream changes get
+# merged into the local branch.
+# it's better to puff out your code regularly rather than waiting for a huge
+# merge snarl later.  note that if you check in the code frequently with the
+# feisty meow scripts, that will also take care of puffing out the code.
+
+source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
+source "$FEISTY_MEOW_SCRIPTS/rev_control/version_control.sh"
+
+##############
+
+dir="$1"; shift
+if [ -z "$dir" ]; then
+  dir=.
+fi
+
+pushd "$dir" &>/dev/null
+test_or_die "changing to directory: $dir"
+tempfile=$(generate_rev_ctrl_filelist)
+test_or_die "generating revision control file list"
+popd &>/dev/null
+
+perform_revctrl_action_on_file "$tempfile" do_careful_git_update
+test_or_die "puffing out repository at: $tempfile"
+
index 7dd199f4c44632623c3d3b123ffda0909b12983e..75f344cf66ab8485f0e8b980f6b83c8eef924859 100644 (file)
@@ -15,14 +15,26 @@ source "$FEISTY_MEOW_SCRIPTS/tty/terminal_titler.sh"
 export MAX_DEPTH=5
 
 # use our splitter tool for lengthy output if it's available.
-if [ ! -z "$(which splitter)" ]; then
+if [ ! -z "$(which splitter 2>/dev/null)" ]; then
   TO_SPLITTER="$(which splitter)"
+  # calculate the number of columsn in the terminal.
+  cols=$(get_maxcols)
+  TO_SPLITTER+=" --maxcol $(($cols - 1))"
 else
   TO_SPLITTER=cat
 fi
 
 ##############
 
+#hmmm: move this to core
+# this makes the status of pipe N into the main return value.
+function promote_pipe_return()
+{
+  ( exit ${PIPESTATUS[$1]} )
+}
+
+##############
+
 # one unpleasantry to take care of first; cygwin barfs aggressively if the TMP directory
 # is a DOS path, but we need it to be a DOS path for our GFFS testing, so that blows.
 # to get past this, TMP gets changed below to a hopefully generic and safe place.
@@ -77,14 +89,26 @@ function do_checkin()
       $blatt
 
       # put all changed and new files in the commit.  not to everyone's liking.
-      git add --all .
+      git add --all . | $TO_SPLITTER
+      promote_pipe_return 0
       test_or_die "git add all new files"
 
       # see if there are any changes in the local repository.
       if ! git diff-index --quiet HEAD --; then
         # tell git about all the files and get a check-in comment.
+#hmmm: begins to look like, you guessed it, a reusable bit that all commit actions could enjoy.
         git commit .
-        test_or_die "git commit"
+        retval=$?
+        test_or_continue "git commit"
+        if [ $retval -ne 0 ]; then
+          echo -e -n "Commit failed or was aborted:\nShould we continue with other check-ins? [y/N] "
+          local line
+          read line
+          if [[ "${line:0:1}" != "y" ]]; then
+            echo "Stopping check-in process due to missing commit and user request."
+            exit 1
+          fi
+        fi
       fi
 
       # a new set of steps we have to take to make sure the branch integrity is good.
@@ -94,7 +118,8 @@ function do_checkin()
       # there could already be committed changes that haven't been pushed yet.
 
       # upload any changes to the upstream repo so others can see them.
-      git push origin "$(my_branch_name)" 2>&1 | grep -v "X11 forwarding request failed" | $TO_SPLITTER
+      git push --tags origin "$(my_branch_name)" 2>&1 | grep -v "X11 forwarding request failed" | $TO_SPLITTER
+      promote_pipe_return 0
       test_or_die "git push"
 
     fi
@@ -165,7 +190,7 @@ function do_report_new
   return 0
 }
 
-# checks in all the folders in a specified list.
+# checks in all the folders in the specified list.
 function checkin_list()
 {
   # make the list of directories unique.
@@ -183,7 +208,7 @@ function checkin_list()
     if [[ $outer =~ /.* ]]; then
       # yep, this path is absolute.  just handle it directly.
       if [ ! -d "$outer" ]; then continue; fi
-      do_checkin $outer
+      do_checkin "$outer"
       test_or_die "running check-in (absolute) on path: $outer"
       sep 28
     else
@@ -191,7 +216,7 @@ function checkin_list()
         # add in the directory component to see if we can find the folder.
         local path="$inner/$outer"
         if [ ! -d "$path" ]; then continue; fi
-        do_checkin $path
+        do_checkin "$path"
         test_or_die "running check-in (relative) on path: $path"
         sep 28
       done
@@ -201,24 +226,62 @@ function checkin_list()
   restore_terminal_title
 }
 
-# takes out the first few carriage returns that are in the input.
-function squash_first_few_crs()
+# does a careful git update on all the folders in the specified list.
+function puff_out_list()
 {
-  i=0
-  while read input_text; do
-    i=$((i+1))
-    if [ $i -le 5 ]; then
-      echo -n "$input_text  "
+  # make the list of directories unique.
+  local list="$(uniquify $*)"
+
+  save_terminal_title
+
+  # turn repo list back into an array.
+  eval "repository_list=( ${REPOSITORY_LIST[*]} )"
+
+  local outer inner
+
+#hmmm: once again, seeing some reusable code in this loop...
+  for outer in "${repository_list[@]}"; do
+    # check the repository first, since it might be an absolute path.
+    if [[ $outer =~ /.* ]]; then
+      # yep, this path is absolute.  just handle it directly.
+      if [ ! -d "$outer" ]; then continue; fi
+      do_careful_git_update "$outer"
+      test_or_die "running puff-out (absolute) on path: $outer"
+      sep 28
     else
-      echo $input_text
+      for inner in $list; do
+        # add in the directory component to see if we can find the folder.
+        local path="$inner/$outer"
+        if [ ! -d "$path" ]; then continue; fi
+        do_careful_git_update "$path"
+        test_or_die "running puff-out (relative) on path: $path"
+        sep 28
+      done
     fi
   done
-  if [ $i -le 3 ]; then
-    # if we're still squashing eols, make sure we don't leave them hanging.
-    echo
-  fi
+
+  restore_terminal_title
 }
 
+#hmmm: to go below.
+### takes out the first few carriage returns that are in the input.
+##function squash_first_few_crs()
+##{
+  ##i=0
+  ##while read input_text; do
+    ##i=$((i+1))
+    ##if [ $i -le 5 ]; then
+      ##echo -n "$input_text  "
+    ##else
+      ##echo $input_text
+    ##fi
+  ##done
+  ##if [ $i -le 3 ]; then
+    ### if we're still squashing eols, make sure we don't leave them hanging.
+    ##echo
+  ##fi
+##}
+
 #hmmm: the below are git specific and should be named that way.
 
 function all_branch_names()
@@ -250,25 +313,45 @@ function check_branch_state()
 {
   local branch="$1"; shift
 
+  if [ -z "$branch" ]; then
+    echo "No branch was passed to check branch state."
+    return 1
+  fi
+
   local to_return=120  # unknown issue.
 
   local local_branch=$(git rev-parse @)
   local remote_branch=$(git rev-parse "$branch")
   local merge_base=$(git merge-base @ "$branch")
 
+  local to_echo=
   if [ "$local_branch" == "$remote_branch" ]; then
-    echo "okay"
+    to_echo="okay"
   elif [ "$local_branch" == "$merge_base" ]; then
-    echo "needs_pull"
+    to_echo="needs_pull"
   elif [ "$remote_branch" == "$merge_base" ]; then
-    echo "needs_push"
+    to_echo="needs_push"
   else
-    echo "diverged"
+    to_echo="diverged"
   fi
 
+  echo -n "$to_echo"
+
   return $to_return
 }
 
+# only shows the branch state if it's not okay.
+# note that this is not the same as a conditional branch (ha ha).
+function show_branch_conditionally()
+{
+  local this_branch="$1"; shift
+
+  local state=$(check_branch_state "$this_branch")
+  if [ "$state" != "okay" ]; then
+    echo "=> branch '$this_branch' state is not clean: $state"
+  fi
+}
+
 # the git update process just gets more and more complex when you bring in
 # branches, so we've moved this here to avoid having a ton of code in the
 # other methods.
@@ -284,41 +367,45 @@ function do_careful_git_update()
     return 0
   fi
 
+  local this_branch="$(my_branch_name)"
+
+  show_branch_conditionally "$this_branch"
+
   # first update all our remote branches to their current state from the repos.
-  git remote update
+  git remote update | $TO_SPLITTER
+  promote_pipe_return 0
   test_or_die "git remote update"
 
-  local this_branch="$(my_branch_name)"
-#appears to be useless; reports no changes when we need to know about remote changes that do exist:
-#hmmm: trying it out again now that things are better elsewhere.  let's see what it says.
-  state=$(check_branch_state "$this_branch")
-  echo "=> branch '$this_branch' state is: $state"
+  show_branch_conditionally "$this_branch"
 
   # this code is now doing what i have to do when i repair the repo.  and it seems to be good so far.
   local branch_list=$(all_branch_names)
   local bran
   for bran in $branch_list; do
 #    echo "synchronizing remote branch: $bran"
-    git checkout "$bran"
+    git checkout "$bran" | $TO_SPLITTER
+    promote_pipe_return 0
     test_or_die "git switching checkout to remote branch: $bran"
 
-    state=$(check_branch_state "$bran")
-    echo "=> branch '$bran' state is: $state"
+    show_branch_conditionally "$this_branch"
 
     remote_branch_info=$(git ls-remote --heads origin $bran 2>/dev/null)
     if [ ! -z "$remote_branch_info" ]; then
       # we are pretty sure the remote branch does exist.
-      git pull --no-ff origin "$bran"
+      git pull --no-ff origin "$bran" | $TO_SPLITTER
+      promote_pipe_return 0
     fi
     test_or_die "git pull of remote branch: $bran"
   done
   # now switch back to our branch.
-  git checkout "$this_branch"
+  git checkout "$this_branch" | $TO_SPLITTER
+  promote_pipe_return 0
   test_or_die "git checking out our current branch: $this_branch"
 
   # now pull down any changes in our own origin in the repo, to stay in synch
   # with any changes from others.
-  git pull --no-ff --all
+  git pull --no-ff --all | $TO_SPLITTER
+  promote_pipe_return 0
   test_or_die "git pulling all upstream"
 
   popd &>/dev/null
@@ -343,19 +430,21 @@ function do_update()
     if test_writeable "CVS"; then
       $blatt
       cvs update . | $TO_SPLITTER
+      promote_pipe_return 0
       test_or_die "cvs update"
     fi
   elif [ -d ".svn" ]; then
     if test_writeable ".svn"; then
       $blatt
       svn update . | $TO_SPLITTER
+      promote_pipe_return 0
       test_or_die "svn update"
     fi
   elif [ -d ".git" ]; then
     if test_writeable ".git"; then
       $blatt
       git pull --no-ff 2>&1 | grep -v "X11 forwarding request failed" | $TO_SPLITTER
-      if [ ${PIPESTATUS[0]} -ne 0 ]; then false; fi
+      promote_pipe_return 0
       test_or_die "git pull of origin without fast forwards"
     fi
   else
@@ -426,8 +515,8 @@ function generate_rev_ctrl_filelist()
 
   local sortfile=$(mktemp /tmp/zz_checkin_sort.XXXXXX)
   sort <"$tempfile" >"$sortfile"
-  \rm "$tempfile"
   echo "$sortfile"
+  \rm "$tempfile"
 }
 
 # iterates across a list of directories contained in a file (first parameter).
@@ -450,7 +539,7 @@ function perform_revctrl_action_on_file()
     pushd "$dirname" &>/dev/null
     echo "[$(pwd)]"
     # pass the current directory plus the remaining parameters from function invocation.
-    $action . $*
+    $action . 
     test_or_die "performing action $action on: $(pwd)"
     sep 28
     popd &>/dev/null
@@ -462,6 +551,6 @@ function perform_revctrl_action_on_file()
 
   restore_terminal_title
 
-  rm $tempfile
+  rm "$tempfile"
 }
 
index f759494973e4b686b50d8d61807810e89869dfef..2ae511cbb8eb50148b9efd2841ee0bddf088463e 100644 (file)
@@ -18,18 +18,18 @@ source "$WORKDIR/shared_site_mgr.sh"
 
 sep
 
-check_application_dir "$APPLICATION_DIR"
+check_application_dir "$BASE_APPLICATION_PATH"
 
 # find proper webroot where the site will be initialized.
 if [ -z "$app_dirname" ]; then
   # no dir was passed, so guess it.
-  find_app_folder "$APPLICATION_DIR"
+  find_app_folder "$BASE_APPLICATION_PATH"
 else
-  test_app_folder "$APPLICATION_DIR" "$app_dirname"
+  test_app_folder "$BASE_APPLICATION_PATH" "$app_dirname"
 fi
 
 # where we expect to find our checkout folder underneath.
-full_app_dir="$APPLICATION_DIR/$app_dirname"
+full_app_dir="$BASE_APPLICATION_PATH/$app_dirname"
 
 # simplistic approach here; just go to the folder and pull the changes.
 
diff --git a/scripts/site_avenger/clean_mapsdemo.sh b/scripts/site_avenger/clean_mapsdemo.sh
new file mode 100644 (file)
index 0000000..5054cdd
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+# some code i wrote to add to revamp that turned out to be unsuitable.
+# but it corrects a problem in cakelampvm v002 release that i find annoying,
+# so here it is as its own file.
+
+# clean out some old files that were not checked in in mapsdemo.
+echo Doing some git repository maintenance in fred account.
+#
+# change over to fred folder
+pushd /home/fred
+test_or_die "changing dir to fred's home; what have you done with fred?"
+
+pushd apps/mapsdemo/avenger5
+test_or_die "changing dir to mapsdemo app"
+
+rpuffer . &>/dev/null
+if [ $? -ne 0 ]; then
+  # it seems our old files are still conflicting this.
+  if [ -f config/config_google.php ]; then
+    \rm -f config/config_google.php
+    test_or_die "removing old config for google"
+  fi
+  if [ -f config/app.php ]; then
+    \rm -f config/app.php
+    test_or_die "removing old config for app"
+  fi
+
+  git reset --hard HEAD
+  test_or_die "resetting git's hard head"
+
+  rpuffer .
+#hmmm: use output saver thing when that exists.
+  test_or_die "puffing out mapsdemo app after inadequate corrective action was taken"
+fi
+
+popd
+
+popd
+#...coolness, if we got to here.
+
+
index 65e782d7b02664a3a08cf7cbf340d564b0a680e7..0235eb5074a7334736f64b69d51b648cf40fc988 100644 (file)
@@ -1,42 +1,60 @@
 #!/bin/bash
 
-# this config file provides the default values for the variables used in our site management scripts.
+# provides the default values for the variables used in our site management scripts.
+
+# config files for site avenger apps usually override nothing, since we
+# auto-construct the app name and domain.
+# if they do need to override anything, they can just specify replacement
+# values for the variables in this file.
 
 ####
 
 # basic information that is constant for all site avenger sites.
 
-APPLICATION_DIR="$HOME/apps"
-DEFAULT_REPOSITORY_ROOT="git@github.com:kwentworth"
-CHECKOUT_DIR_NAME="avenger5"
+# the top level of the user's application storage.
+export BASE_APPLICATION_PATH="$HOME/apps"
+# where the code should come from.
+export DEFAULT_REPOSITORY_ROOT="git@github.com:kwentworth"
+# we checkout the git repository to a directory underneath the
+# app storage directory named this:
+export CHECKOUT_DIR_NAME="avenger5"
+# the subfolder that the web browser will look for the site in,
+# underneath the application's specific path.
+export STORAGE_SUFFIX="/public"
 
 ####
 
-# config files for site avenger apps usually override nothing, since we
-# auto-construct the app name and domain.  but if they do need to override
-# anything, it will be below this point in the file.
-# the derived config file should include the basic configs like so:
-#
-#   source "$WORKDIR/config/default.app"
+# constants within our cakelampvm machine.
+
+# in our scheme, the single IP address that all our domains map to.
+export IP_ADDRESS="10.28.42.20"
+# the email address (where first dot is replaced by @) for the administrator of the domain.
+export SERVER_ADMIN="developer.cakelampvm.com"
+# the name of the name server for the new domains (should already be configured).
+export MAIN_NAME_SERVER="ns.cakelampvm.com"
+# the name of the mail server for a new domain (should already be configured).
+export MAIL_SERVER="mail.cakelampvm.com"
+# the distribution name to be listed in info for the new domain or subdomain.
+export DISTRO="ubuntu"
 
 ####
 
 # deployment information for the application / site.
 
-APPLICATION_NAME="${app_dirname}"
+export APPLICATION_NAME="${app_dirname}"
 
 echo app name was computed as $APPLICATION_NAME
 
 # change this if the site is on the "real" internet.
-DOMAIN_NAME="${app_dirname}.vm"
+export DOMAIN_NAME="${app_dirname}.vm"
 
 echo domain name was computed as $DOMAIN_NAME
 
-REPO_NAME="${app_dirname}.git"
+export REPO_NAME="${app_dirname}"
 
 echo repo name was computed as $REPO_NAME
 
-THEME_NAME="$(capitalize_first_char "${app_dirname}.git")"
+export THEME_NAME="$(capitalize_first_char "${app_dirname}")"
 
 echo theme name was computed as $THEME_NAME
 
index a2bca519b1b348ffff577eff32c0d298f2532252..34fe6ce89fc9e9873ac88225fada9c2f3a228674 100644 (file)
@@ -3,8 +3,8 @@
 # a special override for the mapsdemo site, which we want to put in as
 # a subdomain of the cakelampvm domain.
 
-source "$WORKDIR/config/default.app"
+export DOMAIN_NAME="${APPLICATION_NAME}.cakelampvm.com"
 
-DOMAIN_NAME="${APPLICATION_NAME}.cakelampvm.com"
 
+echo "*** overrode domain name as: $DOMAIN_NAME"
 
index 998fcad57b4aae9517737ab6ea75bacb654b186e..c2ed28d5afaa15f9bb87d552dab1dccab7567528 100644 (file)
 # start with.  The concept of the theme comes from cakephp.
 
 export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
+
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
 
 ############################
 
 function print_instructions()
 {
   echo
-  echo "$(basename $0 .sh) [app dirname] [repository] [theme name]"
+  echo "$(basename $0 .sh) [app dirname] [repository] [theme name] "
+#[user name]
   echo
   echo "All parameters are optional, and intelligent guesses for them will be made."
   echo
   echo "app dirname: The folder where the app will be stored."
   echo "repository: The name of the git repository (short version, no URL)."
   echo "theme name: The name to use for the cakephp theme."
+#  echo "user name: The name of the user to chown the checkout to."
   echo
   exit 0
 }
@@ -46,6 +51,9 @@ function print_instructions()
 app_dirname="$1"; shift
 repo_name="$1"; shift
 theme_name="$1"; shift
+#user_name="$1"; shift
+
+#echo "*** user name is $user_name"
 
 if [ "$app_dirname" == "-help" -o "$app_dirname" == "--help" ]; then
   print_instructions
@@ -55,18 +63,18 @@ source "$WORKDIR/shared_site_mgr.sh"
 
 sep
 
-check_application_dir "$APPLICATION_DIR"
+check_application_dir "$BASE_APPLICATION_PATH"
 
 # find proper webroot where the site will be initialized.
 if [ -z "$app_dirname" ]; then
   # no dir was passed, so guess it.
-  find_app_folder "$APPLICATION_DIR"
+  find_app_folder "$BASE_APPLICATION_PATH"
 else
-  test_app_folder "$APPLICATION_DIR" "$app_dirname"
+  test_app_folder "$BASE_APPLICATION_PATH" "$app_dirname"
 fi
 
 # where we expect to find our checkout folder underneath.
-full_app_dir="$APPLICATION_DIR/$app_dirname"
+full_app_dir="$BASE_APPLICATION_PATH/$app_dirname"
 
 # use our default values for the repository and theme if they're not provided.
 if [ -z "$repo_name" ]; then
@@ -80,6 +88,9 @@ echo "Repository: $repo_name"
 echo "Theme name: $theme_name"
 sep
 
+echo in powerup before update repo with:
+var CHECKOUT_DIR_NAME DEFAULT_REPOSITORY_ROOT
+
 # this should set the site_store_path variable if everything goes well.
 update_repo "$full_app_dir" "$CHECKOUT_DIR_NAME" "$DEFAULT_REPOSITORY_ROOT" "$repo_name"
 test_or_die "Updating the repository storage directory"
@@ -96,5 +107,15 @@ create_site_links "$site_store_path" "$theme_name"
 
 sep
 
+#if [ ! -z "$user_name" ]; then
+#  echo "Chowning the apps folder to be owned by: $user_name"
+##hmmm: have to hope for now for standard group named after user 
+#  chown -R "$user_name:$user_name" "$BASE_APPLICATION_PATH"
+#  test_or_die "Chowning $BASE_APPLICATION_PATH to be owned by $user_name"
+#fi
+
+sep
+
+
 echo "Finished powering up the site in '${app_dirname}'."
 
diff --git a/scripts/site_avenger/revamp_cakelampvm.sh b/scripts/site_avenger/revamp_cakelampvm.sh
new file mode 100644 (file)
index 0000000..ea31020
--- /dev/null
@@ -0,0 +1,152 @@
+#!/bin/bash
+
+# fixes the cakelampvm permissions according to the way.
+
+##############
+
+if [[ $EUID != 0 ]]; then
+  echo "This script must be run as root or sudo."
+  exit 1
+fi
+
+##############
+
+export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
+
+export NO_HELLO=right
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
+source "$FEISTY_MEOW_SCRIPTS/system/common_sysadmin.sh"
+
+##############
+
+echo "Regenerating feisty meow loading dock."
+
+reconfigure_feisty_meow
+test_or_die "feisty meow reconfiguration"
+
+##############
+
+echo "Making some important permission changes..."
+
+# fix up the main web storage.
+chown -R www-data:www-data /var/www 
+test_or_die "chown www-data"
+group_perm /var/www 
+test_or_die "group_perm www-data"
+
+##############
+
+# set up access on some important folders for the developer user.
+chown -R developer:developer /home/developer
+test_or_die "chown developer home"
+harsh_perm /home/developer/.ssh
+test_or_die "harsh_perm setting on developer .ssh"
+chown -R developer:developer /etc/apache2 /etc/bind 
+test_or_die "chown apache2 and bind to developer"
+group_perm /etc/apache2 /etc/bind 
+test_or_die "group perms on apache2 and bind"
+
+##############
+
+# fix perms for fred user.
+chown -R fred:fred /home/fred /home/archives/stuffing 
+test_or_die "chown fred home"
+group_perm $HOME/apps
+test_or_die "group perms on fred's apps"
+harsh_perm /home/fred/.ssh
+test_or_die "harsh_perm setting on fred .ssh"
+chown -R fred:fred /opt/feistymeow.org 
+test_or_die "chown feisty meow to fred"
+group_perm /opt/feistymeow.org 
+test_or_die "group perms on feisty meow"
+
+echo "Done with important permission changes."
+
+##############
+#
+# some slightly tricky bits start here.  we want to massage the vm into the
+# best possible shape without needing to re-release it.
+#
+##############
+
+echo "Updating developer welcome file."
+
+# only update hello if they've still got the file there.  we don't want to
+# keep forcing our hellos at people.
+if [ -f "$HOME/hello.txt" ]; then
+  # copy the most recent hello file into place for the user.
+  \cp -f "$FEISTY_MEOW_APEX/production/sites/cakelampvm.com/hello.txt" "$HOME"
+  test_or_continue "copying hello file for user"
+fi
+
+##############
+
+# install a better editor app.
+
+echo " The script is about to install the bluefish editor and some dependencies.
+If the app is not already installed, then this process takes only about a
+minute on a slower home DSL internet connection..."
+
+apt-get install -y bluefish &> "/tmp/install_bluefish-$(logname).log"
+test_or_continue "installing bluefish editor"
+
+##############
+
+# deploy any site updates here to the VM's cakelampvm.com site.
+#
+# we want to upgrade the default apache site to the latest, since the new
+# version mirrors the one on the internet (but with green checks instead
+# of red X's) and since we also support https on the new default version.
+# we can do this again later if needed, by upping the numbers on the apache
+# site config files.  our original site was 000 and the new version is 001,
+# which we've done as a prefix on the config for some reason.  makes the
+# code below easy at least.
+if [ -L /etc/apache2/sites-enabled/000-default.conf ]; then
+  # the old site is in place still, so let's update that.
+  echo "Updating default web sites to latest version."
+
+  a2enmod ssl
+  test_or_die "enabling SSL for secure websites"
+
+  restart_apache
+  test_or_die "getting SSL loaded in apache"
+
+  a2dissite 000-default
+  test_or_die "disabling old apache site"
+
+  rm -f /etc/apache2/sites-available/000-default.conf 
+  test_or_die "removing old apache site"
+
+  # copy in our new 000 version (which  
+  cp $FEISTY_MEOW_APEX/production/sites/cakelampvm.com/rolling/default_page.001/* \
+      /etc/apache2/sites-available
+  test_or_die "installing new apache default sites"
+
+  # there should only be ours at this version level and with that prefix.
+  a2ensite 001-*
+  test_or_die "enabling new apache default sites"
+
+  restart_apache
+fi
+
+##############
+
+##############
+
+# sequel--tell them they're great and show the hello again also.
+
+echo "
+
+
+"
+regenerate
+echo "
+
+
+Thanks for revamping your cakelampvm.  :-)
+"
+
+##############
+
+
index 580b896d9a634a7b9f193d03e85e3b4edefbec27..3f73b3a8f033a615bbad7c7d85ec436192b7f97f 100644 (file)
 
 source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
 
-# get our configuration loaded.
+# get our configuration loaded, if we know the config file.
+# if there is none, we will use our default version.
 export SITE_MANAGEMENT_CONFIG_FILE
 if [ -z "$SITE_MANAGEMENT_CONFIG_FILE" ]; then
   SITE_MANAGEMENT_CONFIG_FILE="$WORKDIR/config/default.app"
+  echo "Site management config file was not set.  Using default:"
+  echo "  $SITE_MANAGEMENT_CONFIG_FILE"
 fi
+
+# load in at least the default version to get us moving.
 source "$SITE_MANAGEMENT_CONFIG_FILE"
 test_or_die "loading site management configuration from: $SITE_MANAGEMENT_CONFIG_FILE"
 
@@ -33,6 +38,33 @@ function check_application_dir()
   fi
 }
 
+# tries to find an appropriate config file for the application.
+function locate_config_file()
+{
+  local app_dirname="$1"; shift
+
+  local configfile="$WORKDIR/config/${app_dirname}.app"
+  echo "config file?: $configfile"
+  if [ ! -f "$configfile" ]; then
+    # this is not a good config file.  we can't auto-guess the config.
+    echo -e "
+There is no specific site configuration file in:
+  $configfile
+We will continue onward using the default and hope that this project follows
+the standard pattern for cakephp projects."
+    # we'll pull in the default config file we set earlier; this will
+    # reinitialize some variables based on the app name.
+  else
+    # they gave us a valid config file.  let's try using it.
+    export SITE_MANAGEMENT_CONFIG_FILE="$configfile"
+  fi
+
+  # try to load the config.
+  source "$SITE_MANAGEMENT_CONFIG_FILE"
+  test_or_die "loading site management configuration from: $SITE_MANAGEMENT_CONFIG_FILE"
+
+}
+
 # this function will seek out top-level directories in the target directory passed in.
 # if there is only one directory, then it is returned (in the app_dirname variable).
 # otherwise, the user is asked which directory to use.
@@ -98,6 +130,8 @@ function test_app_folder()
     mkdir "$combo"
     test_or_die "Making application directory when not already present"
   fi
+
+  locate_config_file "$dir"
 }
 
 # eases some permissions to enable apache to write log files and do other shopkeeping.
@@ -145,6 +179,9 @@ function update_repo()
   local repo_root="$1"; shift
   local repo_name="$1"; shift
 
+echo here are parms in update repo:
+var full_app_dir checkout_dirname repo_root repo_name
+
   # forget any prior value, since we are going to validate the path.
   unset site_store_path
 
index 79156ea2ac76bb02e1ea1c28e2c0748321a4d552..1336a891917b6871f3bb6f3150311203dcf597af 100644 (file)
@@ -19,18 +19,18 @@ source "$WORKDIR/shared_site_mgr.sh"
 
 sep
 
-check_application_dir "$APPLICATION_DIR"
+check_application_dir "$BASE_APPLICATION_PATH"
 
 # find proper webroot where the site will be initialized.
 if [ -z "$app_dirname" ]; then
   # no dir was passed, so guess it.
-  find_app_folder "$APPLICATION_DIR"
+  find_app_folder "$BASE_APPLICATION_PATH"
 else
-  test_app_folder "$APPLICATION_DIR" "$app_dirname"
+  test_app_folder "$BASE_APPLICATION_PATH" "$app_dirname"
 fi
 
 # where we expect to find our checkout folder underneath.
-full_app_dir="$APPLICATION_DIR/$app_dirname"
+full_app_dir="$BASE_APPLICATION_PATH/$app_dirname"
 
 # use our default values for the repository and theme if they're not provided.
 if [ -z "$repo_name" ]; then
index a63744be2ee02355999c770401ca0c74a3932ded..282d0cdc060f93a7d25746a89f32f43b12c078c6 100644 (file)
@@ -19,18 +19,18 @@ source "$WORKDIR/shared_site_mgr.sh"
 
 sep
 
-check_application_dir "$APPLICATION_DIR"
+check_application_dir "$BASE_APPLICATION_PATH"
 
 # find proper webroot where the site will be initialized.
 if [ -z "$app_dirname" ]; then
   # no dir was passed, so guess it.
-  find_app_folder "$APPLICATION_DIR"
+  find_app_folder "$BASE_APPLICATION_PATH"
 else
-  test_app_folder "$APPLICATION_DIR" "$app_dirname"
+  test_app_folder "$BASE_APPLICATION_PATH" "$app_dirname"
 fi
 
 # where we expect to find our checkout folder underneath.
-full_app_dir="$APPLICATION_DIR/$app_dirname"
+full_app_dir="$BASE_APPLICATION_PATH/$app_dirname"
 
 # use our default values for the repository and theme if they're not provided.
 if [ -z "$repo_name" ]; then
index 762bd1ef6e8ba20e26e171fa99f7c6757fecbb66..c31a33d8390e0e11487dec439146a08e780d3cdb 100644 (file)
@@ -7,6 +7,9 @@
 # is much more powerful if the site is based on cakephp and site avenger.
 
 export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
+
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
 
 ############################
 
@@ -16,6 +19,13 @@ function print_instructions()
   echo "$(basename $0 .sh) {app name}"
   echo
   echo "
+$(basename $0 .sh) will completely set up a web site, including a domain
+name and an apache configuration file.  The site will be acquired from a
+git repository and configured.  At the end of this script, the result should 
+be an almost working website; you may need to fix the site configuration,
+create databases and so forth.
+
+This script must be run as sudo or root; it makes changes to system files.
 app name: The app name parameter is mandatory.  The configuration file for
 this script will be derived from the app name (e.g. if the app name is MyApp,
 then the config file will be 'MyApp.config').  The config files are by
@@ -31,99 +41,53 @@ overridden by setting the SITE_MANAGEMENT_CONFIG_FILE environment variable."
 # check for parameters.
 app_dirname="$1"; shift
 
-if [ -z "$app_dirname" ]; then
-  print_instructions
-fi
-
-source "$WORKDIR/shared_site_mgr.sh"
-
 if [ "$app_dirname" == "-help" -o "$app_dirname" == "--help" ]; then
   print_instructions
+elif [ -z "$app_dirname" ]; then
+  print_instructions
 fi
 
-sep
-
-check_application_dir "$APPLICATION_DIR"
-
-add_domain "$DOMAIN_NAME"
-test_or_die "Setting up domain: $DOMAIN_NAME"
-
-add_apache_site "$APPLICATION_NAME" "$DOMAIN_NAME"
-test_or_die "Setting up apache site for: $APPLICATION_NAME"
-
-powerup "$APPLICATION_NAME" "$REPO_NAME" "$THEME_NAME"
-
-
-
+# force the sudo at the start of the script, rather than waiting halfway
+# through to ask for access.
+sudo bash -c 'echo sudo permissions acquired.'
 
+source "$WORKDIR/shared_site_mgr.sh"
 
 sep
 
-echo "
-Finished standing up the full domain and site in:
-${app_dirname}"
-
-#leave before old crud below
-exit 0
-
-
+check_application_dir "$BASE_APPLICATION_PATH"
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#below is probably not needed.
 # find proper webroot where the site will be initialized.
 if [ -z "$app_dirname" ]; then
   # no dir was passed, so guess it.
-  find_app_folder "$APPLICATION_DIR"
+  find_app_folder "$BASE_APPLICATION_PATH"
 else
-  test_app_folder "$APPLICATION_DIR" "$app_dirname"
+  test_app_folder "$BASE_APPLICATION_PATH" "$app_dirname"
 fi
 
-# where we expect to find our checkout folder underneath.
-full_app_dir="$APPLICATION_DIR/$app_dirname"
+#echo "!! domain being added is: $DOMAIN_NAME"
 
-# use our default values for the repository and theme if they're not provided.
-if [ -z "$repo_name" ]; then
-  repo_name="$app_dirname"
-fi
-if [ -z "$theme_name" ]; then
-  theme_name="$(capitalize_first_char ${app_dirname})"
-fi
+sudo bash "$FEISTY_MEOW_SCRIPTS/system/add_domain.sh" "$DOMAIN_NAME"
+test_or_die "Setting up domain: $DOMAIN_NAME"
 
-echo "Repository: $repo_name"
-echo "Theme name: $theme_name"
 sep
 
-# this should set the site_store_path variable if everything goes well.
-update_repo "$full_app_dir" "$CHECKOUT_DIR_NAME" "$DEFAULT_REPOSITORY_ROOT" "$repo_name"
-test_or_die "Updating the repository storage directory"
+sudo bash "$FEISTY_MEOW_SCRIPTS/system/add_apache_site.sh" "$APPLICATION_NAME" "$DOMAIN_NAME"
+test_or_die "Setting up apache site for: $APPLICATION_NAME"
 
-# update the site to load dependencies.
 sep
-composer_repuff "$site_store_path"
-test_or_die "Installing site dependencies with composer"
 
-# set up the symbolic links needed to achieve siteliness.
-sep
+#echo about to do powerup with: app="$APPLICATION_NAME" repo="$REPO_NAME" theme="$THEME_NAME"
+#echo default repo is "$DEFAULT_REPOSITORY_ROOT" 
 
-create_site_links "$site_store_path" "$theme_name"
+powerup "$APPLICATION_NAME" "$REPO_NAME" "$THEME_NAME"
+# pass the real user name who should own the files.
+# "$(logname)"
 
 sep
 
-echo "Finished powering up the site in '${app_dirname}'."
+echo "
+Finished standing up the full domain and site for: ${app_dirname}
+The domain name is: $DOMAIN_NAME
+"
 
index b72aa8e0fff5a5e5d1ed7a356262de225604dbb1..3e194083baa03488ab4705dd7edd9b30619b82a0 100644 (file)
@@ -1,12 +1,78 @@
 #!/bin/bash
 
-echo "sorry--this script is not implemented yet."
+# this performs the inverse operation of standup, by relying on the
+# remove_domain and remove_apache_site scripts.
+#
+# Author: Chris Koeritz
 
+export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
 
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
 
-# need the inverse of add_domain and add_apache_site.
-# can use the same machinery as standup, just need to invoke these two new removal methods.
+############################
 
-# the decommissioning of the app is a question though.  we don't want to delete it, i'm pretty sure.
-# so how about that part is to do nothing?
+function print_instructions()
+{
+  echo
+  echo "$(basename $0 .sh) {app name}"
+  echo
+  echo "
+$(basename $0 .sh) will drop a web site out of apache server and out of the
+DNS server, as if it never existed.  The site storage is left untouched; we
+don't know what valuable assets lurk there.
+This script must be run as sudo or root; it makes changes to system files.
+"
+  exit 0
+}
+
+############################
+
+# main body of script.
+
+# check for parameters.
+app_dirname="$1"; shift
+
+if [ "$app_dirname" == "-help" -o "$app_dirname" == "--help" ]; then
+  print_instructions
+elif [ -z "$app_dirname" ]; then
+  print_instructions
+fi
+
+# force the sudo at the start of the script, rather than waiting halfway
+# through to ask for access.
+sudo bash -c 'echo sudo permissions acquired.'
+
+source "$WORKDIR/shared_site_mgr.sh"
+
+sep
+
+check_application_dir "$BASE_APPLICATION_PATH"
+
+# find proper webroot where the site will be initialized.
+if [ -z "$app_dirname" ]; then
+  # no dir was passed, so guess it.
+  find_app_folder "$BASE_APPLICATION_PATH"
+else
+  test_app_folder "$BASE_APPLICATION_PATH" "$app_dirname"
+fi
+
+sep
+
+sudo bash "$FEISTY_MEOW_SCRIPTS/system/remove_apache_site.sh" "$DOMAIN_NAME"
+test_or_die "dropping apache site for: $DOMAIN_NAME"
+
+sep
+
+#echo "!! domain being removed is: $DOMAIN_NAME"
+
+sudo bash "$FEISTY_MEOW_SCRIPTS/system/remove_domain.sh" "$DOMAIN_NAME"
+test_or_die "dropping domain: $DOMAIN_NAME"
+
+sep
+
+echo "
+Finished tearing down the domain name and apache site for:
+  $DOMAIN_NAME
+"
 
index e99f371a1dec349de0c82cb79635c132d2044c42..778b22d57d69733837dd271125e25a1d6c87bf96 100644 (file)
 
 # auto-find the scripts, since we might want to run this as sudo.
 export WORKDIR="$( \cd "$(\dirname "$0")" && /bin/pwd )"  # obtain the script's working directory.
-source "$WORKDIR/../core/launch_feisty_meow.sh"
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
 
-# some convenient defaults for our current usage.
-
-BASE_PATH="$HOME/apps"
-STORAGE_SUFFIX="/public"
-
-# this function writes out the new configuration file for the site.
-function write_apache_config()
-{
-  local appname="$1"; shift
-  local sitename="$1"; shift
-  local site_path="$1"; shift
-
-  local site_config="/etc/apache2/sites-available/${sitename}.conf"
-
-  # check if config file already exists and bail if so.
-  if [ -f "$site_config" ]; then
-    echo "The apache configuration file already exists at:"
-    echo "  $site_config"
-    echo "Please remove this file before proceeding, if it is junk.  For example:"
-    echo "  sudo rm $site_config"
-    exit 1
-  fi
-
-  echo "Creating a new apache2 site for $sitename with config file:"
-  echo "  $site_config"
-
-  # if no path, then we default to our standard app storage location.  otherwise, we
-  # put the site where they told us to.
-  if [ -z "$site_path" ]; then
-    # path where site gets checked out, in some arcane manner, and which happens to be
-    # above the path where we put webroot (in the storage suffix, if defined).
-    local path_above="${BASE_PATH}/${appname}"
-    # no slash between appname and suffix, in case suffix is empty.
-    local full_path="${path_above}${STORAGE_SUFFIX}"
-#echo really full path is $full_path
-  else
-    # we'll go with their specification for the site storage.
-    local full_path="$site_path"
-  fi
-
-  echo "
-# set up the user's web folder as an apache user web directory.
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
+source "$FEISTY_MEOW_SCRIPTS/system/common_sysadmin.sh"
 
-# set permissions on the actual app folder.
-<Directory \"$full_path\">
-  Options +ExecCGI +Indexes +FollowSymLinks +Includes +MultiViews 
-  Require all granted
-</Directory>
-
-<VirtualHost *:80>
-    ServerName ${sitename}
-    DocumentRoot ${full_path}
-    ErrorLog \${APACHE_LOG_DIR}/${sitename}-error.log
-    CustomLog \${APACHE_LOG_DIR}/${sitename}-access.log combined
-    Include /etc/apache2/conf-library/basic-options.conf
-    Include /etc/apache2/conf-library/rewrite-enabling.conf
-</VirtualHost>
-" >"$site_config" 
-}
-
-# turns on the config file we create above for apache.
-function enable_site()
-{
-  local sitename="$1"; shift
-  local site_config="/etc/apache2/sites-available/${sitename}.conf"
-
-  outfile="$TMP/apacheout.$RANDOM"
-  a2ensite "$(basename $site_config)" &>$outfile
-  if [ $? -ne 0 ]; then
-    # an error happened, so we show the command's output at least.
-    cat $outfile
-    echo
-    echo "There was a problem enabling the apache config file in:"
-    echo "  $site_config"
-    echo "Please consult the apache error logs for more details."
-    exit 1
-  fi
-  \rm "$outfile"
-}
-
-# restarts the apache2 service.
-function restart_apache()
-{
-  service apache2 restart
-  if [ $? -ne 0 ]; then
-    echo "There was a problem restarting the apache2 service."
-    echo "Please consult the apache error logs for more details."
-    exit 1
-  fi
-}
-
-# sets up the serverpilot storage location for a user hosted web site.
-function maybe_create_site_storage()
-{
-  local our_app="$1"; shift
-  # make sure the base path for storage of all the apps for this user exists.
-  local full_path="$BASE_PATH/$our_app"
-  if [ ! -d "$full_path" ]; then
-    mkdir -p $full_path
-    test_or_die "The app storage path could not be created.\n  Path in question is: $full_path"
-  fi
+# some convenient defaults for our current usage.
 
-  # now give the web server some access to the folder.  this is crucial since the folders
-  # can be hosted in any user folder, and the group permissions will not necessarily be correct already.
-  local chow_path="$full_path"
-  # only the first chmod is recursive; the rest just apply to the specific folder of interest.
-  chmod -R g+rx "$chow_path"
-  # walk backwards up the path and fix perms.
-  while [[ $chow_path != $HOME ]]; do
-echo chow path is now $chow_path
-    chmod g+rx "$chow_path"
-    test_or_die "Failed to add group permissions on the path: $chow_path"
-    # reassert the user's ownership of any directories we might have just created.
-    chown $(logname) "$chow_path"
-    test_or_die "changing ownership to user failed on the path: $chow_path"
-    chow_path="$(dirname "$chow_path")"
-  done
-}
+if [ -z "$BASE_APPLICATION_PATH" ]; then
+  BASE_APPLICATION_PATH="$HOME/apps"
+fi
+if [ -z "$STORAGE_SUFFIX" ]; then
+  STORAGE_SUFFIX="/public"
+fi
 
 # main body of script.
 
-if (( $EUID != 0 )); then
+if [[ $EUID != 0 ]]; then
   echo "This script must be run as root or sudo."
   exit 1
 fi
@@ -146,7 +39,7 @@ This script needs to know (1) the application name for the new site and
 appropriate name for a file-system compatible folder name.  There is an
 optional third parameter (3) the path for site storage.  If the site path
 is not provided, we'll use this path:
-  $BASE_PATH/{app name}/$STORAGE_SUFFIX"
+  $BASE_APPLICATION_PATH/{app name}$STORAGE_SUFFIX"
   exit 1
 fi
 
index 0dabaf2e7b4234392fe214883a4fdd6c3e07e94b..e12faa7be928ddaa8cba56bc9babc60ac2d5e040 100644 (file)
 #!/bin/bash
 
-# this set of functions serve the main purpose of adding new domains or subdomains to the bind9 DNS server on the current host.
-# it is currently highly specific to running a bunch of domains on a linux VM, where the VM has one IP address.
-# note that bind 'named' must already be configured.
-# also, it is assumed that if a subdomain is being added, then the containing domain has already been configured and is 
-# configured in a file similar to "blah.com.conf" in /etc/bind.
+# this set of functions serve the main purpose of adding new domains or
+# subdomains to the bind9 DNS server on the current host.  it is currently
+# highly specific to running a bunch of domains on a linux VM, where the VM
+# has one IP address.  note that the bind 'named' must already be configured.
+# also, it is assumed that, if a subdomain is being added, then the containing
+# domain has already been configured and is configured in a file similar to
+# "blah.com.conf" in /etc/bind.
 #
 # Author: Chris Koeritz
 
-# some defaults that are convenient for current purposes.
-# hmmm: these would need to be parameterized somehow for this script to become really general.
-
-# in our scheme, the single IP address that all our domains map to.
-IP_ADDRESS="10.28.42.20"
-# the email address (where first dot is replaced by @) for the administrator of the domain.
-SERVER_ADMIN="fred.cakelampvm.com"
-# the name of the name server for the new domains (should already be configured).
-MAIN_NAME_SERVER="ns.cakelampvm.com"
-# the name of the mail server for a new domain (should already be configured).
-MAIL_SERVER="mail.cakelampvm.com"
-# the distribution name to be listed in info for the new domain or subdomain.
-DISTRO="ubuntu"
-
-# creates a totally new domain config file for DNS.
-function write_new_domain_file()
-{
-  local domain_name="$1"; shift
-
-  local domain_file="/etc/bind/${domain_name}.conf"
-
-  echo "adding a totally new domain called $domain_name"
-  echo "using the config file: $domain_file"
-
-  if [ -f $domain_file ]; then
-    echo "The domain configuration file already exists at:"
-    echo "  $domain_file"
-    echo "Please remove this file before proceeding, if it is junk.  For example:"
-    echo "  sudo rm $domain_file"
-    exit 1
-  fi
-
-  echo "
-\$TTL 1W
-@      IN SOA  @       ${SERVER_ADMIN}. (
-               2017100801 ; serial
-               2H ; refresh
-               8M ; retry
-               14D ; expiry
-               6H ) ; minimum
-
-       IN NS           ${MAIN_NAME_SERVER}.
-       IN MX   10      ${MAIL_SERVER}.
-
-${domain_name}.        IN A    ${IP_ADDRESS}
-       IN HINFO        \"linux server\" \"${DISTRO}\"
-" >"$domain_file"
-}
-
-# hooks up a new config file into bind's list of zones.
-function add_zone_for_new_domain()
-{
-  local domain_name="$1"; shift
-
-  local domain_file="/etc/bind/${domain_name}.conf"
-
-  echo "adding a new domain configured by ${domain_file} into"
-  echo "the named.conf.local configuration file."
-
-  # append the reference to the new conf file in the zone list.
-  echo "
-zone \"${domain_name}\" in {
-       file \"${domain_file}\";
-       type master;
-       allow-query { any; };
-};
+export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
 
-////////////////////////////////////////////////////////////////////////////
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
+source "$FEISTY_MEOW_SCRIPTS/system/common_sysadmin.sh"
 
-" >> /etc/bind/named.conf.local
-}
-
-# adds a new subdomain under a containing domain.
-function add_new_subdomain()
-{
-  local new_domain="$1"; shift
-
-  # split up the full domain name into subdomain portion and containing domain.
-  local subdomain="${new_domain%.*.*}"
-  local containing_domain="${new_domain#*.}"
-
-  echo "adding a subdomain $subdomain to containing domain $containing_domain"
-
-  local domain_file="/etc/bind/${containing_domain}.conf"
-  # see if config file already exists; if not, complain.
-  if [ ! -f "$domain_file" ]; then
-    echo "The domain configuration file for $new_domain is missing."
-    echo "It should already be present in: $domain_file"
-    echo "Please add the containing domain before trying to add a subdomain."
-    exit 1
-  fi
-
-  # see if subdomain already present in config.
-  if [ $(grep -q "$new_domain" "$domain_file") ]; then
-    echo "The subdomain $subdomain already seems to exist in the domain"
-    echo "configuration file: $domain_file"
-    echo "Please edit the config file to remove the subdomain before trying"
-    echo "to re-add the subdomain."
-    exit 1
-  fi
-
-  # append the new subdomain into the config file.
-  echo "
-${subdomain}.${containing_domain}.    IN A    ${IP_ADDRESS}
-        IN HINFO \"linux server\" \"${DISTRO}\"
-" >> /etc/bind/${containing_domain}.conf
-
-}
+# some defaults that are convenient for current purposes.
+# existing values will be respected over our defaults.
 
-function restart_bind()
-{
-  echo restarting DNS server.
-  service bind9 restart
-  if [ $? -ne 0 ]; then
-    echo "The bind service did not restart properly.  Please check the error logs."
-    exit 1
-  fi
-  echo DNS server restarted.
-}
+if [ -z "$IP_ADDRESS" ]; then
+  # in our scheme, the single IP address that all our domains map to.
+  IP_ADDRESS="10.28.42.20"
+fi
+if [ -z "$SERVER_ADMIN" ]; then
+  # the email address (where first dot is replaced by @) for the administrator of the domain.
+  SERVER_ADMIN="developer.cakelampvm.com"
+fi
+if [ -z "$MAIN_NAME_SERVER" ]; then
+  # the name of the name server for the new domains (should already be configured).
+  MAIN_NAME_SERVER="ns.cakelampvm.com"
+fi
+if [ -z "$MAIL_SERVER" ]; then
+  # the name of the mail server for a new domain (should already be configured).
+  MAIL_SERVER="mail.cakelampvm.com"
+fi
+if [ -z "$DISTRO" ]; then
+  # the distribution name to be listed in info for the new domain or subdomain.
+  DISTRO="ubuntu"
+fi
 
 # main body of script.
 
-if (( $EUID != 0 )); then
+if [[ $EUID != 0 ]]; then
   echo "This script must be run as root or sudo."
   exit 1
 fi
diff --git a/scripts/system/common_sysadmin.sh b/scripts/system/common_sysadmin.sh
new file mode 100644 (file)
index 0000000..4ab80ed
--- /dev/null
@@ -0,0 +1,353 @@
+#!/bin/bash
+
+# this is a library of functions shared by scripts in the system folder.
+#
+# Author: Chris Koeritz
+
+############################################################################
+
+# bind9 methods...
+
+# removes a full domain from the DNS.
+function remove_domain_file()
+{
+  local domain_name="$1"; shift
+
+  local domain_file="/etc/bind/${domain_name}.conf"
+  if [ -f "$domain_file" ]; then
+    # don't destroy, just shuffle.
+    \mv -f "$domain_file" "/tmp/$(basename ${domain_file})-old-${RANDOM}"
+    test_or_die "removing domain file: $domain_file"
+  else
+    echo "Did not see a domain file to remove: $domain_file"
+  fi
+}
+
+# creates a totally new domain config file for DNS.
+function write_new_domain_file()
+{
+  local domain_name="$1"; shift
+
+  local domain_file="/etc/bind/${domain_name}.conf"
+
+  echo "adding a totally new domain called $domain_name"
+  echo "using the config file: $domain_file"
+
+  if [ -f $domain_file ]; then
+    echo
+    echo "The domain configuration file already exists at:"
+    echo "  $domain_file"
+    echo "Since we don't want to tear that down if it has specialized configuration"
+    echo "data in it, we will just leave it in place and consider our job done."
+    echo
+    exit 0
+  fi
+
+  echo "
+\$TTL 1W
+@      IN SOA  @       ${SERVER_ADMIN}. (
+               2017100801 ; serial
+               2H ; refresh
+               8M ; retry
+               14D ; expiry
+               6H ) ; minimum
+
+       IN NS           ${MAIN_NAME_SERVER}.
+       IN MX   10      ${MAIL_SERVER}.
+
+${domain_name}.        IN A    ${IP_ADDRESS}
+       IN HINFO        \"linux server\" \"${DISTRO}\"
+" >"$domain_file"
+
+  # our personalized configuration approach wants the real owner to own the file.
+  chown "$(logname):$(logname)" $domain_file
+  test_or_die "setting ownership on: $domain_file"
+}
+
+# takes a zone back out of the local conf file for bind
+function remove_zone_for_domain()
+{
+  local domain_name="$1"; shift
+
+  local domain_file="/etc/bind/${domain_name}.conf"
+
+  # eat the zone file definition.  this will botch up badly if more text was added
+  # or the zone info shrank.
+  create_chomped_copy_of_file "/etc/bind/named.conf.local" "zone.*${domain_name}" 6
+}
+
+# hooks up a new config file into bind's list of zones.
+function add_zone_for_new_domain()
+{
+  local domain_name="$1"; shift
+
+  local domain_file="/etc/bind/${domain_name}.conf"
+
+  echo "adding a new domain configured by ${domain_file} into"
+  echo "the named.conf.local configuration file."
+
+  # append the reference to the new conf file in the zone list.
+  echo "
+zone \"${domain_name}\" in {
+       file \"${domain_file}\";
+       type master;
+       allow-query { any; };
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+" >> /etc/bind/named.conf.local
+
+  # keep ownership for the real user.
+  chown "$(logname):$(logname)" /etc/bind/named.conf.local
+  test_or_die "setting ownership on: /etc/bind/named.conf.local"
+}
+
+# zaps a subdomain out of the containing domain file.
+function remove_subdomain()
+{
+  local old_domain="$1"; shift
+
+  # split up the full domain name into subdomain portion and containing domain.
+  local subdomain="${old_domain%.*.*}"
+  local containing_domain="${old_domain#*.}"
+
+  echo "removing subdomain $subdomain from containing domain $containing_domain"
+
+  local domain_file="/etc/bind/${containing_domain}.conf"
+  # see if config file already exists; if not, complain.
+  if [ ! -f "$domain_file" ]; then
+    echo "The domain configuration file for $old_domain is missing."
+    echo "It should already be present in: $domain_file"
+    echo "We cannot remove a subdomain if the containing domain isn't there."
+    exit 1
+  fi
+
+  # see if subdomain already present in config.
+  if ! grep -q "$old_domain" "$domain_file"; then
+    echo "The subdomain $subdomain is already missing from the domain"
+    echo "configuration file: $domain_file"
+    echo "Our work is apparently done for removing it."
+    return 0
+  fi
+
+  create_chomped_copy_of_file "$domain_file" "${old_domain}" 2
+}
+
+# adds a new subdomain under a containing domain.
+function add_new_subdomain()
+{
+  local new_domain="$1"; shift
+
+  # split up the full domain name into subdomain portion and containing domain.
+  local subdomain="${new_domain%.*.*}"
+  local containing_domain="${new_domain#*.}"
+
+  echo "adding a subdomain $subdomain to containing domain $containing_domain"
+
+  local domain_file="/etc/bind/${containing_domain}.conf"
+  # see if config file already exists; if not, complain.
+  if [ ! -f "$domain_file" ]; then
+    echo "The domain configuration file for $new_domain is missing."
+    echo "It should already be present in: $domain_file"
+    echo "Please add the containing domain before trying to add a subdomain."
+    exit 1
+  fi
+
+  # see if subdomain already present in config.
+  if grep -q "$new_domain" "$domain_file"; then
+    echo "The subdomain $subdomain already seems to exist in the domain"
+    echo "configuration file: $domain_file"
+    echo "We are considering our work done; if you want to modify the subdomain,"
+    echo "then please call remove_domain on it first."
+    return 0
+  fi
+
+  # append the new subdomain into the config file.
+  echo "${subdomain}.${containing_domain}.    IN A    ${IP_ADDRESS}
+        IN HINFO \"linux server\" \"${DISTRO}\"
+" >> /etc/bind/${containing_domain}.conf
+
+  # keep ownership for real user.
+  chown "$(logname):$(logname)" "/etc/bind/${containing_domain}.conf"
+  test_or_die "setting ownership on: /etc/bind/${containing_domain}.conf"
+}
+
+function restart_bind()
+{
+  echo restarting DNS server.
+  service bind9 restart
+  if [ $? -ne 0 ]; then
+    echo "The bind service did not restart properly.  Please check the error logs."
+    exit 1
+  fi
+  echo DNS service restarted.
+}
+
+############################################################################
+
+# apache2 methods...
+
+# removes a config file for apache given the app name and site name.
+function remove_apache_config()
+{
+  local sitename="$1"; shift
+
+  local site_config="/etc/apache2/sites-available/${sitename}.conf"
+
+  if [ -f "$site_config" ]; then
+    # don't destroy, just shuffle.
+    \mv -f "$site_config" "/tmp/$(basename ${site_config})-old-${RANDOM}"
+    test_or_die "removing site config: $site_config"
+  else
+    echo "Did not see a site config to remove: $site_config"
+  fi
+}
+
+# this function writes out the new configuration file for the site.
+function write_apache_config()
+{
+  local appname="$1"; shift
+  local sitename="$1"; shift
+  local site_path="$1"; shift
+
+  local site_config="/etc/apache2/sites-available/${sitename}.conf"
+
+  # check if config file already exists and bail if so.
+  if [ -f "$site_config" ]; then
+    echo "The apache configuration file already exists at:"
+    echo "  $site_config"
+    echo "Since apache configuration files can get very complex, we do not want to"
+    echo "assume that this file is removable.  Calling the site addition done."
+    exit 0
+  fi
+
+  echo "Creating a new apache2 site for $sitename with config file:"
+  echo "  $site_config"
+
+  # if no path, then we default to our standard app storage location.  otherwise, we
+  # put the site where they told us to.
+  if [ -z "$site_path" ]; then
+    # path where site gets checked out, in some arcane manner, and which happens to be
+    # above the path where we put webroot (in the storage suffix, if defined).
+    local path_above="${BASE_APPLICATION_PATH}/${appname}"
+    # no slash between appname and suffix, in case suffix is empty.
+    local full_path="${path_above}${STORAGE_SUFFIX}"
+#echo really full path is $full_path
+  else
+    # we'll go with their specification for the site storage.
+    local full_path="$site_path"
+  fi
+
+  echo "
+# set up the user's web folder as an apache user web directory.
+
+# set permissions on the actual app folder.
+<Directory \"$full_path\">
+  Options +ExecCGI +Indexes +FollowSymLinks +Includes +MultiViews 
+  Require all granted
+</Directory>
+
+<VirtualHost *:80>
+    ServerName ${sitename}
+    DocumentRoot ${full_path}
+    ErrorLog \${APACHE_LOG_DIR}/${sitename}-error.log
+    CustomLog \${APACHE_LOG_DIR}/${sitename}-access.log combined
+    Include /etc/apache2/conf-library/basic-options.conf
+    Include /etc/apache2/conf-library/rewrite-enabling.conf
+</VirtualHost>
+" >"$site_config" 
+
+  chown "$(logname):$(logname)" "$site_config"
+  test_or_die "setting ownership on: $site_config"
+}
+
+# stops apache from serving up the site.
+function disable_site()
+{
+  local sitename="$1"; shift
+  local site_config="/etc/apache2/sites-available/${sitename}.conf"
+
+  if [ ! -f "$site_config" ]; then
+    echo "The site config did not exist and could not be disabled: $site_config"
+    return 0
+  fi
+
+#hmmm: repeated pattern of hidden output file, very useful.  abstract it...
+  local outfile="$TMP/apacheout.$RANDOM"
+  a2dissite "$(basename $site_config)" &>$outfile
+  if [ $? -ne 0 ]; then
+    # an error happened, so we show the command's output at least.
+    cat $outfile
+    echo
+    echo "There was a problem disabling the apache config file in:"
+    echo "  $site_config"
+    echo "Please consult the apache error logs for more details."
+    exit 1
+  fi
+  \rm "$outfile"
+}
+
+# turns on the config file we create above for apache.
+function enable_site()
+{
+  local sitename="$1"; shift
+  local site_config="/etc/apache2/sites-available/${sitename}.conf"
+
+  local outfile="$TMP/apacheout.$RANDOM"
+  a2ensite "$(basename $site_config)" &>$outfile
+  if [ $? -ne 0 ]; then
+    # an error happened, so we show the command's output at least.
+    cat $outfile
+    echo
+    echo "There was a problem enabling the apache config file in:"
+    echo "  $site_config"
+    echo "Please consult the apache error logs for more details."
+    exit 1
+  fi
+  \rm "$outfile"
+}
+
+# restarts the apache2 service.
+function restart_apache()
+{
+  service apache2 restart
+  if [ $? -ne 0 ]; then
+    echo "There was a problem restarting the apache2 service."
+    echo "Please consult the apache error logs for more details."
+    exit 1
+  fi
+  echo Apache2 service restarted.
+}
+
+# sets up the serverpilot storage location for a user hosted web site.
+function maybe_create_site_storage()
+{
+  local our_app="$1"; shift
+  # make sure the path for storage this app exists for the user.
+  local full_path="$BASE_APPLICATION_PATH/$our_app"
+  if [ ! -d "$full_path" ]; then
+    mkdir -p $full_path
+    test_or_die "The app storage path could not be created.\n  Path in question is: $full_path"
+  fi
+
+  # now give the web server some access to the folder.  this is crucial since the folders
+  # can be hosted in any user folder, and the group permissions will not necessarily be correct already.
+  local chow_path="$full_path"
+  # only the first chmod is recursive; the rest just apply to the specific folder of interest.
+  chmod -R g+rx "$chow_path"
+  # walk backwards up the path and fix perms.
+  while [[ $chow_path != $HOME ]]; do
+#echo chow path is now $chow_path
+    chmod g+rx "$chow_path"
+    test_or_die "Failed to add group permissions on the path: $chow_path"
+    # reassert the user's ownership of any directories we might have just created.
+    chown $(logname) "$chow_path"
+    test_or_die "changing ownership to user failed on the path: $chow_path"
+    chow_path="$(dirname "$chow_path")"
+  done
+}
+
+############################################################################
+
+
diff --git a/scripts/system/remove_apache_site.sh b/scripts/system/remove_apache_site.sh
new file mode 100644 (file)
index 0000000..ef6c8b6
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# uninstalls the apache website for a specified domain.
+
+# auto-find the scripts, since we might want to run this as sudo.
+export WORKDIR="$( \cd "$(\dirname "$0")" && /bin/pwd )"  # obtain the script's working directory.
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
+
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
+source "$FEISTY_MEOW_SCRIPTS/system/common_sysadmin.sh"
+
+# some convenient defaults for our current usage.
+
+if [ -z "$BASE_APPLICATION_PATH" ]; then
+  BASE_APPLICATION_PATH="$HOME/apps"
+fi
+if [ -z "$STORAGE_SUFFIX" ]; then
+  STORAGE_SUFFIX="/public"
+fi
+
+# main body of script.
+
+if [[ $EUID != 0 ]]; then
+  echo "This script must be run as root or sudo."
+  exit 1
+fi
+
+site="$1"; shift
+
+if [ -z "$site" ]; then
+#hmmm: move to a print_instructions function.
+  echo "
+$(basename $0): {dns name} 
+
+This script needs to know (1) the DNS name for the apache virtual host.
+The script will uninstall that site's configuration files for apache2.
+"
+  exit 1
+fi
+
+disable_site "$site"
+remove_apache_config "$site"
+restart_apache
+
diff --git a/scripts/system/remove_domain.sh b/scripts/system/remove_domain.sh
new file mode 100644 (file)
index 0000000..f734878
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+# performs the inverse function of add_domain by deconfiguring a domain
+# in bind.  the domain needs to have been set up by add_domain, or this will
+# not succeed.
+#
+# Author: Chris Koeritz
+
+export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
+export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
+
+source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
+source "$FEISTY_MEOW_SCRIPTS/system/common_sysadmin.sh"
+
+# some defaults that are convenient for current purposes.
+# existing values will be respected over our defaults.
+
+#if [ -z "$IP_ADDRESS" ]; then
+#  # in our scheme, the single IP address that all our domains map to.
+#  IP_ADDRESS="10.28.42.20"
+#fi
+#if [ -z "$SERVER_ADMIN" ]; then
+#  # the email address (where first dot is replaced by @) for the administrator of the domain.
+#  SERVER_ADMIN="developer.cakelampvm.com"
+#fi
+#if [ -z "$MAIN_NAME_SERVER" ]; then
+#  # the name of the name server for the new domains (should already be configured).
+#  MAIN_NAME_SERVER="ns.cakelampvm.com"
+#fi
+#if [ -z "$MAIL_SERVER" ]; then
+#  # the name of the mail server for a new domain (should already be configured).
+#  MAIL_SERVER="mail.cakelampvm.com"
+#fi
+#if [ -z "$DISTRO" ]; then
+#  # the distribution name to be listed in info for the new domain or subdomain.
+#  DISTRO="ubuntu"
+#fi
+
+# main body of script.
+
+if [[ $EUID != 0 ]]; then
+  echo "This script must be run as root or sudo."
+  exit 1
+fi
+
+old_domain="$1"; shift
+
+if [ -z "$old_domain" ]; then
+  echo "This script needs a domain name to remove from DNS." 
+  exit 1
+fi
+
+# if domain name has three or more components, then remove a subdomain.
+# otherwise, remove a full domain.
+if [[ $old_domain == *"."*"."* ]]; then
+  # remove a subdomain from the containing domain.
+  remove_subdomain "$old_domain"
+  restart_bind
+else
+  # remove the full domain in DNS.
+  remove_domain_file "$old_domain"
+  remove_zone_for_domain "$old_domain"
+  restart_bind
+fi
+
+
index 42448571b287ca0754373dece69cd224d7ebe274..3ee02f4b392f67f8778294f578ea30d0801b235a 100644 (file)
@@ -4,4 +4,3 @@ echo "<br>"
 echo "--<br>"
 $FEISTY_MEOW_BINARIES/nechung
 
-
index 8bc6ccd36d3c31b1145b3df0c1c401d58414beba..0203b9ae7fd771bbacbc80b1c2d2319e34462e3f 100644 (file)
@@ -17,7 +17,8 @@ function apply_title_to_terminal()
     title="$(hostname)"
   fi
   
-  if [ "${TERM}" != "dumb" -a -z "$PBS_ENVIRONMENT" -a ! -z "$PS1" ]; then
+  if [ "${TERM}" != "dumb" -a -z "$PBS_ENVIRONMENT" -a \
+        ! -z "$PS1" -a "${TERM}" != "linux" ]; then
     echo -n -e "\033]0;${title}\007"
   else
     # not running interactively, so just echo the title.
@@ -31,28 +32,46 @@ function apply_title_to_terminal()
 function set_terminal_title()
 {
   apply_title_to_terminal $*
+
+#tricky tries to get it to be available when we ask for it in get_terminal_title
+  sync
+#  echo -n
+
+#  # we're enforcing a new title from here on.
+#  unset PRIOR_TERMINAL_TITLE
   save_terminal_title
 }
 
-# reads the current terminal title, if possible, and saves it to our record.
-function save_terminal_title()
+# echoes back the current title on the terminal window, if we can acquire it.
+function get_terminal_title()
 {
+  # this is an important value now; it is checked for in save_terminal_title.
+  local term_title_found="unknown"
   # save the former terminal title if we're running in X with xterm.
   which xprop &>/dev/null
   if [ $? -eq 0 ]; then
     # make sure we're actually using xterm *and* that we have a window ID.
     if [[ "$TERM" =~ .*"xterm".* && ! -z "$WINDOWID" ]]; then
-      local prior_title="$(xprop -id $WINDOWID | perl -nle 'print $1 if /^WM_NAME.+= \"(.*)\"$/')"
-      if [ ! -z "$prior_title" ]; then
-        if [ ! -z "$DEBUG_TERM_TITLE" ]; then
-          echo "saving prior terminal title as '$prior_title'"
-        fi
-        export PRIOR_TERMINAL_TITLE="$prior_title"
-      else
-        if [ ! -z "$DEBUG_TERM_TITLE" ]; then
-          echo "not saving prior terminal title which was empty"
-        fi
-      fi
+      term_title_found="$(xprop -id $WINDOWID | perl -nle 'print $1 if /^WM_NAME.+= \"(.*)\"$/')"
+    fi
+  fi
+  echo -n "$term_title_found"
+}
+
+# reads the current terminal title, if possible, and saves it to our record.
+function save_terminal_title()
+{
+  local title="$(get_terminal_title)"
+  if [ "$title" != "unknown" ]; then
+    # there was a title, so save it.
+    if [ ! -z "$DEBUG_TERM_TITLE" ]; then
+      echo "saving prior terminal title as '$title'"
+    fi
+    export PRIOR_TERMINAL_TITLE="$title"
+  else
+    # the terminal had no title, or we couldn't access it, or there's no terminal.
+    if [ ! -z "$DEBUG_TERM_TITLE" ]; then
+      echo "not saving prior terminal title which was empty"
     fi
   fi
 }
@@ -83,7 +102,7 @@ function label_terminal_with_info()
     fi
     pruned_host=$(echo $HOSTNAME | sed -e 's/^\([^\.]*\)\..*$/\1/')
     date_string=$(date +"%Y %b %e @ %T")
-    user=$USER
+    user=$(logname)
     if [ -z "$user" ]; then
       # try snagging the windoze name.
       user=$USERNAME
index 9c98033fe7031b946f892ffe9f9ead4a995980fd..275bbde0bb51d77b7639dbda413290158d12f082 100644 (file)
@@ -54,4 +54,20 @@ if you need to jam a bunch of videos together, crossfade them, and that kind of
 then try openshot.  it also supports simple saving with different quality levels, which
 lets you drop a bunch of size at the expense of the picture.  sometimes needed.
 
+---------------------------
+music collection management
+---------------------------
+
+dupeguru:
+found this to be pretty helpful in finding my duplicate songs.  it is able to analyze
+when the files are the same, even if their names don't match.
+check: did it even compare by metadata?  not remembering currently.
+
+fdupes:
+another useful tool for finding duplicate tracks in a music collection, but relies on exact
+matches in the names(?).  was not so powerful as dupeguru, but still useful.
+
+
+
+