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