mp.h /size: 87 Kb    last modification: 2025-02-21 11:03
1/*
2    This file was generated by "mtxrun --script "mtx-wtoc.lua" from the metapost cweb
3    files but now maintained as C file.
4*/
5
6# ifndef MP_H
7# define MP_H 1
8
9# include <errno.h>
10# include <string.h>
11# include <float.h>
12# include <math.h>
13# include <stdlib.h>
14# include <stdarg.h>
15# include <ctype.h>
16# include <sys/stat.h>
17# include <time.h>
18# include <setjmp.h>
19
20# ifdef _WIN32
21
22    # include <stdio.h>
23    # include <fcntl.h>
24    # include <io.h>
25
26# else
27
28    # include <unistd.h>
29
30# endif
31
32# include "avl.h"
33# include "auxmemory.h"
34# include "auxposit.h"
35
36/*tex
37
38We used to have three header files: common, mpmp and mplib, but there ws some (growing) dependency on
39the one hand and we decided to target just \LUAMETATEX\ on the other. After all, this is a special
40version. So, we now have one header file only. The variables from |MP_options| are included inside
41the |MP_instance| wholesale. This also permits some further stripping. Actually we can probably get
42rid of the intermediate \POSTSCRIPT\ representation or add a little more abstraction.
43
44*/
45
46# define metapost_version "3.14"
47
48typedef struct MP_instance *MP;
49
50typedef enum mp_number_type {
51    mp_nan_type,
52    mp_scaled_type,
53    mp_fraction_type,
54    mp_angle_type,
55    mp_double_type,
56    mp_binary_type,
57    mp_decimal_type,
58    mp_posit_type
59} mp_number_type;
60
61# define is_number(A) ((A).type != mp_nan_type)
62
63typedef union mp_number_store {
64    void   *num;
65    double  dval;
66    int     val;
67    posit_t pval;
68} mp_number_store;
69
70typedef struct mp_number_data {
71    mp_number_store data;
72    mp_number_type  type;
73} mp_number_data;
74
75typedef struct mp_number_data mp_number;
76
77enum mp_filetype {
78    mp_filetype_terminal, /* the terminal (input) */
79    mp_filetype_program,  /* \MP\ language input */
80    mp_filetype_text      /* first text file for readfrom and writeto primitives */
81};
82
83typedef char *(*mp_file_finder)     (MP, const char *, const char *, int);
84typedef char *(*mp_script_runner)   (MP, const char *m, size_t len, int n);
85typedef void  (*mp_internal_runner) (MP, int action, int n, int type, const char *iname);
86typedef void  (*mp_log_runner)      (MP, int, const char *s, size_t l);
87typedef int   (*mp_overload_runner) (MP, int, const char *, int);
88typedef void  (*mp_error_runner)    (MP, const char *, const char *, int);
89typedef void  (*mp_warning_runner)  (MP, const char *);
90typedef char *(*mp_text_maker)      (MP, const char *, size_t, int);
91typedef void *(*mp_file_opener)     (MP, const char *, const char *, int);
92typedef char *(*mp_file_reader)     (MP, void *, size_t *);
93typedef void  (*mp_file_closer)     (MP, void *);
94typedef int   (*mp_file_eoftest)    (MP, void *);
95typedef void  (*mp_file_flush)      (MP, void *);
96typedef void  (*mp_file_writer)     (MP, void *, const char *);
97
98typedef struct mp_lstring {
99    unsigned char *str;  /* the string value */
100    size_t         len;  /* its length */
101    int            refs; /* number of references */
102} mp_lstring;
103
104typedef mp_lstring *mp_string; /* for pointers to string values */
105
106enum mp_interaction_mode {
107    mp_unspecified_mode, /* extra value for command-line switch */
108    mp_batch_mode,       /* omits all stops and omits terminal output */
109    mp_nonstop_mode,     /* omits all stops */
110    mp_scroll_mode,      /* omits error stops */
111    mp_error_stop_mode,  /* stops at every opportunity to interact */
112    mp_silent_mode       /* stops at every opportunity to interact but not always*/
113};
114
115enum mp_history_state {
116    mp_spotless,             /* |history| value when nothing has been amiss yet */
117    mp_warning_issued,       /* |history| value when |begin_diagnostic| has been called */
118    mp_error_message_issued, /* |history| value when |error| has been called */
119    mp_fatal_error_stop,     /* |history| value when termination was premature */
120    mp_system_error_stop     /* |history| value when termination was due to disaster */
121};
122
123typedef enum mp_math_mode {
124    mp_math_scaled_mode,
125    mp_math_double_mode,
126    mp_math_binary_mode,
127    mp_math_decimal_mode,
128    mp_math_posit_mode
129} mp_math_mode;
130
131typedef struct mp_knot_data *mp_knot;
132
133typedef struct mp_knot_data {
134    mp_number     x_coord;       /* the |x| coordinate of this knot */
135    mp_number     y_coord;       /* the |y| coordinate of this knot */
136    union {
137        mp_number left_x;        /* the |x| coordinate of previous control point */
138        mp_number left_curl;     /* curl information when entering this knot */
139        mp_number left_given;    /* given direction when entering this knot */
140    };
141    union {
142        mp_number left_y;        /* the |y| coordinate of previous control point */
143        mp_number left_tension;  /* tension information when entering this knot */
144    };
145    union {
146        mp_number right_x;       /* the |x| coordinate of next control point */
147        mp_number right_curl;    /* curl information when leaving this knot */
148        mp_number right_given;   /* given direction when leaving this knot */
149    };
150    union {
151        mp_number right_y;       /* the |y| coordinate of next control point */
152        mp_number right_tension; /* tension information when leaving this knot */
153    };
154    mp_knot       next;
155    mp_knot       prev;
156    unsigned char left_type;
157    unsigned char right_type;
158    unsigned char originator;
159    unsigned char state;
160    signed   int  info;
161    /* we now have some 3 bytes slack that we can use */
162} mp_knot_data;
163
164typedef struct mp_graphic_knot_data *mp_graphic_knot;
165
166typedef struct mp_graphic_knot_data {
167    double          x_coord;
168    double          y_coord;
169    double          left_x;
170    double          left_y;
171    double          right_x;
172    double          right_y;
173    mp_graphic_knot next;
174    mp_graphic_knot prev;
175    unsigned char   left_type;
176    unsigned char   right_type;
177    unsigned char   originator;
178    unsigned char   state;
179    signed int      info;
180} mp_graphic_knot_data;
181
182enum mp_knot_originator {
183    mp_program_code,  /* not created by a user */
184    mp_metapost_user  /* created by a user */
185};
186
187enum mp_knot_states {
188    mp_regular_knot,
189    mp_begin_knot,
190    mp_end_knot,
191    mp_single_knot,
192};
193
194# undef term_in
195# undef term_out
196
197typedef struct mp_run_data {
198    void                  *term_in; /* dummy pointer */
199    struct mp_edge_object *edges;
200} mp_run_data;
201
202typedef struct mp_color {
203    union {
204        double red;
205        double cyan;
206    };
207    union {
208        double green;
209        double magenta;
210    };
211    union {
212        double blue;
213        double yellow;
214    };
215    union {
216        double black;
217        double gray;
218    };
219} mp_color;
220
221typedef struct mp_dash_object {
222    double  offset;
223    double *array;
224} mp_dash_object;
225
226/*TEX
227    This mp_graphic_object gets cast onto the fill and stroke. For some reason we don't distinguish
228    between start and stop here.
229*/
230
231typedef struct mp_graphic_object {
232    int                       type;
233    int                       stacking;
234    struct mp_graphic_object *next;
235} mp_graphic_object;
236
237typedef struct mp_shape_object {
238    int                       type;
239    int                       stacking;
240    struct mp_graphic_object *next;
241    char                     *pre_script;
242    char                     *post_script;
243    size_t                    pre_length;
244    size_t                    post_length;
245    mp_color                  color;
246    mp_graphic_knot           path;
247    mp_graphic_knot           htap;
248    mp_graphic_knot           pen;
249    double                    miterlimit;
250    mp_dash_object           *dash;
251    unsigned char             color_model;
252    unsigned char             linejoin;
253    unsigned char             linecap;
254    unsigned char             padding_0; /* pen_type */
255    unsigned char             curvature;
256    unsigned char             padding_1;
257    unsigned char             padding_2;
258    unsigned char             padding_3;
259} mp_shape_object;
260
261typedef struct mp_start_object {
262    int                       type;
263    int                       stacking;
264    struct mp_graphic_object *next;
265    char                     *pre_script;
266    char                     *post_script;
267    size_t                    pre_length;
268    size_t                    post_length;
269    mp_graphic_knot           path;
270} mp_start_object;
271
272typedef struct mp_stop_object {
273    int                       type;
274    int                       stacking;
275    struct mp_graphic_object *next;
276    char                     *pre_script;
277    char                     *post_script;
278    size_t                    pre_length;
279    size_t                    post_length;
280    mp_graphic_knot           path;
281} mp_stop_object;
282
283typedef struct mp_edge_object {
284    struct mp_graphic_object *body;
285    struct mp_edge_object    *next;
286    MP                        parent;
287    double                    minx;
288    double                    miny;
289    double                    maxx;
290    double                    maxy;
291    double                    width;
292    double                    height;
293    double                    depth;
294    double                    italic;
295    int                       charcode;
296    int                       padding;
297} mp_edge_object;
298
299typedef void (*mp_backend_writer) (MP, void *);
300
301typedef struct MP_options {
302    int                halt_on_error; /* do we quit at the first error? */
303    void              *userdata;      /* this allows the calling application to setup local (e.g. L for Lua) */
304    char              *banner;        /* the banner that is printed to the screen and log */
305    int                utf8_mode;
306    int                text_mode;
307    int                show_mode;
308    mp_file_finder     find_file;
309    mp_script_runner   run_script;
310    mp_internal_runner run_internal;
311    mp_log_runner      run_logger;
312    mp_overload_runner run_overload;
313    mp_error_runner    run_error;
314    mp_warning_runner  run_warning;
315    mp_text_maker      make_text;
316    mp_file_opener     open_file;
317    mp_file_closer     close_file;
318    mp_file_reader     read_file;
319    mp_file_writer     write_file;
320    int                find_file_id;
321    int                run_script_id;
322    int                run_internal_id;
323    int                run_logger_id;
324    int                run_overload_id;
325    int                run_error_id;
326    int                run_warning_id;
327    int                make_text_id;
328    int                open_file_id;
329    int                interaction;
330    int                random_seed;
331    int                math_mode;
332    char              *job_name;
333    mp_backend_writer  shipout_backend;
334} MP_options;
335
336typedef enum mp_color_model {
337    mp_no_model,
338    mp_grey_model,
339    mp_rgb_model,
340    mp_cmyk_model,
341    mp_uninitialized_model,
342} mp_color_model;
343
344typedef enum mp_knot_type {
345    mp_endpoint_knot,  /* |mp_left_type| at path beginning and |mp_right_type| at path end */
346    mp_explicit_knot,  /* |mp_left_type| or |mp_right_type| when control points are known */
347    mp_given_knot,     /* |mp_left_type| or |mp_right_type| when a direction is given */
348    mp_curl_knot,      /* |mp_left_type| or |mp_right_type| when a curl is desired */
349    mp_open_knot,      /* |mp_left_type| or |mp_right_type| when \MP\ should choose the direction */
350    mp_end_cycle_knot
351} mp_knot_type;
352
353enum mp_graphical_object_code {
354    mp_unset_code,
355    mp_fill_code,
356    mp_stroked_code,
357    mp_start_clip_code,   /* |type| of a node that starts clipping */
358    mp_start_group_code,  /* |type| of a node that gives a |setgroup| path */
359    mp_start_bounds_code, /* |type| of a node that gives a |setbounds| path */
360    mp_stop_clip_code,    /* |type| of a node that stops clipping */
361    mp_stop_group_code,   /* |type| of a node that stops grouping */
362    mp_stop_bounds_code,  /* |type| of a node that stops |setbounds| */
363    mp_final_graphic
364};
365
366typedef enum mp_command_code {
367    mp_undefined_command,
368    mp_btex_command,                /* begin \TeX\ material (|btex|, |verbatimtex|) */
369    mp_etex_command,                /* end \TeX\ material (|etex|) */
370    mp_if_test_command,             /* conditional text (|if|) */
371    mp_fi_or_else_command,          /* delimiters for conditionals (|elseif|, |else|, |fi|) */
372    mp_input_command,               /* input a source file (|input|, |endinput|) */
373    mp_iteration_command,           /* iterate (|for|, |forsuffixes|, |forever|, |endfor|) */
374    mp_repeat_loop_command,         /* special command substituted for |endfor| */
375    mp_exit_test_command,           /* premature exit from a loop (|exitif|) */
376    mp_relax_command,               /* do nothing (|\char`\\|) */
377    mp_scan_tokens_command,         /* put a string into the input buffer */
378    mp_runscript_command,           /* put a script result string into the input buffer */
379    mp_maketext_command,            /* make a text (typesetting) */
380    mp_expand_after_command,        /* look ahead one token */
381    mp_defined_macro_command,       /* a macro defined by the user */
382    mp_save_command,                /* save a list of tokens (|save|) */
383    mp_interim_command,             /* save an internal quantity (|interim|) */
384    mp_let_command,                 /* redefine a symbolic token (|let|) */
385    mp_new_internal_command,        /* define a new internal quantity (|newinternal|) */
386    mp_macro_def_command,           /* define a macro (|def|, |vardef|, etc.) */
387    mp_ship_out_command,            /* output a character (|shipout|) */
388    mp_add_to_command,              /* add to edges (|addto|) */
389    mp_bounds_command,              /* add bounding path to edges (|setbounds|, |clip|) */
390    mp_protection_command,          /* set protection flag (|outer|, |inner|) */
391    mp_property_command,
392    mp_show_command,                /* diagnostic output (|show|, |showvariable|, etc.) */
393    mp_mode_command,                /* set interaction level (|batchmode|, etc.) */
394    mp_only_set_command,            /* initialize random number generator (|randomseed|) */
395    mp_message_command,             /* communicate to user (|message|, |errmessage|) */
396    mp_every_job_command,           /* designate a starting token (|everyjob|) */
397    mp_delimiters_command,          /* define a pair of delimiters (|delimiters|) */
398    mp_write_command,               /* write text to a file (|write|) */
399    mp_type_name_command,           /* declare a type (|numeric|, |pair|, etc.) */
400    mp_left_delimiter_command,      /* the left delimiter of a matching pair */
401    mp_begin_group_command,         /* beginning of a group (|begingroup|) */
402    mp_nullary_command,             /* an operator without arguments (e.g., |normaldeviate|) */
403    mp_unary_command,               /* an operator with one argument (e.g., |sqrt|) */
404    mp_str_command,                 /* convert a suffix to a string (|str|) */
405    mp_void_command,                /* convert a suffix to a boolean (|void|) */
406    mp_cycle_command,               /* close a cyclic path (|cycle|) */
407    mp_of_binary_command,           /* binary operation taking |of| (e.g., |point|) */
408    mp_capsule_command,             /* a value that has been put into a token list */
409    mp_string_command,              /* a string constant (e.g., |"hello"|) */
410    mp_internal_command,            /* internal numeric parameter (e.g., |pausing|) */
411    mp_tag_command,                 /* a symbolic token without a primitive meaning */
412    mp_numeric_command,             /* a numeric constant (e.g., |3.14159|) */
413    mp_plus_or_minus_command,       /* either |+| or |-| */
414    mp_secondary_def_command,       /* a macro defined by |secondarydef| */
415    mp_tertiary_binary_command,     /* an operator at the tertiary level (e.g., |++|) */
416    mp_left_brace_command,          /* the operator `|\char||| */
417    mp_path_join_command,           /* the operator |..| */
418    mp_path_connect_command,        /* the operator |--| */
419    mp_ampersand_command,           /* the operator `\.\&' */
420    mp_tertiary_def_command,        /* a macro defined by |tertiarydef| */
421    mp_primary_binary_command,      /* an operator at the expression level (e.g., |<|) */
422    mp_equals_command,              /* the operator |=| */
423    mp_and_command,                 /* the operator |and| */
424    mp_primary_def_command,         /* a macro defined by |primarydef| */
425    mp_slash_command,               /* the operator |/| */
426    mp_secondary_binary_command,    /* an operator at the binary level (e.g., |shifted|) */
427    mp_parameter_commmand,          /* type of parameter (|primary|, |expr|, |suffix|, etc.) */
428    mp_controls_command,            /* specify control points explicitly (|controls|) */
429    mp_tension_command,             /* specify tension between knots (|tension|) */
430    mp_at_least_command,            /* bounded tension value (|atleast|) */
431    mp_curl_command,                /* specify curl at an end knot (|curl|) */
432    mp_macro_special_command,       /* special macro operators (|quote|, |\#\AT!|, etc.) */
433    mp_right_delimiter_command,     /* the right delimiter of a matching pair */
434    mp_left_bracket_command,        /* the operator |[| */
435    mp_right_bracket_command,       /* the operator |]| */
436    mp_right_brace_command,         /* the operator `|\char|}| */
437    mp_with_option_command,         /* option for filling (|withpen|, |withweight|, etc.) */
438    mp_thing_to_add_command,        /* variant of |addto| (|contour|, |doublepath|, |also|) */
439    mp_of_command,                  /* the operator |of| */
440    mp_to_command,                  /* the operator |to| */
441    mp_step_command,                /* the operator |step| */
442    mp_until_command,               /* the operator |until| */
443    mp_within_command,              /* the operator |within| */
444    mp_assignment_command,          /* the operator |:=| */
445    mp_colon_command,               /* the operator |:| */
446    mp_comma_command,               /* the operator |,|, must be |colon+1| */
447    mp_semicolon_command,           /* the operator |;|, must be |comma+1| */
448    mp_end_group_command,           /* end a group (|endgroup|), must be |semicolon+1| */
449    mp_stop_command,                /* end a job (|end|, |dump|), must be |end_group+1| */
450 // mp_outer_tag_command,           /* protection code added to command code */
451    mp_undefined_cs_command,        /* protection code added to command code */
452} mp_command_code;
453
454typedef enum mp_variable_type {
455    mp_undefined_type,        /* no type has been declared */
456    mp_vacuous_type,          /* no expression was present */
457    mp_boolean_type,          /* |boolean| with a known value */
458    mp_unknown_boolean_type,
459    mp_string_type,           /* |string| with a known value */
460    mp_unknown_string_type,
461    mp_pen_type,              /* |pen| with a known value */
462    mp_unknown_pen_type,
463    mp_nep_type,              /* |pen| with a known value */
464    mp_unknown_nep_type,
465    mp_path_type,             /* |path| with a known value */
466    mp_unknown_path_type,
467    mp_picture_type,          /* |picture| with a known value */
468    mp_unknown_picture_type,
469    mp_transform_type,        /* |transform| variable or capsule */
470    mp_color_type,            /* |color| variable or capsule */
471    mp_cmykcolor_type,        /* |cmykcolor| variable or capsule */
472    mp_pair_type,             /* |pair| variable or capsule */
473    mp_numeric_type,          /* variable that has been declared |numeric| but not used */
474    mp_known_type,            /* |numeric| with a known value */
475    mp_dependent_type,        /* a linear combination with |fraction| coefficients */
476    mp_proto_dependent_type,  /* a linear combination with |scaled| coefficients */
477    mp_independent_type,      /* |numeric| with unknown value */
478    mp_token_list_type,       /* variable name or suffix argument or text argument */
479    mp_structured_type,       /* variable with subscripts and attributes */
480    mp_unsuffixed_macro_type, /* variable defined with |vardef| but no |\AT!\#| */
481    mp_suffixed_macro_type,   /* variable defined with |vardef| and |\AT!\#| */
482    mp_symbol_node_type,
483    mp_token_node_type,
484    mp_value_node_type,
485    mp_attribute_node_type,
486    mp_subscript_node_type,
487    mp_pair_node_type,
488    mp_transform_node_type,
489    mp_color_node_type,
490    mp_cmykcolor_node_type,
491    /*
492        It is important that the next 7 items remain in this order, for export as
493        well as switch/case offsets.
494    */
495    mp_fill_node_type,
496    mp_stroked_node_type,
497    mp_start_clip_node_type,
498    mp_start_group_node_type,
499    mp_start_bounds_node_type,
500    mp_stop_clip_node_type,
501    mp_stop_group_node_type,
502    mp_stop_bounds_node_type,
503    mp_dash_node_type,
504    mp_dep_node_type,
505    mp_if_node_type,
506    mp_edge_header_node_type,
507} mp_variable_type;
508
509typedef enum mp_name_type_type {
510    mp_root_operation,              /* |name_type| at the top level of a variable */
511    mp_saved_root_operation,        /* same, when the variable has been saved */
512    mp_structured_root_operation,   /* |name_type| where a |mp_structured| branch occurs */
513    mp_subscript_operation,         /* |name_type| in a subscript node */
514    mp_attribute_operation,         /* |name_type| in an attribute node */
515    mp_x_part_operation,            /* |name_type| in the |xpart| of a node */
516    mp_y_part_operation,            /* |name_type| in the |ypart| of a node */
517    mp_xx_part_operation,           /* |name_type| in the |xxpart| of a node */
518    mp_xy_part_operation,           /* |name_type| in the |xypart| of a node */
519    mp_yx_part_operation,           /* |name_type| in the |yxpart| of a node */
520    mp_yy_part_operation,           /* |name_type| in the |yypart| of a node */
521    mp_red_part_operation,          /* |name_type| in the |redpart| of a node */
522    mp_green_part_operation,        /* |name_type| in the |greenpart| of a node */
523    mp_blue_part_operation,         /* |name_type| in the |bluepart| of a node */
524    mp_cyan_part_operation,         /* |name_type| in the |redpart| of a node */
525    mp_magenta_part_operation,      /* |name_type| in the |greenpart| of a node */
526    mp_yellow_part_operation,       /* |name_type| in the |bluepart| of a node */
527    mp_black_part_operation,        /* |name_type| in the |greenpart| of a node */
528    mp_grey_part_operation,         /* |name_type| in the |greypart| of a node */
529    mp_capsule_operation,           /* |name_type| in stashed-away subexpressions */
530    mp_token_operation,             /* |name_type| in a numeric token or string token */
531    mp_boolean_type_operation,      /* the order needs to match the types (as we use deltas) ! */
532    mp_string_type_operation,
533    mp_pen_type_operation,
534    mp_nep_type_operation,
535    mp_path_type_operation,
536    mp_picture_type_operation,
537    mp_transform_type_operation,
538    mp_color_type_operation,
539    mp_cmykcolor_type_operation,
540    mp_pair_type_operation,
541    mp_numeric_type_operation,
542    /* Symbolic nodes also have |name_type|, which is a different enumeration */
543    mp_normal_operation,
544    mp_internal_operation,          /* for values of internals */
545    mp_macro_operation,             /* for macro names */
546    mp_expr_operation,              /* for macro parameters if type |expr| */
547    mp_suffix_operation,            /* for macro parameters if type |suffix| */
548    mp_text_operation,              /* for macro parameters if type |text| */
549    /* snippet: operation codes */
550    mp_true_operation,              /* operation code for |true| */
551    mp_false_operation,             /* operation code for |false| */
552    mp_null_picture_operation,      /* operation code for |nullpicture| */
553    mp_null_pen_operation,          /* operation code for |nullpen| */
554    mp_read_string_operation,       /* operation code for |readstring| */
555    mp_pen_circle_operation,        /* operation code for |pencircle| */
556    mp_normal_deviate_operation,    /* operation code for |normaldeviate| */
557    mp_read_from_operation,         /* operation code for |readfrom| */
558    mp_close_from_operation,        /* operation code for |closefrom| */
559    mp_odd_operation,               /* operation code for |odd| */
560    mp_known_operation,             /* operation code for |known| */
561    mp_unknown_operation,           /* operation code for |unknown| */
562    mp_not_operation,               /* operation code for |not| */
563    mp_decimal_operation,           /* operation code for |decimal| */
564    mp_reverse_operation,           /* operation code for |reverse| */
565    mp_uncycle_operation,           /* operation code for |uncycle| */
566    mp_make_path_operation,         /* operation code for |makepath| */
567    mp_make_pen_operation,          /* operation code for |makepen| */
568    mp_make_nep_operation,          /* operation code for |makenep| */
569    mp_convexed_operation,          /* operation code for |convexed| */
570    mp_uncontrolled_operation,      /* operation code for |uncontrolled| */
571    mp_oct_operation,               /* operation code for |oct| */
572    mp_hex_operation,               /* operation code for |hex| */
573    mp_ASCII_operation,             /* operation code for |ASCII| */
574    mp_char_operation,              /* operation code for |char| */
575    mp_length_operation,            /* operation code for |length| */
576    mp_no_length_operation,         /* operation code for |nolength| */
577    mp_turning_operation,           /* operation code for |turningnumber| */
578    mp_color_model_operation,       /* operation code for |colormodel| */
579    mp_path_part_operation,         /* operation code for |pathpart| */
580    mp_pen_part_operation,          /* operation code for |penpart| */
581    mp_dash_part_operation,         /* operation code for |dashpart| */
582    mp_prescript_part_operation,    /* operation code for |prescriptpart| */
583    mp_postscript_part_operation,   /* operation code for |postscriptpart| */
584    mp_stacking_part_operation,     /* operation code for |stackingpart| */
585    mp_sqrt_operation,              /* operation code for |sqrt| */
586    mp_m_exp_operation,             /* operation code for |mexp| */
587    mp_m_log_operation,             /* operation code for |mlog| */
588    mp_sin_d_operation,             /* operation code for |sind| */
589    mp_cos_d_operation,             /* operation code for |cosd| */
590    mp_floor_operation,             /* operation code for |floor| */
591    mp_uniform_deviate_operation,   /* operation code for |uniformdeviate| */
592    mp_ll_corner_operation,         /* operation code for |llcorner| */
593    mp_lr_corner_operation,         /* operation code for |lrcorner| */
594    mp_ul_corner_operation,         /* operation code for |ulcorner| */
595    mp_ur_corner_operation,         /* operation code for |urcorner| */
596    mp_center_of_operation,         /* operation code for |centerof| */
597    mp_center_of_mass_operation,    /* operation code for |centerofmass| */
598    mp_corners_operation,           /* operation code for |corners| */
599    mp_x_range_operation,           /* operation code for |xrange| */
600    mp_y_range_operation,           /* operation code for |yrange| */
601    mp_delta_point_operation,       /* operation code for |deltapoint| */
602    mp_delta_precontrol_operation,  /* operation code for |deltaprecontrol| */
603    mp_delta_postcontrol_operation, /* operation code for |deltapostcontrol| */
604    mp_delta_direction_operation,   /* operation code for |deltadirection| */
605    mp_arc_length_operation,        /* operation code for |arclength| */
606    mp_angle_operation,             /* operation code for |angle| */
607    mp_cycle_operation,             /* operation code for |cycle| */
608    mp_no_cycle_operation,          /* operation code for |nocycle| */
609    mp_x_relative_operation,        /* operation code for |xrelative| */
610    mp_y_relative_operation,        /* operation code for |yrelative| */
611    mp_xy_relative_operation,       /* operation code for |xyrelative| */
612    mp_x_absolute_operation,        /* operation code for |xabsolute| */
613    mp_y_absolute_operation,        /* operation code for |yabsolute| */
614    mp_xy_absolute_operation,       /* operation code for |xyabsolute| */
615    mp_filled_operation,            /* operation code for |filled| */
616    mp_stroked_operation,           /* operation code for |stroked| */
617    mp_clipped_operation,           /* operation code for |clipped| */
618    mp_grouped_operation,           /* operation code for |bounded| */
619    mp_bounded_operation,           /* operation code for |grouped| */
620    mp_plus_operation,              /* operation code for \.+ */
621    mp_minus_operation,             /* operation code for \.- */
622    mp_times_operation,             /* operation code for \.* */
623    mp_over_operation,              /* operation code for \./ */
624    mp_power_operation,             /* operation code for \.^ */
625    mp_pythag_add_operation,        /* operation code for |++| */
626    mp_pythag_sub_operation,        /* operation code for |+-+| */
627    mp_or_operation,                /* operation code for |or| */
628    mp_and_operation,               /* operation code for |and| */
629    mp_less_than_operation,         /* operation code for \.< */
630    mp_less_or_equal_operation,     /* operation code for |<=| */
631    mp_greater_than_operation,      /* operation code for \.> */
632    mp_greater_or_equal_operation,  /* operation code for |>=| */
633    mp_equal_operation,             /* operation code for \.= */
634    mp_unequal_operation,           /* operation code for |<>| */
635    mp_concat_operation,            /* operation code for \.\& */
636    mp_just_append_operation,       /* operation code for \.\&\& */
637    mp_tolerant_concat_operation,   /* operation code for \.\&\&\& */
638    mp_tolerant_append_operation,   /* operation code for \.\&\&\&\& */
639    mp_rotated_operation,           /* operation code for |rotated| */
640    mp_slanted_operation,           /* operation code for |slanted| */
641    mp_scaled_operation,            /* operation code for |scaled| */
642    mp_shifted_operation,           /* operation code for |shifted| */
643    mp_transformed_operation,       /* operation code for |transformed| */
644    mp_x_scaled_operation,          /* operation code for |xscaled| */
645    mp_y_scaled_operation,          /* operation code for |yscaled| */
646    mp_z_scaled_operation,          /* operation code for |zscaled| */
647    mp_xy_scaled_operation,         /* operation code for |xyscaled| */
648    mp_uncycled_operation,          /* operation code for |uncycled| */
649    mp_intertimes_operation,        /* operation code for |intersectiontimes| */
650    mp_intertimes_list_operation,   /* operation code for |intersectiontimeslist| */
651    mp_double_dot_operation,        /* operation code for improper |..| */
652    /* the |of| operations: */
653    mp_substring_operation,         /* operation code for |substring| */
654    mp_subpath_operation,           /* operation code for |subpath| */
655    mp_direction_time_operation,    /* operation code for |directiontime| */
656    mp_point_operation,             /* operation code for |point| */
657    mp_precontrol_operation,        /* operation code for |precontrol| */
658    mp_postcontrol_operation,       /* operation code for |postcontrol| */
659    mp_direction_operation,         /* operation code for |direction| */
660    mp_path_point_operation,        /* operation code for |pathpoint| */
661    mp_path_precontrol_operation,   /* operation code for |pathprecontrol| */
662    mp_path_postcontrol_operation,  /* operation code for |pathpostcontrol| */
663    mp_path_direction_operation,    /* operation code for |pathdirection| */
664    mp_path_state_operation,        /* operation code for |pathstate| */
665    mp_path_index_operation,        /* operation code for |pathindex| */
666    mp_path_lastindex_operation,    /* operation code for |pathlastindex| */
667    mp_path_length_operation,       /* operation code for |pathlength| */
668    mp_path_first_operation,        /* operation code for |pathfirst| */
669    mp_path_last_operation,         /* operation code for |pathlast| */
670    mp_pen_offset_operation,        /* operation code for |penoffset| */
671    mp_arc_time_operation,          /* operation code for |arctime| */
672    mp_arc_point_operation,         /* operation code for |arcpoint| */
673    mp_arc_point_list_operation,    /* operation code for |arcpointlist| */
674    mp_subarc_length_operation,     /* operation code for |subarclength| */
675    mp_version_operation,           /* operation code for |mpversion| */
676    mp_envelope_operation,          /* operation code for |envelope| */
677    mp_boundingpath_operation,      /* operation code for |boundingpath| */
678} mp_name_type_type;
679
680# define mp_min_of_operation mp_substring_operation
681
682typedef enum mp_class_codes {
683    mp_digit_class             =  0, /* the class number of |0123456789| */
684    mp_period_class            =  1, /* the class number of |.| */
685    mp_space_class             =  2, /* the class number of spaces and nonstandard characters */
686    mp_percent_class           =  3, /* the class number of `\.\%' */
687    mp_string_class            =  4, /* the class number of |"| */
688    mp_comma_class             =  5, /* the , */
689    mp_semicolon_class         =  6, /* the ; */
690    mp_left_parenthesis_class  =  7, /* the class number of |(| */
691    mp_right_parenthesis_class =  8, /* the class number of |)| */
692    mp_letter_class            =  9, /* letters and the underline character */
693    mp_suffix_class            = 15,
694    mp_left_bracket_class      = 17, /* |[| */
695    mp_right_bracket_class     = 18, /* |]| */
696    mp_brace_class             = 19,
697    mp_invalid_class           = 20, /* bad character in the input */
698    mp_max_class               = 20, /* the largest class number */
699} mp_class_codes;
700
701typedef enum mp_text_codes {
702    mp_forever_text,     /* |token_type| code for loop texts */
703    mp_loop_text,        /* |token_type| code for loop texts */
704    mp_parameter_text,   /* |token_type| code for parameter texts */
705    mp_backed_up_text,   /* |token_type| code for texts to be reread */
706    mp_inserted_text,    /* |token_type| code for inserted texts */
707    mp_macro_text,       /* |token_type| code for macro replacement texts */
708    mp_file_bottom_text, /* lowest file code */
709} mp_text_codes;
710
711typedef enum mp_scanner_states {
712    mp_normal_state,        /* |scanner_status| at \quote {quiet times} */
713    mp_skipping_state,      /* |scanner_status| when false conditional text is being skipped */
714    mp_flushing_state,      /* |scanner_status| when junk after a statement is being ignored */
715    mp_absorbing_state,     /* |scanner_status| when a |text| parameter is being scanned */
716    mp_var_defining_state,  /* |scanner_status| when a |vardef| is being scanned */
717    mp_op_defining_state,   /* |scanner_status| when a macro |def| is being scanned */
718    mp_loop_defining_state, /* |scanner_status| when a |for| loop is being scanned */
719    mp_tex_flushing_state,
720} mp_scanner_states;
721
722typedef enum mp_verbatim_codes {
723    mp_btex_code,
724    mp_verbatim_code,
725} mp_verbatim_codes;
726
727typedef enum mp_def_codes {
728    mp_end_def_code,       /* command modifier for |enddef| */
729    mp_def_code,           /* command modifier for |def| */
730    mp_var_def_code,       /* command modifier for |vardef| */
731    mp_primary_def_code,   /* command modifier for |primarydef| */
732    mp_secondary_def_code, /* command modifier for |secondarydef| */
733    mp_tertiary_def_code,  /* command modifier for |tertiarydef| */
734} mp_def_codes;
735
736typedef enum mp_only_set_codes {
737    mp_random_seed_code,
738    mp_max_knot_pool_code,
739} mp_only_set_codes;
740
741typedef enum mp_for_codes {
742    mp_end_for_code,           /* command modifier for |endfor| */
743    mp_start_forever_code,     /* command modifier for |forever| */
744    mp_start_for_code,         /* command modifier for |for| */
745    mp_start_forsuffixes_code, /* command modifier for |forsuffixes| */
746} mp_for_codes;
747
748typedef enum mp_macro_fix_codes {
749    mp_macro_quote_code,  /* |macro_special| modifier for |quote| */
750    mp_macro_prefix_code, /* |macro_special| modifier for |\#\AT!| */
751    mp_macro_at_code,     /* |macro_special| modifier for |\AT!| */
752    mp_macro_suffix_code, /* |macro_special| modifier for |\AT!\#| */
753} mp_macro_fix_codes;
754
755typedef enum mp_controls_codes {
756    mp_both_controls_code, 
757    mp_first_control_code,
758    mp_second_control_code,
759} mp_controls_codes;
760
761typedef enum mp_if_codes {
762    mp_no_if_code,
763    mp_if_code,      /* code for |if| being evaluated */
764    mp_fi_code,      /* code for |fi| */
765    mp_else_code,    /* code for |else| */
766    mp_else_if_code, /* code for |elseif| */
767} mp_if_codes;
768
769typedef enum mp_show_codes {
770    mp_show_token_code,        /* show the meaning of a single token */
771    mp_show_stats_code,        /* show current memory and string usage */
772    mp_show_code,              /* show a list of expressions */
773    mp_show_var_code,          /* show a variable and its descendents */
774    mp_show_dependencies_code, /* show dependent variables in terms of independents */
775} mp_show_codes;
776
777typedef enum mp_with_codes {
778    mp_with_pen_code,
779    mp_with_dashed_code,
780    mp_with_pre_script_code,
781    mp_with_post_script_code,
782    mp_with_nested_pre_script_code,
783    mp_with_nested_post_script_code,
784    mp_with_stacking_code,
785    mp_with_no_model_code,
786    mp_with_grey_model_code,
787    mp_with_uninitialized_model_code,
788    mp_with_rgb_model_code,
789    mp_with_cmyk_model_code,
790    mp_with_linecap_code,
791    mp_with_linejoin_code,
792    mp_with_miterlimit_code,
793    mp_with_curvature_code,
794    mp_with_nothing_code,    /* quits scanning of a with, avoids lookahead */
795} mp_with_codes;
796
797typedef enum mp_add_codes {
798    mp_add_double_path_code, /* command modifier for |doublepath| */
799    mp_add_contour_code,     /* command modifier for |contour| */
800    mp_add_also_code,        /* command modifier for |also| */
801} mp_add_codes ;
802
803typedef enum mp_message_codes {
804    mp_normal_message_code,
805    mp_error_message_code,
806    mp_error_help_code,
807} mp_message_codes;
808
809typedef enum mp_protection_codes {
810    mp_inner_protection_code,
811    mp_outer_protection_code,
812} mp_protection_codes;
813
814typedef enum mp_input_codes {
815    mp_input_code,
816    mp_end_input_code,
817} mp_input_codes;
818
819typedef enum mp_stop_codes {
820    mp_end_code,
821    mp_dump_code,
822} mp_stop_codes;
823
824/* types in the outer block */
825
826typedef void   (*convert_func)                      (mp_number *r);
827typedef void   (*m_log_func)                        (MP mp, mp_number *r, mp_number *a);
828typedef void   (*m_exp_func)                        (MP mp, mp_number *r, mp_number *a);
829typedef void   (*m_unif_rand_func)                  (MP mp, mp_number *ret, mp_number *x_orig);
830typedef void   (*m_norm_rand_func)                  (MP mp, mp_number *ret);
831typedef void   (*pyth_add_func)                     (MP mp, mp_number *r, mp_number *a, mp_number *b);
832typedef void   (*pyth_sub_func)                     (MP mp, mp_number *r, mp_number *a, mp_number *b);
833typedef void   (*power_of_func)                     (MP mp, mp_number *r, mp_number *a, mp_number *b);
834typedef void   (*n_arg_func)                        (MP mp, mp_number *r, mp_number *a, mp_number *b);
835typedef void   (*velocity_func)                     (MP mp, mp_number *r, mp_number *a, mp_number *b, mp_number *c, mp_number *d, mp_number *e);
836typedef int    (*ab_vs_cd_func)                     (mp_number *a, mp_number *b, mp_number *c, mp_number *d);
837typedef void   (*crossing_point_func)               (MP mp, mp_number *r, mp_number *a, mp_number *b, mp_number *c);
838typedef void   (*number_from_int_func)              (mp_number *A, int B);
839typedef void   (*number_from_boolean_func)          (mp_number *A, int B);
840typedef void   (*number_from_scaled_func)           (mp_number *A, int B);
841typedef void   (*number_from_double_func)           (mp_number *A, double B);
842typedef void   (*number_from_addition_func)         (mp_number *A, mp_number *B, mp_number *C);
843typedef void   (*number_half_from_addition_func)    (mp_number *A, mp_number *B, mp_number *C);
844typedef void   (*number_from_subtraction_func)      (mp_number *A, mp_number *B, mp_number *C);
845typedef void   (*number_half_from_subtraction_func) (mp_number *A, mp_number *B, mp_number *C);
846typedef void   (*number_from_div_func)              (mp_number *A, mp_number *B, mp_number *C);
847typedef void   (*number_from_mul_func)              (mp_number *A, mp_number *B, mp_number *C);
848typedef void   (*number_from_int_div_func)          (mp_number *A, mp_number *B, int C);
849typedef void   (*number_from_int_mul_func)          (mp_number *A, mp_number *B, int C);
850typedef void   (*number_from_of_the_way_func)       (MP mp, mp_number *A, mp_number *t, mp_number *B, mp_number *C);
851typedef void   (*number_negate_func)                (mp_number *A);
852typedef void   (*number_add_func)                   (mp_number *A, mp_number *B);
853typedef void   (*number_subtract_func)              (mp_number *A, mp_number *B);
854typedef void   (*number_modulo_func)                (mp_number *A, mp_number *B);
855typedef void   (*number_half_func)                  (mp_number *A);
856typedef void   (*number_double_func)                (mp_number *A);
857typedef void   (*number_abs_func)                   (mp_number *A);
858typedef void   (*number_clone_func)                 (mp_number *A, mp_number *B);
859typedef void   (*number_negated_clone_func)         (mp_number *A, mp_number *B);
860typedef void   (*number_abs_clone_func)             (mp_number *A, mp_number *B);
861typedef void   (*number_swap_func)                  (mp_number *A, mp_number *B);
862typedef void   (*number_add_scaled_func)            (mp_number *A, int b);
863typedef void   (*number_multiply_int_func)          (mp_number *A, int b);
864typedef void   (*number_divide_int_func)            (mp_number *A, int b);
865typedef int    (*number_to_int_func)                (mp_number *A);
866typedef int    (*number_to_boolean_func)            (mp_number *A);
867typedef int    (*number_to_scaled_func)             (mp_number *A);
868typedef int    (*number_round_func)                 (mp_number *A);
869typedef void   (*number_floor_func)                 (mp_number *A);
870typedef double (*number_to_double_func)             (mp_number *A);
871typedef int    (*number_odd_func)                   (mp_number *A);
872typedef int    (*number_equal_func)                 (mp_number *A, mp_number *B);
873typedef int    (*number_less_func)                  (mp_number *A, mp_number *B);
874typedef int    (*number_greater_func)               (mp_number *A, mp_number *B);
875typedef int    (*number_non_equal_abs_func)         (mp_number *A, mp_number *B);
876typedef void   (*make_scaled_func)                  (MP mp, mp_number *ret, mp_number *A, mp_number *B);
877typedef void   (*make_fraction_func)                (MP mp, mp_number *ret, mp_number *A, mp_number *B);
878typedef void   (*take_fraction_func)                (MP mp, mp_number *ret, mp_number *A, mp_number *B);
879typedef void   (*take_scaled_func)                  (MP mp, mp_number *ret, mp_number *A, mp_number *B);
880typedef void   (*sin_cos_func)                      (MP mp, mp_number *A, mp_number *S, mp_number *C);
881typedef void   (*slow_add_func)                     (MP mp, mp_number *A, mp_number *S, mp_number *C);
882typedef void   (*sqrt_func)                         (MP mp, mp_number *ret, mp_number *A);
883typedef void   (*init_randoms_func)                 (MP mp, int seed);
884typedef void   (*allocate_number_func)              (MP mp, mp_number *A, mp_number_type t);
885typedef void   (*allocate_number_clone_func)        (MP mp, mp_number *A, mp_number_type t, mp_number *B);
886typedef void   (*allocate_number_abs_func)          (MP mp, mp_number *A, mp_number_type t, mp_number *B);
887typedef void   (*allocate_number_double_func)       (MP mp, mp_number *A, double B);
888typedef void   (*free_number_func)                  (MP mp, mp_number *n);
889typedef void   (*fraction_to_round_scaled_func)     (mp_number *n);
890typedef void   (*print_func)                        (MP mp, mp_number *A);
891typedef char  *(*tostring_func)                     (MP mp, mp_number *A);
892typedef void   (*scan_func)                         (MP mp, int A);
893typedef void   (*mp_free_func)                      (MP mp);
894typedef void   (*set_precision_func)                (MP mp);
895
896/*tex
897    We use a prefix |md_| so that we don't get complaints about recursive macro definitions. This
898    is cleaner than redefining the macros.
899*/
900
901typedef struct math_data {
902    mp_number                         md_precision_default;
903    mp_number                         md_precision_max;
904    mp_number                         md_precision_min;
905    mp_number                         md_epsilon_t;
906    mp_number                         md_inf_t;
907    mp_number                         md_negative_inf_t;
908    mp_number                         md_one_third_inf_t;
909    mp_number                         md_zero_t;
910    mp_number                         md_unity_t;
911    mp_number                         md_two_t;
912    mp_number                         md_three_t;
913    mp_number                         md_half_unit_t;
914    mp_number                         md_three_quarter_unit_t;
915    mp_number                         md_fraction_one_t;
916    mp_number                         md_fraction_half_t;
917    mp_number                         md_fraction_three_t;
918    mp_number                         md_fraction_four_t;
919    mp_number                         md_one_eighty_deg_t;
920    mp_number                         md_negative_one_eighty_deg_t;
921    mp_number                         md_three_sixty_deg_t;
922    mp_number                         md_one_k;
923    mp_number                         md_sqrt_8_e_k;
924    mp_number                         md_twelve_ln_2_k;
925    mp_number                         md_coef_bound_k;
926    mp_number                         md_coef_bound_minus_1;
927    mp_number                         md_twelvebits_3;
928    mp_number                         md_arc_tol_k;
929    mp_number                         md_twentysixbits_sqrt2_t;
930    mp_number                         md_twentyeightbits_d_t;
931    mp_number                         md_twentysevenbits_sqrt2_d_t;
932    mp_number                         md_fraction_threshold_t;
933    mp_number                         md_half_fraction_threshold_t;
934    mp_number                         md_scaled_threshold_t;
935    mp_number                         md_half_scaled_threshold_t;
936    mp_number                         md_near_zero_angle_t;
937    mp_number                         md_p_over_v_threshold_t;
938    mp_number                         md_equation_threshold_t;
939    mp_number                         md_warning_limit_t;
940    allocate_number_func              md_allocate;
941    allocate_number_clone_func        md_allocate_clone;
942    allocate_number_abs_func          md_allocate_abs;
943    allocate_number_double_func       md_allocate_double;
944    free_number_func                  md_free;
945    number_from_int_func              md_from_int;
946    number_from_boolean_func          md_from_boolean;
947    number_from_scaled_func           md_from_scaled;
948    number_from_double_func           md_from_double;
949    number_from_addition_func         md_from_addition;
950    number_half_from_addition_func    md_half_from_addition;
951    number_from_subtraction_func      md_from_subtraction;
952    number_half_from_subtraction_func md_half_from_subtraction;
953    number_from_div_func              md_from_div;
954    number_from_mul_func              md_from_mul;
955    number_from_int_div_func          md_from_int_div;
956    number_from_int_mul_func          md_from_int_mul;
957    number_from_of_the_way_func       md_from_of_the_way;
958    number_negate_func                md_negate;
959    number_add_func                   md_add;
960    number_subtract_func              md_subtract;
961    number_half_func                  md_half;
962    number_modulo_func                md_modulo;
963    number_double_func                md_do_double;
964    number_abs_func                   md_abs;
965    number_clone_func                 md_clone;
966    number_negated_clone_func         md_negated_clone;
967    number_abs_clone_func             md_abs_clone;
968    number_swap_func                  md_swap;
969    number_add_scaled_func            md_add_scaled;
970    number_multiply_int_func          md_multiply_int;
971    number_divide_int_func            md_divide_int;
972    number_to_int_func                md_to_int;
973    number_to_boolean_func            md_to_boolean;
974    number_to_scaled_func             md_to_scaled;
975    number_to_double_func             md_to_double;
976    number_odd_func                   md_odd;
977    number_equal_func                 md_equal;
978    number_less_func                  md_less;
979    number_greater_func               md_greater;
980    number_non_equal_abs_func         md_non_equal_abs;
981    number_round_func                 md_round_unscaled;
982    number_floor_func                 md_floor_scaled;
983    make_scaled_func                  md_make_scaled;
984    make_fraction_func                md_make_fraction;
985    take_fraction_func                md_take_fraction;
986    take_scaled_func                  md_take_scaled;
987    velocity_func                     md_velocity;
988    ab_vs_cd_func                     md_ab_vs_cd;
989    crossing_point_func               md_crossing_point;
990    n_arg_func                        md_n_arg;
991    m_log_func                        md_m_log;
992    m_exp_func                        md_m_exp;
993    m_unif_rand_func                  md_m_unif_rand;
994    m_norm_rand_func                  md_m_norm_rand;
995    pyth_add_func                     md_pyth_add;
996    pyth_sub_func                     md_pyth_sub;
997    power_of_func                     md_power_of;
998    fraction_to_round_scaled_func     md_fraction_to_round_scaled;
999    convert_func                      md_fraction_to_scaled;
1000    convert_func                      md_scaled_to_fraction;
1001    convert_func                      md_scaled_to_angle;
1002    convert_func                      md_angle_to_scaled;
1003    init_randoms_func                 md_init_randoms;
1004    sin_cos_func                      md_sin_cos;
1005    sqrt_func                         md_sqrt;
1006    slow_add_func                     md_slow_add;
1007    print_func                        md_print;
1008    tostring_func                     md_tostring;
1009    scan_func                         md_scan_numeric;
1010    scan_func                         md_scan_fractional;
1011    mp_free_func                      md_free_math;
1012    set_precision_func                md_set_precision;
1013} math_data;
1014
1015typedef struct mp_value_node_data *mp_value_node;
1016typedef struct mp_node_data       *mp_node;
1017typedef struct mp_symbol_entry    *mp_symbol;
1018
1019typedef unsigned short quarterword; /* 1/4 of a 64 bit word */
1020typedef int            halfword;    /* 1/2 of a 64 bit word */
1021
1022typedef struct mp_independent_data {
1023    int scale;  /* only for |indep_scale|, used together with |serial| */
1024    int serial; /* only for |indep_value|, used together with |scale| */
1025} mp_independent_data;
1026
1027typedef struct mp_value_data {
1028    mp_independent_data indep;
1029    mp_number           n;
1030    mp_string           str;
1031    mp_symbol           sym;
1032    mp_node             node;
1033    mp_knot             p;
1034} mp_value_data;
1035
1036typedef struct mp_value {
1037    mp_variable_type type;
1038    int              padding;
1039    mp_value_data    data;
1040} mp_value;
1041
1042/*tex
1043
1044\MP\ also has a bunch of internal parameters that a user might want to fuss with. Every such
1045parameter has an identifying code number, defined here.
1046
1047*/
1048
1049typedef enum mp_given_internal {
1050    mp_number_system_internal = 1,   /* the number system as set up by |numbersystem| */
1051    mp_number_precision_internal,    /* the number system precision as set up by |numberprecision| */
1052    mp_job_name_internal,            /* the jobname as set up from the options stucture */
1053    mp_tracing_titles_internal,      /* show titles online when they appear */
1054    mp_tracing_equations_internal,   /* show each variable when it becomes known */
1055    mp_tracing_capsules_internal,    /* show capsules too */
1056    mp_tracing_choices_internal,     /* show the control points chosen for paths */
1057    mp_tracing_specs_internal,       /* show path subdivision prior to filling with polygonal a pen */
1058    mp_tracing_commands_internal,    /* show commands and operations before they are performed */
1059    mp_tracing_restores_internal,    /* show when a variable or internal is restored */
1060    mp_tracing_macros_internal,      /* show macros before they are expanded */
1061    mp_tracing_output_internal,      /* dummy */
1062    mp_tracing_stats_internal,       /* show memory usage at end of job */ /* now a dummy */
1063    mp_tracing_online_internal,      /* show long diagnostics on terminal and in the log file */
1064    mp_year_internal,                /* the current year (e.g., 1984) */
1065    mp_month_internal,               /* the current month (e.g., 3 $\equiv$ March) */
1066    mp_day_internal,                 /* the current day of the month */
1067    mp_time_internal,                /* the number of minutes past midnight when this job started */
1068    mp_hour_internal,                /* the number of hours past midnight when this job started */
1069    mp_minute_internal,              /* the number of minutes in that hour when this job started */
1070    mp_char_code_internal,           /* the number of the next character to be output */
1071    mp_char_wd_internal,             /* the width of the next character to be output */
1072    mp_char_ht_internal,             /* the height of the next character to be output */
1073    mp_char_dp_internal,             /* the depth of the next character to be output */
1074    mp_char_ic_internal,             /* the italic correction of the next character to be output */
1075    mp_pausing_internal,             /* dummy */
1076    mp_showstopping_internal,        /* positive to stop after each |show| command */
1077    mp_texscriptmode_internal,       /* controls spacing in texmode */
1078    mp_overloadmode_internal,
1079    mp_linejoin_internal,            /* as in \ps: 0 for mitered, 1 for round, 2 for beveled */
1080    mp_linecap_internal,             /* as in \ps: 0 for butt, 1 for round, 2 for square */
1081    mp_stacking_internal,
1082    mp_miterlimit_internal,          /* controls miter length as in \ps */
1083    mp_warning_check_internal,       /* controls error message when variable value is large */
1084    mp_default_zero_angle_internal,   
1085    mp_true_corners_internal,        /* positive to make |llcorner| etc. ignore |setbounds| */
1086    mp_default_color_model_internal, /* the default color model for unspecified items */
1087    mp_restore_clip_color_internal,
1088    mp_less_digits_internal,
1089    mp_intersection_precision_internal,
1090    mp_join_tolerance_internal,
1091} mp_given_internal;
1092
1093# define max_given_internal mp_join_tolerance_internal
1094
1095typedef struct mp_internal {
1096    mp_value  v;
1097    char     *intname;
1098    int       run;
1099    int       padding;
1100} mp_internal;
1101
1102typedef struct mp_symbol_entry {
1103    int        type;
1104    int        property; /* we had padding room anyway */
1105    mp_value   v;
1106    mp_string  text;
1107    void      *parent;
1108} mp_symbol_entry;
1109
1110typedef enum mp_macro_info {
1111    mp_general_macro,    /* preface to a macro defined with a parameter list */
1112    mp_primary_macro,    /* preface to a macro with a |primary| parameter */
1113    mp_secondary_macro,  /* preface to a macro with a |secondary| parameter */
1114    mp_tertiary_macro,   /* preface to a macro with a |tertiary| parameter */
1115    mp_expr_macro,       /* preface to a macro with an undelimited |expr| parameter */
1116    mp_of_macro,         /* preface to a macro with undelimited `|expr| |x| |of|~|y|' parameters */
1117    mp_suffix_macro,     /* preface to a macro with an undelimited |suffix| parameter */
1118    mp_text_macro,       /* preface to a macro with an undelimited |text| parameter */
1119    mp_expr_parameter,   /* used by |expr| primitive */
1120    mp_suffix_parameter, /* used by |suffix| primitive */
1121    mp_text_parameter    /* used by |text| primitive */
1122} mp_macro_info;
1123
1124typedef struct mp_save_data {
1125    int                  type;
1126    int                  padding;
1127    mp_internal          value;
1128    struct mp_save_data *link;
1129} mp_save_data;
1130
1131enum mp_bb_code {
1132    mp_x_code, /* index for |minx| and |maxx| */
1133    mp_y_code  /* index for |miny| and |maxy| */
1134};
1135
1136typedef struct mp_dash_node_data *mp_dash_node;
1137
1138typedef struct mp_in_state_record {
1139    int       start_field;
1140    int       loc_field;
1141    int       limit_field;
1142    int       index_field;
1143    mp_node   nstart_field;
1144    mp_node   nloc_field;
1145    mp_string name_field;
1146} mp_in_state_record;
1147
1148typedef struct mp_subst_list_item {
1149    mp_name_type_type          info_mod;
1150    int                        value_mod;
1151    int                        value_data;
1152    int                        padding;
1153    mp_symbol                  info;
1154    struct mp_subst_list_item *link;
1155} mp_subst_list_item;
1156
1157typedef struct mp_loop_data {
1158    mp_symbol            var ;        /* the var of the loop */
1159    mp_node              info;        /* iterative text of this loop */
1160    mp_node              type;        /* the special type of this loop, or a pointer into mem */
1161    mp_node              list;        /* the remaining list elements */
1162    mp_node              list_start;  /* head fo the list of elements */
1163    mp_number            old_value;   /* previous value of current arithmetic value */
1164    mp_number            value;       /* current arithmetic value */
1165    mp_number            step_size;   /* arithmetic step size */
1166    mp_number            final_value; /* end arithmetic value */
1167    struct mp_loop_data *link;        /* the enclosing loop, if any */
1168    mp_knot              point;
1169} mp_loop_data;
1170
1171typedef struct File {
1172    FILE *f;
1173} File;
1174
1175/* constants in the outer block */
1176
1177/* The size of stack for bisection algorithms; it should probably be left at this value. */
1178
1179# define bistack_size 1500
1180
1181typedef struct MP_instance {
1182    /*  */
1183    void               *userdata;               /* this allows the calling application to setup local (e.g. L for Lua) */
1184    char               *banner;                 /* the banner that is printed to the screen and log */
1185    int                 utf8_mode;
1186    int                 text_mode;
1187    int                 show_mode;
1188    int                 halt_on_error;          /* do we quit at the first error? */
1189    /*  */
1190    mp_file_finder      find_file;
1191    mp_script_runner    run_script;
1192    mp_internal_runner  run_internal;
1193    mp_log_runner       run_logger;
1194    mp_overload_runner  run_overload;
1195    mp_error_runner     run_error;
1196    mp_warning_runner   run_warning;
1197    mp_text_maker       make_text;
1198    mp_file_opener      open_file;
1199    mp_file_closer      close_file;
1200    mp_file_reader      read_file;
1201    mp_file_writer      write_file;
1202    int                 find_file_id;
1203    int                 run_script_id;
1204    int                 run_internal_id;
1205    int                 run_logger_id;
1206    int                 run_overload_id;
1207    int                 run_error_id;
1208    int                 run_warning_id;
1209    int                 make_text_id;
1210    int                 open_file_id;
1211    /*  */
1212    int                 less_digits; 
1213    int                 interaction;
1214    int                 random_seed;
1215    int                 math_mode;
1216    /*  */
1217    char               *job_name;
1218    /*  */
1219    mp_backend_writer   shipout_backend;
1220    /*  */
1221    math_data          *math;
1222    /*  */
1223    int                 max_in_open;            /* maximum number of input files and error insertions that can be going on simultaneously */
1224    int                 param_size;             /* maximum number of simultaneous macro parameters */
1225    /*  */
1226    char               *name_of_file;           /* the name of a system file */
1227    /*  */
1228    size_t              buf_size;               /* maximum number of characters simultaneously present in current lines of open files */
1229    unsigned char      *buffer;                 /* lines of characters being read */
1230    size_t              first;                  /* the first unused position in |buffer| */
1231    size_t              last;                   /* end of the line just input to |buffer| */
1232    size_t              max_buf_stack;          /* largest index used in |buffer| */
1233    /*  */
1234    void               *term_in;                /* the terminal as an input file */
1235    /*  */
1236    avl_tree            strings;                /* string avl tree */
1237    unsigned char      *cur_string;             /*  current string buffer */
1238    size_t              cur_length;             /* current index in that buffer */
1239    size_t              cur_string_size;        /*  malloced size of |cur_string| */
1240    /*  */
1241    int                 pool_in_use;            /* total number of string bytes actually in use */
1242    int                 max_pl_used;            /* maximum |pool_in_use| so far */
1243    int                 strs_in_use;            /* total number of strings actually in use */
1244    int                 max_strs_used;          /* maximum |strs_in_use| so far */
1245    /*  */
1246    unsigned int        selector;               /* where to print a message */
1247    unsigned int        term_offset;            /* the number of characters on the current terminal line */
1248    unsigned int        file_offset;            /* the number of characters on the current file line */
1249    /*  */
1250    int                 history;                /* has the source input been clean so far? */
1251    int                 error_count;            /* the number of scrolled errors since the last statement ended */
1252    /*  */
1253    int                 use_err_help;           /* should the |err_help| string be shown? */
1254    int                 padding_help;           /* well ... why not.  */
1255    mp_string           err_help;               /* a string set up by |errhelp| */
1256    /*  */
1257    jmp_buf            *jump_buf;
1258    /*  */
1259    int                 run_state;              /* are we processing input ? */
1260    int                 finished;               /* set true by |close_files_and_terminate| */
1261    /*  */
1262    int                 arith_error;
1263    /*  */
1264    mp_number           randoms[55];            /* the last 55 random values generated */
1265    int                 j_random;               /* the number of unused |randoms| */
1266    int                 j_padding;              /* the number of unused |randoms| */
1267    /*  */
1268    mp_node             token_nodes;
1269    mp_node             pair_nodes;
1270    int                 num_token_nodes;
1271    int                 num_pair_nodes;
1272    mp_knot             knot_nodes;
1273    mp_node             value_nodes;
1274    int                 max_knot_nodes;
1275    int                 num_knot_nodes;
1276    int                 num_value_nodes;
1277    mp_node             symbolic_nodes;
1278    int                 num_symbolic_nodes;
1279    /*  */
1280    size_t              var_used;               /* how much memory is in use */
1281    size_t              var_used_max;           /* how much memory was in use max */
1282    /*  */
1283    mp_dash_node        null_dash;
1284    mp_value_node       dep_head;
1285    mp_node             inf_val;
1286    mp_node             zero_val;
1287    mp_node             temp_val;
1288    mp_node             end_attr;
1289    mp_node             bad_vardef;
1290    mp_node             temp_head;
1291    mp_node             hold_head;
1292    mp_node             spec_head;
1293    /*  */
1294    mp_internal        *internal;               /* the values of internal quantities */
1295    int                 int_ptr;                /* the maximum internal quantity defined so far */
1296    int                 max_internal;           /* current maximum number of internal quantities */
1297    /*  */
1298    unsigned int        old_selector;
1299    /*  */
1300    int                 char_class[256];
1301    /*  */
1302    int                 st_count;               /* total number of known identifiers */
1303    avl_tree            symbols;                /* avl tree of symbolic tokens */
1304    avl_tree            frozen_symbols;         /* avl tree of frozen symbolic tokens */
1305    avl_iterator        symbol_iterator;
1306    mp_symbol           frozen_bad_vardef;
1307    mp_symbol           frozen_colon;
1308    mp_symbol           frozen_end_def;
1309    mp_symbol           frozen_end_for;
1310    mp_symbol           frozen_end_group;
1311    mp_symbol           frozen_etex;
1312    mp_symbol           frozen_fi;
1313    mp_symbol           frozen_inaccessible;
1314    mp_symbol           frozen_left_bracket;
1315    mp_symbol           frozen_repeat_loop;
1316    mp_symbol           frozen_right_delimiter;
1317    mp_symbol           frozen_semicolon;
1318    mp_symbol           frozen_slash;
1319    mp_symbol           frozen_undefined;
1320    mp_symbol           frozen_dump;
1321    /*  */
1322    mp_symbol           id_lookup_test;
1323    /*  */
1324    mp_save_data       *save_ptr;               /* the most recently saved item */
1325    /*  */
1326    mp_knot             path_tail;              /* the node that links to the beginning of a path */
1327    /*  */
1328    int                 path_size;              /* maximum number of knots between breakpoints of a path */
1329    int                 path_padding;           /* be nice */
1330    mp_number          *delta_x;
1331    mp_number          *delta_y;
1332    mp_number          *delta;                  /* knot differences */
1333    mp_number          *psi;                    /* turning angles */
1334    /*  */
1335    mp_number          *theta;                  /* values of $\theta_k$ */
1336    mp_number          *uu;                     /* values of $u_k$ */
1337    mp_number          *vv;                     /* values of $v_k$ */
1338    mp_number          *ww;                     /* values of $w_k$ */
1339    /*  */
1340    mp_number           st;
1341    mp_number           ct;
1342    mp_number           sf;
1343    mp_number           cf;                     /* sines and cosines */
1344    /*  */
1345    mp_number           bbmin[2];
1346    mp_number           bbmax[2];
1347    /*  */
1348    mp_number           half_cos[8];            /* ${1\over2}\cos(45k)$ */
1349    mp_number           d_cos[8];               /* a magic constant times $\cos(45k)$ */
1350    /*  */
1351    mp_number           cur_x;
1352    mp_number           cur_y;                  /* all-purpose return value registers */
1353    /*  */
1354    int                 spec_offset;            /* number of pen edges between |h| and the initial offset */
1355    int                 spec_padding;           /* be nice */
1356    /*  */
1357    mp_knot             spec_p1;
1358    mp_knot             spec_p2;                /* pointers to distinguished knots */
1359    /*  */
1360    unsigned int        tol_step;               /* either 0 or 3, usually */
1361    /*  */
1362    mp_number          *bisect_stack;
1363    int                 bisect_ptr;
1364    /*  */
1365    mp_number           cur_t;
1366    mp_number           cur_tt;                 /* controls and results of |cubic_intersection| */
1367    int                 time_to_go;             /* this many backtracks before giving up */
1368    mp_number           max_t;                  /* maximum of $2^{l+1}$ so far achieved */
1369    /*  */
1370    mp_number           delx;
1371    mp_number           dely;                   /* the components of $\Delta=2^l(w_0-z_0)$ */
1372    int                 tol;                    /* bound on the uncertainty in the overlap test */
1373    int                 uv;
1374    int                 xy;                     /* pointers to the current packets of interest */
1375    int                 three_l;                /* |tol_step| times the bisection level */
1376    mp_number           appr_t;
1377    mp_number           appr_tt;                /* best approximations known to the answers */
1378    /*  */
1379    int                 serial_no;              /* the most recent serial number */
1380    /*  */
1381    int                 fix_needed;             /* does at least one |independent| variable need scaling? */
1382    int                 watch_coefs;            /* should we scale coefficients that exceed |coef_bound|? */
1383    mp_value_node       dep_final;              /* location of the constant term and final link */
1384    /*  */
1385    mp_node             cur_mod_;               /* current command, symbol, and its operands */
1386    /*  */
1387    mp_in_state_record *input_stack;
1388    int                 input_ptr;              /* first unused location of |input_stack| */
1389    int                 max_in_stack;           /* largest value of |input_ptr| when pushing */
1390    mp_in_state_record  cur_input;              /* the \quote {top} input state */
1391    int                 stack_size;             /* maximum number of simultaneous input sources */
1392    /*  */
1393    int                 in_open;                /* the number of lines in the buffer, less one */
1394    int                 in_open_max;            /* highest value of |in_open| ever seen */
1395    unsigned int        open_parens;            /* the number of open text files */
1396    void              **input_file;
1397    int                *line_stack;             /* the line number for each file */
1398    /*  */
1399    mp_node            *param_stack;            /* token list pointers for parameters */
1400    int                 param_ptr;              /* first unused entry in |param_stack| */
1401    int                 max_param_stack;        /* largest value of |param_ptr| */
1402    /*  */
1403    int                 file_ptr;               /* shallowest level shown by |show_context| */
1404    /*  */
1405    int                 scanner_status;         /* are we scanning at high speed? */
1406    mp_symbol           warning_info;           /* if so, what else do we need to know, in case an error occurs? */
1407    int                 warning_line;
1408    mp_node             warning_info_node;
1409    /*  */
1410    int                 force_eof;              /* should the next |input| be aborted early? */
1411    /*  */
1412    mp_symbol           bg_loc;
1413    mp_symbol           eg_loc;                 /* hash addresses of |begingroup| and |endgroup| */
1414    /*  */
1415    int                 expand_depth_count;     /* current expansion depth */
1416    int                 expand_depth;           /* current expansion depth */
1417    /*  */
1418    mp_node             cond_ptr;               /* top of the condition stack */
1419    int                 if_limit;               /* upper bound on |fi_or_else| codes */
1420    int                 cur_if;                 /* type of conditional being worked on */
1421    int                 if_line;                /* line where that conditional began */
1422    /*  */
1423    mp_loop_data       *loop_ptr;               /* top of the loop-control-node stack */
1424    /*  */
1425    char               *cur_name;               /* name of file just scanned */
1426    /*  */
1427    int                 quoted_filename;        /* whether the filename is wrapped in " markers */
1428    /*  */
1429    int                 max_read_files;         /* maximum number of simultaneously open |readfrom| files */
1430    void              **rd_file;                /* |readfrom| files */
1431    char              **rd_fname;               /* corresponding file name or 0 if file not open */
1432    int                 read_files;             /* number of valid entries in the above arrays */
1433    int                 max_write_files;        /* maximum number of simultaneously open |write| */
1434    void              **wr_file;                /* |write| files */
1435    char              **wr_fname;               /* corresponding file name or 0 if file not open */
1436    int                 write_files;            /* number of valid entries in the above arrays */
1437    /*  */
1438    mp_value            cur_exp;                /* the value of the expression just found */
1439    /*  */
1440    mp_number           max_c   [mp_proto_dependent_type + 1]; /* max coefficient magnitude */
1441    mp_value_node       max_ptr [mp_proto_dependent_type + 1]; /* where |p| occurs with |max_c| */
1442    mp_value_node       max_link[mp_proto_dependent_type + 1]; /* other occurrences of |p| */
1443    /*  */
1444    int                 var_flag;               /* command that wants a variable */
1445    /*  */
1446    mp_string           eof_line;
1447    mp_string           eof_file;
1448    /*  */
1449    mp_number           txx;                    /* current transform coefficients */
1450    mp_number           txy;
1451    mp_number           tyx;
1452    mp_number           tyy;
1453    mp_number           tx;
1454    mp_number           ty;
1455    /*  */
1456    mp_run_data         run_data;
1457    /*  */
1458    int                 last_add_type;          /* command modifier that identifies the last |addto| command */
1459    /*  */
1460    mp_symbol           every_job_sym;
1461    /*  */
1462    int                 long_help_seen;         /* has the long |\\errmessage| help been used? */
1463    /*  */
1464    int                 ten_pow[10];            /* $10^0..10^9$ */
1465    int                 scaled_out;             /* amount of |scaled| that was taken out in |divide_scaled| */
1466    /*  */
1467} MP_instance;
1468
1469/*tex
1470
1471The user's terminal acts essentially like other files of text, except that it is used both for input
1472and for output. When the terminal is considered an input file, the file variable is called |term_in|,
1473and when it is considered an output file the file variable is |term_out|.
1474
1475Sometimes it is necessary to synchronize the input/output mixture that happens on the user's terminal,
1476and three system-dependent procedures are used for this purpose. The first of these, |update_terminal|,
1477is called when we want to make sure that everything we have output to the terminal so far has actually
1478left the computer's internal buffers and been sent. The second, |clear_terminal|, is called when we
1479wish to cancel any input that the user may have typed ahead (since we are about to issue an unexpected
1480error message). The third, |wake_up_terminal|, is supposed to revive the terminal if the user has
1481disabled it by some instruction to the operating system. The following macros show how these operations
1482can be specified:The global variable |loc| should be set so that the character to be read next by \MP\
1483is in |buffer [loc]|. This character should not be blank, and we should have |loc < last|.
1484
1485*/
1486
1487// # define update_terminal()  mp_print_nl_only(mp); /* empty the terminal output buffer */
1488// # define clear_terminal()                         /* clear the terminal input buffer */
1489// # define wake_up_terminal() mp_print_nl_only(mp); /* cancel the user's cancellation of output */
1490
1491typedef enum mp_selectors {
1492    mp_new_string_selector,   /* printing is deflected to the string pool */
1493    mp_no_print_selector,     /* |selector| setting that makes data disappear */
1494    mp_term_only_selector,    /* printing is destined for the terminal only */
1495    mp_log_only_selector,     /* printing is destined for the transcript file only */
1496    mp_term_and_log_selector, /* normal |selector| setting */
1497    mp_first_file_selector,   /* first write file selector */
1498} mp_selectors;
1499
1500typedef enum mp_logging_targets {
1501    mp_void_logging_target,
1502    mp_term_logging_target,
1503    mp_file_logging_target,
1504    mp_both_logging_target,
1505    mp_error_logging_target,
1506} mp_logging_targets;
1507
1508# define mp_fputs(b,f)            (mp->write_file)(mp, f, b)
1509# define mp_log_string(target,s)  (mp->run_logger)(mp, target, s, strlen(s))
1510# define mp_log_mpstr(target,s,l) (mp->run_logger)(mp, target, s, l)
1511# define mp_log_cr(target)        (mp->run_logger)(mp, target, "\n", 1)
1512# define mp_log_chr(target,s)     { unsigned char ss[2] = { s, 0 }; (mp->run_logger)(mp, target, (const char *) ss, 1); }
1513# define mp_log_error(s)          (mp->run_logger)(mp, mp_error_logging_target, s, strlen(s))
1514
1515typedef struct mp_node_data {
1516    union {
1517        mp_command_code  command;
1518        mp_variable_type type;
1519    };
1520    mp_name_type_type    name_type;
1521    int                  hasnumber;
1522    int                  padding;
1523    struct mp_node_data *link;
1524    /* specific */
1525    mp_value_data        data;
1526} mp_node_data;
1527typedef struct mp_node_data *mp_symbolic_node;
1528
1529typedef enum mp_linecap_codes {
1530    mp_butt_linecap_code,
1531    mp_rounded_linecap_code,
1532    mp_squared_linecap_code,
1533    /* see below */
1534    mp_weird_linecap_code,
1535} mp_linecap_codes;
1536
1537typedef enum mp_linejoin_codes {
1538    mp_mitered_linejoin_code,
1539    mp_rounded_linejoin_code,
1540    mp_beveled_linejoin_code,
1541    /* we see this value being used */
1542    mp_weird_linejoin_code,
1543} mp_linejoin_codes;
1544
1545typedef enum mp_curvature_codes {
1546    mp_default_curvature_code,
1547    mp_always_curvature_code,
1548    /* we see this value being used */
1549    mp_weird_curvature_code,
1550} mp_curvature_codes;
1551
1552# define internal_value(A)        mp->internal[(A)].v.data.n
1553# define internal_string(A)       mp->internal[A].v.data.str
1554# define set_internal_string(A,B) mp->internal[(A)].v.data.str=(B)
1555# define internal_name(A)         mp->internal[(A)].intname
1556# define set_internal_name(A,B)   mp->internal[(A)].intname=(B)
1557# define internal_type(A)         mp->internal[A].v.type
1558# define set_internal_type(A,B)   mp->internal[(A)].v.type=(B)
1559# define internal_run(A)          mp->internal[(A)].run
1560# define set_internal_run(A,B)    mp->internal[(A)].run=(B)
1561
1562typedef struct mp_node_data *mp_token_node;
1563
1564typedef struct mp_value_node_data {
1565    mp_variable_type     type;
1566    mp_name_type_type    name_type;
1567    int                  hasnumber;
1568    int                  padding;
1569    struct mp_node_data *link;
1570    /* specific */
1571    mp_value_data        data;
1572    mp_number            subscript;
1573    mp_symbol            hashloc;
1574    mp_node              parent;
1575    mp_node              attr_head;
1576    mp_node              subscr_head;
1577} mp_value_node_data;
1578
1579typedef struct mp_pair_node_data {
1580    mp_variable_type     type;
1581    mp_name_type_type    name_type;
1582    int                  hasnumber;
1583    int                  padding;
1584    struct mp_node_data *link;
1585    /* specific */
1586    mp_node              x_part;
1587    mp_node              y_part;
1588} mp_pair_node_data;
1589
1590typedef struct mp_pair_node_data *mp_pair_node;
1591
1592typedef struct mp_transform_node_data {
1593    mp_variable_type     type;
1594    mp_name_type_type    name_type;
1595    int                  hasnumber;
1596    int                  padding;
1597    struct mp_node_data *link;
1598    /* specific */
1599    mp_node              tx_part;
1600    mp_node              ty_part;
1601    mp_node              xx_part;
1602    mp_node              yx_part;
1603    mp_node              xy_part;
1604    mp_node              yy_part;
1605} mp_transform_node_data;
1606
1607typedef struct mp_transform_node_data *mp_transform_node;
1608
1609typedef struct mp_color_node_data {
1610    mp_variable_type     type;
1611    mp_name_type_type    name_type;
1612    int                  hasnumber;
1613    int                  padding;
1614    struct mp_node_data *link;
1615    /* specific */
1616    union {
1617        mp_node red_part;
1618        mp_node cyan_part;
1619    };
1620    union {
1621        mp_node green_part;
1622        mp_node magenta_part;
1623    };
1624    union {
1625        mp_node blue_part;
1626        mp_node yellow_part;
1627    };
1628    union {
1629        mp_node grey_part;
1630        mp_node black_part;
1631    };
1632} mp_color_node_data;
1633
1634typedef struct mp_color_node_data *mp_color_node;
1635
1636typedef struct mp_shape_node_data {
1637    mp_variable_type     type;
1638    mp_name_type_type    name_type;
1639    int                  hasnumber;
1640    int                  stacking;
1641    struct mp_node_data *link;
1642    /*common */
1643    mp_string            pre_script;
1644    mp_string            post_script;
1645    union {
1646        mp_number        red;
1647        mp_number        cyan;
1648    };
1649    union {
1650        mp_number        green;
1651        mp_number        magenta;
1652    };
1653    union {
1654        mp_number        blue;
1655        mp_number        yellow;
1656    };
1657    union {
1658        mp_number        black;
1659        mp_number        grey;
1660    };
1661    /* specific to paths */
1662    mp_knot              path;
1663    mp_knot              pen;
1664    mp_node              dash;
1665    mp_number            dashscale;
1666    mp_number            miterlimit;
1667    unsigned char        color_model;
1668    unsigned char        linejoin;
1669    unsigned char        linecap;
1670    unsigned char        pen_type;
1671    unsigned char        curvature;
1672    unsigned char        padding_1;
1673    unsigned char        padding_2;
1674    unsigned char        padding_3;
1675} mp_shape_node_data;
1676
1677typedef struct mp_shape_node_data *mp_shape_node;
1678
1679typedef struct mp_start_node_data {
1680    mp_variable_type     type;
1681    mp_name_type_type    name_type;
1682    int                  hasnumber;
1683    int                  stacking;
1684    struct mp_node_data *link;
1685    /* specific */
1686    mp_string            pre_script;
1687    mp_string            post_script;
1688    mp_knot              path;
1689} mp_start_node_data;
1690
1691typedef struct mp_start_node_data *mp_start_node;
1692
1693typedef struct mp_stop_node_data {
1694    mp_variable_type     type;
1695    mp_name_type_type    name_type;
1696    int                  hasnumber;
1697    int                  stacking;
1698    struct mp_node_data *link;
1699    /* specific */
1700} mp_stop_node_data;
1701
1702typedef struct mp_stop_node_data *mp_stop_node;
1703
1704typedef struct mp_dash_node_data {
1705    mp_variable_type     type;
1706    mp_name_type_type    name_type;
1707    int                  hasnumber;
1708    int                  padding;
1709    struct mp_node_data *link;
1710    /* specific */
1711    mp_number            start_x; /* the starting $x$~coordinate in a dash node */
1712    mp_number            stop_x;  /* the ending $x$~coordinate in a dash node */
1713    mp_number            dash_y;  /* $y$ value for the dash list in an edge header */
1714    mp_node              dash_info;
1715} mp_dash_node_data;
1716
1717typedef struct mp_edge_header_node_data {
1718    mp_variable_type     type;
1719    mp_name_type_type    name_type;
1720    int                  hasnumber;
1721    int                  padding;
1722    struct mp_node_data *link;
1723    /* specific */
1724    mp_number            start_x;
1725    mp_number            stop_x;
1726    mp_number            dash_y;
1727    mp_node              dash_info;
1728    mp_number            minx;
1729    mp_number            miny;
1730    mp_number            maxx;
1731    mp_number            maxy;
1732    mp_node              bblast;
1733    int                  bbtype; /* tells how bounding box data depends on |truecorners| */
1734    int                  ref_count; 
1735    mp_node              list;
1736    mp_node              obj_tail;  
1737} mp_edge_header_node_data;
1738
1739typedef struct mp_edge_header_node_data *mp_edge_header_node;
1740
1741typedef enum mp_bound_codes {
1742    mp_no_bounds_code,    /* |bbtype| value when bounding box data is valid for all |truecorners| values */
1743    mp_bounds_set_code,   /* |bbtype| value when bounding box data is for |truecorners|${}\le 0$ */
1744    mp_bounds_unset_code, /* |bbtype| value when bounding box data is for |truecorners|${}>0$ */
1745} mp_bound_codes;
1746
1747typedef struct mp_if_node_data {
1748    mp_variable_type     type;
1749    mp_name_type_type    name_type;
1750    int                  hasnumber;
1751    int                  if_line_field;
1752    struct mp_node_data *link;
1753} mp_if_node_data;
1754
1755typedef struct mp_if_node_data *mp_if_node;
1756
1757typedef enum mp_expression_scan_types {
1758    mp_expression_scan_code,
1759    mp_primary_scan_code,
1760    mp_secondary_scan_code,
1761    mp_tertiary_scan_code,
1762} mp_expression_scan_types;
1763
1764typedef enum mp_internal_action_types {
1765    mp_initialize_internal_code,
1766    mp_save_internal_code, 
1767    mp_restore_internal_code, 
1768 // mp_tracing_internal_code, 
1769} mp_internal_action_types; 
1770
1771/* mp header stuff */
1772
1773extern void             mp_print_e_str                (MP mp, const char *s);
1774//     void             mp_print_e_chr                (MP mp, unsigned char k);
1775extern void             mp_show_context               (MP mp);
1776extern void             mp_error                      (MP mp, const char *msg, const char *hlp);
1777extern void             mp_warn                       (MP mp, const char *msg);
1778extern void             mp_fatal_error                (MP mp, const char *s);
1779extern  void            mp_confusion                  (MP mp, const char *s);
1780
1781extern int              mp_initialize_symbol_traverse (MP mp);
1782extern void             mp_kill_symbol_traverse       (MP mp);
1783extern void            *mp_fetch_symbol_traverse      (MP mp);
1784extern void            *mp_fetch_symbol               (MP mp, char *s);
1785
1786extern int              mp_close_path_cycle           (MP mp, mp_knot p, mp_knot q);
1787extern int              mp_close_path                 (MP mp, mp_knot q, mp_knot first);
1788
1789extern mp_knot          mp_create_knot                (MP mp);
1790
1791extern mp_knot          mp_append_knot                (MP mp, mp_knot p, double x, double y);
1792extern mp_knot          mp_append_knot_xy             (MP mp, mp_knot p, double x, double y);
1793
1794extern int              mp_set_knot_curl              (MP mp, mp_knot q, double value);
1795extern int              mp_set_knot_left_curl         (MP mp, mp_knot q, double value);
1796extern int              mp_set_knot_right_curl        (MP mp, mp_knot q, double value);
1797extern int              mp_set_knot_simple_curl       (MP mp, mp_knot q);
1798extern int              mp_set_knotpair_curls         (MP mp, mp_knot p, mp_knot q, double t1, double t2) ;
1799extern int              mp_set_knotpair_tensions      (MP mp, mp_knot p, mp_knot q, double t1, double t2) ;
1800extern int              mp_set_knot_left_tension      (MP mp, mp_knot p, double t1);
1801extern int              mp_set_knot_right_tension     (MP mp, mp_knot p, double t1);
1802extern int              mp_set_knot_left_control      (MP mp, mp_knot p, double t1, double t2);
1803extern int              mp_set_knot_right_control     (MP mp, mp_knot p, double t1, double t2);
1804extern int              mp_set_knotpair_controls      (MP mp, mp_knot p, mp_knot q, double x1, double y1, double x2, double y2);
1805extern int              mp_set_knot_direction         (MP mp, mp_knot q, double x, double y) ;
1806extern int              mp_set_knotpair_directions    (MP mp, mp_knot p, mp_knot q, double x1, double y1, double x2, double y2);
1807
1808extern int              mp_solve_path                 (MP mp, mp_knot first);
1809extern void             mp_free_path                  (MP mp, mp_knot p);
1810
1811extern double           mp_number_as_double           (MP mp, mp_number n);
1812
1813extern void             mp_set_internal               (MP mp, char *n, char *v, int isstring);
1814
1815extern  int             mp_skip_token_value           (MP mp, int token);
1816
1817extern  void            mp_scan_next_value            (MP mp, int keep, int *token, int *mode, int *kind);
1818extern  void            mp_scan_expr_value            (MP mp, int keep, int *kind);
1819extern  void            mp_scan_token_value           (MP mp, int keep, int *token, int *mode, int *kind);
1820extern  void            mp_scan_symbol_value          (MP mp, int keep, char **s, int expand);
1821extern  void            mp_scan_property_value        (MP mp, int keep, int *kind, char **s, int *property, int *detail);
1822extern  void            mp_scan_numeric_value         (MP mp, int primary, double *d);
1823extern  void            mp_scan_boolean_value         (MP mp, int primary, int *b);
1824extern  void            mp_scan_string_value          (MP mp, int primary, char **s, size_t *l);
1825extern  void            mp_scan_pair_value            (MP mp, int primary, double *x, double *y);
1826extern  void            mp_scan_color_value           (MP mp, int primary, double *r, double *g, double *b);
1827extern  void            mp_scan_cmykcolor_value       (MP mp, int primary, double *c, double *m, double *y, double *k);
1828extern  void            mp_scan_transform_value       (MP mp, int primary, double *x, double *y, double *xx, double *xy, double *yx, double *yy);
1829extern  void            mp_scan_path_value            (MP mp, int primary, mp_knot *k);
1830
1831extern  void            mp_push_numeric_value         (MP mp, double n);
1832extern  void            mp_push_integer_value         (MP mp, int i);
1833extern  void            mp_push_boolean_value         (MP mp, int b);
1834extern  void            mp_push_string_value          (MP mp, const char *s, int l);
1835extern  void            mp_push_pair_value            (MP mp, double x, double y);
1836extern  void            mp_push_color_value           (MP mp, double r, double g, double b);
1837extern  void            mp_push_cmykcolor_value       (MP mp, double c, double m, double y, double k);
1838extern  void            mp_push_transform_value       (MP mp, double x, double y, double xx, double xy, double yx, double yy);
1839extern  void            mp_push_path_value            (MP mp, mp_knot k);
1840
1841extern  void            mp_new_randoms                (MP mp);
1842
1843/* mplib export header stuff */
1844
1845extern MP               mp_initialize                 (MP_options *opt);
1846extern void             mplib_shipout_backend         (MP mp, void *h);
1847extern  int             mp_run                        (MP mp);
1848extern  int             mp_execute                    (MP mp, const char *s, size_t l);
1849extern  int             mp_finish                     (MP mp);
1850extern  char           *mp_metapost_version           (void);
1851extern mp_run_data     *mp_rundata                    (MP mp);
1852extern MP_options      *mp_options                    (void);
1853extern void            *mp_userdata                   (MP mp);
1854extern int              mp_status                     (MP mp);
1855extern int              mp_finished                   (MP mp);
1856
1857
1858extern mp_edge_object  *mp_graphic_export             (MP mp, mp_edge_header_node h);
1859extern void             mp_graphic_toss_objects       (mp_edge_object *hh);
1860extern void             mp_graphic_toss_object        (mp_graphic_object *p);
1861
1862/* memory management header stuff */
1863
1864extern void            *mp_memory_allocate            (size_t size);
1865extern void            *mp_memory_clear_allocate      (size_t size);
1866extern void            *mp_memory_reallocate          (void *p, size_t size);
1867extern void             mp_memory_free                (void *p);
1868
1869# endif
1870