~ubuntu-branches/ubuntu/wily/luatex/wily

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/ocp/readocp.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2010-04-29 00:47:19 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100429004719-o42etkqe90n97b9e
Tags: 0.60.1-1
* new upstream release, adapt build-script patch
* disable patch: upstream-epstopdf_cc_no_xpdf_patching, included upstream
* disable patch: libpoppler-0.12, not needed anymore

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* readocp.c
2
 
   
3
 
   Copyright 2009 Taco Hoekwater <taco@luatex.org>
4
 
 
5
 
   This file is part of LuaTeX.
6
 
 
7
 
   LuaTeX is free software; you can redistribute it and/or modify it under
8
 
   the terms of the GNU General Public License as published by the Free
9
 
   Software Foundation; either version 2 of the License, or (at your
10
 
   option) any later version.
11
 
 
12
 
   LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13
 
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
 
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15
 
   License for more details.
16
 
 
17
 
   You should have received a copy of the GNU General Public License along
18
 
   with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
19
 
 
20
 
#include "ptexlib.h"
21
 
 
22
 
 
23
 
static const char _svn_version[] =
24
 
    "$Id: readocp.c 3261 2009-12-18 11:38:21Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.50.0/source/texk/web2c/luatexdir/ocp/readocp.c $";
25
 
 
26
 
extern int program_name_set;    /* in lkpselib.c */
27
 
 
28
 
static char *b_test_in(char *nam)
29
 
{
30
 
    if (program_name_set) {
31
 
        return (char *) kpse_find_file(nam, kpse_program_binary_format, true);
32
 
    }
33
 
    return NULL;
34
 
}
35
 
 
36
 
 
37
 
 
38
 
 
39
 
static unsigned char *ocp_buffer = NULL;        /* byte buffer for ocp files */
40
 
static int ocp_size = 0;    /* total size of the ocp file */
41
 
static int ocp_cur = 0;     /* index into |ocp_buffer| */
42
 
 
43
 
void init_null_ocp(str_number a, str_number n)
44
 
{
45
 
    ocp_ptr = null_ocp;
46
 
    allocate_ocp_table(null_ocp, 17);
47
 
    ocp_file_size(null_ocp) = 17;
48
 
    ocp_name(null_ocp) = n;
49
 
    ocp_area(null_ocp) = a;
50
 
    ocp_external(null_ocp) = 0;
51
 
    ocp_external_arg(null_ocp) = 0;
52
 
    ocp_input(null_ocp) = 1;
53
 
    ocp_output(null_ocp) = 1;
54
 
    ocp_no_tables(null_ocp) = 0;
55
 
    ocp_no_states(null_ocp) = 1;
56
 
    ocp_table_base(f) = offset_ocp_info;
57
 
    ocp_state_base(f) = offset_ocp_info;
58
 
    ocp_info(null_ocp, offset_ocp_info) = offset_ocp_info + 2;  /* number of entries */
59
 
    ocp_info(null_ocp, offset_ocp_info + 1) = offset_ocp_info + 5;      /* number of entries */
60
 
    ocp_info(null_ocp, offset_ocp_info + 2) = 23;       /* |OTP_LEFT_START| */
61
 
    ocp_info(null_ocp, offset_ocp_info + 3) = 3;        /* |OTP_RIGHT_CHAR| */
62
 
    ocp_info(null_ocp, offset_ocp_info + 4) = 36;       /* |OTP_STOP| */
63
 
}
64
 
 
65
 
 
66
 
 
67
 
/* $\Omega$ checks the information of a \.{OCP} file for validity as the
68
 
file is being read in, so that no further checks will be needed when
69
 
typesetting is going on. The somewhat tedious subroutine that does this
70
 
is called |read_ocp_info|. It has three parameters: the user ocp
71
 
identifier~|u|, and the file name and area strings |nom| and |aire|.
72
 
 
73
 
The subroutine opens and closes a global file variable called |ocp_file|.
74
 
It returns the value of the internal ocp number that was just loaded.
75
 
If an error is detected, an error message is issued and no ocp
76
 
information is stored; |null_ocp| is returned in this case.
77
 
 
78
 
*/
79
 
 
80
 
/* do this when the \.{OCP} data is wrong */
81
 
#define ocp_abort(A) do {                               \
82
 
    tprint("OCP file error (");                         \
83
 
    tprint(A); tprint(")"); print_ln();                 \
84
 
    goto BAD_OCP;                                       \
85
 
} while (0)
86
 
 
87
 
/* macros for reading and storing ocp data */
88
 
 
89
 
#define add_to_ocp_info(A) ocp_tables[f][ocpmem_run_ptr++]=(A)
90
 
#define ocp_read(A) do {                                                \
91
 
    ocpword=ocp_buffer[ocp_cur++];                                      \
92
 
    if (ocpword>127) ocp_abort("checking first octet");                 \
93
 
    ocpword=ocpword*0400+ocp_buffer[ocp_cur++];                         \
94
 
    ocpword=ocpword*0400+ocp_buffer[ocp_cur++];                         \
95
 
    ocpword=ocpword*0400+ocp_buffer[ocp_cur++];                         \
96
 
    (A)=ocpword;                                                        \
97
 
  } while (0)
98
 
 
99
 
#define ocp_read_all(A) ocp_read(A)
100
 
#define ocp_read_info do { ocp_read_all(ocpword); add_to_ocp_info(ocpword); } while (0)
101
 
 
102
 
 
103
 
 
104
 
/* input a \.{OCP} file */
105
 
internal_ocp_number
106
 
read_ocp_info(pointer u, char *nom, char *aire, char *ext, boolean external_ocp)
107
 
{
108
 
    boolean file_opened;        /* was |ocp_file| successfully opened? */
109
 
    boolean res;
110
 
    int callback_id;
111
 
    char *cnam;                 /* C version of file name */
112
 
    internal_ocp_number f;      /* the new ocp's number */
113
 
    internal_ocp_number g;      /* the number to return */
114
 
    int ocpword;
115
 
    ocp_index ocpmem_run_ptr;
116
 
    int ocp_length, real_ocp_length;        /* length of ocp file */
117
 
    ocp_index previous_address;
118
 
    int temp_ocp_input;
119
 
    int temp_ocp_output;
120
 
    int temp_ocp_no_tables;
121
 
    int temp_ocp_no_states;
122
 
    int i, new_offset, room_for_tables, room_for_states;
123
 
    g = null_ocp;
124
 
    f = null_ocp;
125
 
    cnam = NULL;
126
 
    file_opened = false;
127
 
    if (external_ocp) {
128
 
        /*  @<Check |ocp_file| exists@> */
129
 
        cnam = xmalloc(strlen(nom) + strlen(aire) + strlen(ext) + 1);
130
 
        sprintf(cnam, "%s%s%s", aire, nom, ext);
131
 
        cnam = b_test_in(cnam);
132
 
        if (!cnam)
133
 
            ocp_abort("opening file");
134
 
        f = ocp_ptr + 1;
135
 
        allocate_ocp_table(f, 13);
136
 
        ocp_file_size(f) = 13;
137
 
        ocp_external(f) = maketexstring(cnam);
138
 
        scan_string_argument();
139
 
        ocp_external_arg(f) = cur_val;
140
 
        ocp_name(f) = get_nullstr();
141
 
        ocp_area(f) = get_nullstr();
142
 
        ocp_state_base(f) = 0;
143
 
        ocp_table_base(f) = 0;
144
 
        ocp_input(f) = 1;
145
 
        ocp_output(f) = 1;
146
 
        ocp_info(f, offset_ocp_info) = 0;
147
 
        ocp_ptr = f;
148
 
        g = f;
149
 
        goto DONE;
150
 
 
151
 
    } else {
152
 
        /* @<Open |ocp_file| for input@>; */
153
 
        char *cname = xmalloc(strlen(nom) + strlen(aire) + strlen(".ocp") + 1);
154
 
        sprintf(cname, "%s%s.ocp", aire, nom);
155
 
        if (ocp_buffer != NULL)
156
 
            xfree(ocp_buffer);
157
 
        ocp_cur = 0;
158
 
        ocp_buffer = NULL;
159
 
        ocp_size = 0;
160
 
        cnam = luatex_find_file(cname, find_ocp_file_callback);
161
 
        callback_id = callback_defined(read_ocp_file_callback);
162
 
        if (cnam && callback_id > 0) {
163
 
            res = run_callback(callback_id, "S->bSd", cnam,
164
 
                               &file_opened, &ocp_buffer, &ocp_size);
165
 
            if (!res)
166
 
                ocp_abort("callback error");
167
 
            if (!file_opened)
168
 
                ocp_abort("opening file");
169
 
        } else {
170
 
            FILE *ocp_file = NULL;
171
 
            if (!cnam)
172
 
                cnam = cname;
173
 
            if (!luatex_open_input
174
 
                (&ocp_file, cnam, kpse_ocp_format, FOPEN_RBIN_MODE, true))
175
 
                ocp_abort("opening file");
176
 
            file_opened = true;
177
 
            res = read_ocp_file(ocp_file, &ocp_buffer, &ocp_size);
178
 
            close_file(ocp_file);
179
 
            if (!res)
180
 
                ocp_abort("reading file");
181
 
        }
182
 
        if (ocp_size == 0)
183
 
            ocp_abort("checking size");
184
 
 
185
 
        /* @<Read the {\.{OCP}} file@>; */
186
 
        f = ocp_ptr + 1;
187
 
        ocpmem_run_ptr = offset_ocp_info;
188
 
        ocp_read(ocp_length);
189
 
        real_ocp_length = ocp_length - 7;
190
 
        ocp_read_all(temp_ocp_input);
191
 
        ocp_read_all(temp_ocp_output);
192
 
        ocp_read_all(temp_ocp_no_tables);
193
 
        ocp_read_all(room_for_tables);
194
 
        ocp_read_all(temp_ocp_no_states);
195
 
        ocp_read_all(room_for_states);
196
 
        if (real_ocp_length !=
197
 
            (temp_ocp_no_tables + room_for_tables +
198
 
             temp_ocp_no_states + room_for_states))
199
 
            ocp_abort("checking size");
200
 
        real_ocp_length = real_ocp_length + 12 +
201
 
            temp_ocp_no_states + temp_ocp_no_tables;
202
 
        allocate_ocp_table(f, real_ocp_length);
203
 
        ocp_external(f) = 0;
204
 
        ocp_external_arg(f) = 0;
205
 
        ocp_file_size(f) = real_ocp_length;
206
 
        ocp_input(f) = temp_ocp_input;
207
 
        ocp_output(f) = temp_ocp_output;
208
 
        ocp_no_tables(f) = temp_ocp_no_tables;
209
 
        ocp_no_states(f) = temp_ocp_no_states;
210
 
        ocp_table_base(f) = ocpmem_run_ptr;
211
 
        if (ocp_no_tables(f) != 0) {
212
 
            previous_address = ocpmem_run_ptr + 2 * (ocp_no_tables(f));
213
 
            for (i = 1; i <= ocp_no_tables(f); i++) {
214
 
                add_to_ocp_info(previous_address);
215
 
                ocp_read_all(new_offset);
216
 
                add_to_ocp_info(new_offset);
217
 
                previous_address = previous_address + new_offset;
218
 
            }
219
 
        }
220
 
        if (room_for_tables != 0) {
221
 
            for (i = 1; i <= room_for_tables; i++) {
222
 
                ocp_read_info;
223
 
            }
224
 
        }
225
 
        ocp_state_base(f) = ocpmem_run_ptr;
226
 
        if (ocp_no_states(f) != 0) {
227
 
            previous_address = ocpmem_run_ptr + 2 * (ocp_no_states(f));
228
 
            for (i = 1; i <= ocp_no_states(f); i++) {
229
 
                add_to_ocp_info(previous_address);
230
 
                ocp_read_all(new_offset);
231
 
                add_to_ocp_info(new_offset);
232
 
                previous_address = previous_address + new_offset;
233
 
            }
234
 
        }
235
 
        if (room_for_states != 0) {
236
 
            for (i = 1; i <= room_for_states; i++) {
237
 
                ocp_read_info;
238
 
            }
239
 
        }
240
 
        ocp_ptr = f;
241
 
        g = f;
242
 
        goto DONE;
243
 
    }
244
 
  BAD_OCP:
245
 
    {
246
 
        /* @<Report that the ocp won't be loaded@>; */
247
 
        /* $\Omega$ does not give precise details about why it
248
 
           rejects a particular \.{OCP} file. */
249
 
        char *hlp[] = {
250
 
            "I wasn't able to read the data for this ocp,",
251
 
            "so I will ignore the ocp specification.",
252
 
            NULL
253
 
        };
254
 
        char errmsg[256];
255
 
        char *c = makecstring(cs_text(u));
256
 
        if (file_opened) {
257
 
            snprintf(errmsg, 255,
258
 
                     "Translation process \\%s=%s not loadable: Bad ocp file",
259
 
                     c, cnam);
260
 
        } else {
261
 
            snprintf(errmsg, 255,
262
 
                     "Translation process \\%s=%s not loadable: ocp file not found",
263
 
                     c, cnam);
264
 
        }
265
 
        free(c);
266
 
        tex_error(errmsg, hlp);
267
 
    }
268
 
  DONE:
269
 
    ocp_name(f) = maketexstring(nom);
270
 
    ocp_area(f) = maketexstring(aire);
271
 
    return g;
272
 
}