plugin-script.c

     
   1  //! @file plugin-script.c
   2  //! @author J. Marcel van der Veer
   3  
   4  //! @section Copyright
   5  //!
   6  //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
   7  //! Copyright 2001-2025 J. Marcel van der Veer [algol68g@xs4all.nl].
   8  
   9  //! @section License
  10  //!
  11  //! This program is free software; you can redistribute it and/or modify it 
  12  //! under the terms of the GNU General Public License as published by the 
  13  //! Free Software Foundation; either version 3 of the License, or 
  14  //! (at your option) any later version.
  15  //!
  16  //! This program is distributed in the hope that it will be useful, but 
  17  //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  //! more details. You should have received a copy of the GNU General Public 
  20  //! License along with this program. If not, see [http://www.gnu.org/licenses/].
  21  
  22  //! @section Synopsis
  23  //!
  24  //! Plugin script builder routines.
  25  
  26  #include "a68g.h"
  27  #include "a68g-prelude.h"
  28  #include "a68g-optimiser.h"
  29  #include "a68g-options.h"
  30  
  31  #if defined (BUILD_A68G_COMPILER)
  32  
  33  //! @brief Build shell script from program.
  34  
  35  void build_script (void)
  36  {
  37  #if !defined (BUILD_A68G_COMPILER)
  38    return;
  39  #endif
  40    BUFFER cmd;
  41    BUFCLR (cmd);
  42    announce_phase ("script builder");
  43    ABEND (OPTION_OPT_LEVEL (&A68G_JOB) == 0, ERROR_ACTION, __func__);
  44  // Flatten the source file.
  45    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SOURCE_NAME (&A68G_JOB)) >= 0);
  46    FILE_T source = open (cmd, O_WRONLY | O_CREAT | O_TRUNC, A68G_PROTECTION);
  47    ABEND (source == -1, ERROR_ACTION, cmd);
  48    for (LINE_T *sl = TOP_LINE (&A68G_JOB); sl != NO_LINE; FORWARD (sl)) {
  49      size_t len = strlen (STRING (sl));
  50      if (len == 0 || (STRING (sl))[len - 1] != NEWLINE_CHAR) {
  51        ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s\n%d\n%s\n", FILENAME (sl), NUMBER (sl), STRING (sl)) >= 0);
  52      } else {
  53        ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s\n%d\n%s", FILENAME (sl), NUMBER (sl), STRING (sl)) >= 0);
  54      }
  55      WRITE (source, cmd);
  56    }
  57    ASSERT (close (source) == 0);
  58  // Compress source and dynamic library.
  59    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "cp %s %s.%s", FILE_PLUGIN_NAME (&A68G_JOB), HIDDEN_TEMP_FILE_NAME, FILE_PLUGIN_NAME (&A68G_JOB)) >= 0);
  60    int ret = system (cmd);
  61    ABEND (ret != 0, ERROR_ACTION, cmd);
  62    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "tar czf %s.%s.tgz %s.%s %s.%s", HIDDEN_TEMP_FILE_NAME, FILE_GENERIC_NAME (&A68G_JOB), HIDDEN_TEMP_FILE_NAME, FILE_SOURCE_NAME (&A68G_JOB), HIDDEN_TEMP_FILE_NAME, FILE_PLUGIN_NAME (&A68G_JOB)) >= 0);
  63    ret = system (cmd);
  64    ABEND (ret != 0, ERROR_ACTION, cmd);
  65  // Compose script.
  66    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SCRIPT_NAME (&A68G_JOB)) >= 0);
  67    FILE_T script = open (cmd, O_WRONLY | O_CREAT | O_TRUNC, A68G_PROTECTION);
  68    ABEND (script == -1, ERROR_ACTION, cmd);
  69    char *strop = "";
  70    if (OPTION_STROPPING (&A68G_JOB) == QUOTE_STROPPING) {
  71      strop = "--run-quote-script";
  72    } else {
  73      strop = "--run-script";
  74    }
  75    ASSERT (a68g_bufprt (A68G (output_line), SNPRINTF_SIZE, "#! %s/a68g %s\n", BINDIR, strop) >= 0);
  76    WRITE (script, A68G (output_line));
  77    ASSERT (a68g_bufprt (A68G (output_line), SNPRINTF_SIZE, "%s\n%s --verify \"%s\"\n", FILE_GENERIC_NAME (&A68G_JOB), optimisation_option (), PACKAGE_STRING) >= 0);
  78    WRITE (script, A68G (output_line));
  79    ASSERT (close (script) == 0);
  80    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "cat %s.%s %s.%s.tgz > %s", HIDDEN_TEMP_FILE_NAME, FILE_SCRIPT_NAME (&A68G_JOB), HIDDEN_TEMP_FILE_NAME, FILE_GENERIC_NAME (&A68G_JOB), FILE_SCRIPT_NAME (&A68G_JOB)) >= 0);
  81    ret = system (cmd);
  82    ABEND (ret != 0, ERROR_ACTION, cmd);
  83    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s", FILE_SCRIPT_NAME (&A68G_JOB)) >= 0);
  84    ret = chmod (cmd, (__mode_t) (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH));  // -rwx-r-xr-x
  85    ABEND (ret != 0, ERROR_ACTION, cmd);
  86    ABEND (ret != 0, ERROR_ACTION, cmd);
  87  // Clean up.
  88    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s.%s.tgz", HIDDEN_TEMP_FILE_NAME, FILE_GENERIC_NAME (&A68G_JOB)) >= 0);
  89    ret = remove (cmd);
  90    ABEND (ret != 0, ERROR_ACTION, cmd);
  91    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SOURCE_NAME (&A68G_JOB)) >= 0);
  92    ret = remove (cmd);
  93    ABEND (ret != 0, ERROR_ACTION, cmd);
  94    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_PLUGIN_NAME (&A68G_JOB)) >= 0);
  95    ret = remove (cmd);
  96    ABEND (ret != 0, ERROR_ACTION, cmd);
  97    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SCRIPT_NAME (&A68G_JOB)) >= 0);
  98    ret = remove (cmd);
  99    ABEND (ret != 0, ERROR_ACTION, cmd);
 100  }
 101  
 102  //! @brief Load program from shell script .
 103  
 104  void load_script (void)
 105  {
 106  #if !defined (BUILD_A68G_COMPILER)
 107    return;
 108  #endif
 109    BUFFER cmd; char ch;
 110    BUFCLR (cmd);
 111    announce_phase ("script loader");
 112  // Decompress the archive.
 113    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "sed '1,3d' < %s | tar xzf -", FILE_INITIAL_NAME (&A68G_JOB)) >= 0);
 114    ABEND (system (cmd) != 0, ERROR_ACTION, cmd);
 115  // Reread the header.
 116    FILE_T script = open (FILE_INITIAL_NAME (&A68G_JOB), O_RDONLY);
 117    ABEND (script == -1, ERROR_ACTION, cmd);
 118  // Skip the #! a68g line.
 119    ASSERT (io_read (script, &ch, 1) == 1);
 120    while (ch != NEWLINE_CHAR) {
 121      ASSERT (io_read (script, &ch, 1) == 1);
 122    }
 123  // Read the generic filename.
 124    A68G (input_line)[0] = NULL_CHAR;
 125    int k = 0;
 126    ASSERT (io_read (script, &ch, 1) == 1);
 127    while (ch != NEWLINE_CHAR) {
 128      A68G (input_line)[k++] = ch;
 129      ASSERT (io_read (script, &ch, 1) == 1);
 130    }
 131    A68G (input_line)[k] = NULL_CHAR;
 132    ASSERT (a68g_bufprt (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, A68G (input_line)) >= 0);
 133    FILE_INITIAL_NAME (&A68G_JOB) = new_string (cmd, NO_TEXT);
 134  // Read options.
 135    A68G (input_line)[0] = NULL_CHAR;
 136    k = 0;
 137    ASSERT (io_read (script, &ch, 1) == 1);
 138    while (ch != NEWLINE_CHAR) {
 139      A68G (input_line)[k++] = ch;
 140      ASSERT (io_read (script, &ch, 1) == 1);
 141    }
 142    isolate_options (A68G (input_line), NO_LINE);
 143    (void) set_options (OPTION_LIST (&A68G_JOB), A68G_FALSE);
 144    ASSERT (close (script) == 0);
 145  }
 146  
 147  //! @brief Rewrite source for shell script .
 148  
 149  void rewrite_script_source (void)
 150  {
 151  // Rebuild the source file.
 152    ASSERT (remove (FILE_SOURCE_NAME (&A68G_JOB)) == 0);
 153    FILE_T source = open (FILE_SOURCE_NAME (&A68G_JOB), O_WRONLY | O_CREAT | O_TRUNC, A68G_PROTECTION);
 154    ABEND (source == -1, ERROR_ACTION, FILE_SOURCE_NAME (&A68G_JOB));
 155    for (LINE_T *ref_l = TOP_LINE (&A68G_JOB); ref_l != NO_LINE; FORWARD (ref_l)) {
 156      WRITE (source, STRING (ref_l));
 157      size_t len = strlen (STRING (ref_l));
 158      if (len == 0 || (STRING (ref_l))[len - 1] != NEWLINE_CHAR) {
 159        WRITE (source, NEWLINE_STRING);
 160      }
 161    }
 162  // Wrap it up.
 163    ASSERT (close (source) == 0);
 164  }
 165  
 166  #endif
     


© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)