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-2023 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-mp.h"
  29  #include "a68g-optimiser.h"
  30  #include "a68g-genie.h"
  31  #include "a68g-options.h"
  32  
  33  #if defined (BUILD_A68_COMPILER)
  34  
  35  //! @brief Build shell script from program.
  36  
  37  void build_script (void)
  38  {
  39    int ret;
  40    FILE_T script, source;
  41    LINE_T *sl;
  42    BUFFER cmd;
  43    char *strop;
  44  #if !defined (BUILD_A68_COMPILER)
  45    return;
  46  #endif
  47    announce_phase ("script builder");
  48    ABEND (OPTION_OPT_LEVEL (&A68_JOB) == 0, ERROR_ACTION, __func__);
  49  // Flatten the source file.
  50    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SOURCE_NAME (&A68_JOB)) >= 0);
  51    source = open (cmd, O_WRONLY | O_CREAT | O_TRUNC, A68_PROTECTION);
  52    ABEND (source == -1, ERROR_ACTION, cmd);
  53    for (sl = TOP_LINE (&A68_JOB); sl != NO_LINE; FORWARD (sl)) {
  54      if (strlen (STRING (sl)) == 0 || (STRING (sl))[strlen (STRING (sl)) - 1] != NEWLINE_CHAR) {
  55        ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s\n%d\n%s\n", FILENAME (sl), NUMBER (sl), STRING (sl)) >= 0);
  56      } else {
  57        ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s\n%d\n%s", FILENAME (sl), NUMBER (sl), STRING (sl)) >= 0);
  58      }
  59      WRITE (source, cmd);
  60    }
  61    ASSERT (close (source) == 0);
  62  // Compress source and dynamic library.
  63    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "cp %s %s.%s", FILE_PLUGIN_NAME (&A68_JOB), HIDDEN_TEMP_FILE_NAME, FILE_PLUGIN_NAME (&A68_JOB)) >= 0);
  64    ret = system (cmd);
  65    ABEND (ret != 0, ERROR_ACTION, cmd);
  66    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "tar czf %s.%s.tgz %s.%s %s.%s", HIDDEN_TEMP_FILE_NAME, FILE_GENERIC_NAME (&A68_JOB), HIDDEN_TEMP_FILE_NAME, FILE_SOURCE_NAME (&A68_JOB), HIDDEN_TEMP_FILE_NAME, FILE_PLUGIN_NAME (&A68_JOB)) >= 0);
  67    ret = system (cmd);
  68    ABEND (ret != 0, ERROR_ACTION, cmd);
  69  // Compose script.
  70    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SCRIPT_NAME (&A68_JOB)) >= 0);
  71    script = open (cmd, O_WRONLY | O_CREAT | O_TRUNC, A68_PROTECTION);
  72    ABEND (script == -1, ERROR_ACTION, cmd);
  73    strop = "";
  74    if (OPTION_STROPPING (&A68_JOB) == QUOTE_STROPPING) {
  75      strop = "--run-quote-script";
  76    } else {
  77      strop = "--run-script";
  78    }
  79    ASSERT (snprintf (A68 (output_line), SNPRINTF_SIZE, "#! %s/a68g %s\n", BINDIR, strop) >= 0);
  80    WRITE (script, A68 (output_line));
  81    ASSERT (snprintf (A68 (output_line), SNPRINTF_SIZE, "%s\n%s --verify \"%s\"\n", FILE_GENERIC_NAME (&A68_JOB), optimisation_option (), PACKAGE_STRING) >= 0);
  82    WRITE (script, A68 (output_line));
  83    ASSERT (close (script) == 0);
  84    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "cat %s.%s %s.%s.tgz > %s", HIDDEN_TEMP_FILE_NAME, FILE_SCRIPT_NAME (&A68_JOB), HIDDEN_TEMP_FILE_NAME, FILE_GENERIC_NAME (&A68_JOB), FILE_SCRIPT_NAME (&A68_JOB)) >= 0);
  85    ret = system (cmd);
  86    ABEND (ret != 0, ERROR_ACTION, cmd);
  87    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s", FILE_SCRIPT_NAME (&A68_JOB)) >= 0);
  88    ret = chmod (cmd, (__mode_t) (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH));  // -rwx-r-xr-x
  89    ABEND (ret != 0, ERROR_ACTION, cmd);
  90    ABEND (ret != 0, ERROR_ACTION, cmd);
  91  // Clean up.
  92    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s.%s.tgz", HIDDEN_TEMP_FILE_NAME, FILE_GENERIC_NAME (&A68_JOB)) >= 0);
  93    ret = remove (cmd);
  94    ABEND (ret != 0, ERROR_ACTION, cmd);
  95    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SOURCE_NAME (&A68_JOB)) >= 0);
  96    ret = remove (cmd);
  97    ABEND (ret != 0, ERROR_ACTION, cmd);
  98    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_PLUGIN_NAME (&A68_JOB)) >= 0);
  99    ret = remove (cmd);
 100    ABEND (ret != 0, ERROR_ACTION, cmd);
 101    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, FILE_SCRIPT_NAME (&A68_JOB)) >= 0);
 102    ret = remove (cmd);
 103    ABEND (ret != 0, ERROR_ACTION, cmd);
 104  }
 105  
 106  //! @brief Load program from shell script .
 107  
 108  void load_script (void)
 109  {
 110    int k; FILE_T script; BUFFER cmd; char ch;
 111  #if !defined (BUILD_A68_COMPILER)
 112    return;
 113  #endif
 114    announce_phase ("script loader");
 115  // Decompress the archive.
 116    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "sed '1,3d' < %s | tar xzf -", FILE_INITIAL_NAME (&A68_JOB)) >= 0);
 117    ABEND (system (cmd) != 0, ERROR_ACTION, cmd);
 118  // Reread the header.
 119    script = open (FILE_INITIAL_NAME (&A68_JOB), O_RDONLY);
 120    ABEND (script == -1, ERROR_ACTION, cmd);
 121  // Skip the #! a68g line.
 122    ASSERT (io_read (script, &ch, 1) == 1);
 123    while (ch != NEWLINE_CHAR) {
 124      ASSERT (io_read (script, &ch, 1) == 1);
 125    }
 126  // Read the generic filename.
 127    A68 (input_line)[0] = NULL_CHAR;
 128    k = 0;
 129    ASSERT (io_read (script, &ch, 1) == 1);
 130    while (ch != NEWLINE_CHAR) {
 131      A68 (input_line)[k++] = ch;
 132      ASSERT (io_read (script, &ch, 1) == 1);
 133    }
 134    A68 (input_line)[k] = NULL_CHAR;
 135    ASSERT (snprintf (cmd, SNPRINTF_SIZE, "%s.%s", HIDDEN_TEMP_FILE_NAME, A68 (input_line)) >= 0);
 136    FILE_INITIAL_NAME (&A68_JOB) = new_string (cmd, NO_TEXT);
 137  // Read options.
 138    A68 (input_line)[0] = NULL_CHAR;
 139    k = 0;
 140    ASSERT (io_read (script, &ch, 1) == 1);
 141    while (ch != NEWLINE_CHAR) {
 142      A68 (input_line)[k++] = ch;
 143      ASSERT (io_read (script, &ch, 1) == 1);
 144    }
 145    isolate_options (A68 (input_line), NO_LINE);
 146    (void) set_options (OPTION_LIST (&A68_JOB), A68_FALSE);
 147    ASSERT (close (script) == 0);
 148  }
 149  
 150  //! @brief Rewrite source for shell script .
 151  
 152  void rewrite_script_source (void)
 153  {
 154    LINE_T *ref_l = NO_LINE;
 155    FILE_T source;
 156  // Rebuild the source file.
 157    ASSERT (remove (FILE_SOURCE_NAME (&A68_JOB)) == 0);
 158    source = open (FILE_SOURCE_NAME (&A68_JOB), O_WRONLY | O_CREAT | O_TRUNC, A68_PROTECTION);
 159    ABEND (source == -1, ERROR_ACTION, FILE_SOURCE_NAME (&A68_JOB));
 160    for (ref_l = TOP_LINE (&A68_JOB); ref_l != NO_LINE; FORWARD (ref_l)) {
 161      WRITE (source, STRING (ref_l));
 162      if (strlen (STRING (ref_l)) == 0 || (STRING (ref_l))[strlen (STRING (ref_l) - 1)] != NEWLINE_CHAR) {
 163        WRITE (source, NEWLINE_STRING);
 164      }
 165    }
 166  // Wrap it up.
 167    ASSERT (close (source) == 0);
 168  }
 169  
 170  #endif