summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/ocp/readocp.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/ocp/readocp.w')
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/readocp.w273
1 files changed, 273 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/ocp/readocp.w b/Build/source/texk/web2c/luatexdir/ocp/readocp.w
new file mode 100644
index 00000000000..7beee600347
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/readocp.w
@@ -0,0 +1,273 @@
+% readocp.w
+%
+% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+
+% This file is part of LuaTeX.
+
+% LuaTeX 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.
+
+% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+% License for more details.
+
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: readocp.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/ocp/readocp.w $";
+
+@ @c
+static char *b_test_in(char *nam)
+{
+ if (program_name_set) {
+ return (char *) kpse_find_file(nam, kpse_program_binary_format, true);
+ }
+ return NULL;
+}
+
+
+static unsigned char *ocp_buffer = NULL; /* byte buffer for ocp files */
+static int ocp_size = 0; /* total size of the ocp file */
+static int ocp_cur = 0; /* index into |ocp_buffer| */
+
+@ @c
+void init_null_ocp(str_number a, str_number n)
+{
+ ocp_ptr = null_ocp;
+ allocate_ocp_table(null_ocp, 17);
+ ocp_file_size(null_ocp) = 17;
+ ocp_name(null_ocp) = n;
+ ocp_area(null_ocp) = a;
+ ocp_external(null_ocp) = 0;
+ ocp_external_arg(null_ocp) = 0;
+ ocp_input(null_ocp) = 1;
+ ocp_output(null_ocp) = 1;
+ ocp_no_tables(null_ocp) = 0;
+ ocp_no_states(null_ocp) = 1;
+ ocp_table_base(f) = offset_ocp_info;
+ ocp_state_base(f) = offset_ocp_info;
+ ocp_info(null_ocp, offset_ocp_info) = offset_ocp_info + 2; /* number of entries */
+ ocp_info(null_ocp, offset_ocp_info + 1) = offset_ocp_info + 5; /* number of entries */
+ ocp_info(null_ocp, offset_ocp_info + 2) = 23; /* |OTP_LEFT_START| */
+ ocp_info(null_ocp, offset_ocp_info + 3) = 3; /* |OTP_RIGHT_CHAR| */
+ ocp_info(null_ocp, offset_ocp_info + 4) = 36; /* |OTP_STOP| */
+}
+
+
+
+@ $\Omega$ checks the information of a \.{OCP} file for validity as the
+file is being read in, so that no further checks will be needed when
+typesetting is going on. The somewhat tedious subroutine that does this
+is called |read_ocp_info|. It has three parameters: the user ocp
+identifier~|u|, and the file name and area strings |nom| and |aire|.
+
+The subroutine opens and closes a global file variable called |ocp_file|.
+It returns the value of the internal ocp number that was just loaded.
+If an error is detected, an error message is issued and no ocp
+information is stored; |null_ocp| is returned in this case.
+
+@c
+/* do this when the \.{OCP} data is wrong */
+#define ocp_abort(A) do { \
+ tprint("OCP file error ("); \
+ tprint(A); tprint(")"); print_ln(); \
+ goto BAD_OCP; \
+} while (0)
+
+/* macros for reading and storing ocp data */
+
+#define add_to_ocp_info(A) ocp_tables[f][ocpmem_run_ptr++]=(A)
+#define ocp_read(A) do { \
+ ocpword=ocp_buffer[ocp_cur++]; \
+ if (ocpword>127) ocp_abort("checking first octet"); \
+ ocpword=ocpword*0400+ocp_buffer[ocp_cur++]; \
+ ocpword=ocpword*0400+ocp_buffer[ocp_cur++]; \
+ ocpword=ocpword*0400+ocp_buffer[ocp_cur++]; \
+ (A)=ocpword; \
+ } while (0)
+
+#define ocp_read_all(A) ocp_read(A)
+#define ocp_read_info do { ocp_read_all(ocpword); add_to_ocp_info(ocpword); } while (0)
+
+
+
+@ Input a \.{OCP} file
+
+@c
+internal_ocp_number
+read_ocp_info(pointer u, char *nom, char *aire, char *ext, boolean external_ocp)
+{
+ boolean file_opened; /* was |ocp_file| successfully opened? */
+ boolean res;
+ int callback_id;
+ char *cnam; /* C version of file name */
+ internal_ocp_number f; /* the new ocp's number */
+ internal_ocp_number g; /* the number to return */
+ int ocpword;
+ ocp_index ocpmem_run_ptr;
+ int ocp_length, real_ocp_length; /* length of ocp file */
+ ocp_index previous_address;
+ int temp_ocp_input;
+ int temp_ocp_output;
+ int temp_ocp_no_tables;
+ int temp_ocp_no_states;
+ int i, new_offset, room_for_tables, room_for_states;
+ g = null_ocp;
+ f = null_ocp;
+ cnam = NULL;
+ file_opened = false;
+ if (external_ocp) {
+ /* Check |ocp_file| exists */
+ cnam =
+ xmalloc((unsigned) (strlen(nom) + strlen(aire) + strlen(ext) + 1));
+ sprintf(cnam, "%s%s%s", aire, nom, ext);
+ cnam = b_test_in(cnam);
+ if (!cnam)
+ ocp_abort("opening file");
+ f = ocp_ptr + 1;
+ allocate_ocp_table(f, 13);
+ ocp_file_size(f) = 13;
+ ocp_external(f) = maketexstring(cnam);
+ scan_string_argument();
+ ocp_external_arg(f) = cur_val;
+ ocp_name(f) = get_nullstr();
+ ocp_area(f) = get_nullstr();
+ ocp_state_base(f) = 0;
+ ocp_table_base(f) = 0;
+ ocp_input(f) = 1;
+ ocp_output(f) = 1;
+ ocp_info(f, offset_ocp_info) = 0;
+ ocp_ptr = f;
+ g = f;
+ goto DONE;
+
+ } else {
+ /* Open |ocp_file| for input */
+ char *cname = xmalloc((unsigned)
+ (strlen(nom) + strlen(aire) + strlen(".ocp") +
+ 1));
+ sprintf(cname, "%s%s.ocp", aire, nom);
+ xfree(ocp_buffer);
+ ocp_cur = 0;
+ ocp_size = 0;
+ cnam = luatex_find_file(cname, find_ocp_file_callback);
+ callback_id = callback_defined(read_ocp_file_callback);
+ if (cnam && callback_id > 0) {
+ res = run_callback(callback_id, "S->bSd", cnam,
+ &file_opened, &ocp_buffer, &ocp_size);
+ if (!res)
+ ocp_abort("callback error");
+ if (!file_opened)
+ ocp_abort("opening file");
+ } else {
+ FILE *ocp_file = NULL;
+ if (!cnam)
+ cnam = cname;
+ if (!luatex_open_input
+ (&ocp_file, cnam, kpse_ocp_format, FOPEN_RBIN_MODE, true))
+ ocp_abort("opening file");
+ file_opened = true;
+ res = read_ocp_file(ocp_file, &ocp_buffer, &ocp_size);
+ close_file(ocp_file);
+ if (!res)
+ ocp_abort("reading file");
+ }
+ if (ocp_size == 0)
+ ocp_abort("checking size");
+
+ /* Read the {\.{OCP}} file */
+ f = ocp_ptr + 1;
+ ocpmem_run_ptr = offset_ocp_info;
+ ocp_read(ocp_length);
+ real_ocp_length = ocp_length - 7;
+ ocp_read_all(temp_ocp_input);
+ ocp_read_all(temp_ocp_output);
+ ocp_read_all(temp_ocp_no_tables);
+ ocp_read_all(room_for_tables);
+ ocp_read_all(temp_ocp_no_states);
+ ocp_read_all(room_for_states);
+ if (real_ocp_length !=
+ (temp_ocp_no_tables + room_for_tables +
+ temp_ocp_no_states + room_for_states))
+ ocp_abort("checking size");
+ real_ocp_length = real_ocp_length + 12 +
+ temp_ocp_no_states + temp_ocp_no_tables;
+ allocate_ocp_table(f, real_ocp_length);
+ ocp_external(f) = 0;
+ ocp_external_arg(f) = 0;
+ ocp_file_size(f) = real_ocp_length;
+ ocp_input(f) = temp_ocp_input;
+ ocp_output(f) = temp_ocp_output;
+ ocp_no_tables(f) = temp_ocp_no_tables;
+ ocp_no_states(f) = temp_ocp_no_states;
+ ocp_table_base(f) = ocpmem_run_ptr;
+ if (ocp_no_tables(f) != 0) {
+ previous_address = ocpmem_run_ptr + 2 * (ocp_no_tables(f));
+ for (i = 1; i <= ocp_no_tables(f); i++) {
+ add_to_ocp_info(previous_address);
+ ocp_read_all(new_offset);
+ add_to_ocp_info(new_offset);
+ previous_address = previous_address + new_offset;
+ }
+ }
+ if (room_for_tables != 0) {
+ for (i = 1; i <= room_for_tables; i++) {
+ ocp_read_info;
+ }
+ }
+ ocp_state_base(f) = ocpmem_run_ptr;
+ if (ocp_no_states(f) != 0) {
+ previous_address = ocpmem_run_ptr + 2 * (ocp_no_states(f));
+ for (i = 1; i <= ocp_no_states(f); i++) {
+ add_to_ocp_info(previous_address);
+ ocp_read_all(new_offset);
+ add_to_ocp_info(new_offset);
+ previous_address = previous_address + new_offset;
+ }
+ }
+ if (room_for_states != 0) {
+ for (i = 1; i <= room_for_states; i++) {
+ ocp_read_info;
+ }
+ }
+ ocp_ptr = f;
+ g = f;
+ goto DONE;
+ }
+ BAD_OCP:
+ {
+ /* Report that the ocp won't be loaded */
+ /* $\Omega$ does not give precise details about why it
+ rejects a particular \.{OCP} file. */
+ const char *hlp[] = {
+ "I wasn't able to read the data for this ocp,",
+ "so I will ignore the ocp specification.",
+ NULL
+ };
+ char errmsg[256];
+ char *c = makecstring(cs_text(u));
+ if (file_opened) {
+ snprintf(errmsg, 255,
+ "Translation process \\%s=%s not loadable: Bad ocp file",
+ c, cnam);
+ } else {
+ snprintf(errmsg, 255,
+ "Translation process \\%s=%s not loadable: ocp file not found",
+ c, cnam);
+ }
+ free(c);
+ tex_error(errmsg, hlp);
+ }
+ DONE:
+ ocp_name(f) = maketexstring(nom);
+ ocp_area(f) = maketexstring(aire);
+ return g;
+}