/* This file was generated by "mtxrun --script "mtx-wtoc.lua" from the metapost cweb files but now maintained as C file. */ # ifndef MP_H # define MP_H 1 # include # include # include # include # include # include # include # include # include # include # ifdef _WIN32 # include # include # include # else # include # endif # include "avl.h" # include "auxmemory.h" # include "auxposit.h" /*tex We used to have three header files: common, mpmp and mplib, but there ws some (growing) dependency on the one hand and we decided to target just \LUAMETATEX\ on the other. After all, this is a special version. So, we now have one header file only. The variables from |MP_options| are included inside the |MP_instance| wholesale. This also permits some further stripping. Actually we can probably get rid of the intermediate \POSTSCRIPT\ representation or add a little more abstraction. */ # define metapost_version "3.15.01" typedef struct MP_instance *MP; typedef enum mp_number_type { mp_nan_type, mp_scaled_type, mp_fraction_type, mp_angle_type, mp_double_type, mp_binary_type, mp_decimal_type, mp_posit_type } mp_number_type; # define is_number(A) ((A).type != mp_nan_type) typedef union mp_number_store { void *num; double dval; int val; posit_t pval; } mp_number_store; typedef struct mp_number_data { mp_number_store data; mp_number_type type; } mp_number_data; typedef struct mp_number_data mp_number; enum mp_filetype { mp_filetype_terminal, /* the terminal (input) */ mp_filetype_program, /* \MP\ language input */ mp_filetype_text /* first text file for readfrom and writeto primitives */ }; typedef char *(*mp_file_finder) (MP, const char *, const char *, int); typedef char *(*mp_script_runner) (MP, const char *m, size_t len, int n); typedef void (*mp_internal_runner) (MP, int action, int n, int type, const char *iname); typedef void (*mp_log_runner) (MP, int, const char *s, size_t l); typedef int (*mp_overload_runner) (MP, int, const char *, int); typedef void (*mp_error_runner) (MP, const char *, const char *, int); typedef void (*mp_warning_runner) (MP, const char *); typedef void (*mp_status_runner) (MP); typedef char *(*mp_text_maker) (MP, const char *, size_t, int); typedef void *(*mp_file_opener) (MP, const char *, const char *, int); typedef char *(*mp_file_reader) (MP, void *, size_t *); typedef void (*mp_file_closer) (MP, void *); typedef int (*mp_file_eoftest) (MP, void *); typedef void (*mp_file_flush) (MP, void *); typedef void (*mp_file_writer) (MP, void *, const char *); typedef struct mp_lstring { unsigned char *str; /* the string value */ size_t len; /* its length */ int refs; /* number of references */ } mp_lstring; typedef mp_lstring *mp_string; /* for pointers to string values */ enum mp_interaction_mode { mp_unspecified_mode, /* extra value for command-line switch */ mp_batch_mode, /* omits all stops and omits terminal output */ mp_nonstop_mode, /* omits all stops */ mp_scroll_mode, /* omits error stops */ mp_error_stop_mode, /* stops at every opportunity to interact */ mp_silent_mode /* stops at every opportunity to interact but not always*/ }; enum mp_history_state { mp_spotless, /* |history| value when nothing has been amiss yet */ mp_warning_issued, /* |history| value when |begin_diagnostic| has been called */ mp_error_message_issued, /* |history| value when |error| has been called */ mp_fatal_error_stop, /* |history| value when termination was premature */ mp_system_error_stop /* |history| value when termination was due to disaster */ }; typedef enum mp_math_mode { mp_math_scaled_mode, mp_math_double_mode, mp_math_binary_mode, mp_math_decimal_mode, mp_math_posit_mode } mp_math_mode; typedef struct mp_graphic_object *mp_graphic_object_node; typedef struct mp_dash_object *mp_dash_object_node; typedef struct mp_shape_object *mp_shape_object_node; typedef struct mp_start_object *mp_start_object_node; typedef struct mp_stop_object *mp_stop_object_node; typedef struct mp_edge_object *mp_edge_object_node; typedef struct mp_knot_object *mp_knot_object_node; typedef struct mp_knot_data *mp_knot; typedef struct mp_knot_data { mp_number x_coord; /* the |x| coordinate of this knot */ mp_number y_coord; /* the |y| coordinate of this knot */ union { mp_number left_x; /* the |x| coordinate of previous control point */ mp_number left_curl; /* curl information when entering this knot */ mp_number left_given; /* given direction when entering this knot */ }; union { mp_number left_y; /* the |y| coordinate of previous control point */ mp_number left_tension; /* tension information when entering this knot */ }; union { mp_number right_x; /* the |x| coordinate of next control point */ mp_number right_curl; /* curl information when leaving this knot */ mp_number right_given; /* given direction when leaving this knot */ }; union { mp_number right_y; /* the |y| coordinate of next control point */ mp_number right_tension; /* tension information when leaving this knot */ }; union { mp_knot next; mp_knot link; /* fr memory pool */ }; mp_knot prev; unsigned char left_type; unsigned char right_type; unsigned char originator; unsigned char state; signed int info; /* we now have some 3 bytes slack that we can use */ } mp_knot_data; typedef struct mp_knot_object { double x_coord; double y_coord; double left_x; double left_y; double right_x; double right_y; union { mp_knot_object_node next; mp_knot_object_node link; }; mp_knot_object_node prev; unsigned char left_type; unsigned char right_type; unsigned char originator; unsigned char state; signed int info; } mp_knot_object; enum mp_knot_originator { mp_program_code, /* not created by a user */ mp_metapost_user /* created by a user */ }; enum mp_knot_states { mp_regular_knot, mp_begin_knot, mp_end_knot, mp_single_knot, }; # undef term_in # undef term_out typedef struct mp_run_data { void *term_in; /* dummy pointer */ mp_edge_object_node edges; } mp_run_data; typedef struct mp_color { union { double red; double cyan; }; union { double green; double magenta; }; union { double blue; double yellow; }; union { double black; double gray; }; } mp_color; /*TEX This mp_graphic_object gets cast onto the fill and stroke. For some reason we don't distinguish between start and stop here. The regular \METAPOST\ nodes get transformed into these. The backend uses doubles while the frontend uses scaled, doubles, posits or decimals. */ typedef struct mp_graphic_object { int type; int stacking; union { mp_graphic_object_node link; mp_graphic_object_node next; }; } mp_graphic_object; typedef struct mp_dash_object { double offset; double *array; union { mp_dash_object_node link; mp_dash_object_node next; }; } mp_dash_object; typedef struct mp_shape_object { int type; int stacking; union { mp_graphic_object_node link; mp_graphic_object_node next; }; char *pre_script; char *post_script; size_t pre_length; size_t post_length; mp_color color; mp_knot_object_node path; mp_knot_object_node htap; mp_knot_object_node pen; double miterlimit; mp_dash_object *dash; unsigned char color_model; unsigned char linejoin; unsigned char linecap; unsigned char padding_0; /* pen_type */ unsigned char curvature; unsigned char padding_1; unsigned char padding_2; unsigned char padding_3; char *bytemap; int bytemapnx; int bytemapny; int bytemapnz; } mp_shape_object; typedef struct mp_start_object { int type; int stacking; union { mp_edge_object_node next; mp_edge_object_node link; }; char *pre_script; char *post_script; size_t pre_length; size_t post_length; mp_knot_object_node path; } mp_start_object; typedef struct mp_stop_object { int type; int stacking; union { mp_edge_object_node next; mp_edge_object_node link; }; char *pre_script; char *post_script; size_t pre_length; size_t post_length; mp_knot_object_node path; } mp_stop_object; typedef struct mp_edge_object { mp_graphic_object_node body; union { mp_edge_object_node next; mp_edge_object_node link; }; MP parent; double minx; double miny; double maxx; double maxy; double width; double height; double depth; double italic; int charcode; int padding; } mp_edge_object; typedef void (*mp_backend_writer) (MP, void *); typedef struct MP_options { int halt_on_error; /* do we quit at the first error? */ void *userdata; /* this allows the calling application to setup local (e.g. L for Lua) */ char *banner; /* the banner that is printed to the screen and log */ int utf8_mode; int text_mode; int show_mode; mp_file_finder find_file; mp_script_runner run_script; mp_internal_runner run_internal; mp_log_runner run_logger; mp_overload_runner run_overload; mp_error_runner run_error; mp_warning_runner run_warning; mp_status_runner run_status; mp_text_maker make_text; mp_file_opener open_file; mp_file_closer close_file; mp_file_reader read_file; mp_file_writer write_file; int find_file_id; int run_script_id; int run_internal_id; int run_logger_id; int run_overload_id; int run_error_id; int run_warning_id; int run_status_id; int make_text_id; int open_file_id; int interaction; int random_seed; int math_mode; char *job_name; mp_backend_writer shipout_backend; } MP_options; typedef enum mp_color_model { mp_no_model, mp_grey_model, mp_rgb_model, mp_cmyk_model, mp_uninitialized_model, } mp_color_model; typedef enum mp_knot_type { mp_endpoint_knot, /* |mp_left_type| at path beginning and |mp_right_type| at path end */ mp_explicit_knot, /* |mp_left_type| or |mp_right_type| when control points are known */ mp_given_knot, /* |mp_left_type| or |mp_right_type| when a direction is given */ mp_curl_knot, /* |mp_left_type| or |mp_right_type| when a curl is desired */ mp_open_knot, /* |mp_left_type| or |mp_right_type| when \MP\ should choose the direction */ mp_end_cycle_knot } mp_knot_type; enum mp_graphical_object_code { mp_unset_code, mp_fill_code, mp_stroked_code, mp_start_clip_code, /* |type| of a node that starts clipping */ mp_start_group_code, /* |type| of a node that gives a |setgroup| path */ mp_start_bounds_code, /* |type| of a node that gives a |setbounds| path */ mp_stop_clip_code, /* |type| of a node that stops clipping */ mp_stop_group_code, /* |type| of a node that stops grouping */ mp_stop_bounds_code, /* |type| of a node that stops |setbounds| */ mp_final_graphic }; typedef enum mp_command_code { mp_undefined_command, mp_btex_command, /* begin \TeX\ material (|btex|, |verbatimtex|) */ mp_etex_command, /* end \TeX\ material (|etex|) */ mp_if_test_command, /* conditional text (|if|) */ mp_fi_or_else_command, /* delimiters for conditionals (|elseif|, |else|, |fi|) */ mp_input_command, /* input a source file (|input|, |endinput|) */ mp_iteration_command, /* iterate (|for|, |forsuffixes|, |forever|, |endfor|) */ mp_repeat_loop_command, /* special command substituted for |endfor| */ mp_exit_test_command, /* premature exit from a loop (|exitif|) */ mp_relax_command, /* do nothing (|\char`\\|) */ mp_scan_tokens_command, /* put a string into the input buffer */ mp_runscript_command, /* put a script result string into the input buffer */ mp_maketext_command, /* make a text (typesetting) */ mp_expand_after_command, /* look ahead one token */ mp_defined_macro_command, /* a macro defined by the user */ mp_save_command, /* save a list of tokens (|save|) */ mp_interim_command, /* save an internal quantity (|interim|) */ mp_let_command, /* redefine a symbolic token (|let|) */ mp_new_internal_command, /* define a new internal quantity (|newinternal|) */ mp_bytemap_command, mp_macro_def_command, /* define a macro (|def|, |vardef|, etc.) */ mp_ship_out_command, /* output a character (|shipout|) */ mp_add_to_command, /* add to edges (|addto|) */ mp_bounds_command, /* add bounding path to edges (|setbounds|, |clip|) */ mp_protection_command, /* set protection flag (|outer|, |inner|) */ mp_property_command, mp_show_command, /* diagnostic output (|show|, |showvariable|, etc.) */ mp_mode_command, /* set interaction level (|batchmode|, etc.) */ mp_only_set_command, /* initialize random number generator (|randomseed|) */ mp_message_command, /* communicate to user (|message|, |errmessage|) */ mp_every_job_command, /* designate a starting token (|everyjob|) */ mp_delimiters_command, /* define a pair of delimiters (|delimiters|) */ mp_write_command, /* write text to a file (|write|) */ mp_type_name_command, /* declare a type (|numeric|, |pair|, etc.) */ mp_left_delimiter_command, /* the left delimiter of a matching pair */ mp_begin_group_command, /* beginning of a group (|begingroup|) */ mp_nullary_command, /* an operator without arguments (e.g., |normaldeviate|) */ mp_unary_command, /* an operator with one argument (e.g., |sqrt|) */ mp_str_command, /* convert a suffix to a string (|str|) */ mp_void_command, /* convert a suffix to a boolean (|void|) */ mp_cycle_command, /* close a cyclic path (|cycle|) */ mp_of_binary_command, /* binary operation taking |of| (e.g., |point|) */ mp_capsule_command, /* a value that has been put into a token list */ mp_string_command, /* a string constant (e.g., |"hello"|) */ mp_internal_command, /* internal numeric parameter (e.g., |pausing|) */ mp_tag_command, /* a symbolic token without a primitive meaning */ mp_numeric_command, /* a numeric constant (e.g., |3.14159|) */ mp_plus_or_minus_command, /* either |+| or |-| */ mp_secondary_def_command, /* a macro defined by |secondarydef| */ mp_tertiary_binary_command, /* an operator at the tertiary level (e.g., |++|) */ mp_left_brace_command, /* the operator `|\char||| */ mp_path_join_command, /* the operator |..| */ mp_path_connect_command, /* the operator |--| */ mp_ampersand_command, /* the operator `\.\&' */ mp_tertiary_def_command, /* a macro defined by |tertiarydef| */ mp_primary_binary_command, /* an operator at the expression level (e.g., |<|) */ mp_equals_command, /* the operator |=| */ mp_and_command, /* the operator |and| */ mp_primary_def_command, /* a macro defined by |primarydef| */ mp_slash_command, /* the operator |/| */ mp_secondary_binary_command, /* an operator at the binary level (e.g., |shifted|) */ mp_parameter_commmand, /* type of parameter (|primary|, |expr|, |suffix|, etc.) */ mp_controls_command, /* specify control points explicitly (|controls|) */ mp_tension_command, /* specify tension between knots (|tension|) */ mp_at_least_command, /* bounded tension value (|atleast|) */ mp_curl_command, /* specify curl at an end knot (|curl|) */ mp_macro_special_command, /* special macro operators (|quote|, |\#\AT!|, etc.) */ mp_right_delimiter_command, /* the right delimiter of a matching pair */ mp_left_bracket_command, /* the operator |[| */ mp_right_bracket_command, /* the operator |]| */ mp_right_brace_command, /* the operator `|\char|}| */ mp_with_option_command, /* option for filling (|withpen|, |withweight|, etc.) */ mp_thing_to_add_command, /* variant of |addto| (|contour|, |doublepath|, |also|) */ mp_of_command, /* the operator |of| */ mp_to_command, /* the operator |to| */ mp_step_command, /* the operator |step| */ mp_until_command, /* the operator |until| */ mp_within_command, /* the operator |within| */ mp_assignment_command, /* the operator |:=| */ mp_colon_command, /* the operator |:| */ mp_comma_command, /* the operator |,|, must be |colon+1| */ mp_semicolon_command, /* the operator |;|, must be |comma+1| */ mp_end_group_command, /* end a group (|endgroup|), must be |semicolon+1| */ mp_stop_command, /* end a job (|end|, |dump|), must be |end_group+1| */ // mp_outer_tag_command, /* protection code added to command code */ mp_undefined_cs_command, /* protection code added to command code */ } mp_command_code; typedef enum mp_variable_type { mp_undefined_type, /* no type has been declared */ mp_vacuous_type, /* no expression was present */ mp_boolean_type, /* |boolean| with a known value */ mp_unknown_boolean_type, mp_string_type, /* |string| with a known value */ mp_unknown_string_type, mp_pen_type, /* |pen| with a known value */ mp_unknown_pen_type, mp_nep_type, /* |pen| with a known value */ mp_unknown_nep_type, mp_path_type, /* |path| with a known value */ mp_unknown_path_type, mp_picture_type, /* |picture| with a known value */ mp_unknown_picture_type, mp_transform_type, /* |transform| variable or capsule */ mp_color_type, /* |color| variable or capsule */ mp_cmykcolor_type, /* |cmykcolor| variable or capsule */ mp_pair_type, /* |pair| variable or capsule */ mp_numeric_type, /* variable that has been declared |numeric| but not used */ mp_known_type, /* |numeric| with a known value */ mp_dependent_type, /* a linear combination with |fraction| coefficients */ mp_proto_dependent_type, /* a linear combination with |scaled| coefficients */ mp_independent_type, /* |numeric| with unknown value */ mp_token_list_type, /* variable name or suffix argument or text argument */ mp_structured_type, /* variable with subscripts and attributes */ mp_unsuffixed_macro_type, /* variable defined with |vardef| but no |\AT!\#| */ mp_suffixed_macro_type, /* variable defined with |vardef| and |\AT!\#| */ mp_symbol_node_type, mp_token_node_type, mp_value_node_type, mp_attribute_node_type, mp_subscript_node_type, mp_pair_node_type, mp_transform_node_type, mp_color_node_type, mp_cmykcolor_node_type, /* It is important that the next 7 items remain in this order, for export as well as switch/case offsets. */ mp_fill_node_type, mp_stroked_node_type, mp_start_clip_node_type, mp_start_group_node_type, mp_start_bounds_node_type, mp_stop_clip_node_type, mp_stop_group_node_type, mp_stop_bounds_node_type, mp_dash_node_type, mp_dep_node_type, mp_if_node_type, mp_edge_header_node_type, } mp_variable_type; typedef enum mp_name_type_type { mp_root_operation, /* |name_type| at the top level of a variable */ mp_saved_root_operation, /* same, when the variable has been saved */ mp_structured_root_operation, /* |name_type| where a |mp_structured| branch occurs */ mp_subscript_operation, /* |name_type| in a subscript node */ mp_attribute_operation, /* |name_type| in an attribute node */ mp_x_part_operation, /* |name_type| in the |xpart| of a node */ mp_y_part_operation, /* |name_type| in the |ypart| of a node */ mp_xx_part_operation, /* |name_type| in the |xxpart| of a node */ mp_xy_part_operation, /* |name_type| in the |xypart| of a node */ mp_yx_part_operation, /* |name_type| in the |yxpart| of a node */ mp_yy_part_operation, /* |name_type| in the |yypart| of a node */ mp_red_part_operation, /* |name_type| in the |redpart| of a node */ mp_green_part_operation, /* |name_type| in the |greenpart| of a node */ mp_blue_part_operation, /* |name_type| in the |bluepart| of a node */ mp_cyan_part_operation, /* |name_type| in the |redpart| of a node */ mp_magenta_part_operation, /* |name_type| in the |greenpart| of a node */ mp_yellow_part_operation, /* |name_type| in the |bluepart| of a node */ mp_black_part_operation, /* |name_type| in the |greenpart| of a node */ mp_grey_part_operation, /* |name_type| in the |greypart| of a node */ mp_capsule_operation, /* |name_type| in stashed-away subexpressions */ mp_token_operation, /* |name_type| in a numeric token or string token */ mp_boolean_type_operation, /* the order needs to match the types (as we use deltas) ! */ mp_string_type_operation, mp_pen_type_operation, mp_nep_type_operation, mp_path_type_operation, mp_picture_type_operation, mp_transform_type_operation, mp_color_type_operation, mp_cmykcolor_type_operation, mp_pair_type_operation, mp_numeric_type_operation, /* Symbolic nodes also have |name_type|, which is a different enumeration */ mp_normal_operation, mp_internal_operation, /* for values of internals */ mp_macro_operation, /* for macro names */ mp_expr_operation, /* for macro parameters if type |expr| */ mp_suffix_operation, /* for macro parameters if type |suffix| */ mp_text_operation, /* for macro parameters if type |text| */ /* snippet: operation codes */ mp_true_operation, /* operation code for |true| */ mp_false_operation, /* operation code for |false| */ mp_null_picture_operation, /* operation code for |nullpicture| */ mp_null_pen_operation, /* operation code for |nullpen| */ mp_read_string_operation, /* operation code for |readstring| */ mp_pen_circle_operation, /* operation code for |pencircle| */ mp_normal_deviate_operation, /* operation code for |normaldeviate| */ mp_read_from_operation, /* operation code for |readfrom| */ mp_close_from_operation, /* operation code for |closefrom| */ mp_odd_operation, /* operation code for |odd| */ mp_known_operation, /* operation code for |known| */ mp_unknown_operation, /* operation code for |unknown| */ mp_not_operation, /* operation code for |not| */ mp_decimal_operation, /* operation code for |decimal| */ mp_reverse_operation, /* operation code for |reverse| */ mp_uncycle_operation, /* operation code for |uncycle| */ mp_make_path_operation, /* operation code for |makepath| */ mp_make_pen_operation, /* operation code for |makepen| */ mp_make_nep_operation, /* operation code for |makenep| */ mp_convexed_operation, /* operation code for |convexed| */ mp_uncontrolled_operation, /* operation code for |uncontrolled| */ mp_oct_operation, /* operation code for |oct| */ mp_hex_operation, /* operation code for |hex| */ mp_ASCII_operation, /* operation code for |ASCII| */ mp_char_operation, /* operation code for |char| */ mp_segments_operation, /* operation code for |segments| */ mp_length_operation, /* operation code for |length| */ mp_no_length_operation, /* operation code for |nolength| */ mp_turning_operation, /* operation code for |turningnumber| */ mp_color_model_operation, /* operation code for |colormodel| */ mp_path_part_operation, /* operation code for |pathpart| */ mp_pen_part_operation, /* operation code for |penpart| */ mp_dash_part_operation, /* operation code for |dashpart| */ mp_prescript_part_operation, /* operation code for |prescriptpart| */ mp_postscript_part_operation, /* operation code for |postscriptpart| */ mp_stacking_part_operation, /* operation code for |stackingpart| */ mp_sqrt_operation, /* operation code for |sqrt| */ mp_norm_operation, /* operation code for |knownnorm| */ mp_m_exp_operation, /* operation code for |mexp| */ mp_m_log_operation, /* operation code for |mlog| */ mp_sin_d_operation, /* operation code for |sind| */ mp_cos_d_operation, /* operation code for |cosd| */ mp_floor_operation, /* operation code for |floor| */ mp_uniform_deviate_operation, /* operation code for |uniformdeviate| */ mp_ll_corner_operation, /* operation code for |llcorner| */ mp_lr_corner_operation, /* operation code for |lrcorner| */ mp_ul_corner_operation, /* operation code for |ulcorner| */ mp_ur_corner_operation, /* operation code for |urcorner| */ mp_corners_operation, /* operation code for |corners| */ mp_center_of_operation, /* operation code for |centerof| */ mp_center_of_mass_operation, /* operation code for |centerofmass| */ mp_x_range_operation, /* operation code for |xrange| */ mp_y_range_operation, /* operation code for |yrange| */ mp_delta_point_operation, /* operation code for |deltapoint| */ mp_delta_precontrol_operation, /* operation code for |deltaprecontrol| */ mp_delta_postcontrol_operation, /* operation code for |deltapostcontrol| */ mp_delta_direction_operation, /* operation code for |deltadirection| */ mp_arc_length_operation, /* operation code for |arclength| */ mp_angle_operation, /* operation code for |angle| */ mp_cycle_operation, /* operation code for |cycle| */ mp_no_cycle_operation, /* operation code for |nocycle| */ mp_x_relative_operation, /* operation code for |xrelative| */ mp_y_relative_operation, /* operation code for |yrelative| */ mp_xy_relative_operation, /* operation code for |xyrelative| */ mp_x_absolute_operation, /* operation code for |xabsolute| */ mp_y_absolute_operation, /* operation code for |yabsolute| */ mp_xy_absolute_operation, /* operation code for |xyabsolute| */ mp_filled_operation, /* operation code for |filled| */ mp_stroked_operation, /* operation code for |stroked| */ mp_clipped_operation, /* operation code for |clipped| */ mp_grouped_operation, /* operation code for |bounded| */ mp_bounded_operation, /* operation code for |grouped| */ mp_plus_operation, /* operation code for \.+ */ mp_minus_operation, /* operation code for \.- */ mp_times_operation, /* operation code for \.* */ mp_over_operation, /* operation code for \./ */ mp_power_operation, /* operation code for \.^ */ mp_pythag_add_operation, /* operation code for |++| */ mp_pythag_sub_operation, /* operation code for |+-+| */ mp_dotprod_operation, /* operation code for |knowndotprod| */ mp_crossprod_operation, /* operation code for |knowncrossprod| */ mp_div_operation, /* operation code for |knowndiv| */ mp_mod_operation, /* operation code for |knownmod| */ mp_or_operation, /* operation code for |or| */ mp_and_operation, /* operation code for |and| */ mp_less_than_operation, /* operation code for \.< */ mp_less_or_equal_operation, /* operation code for |<=| */ mp_greater_than_operation, /* operation code for \.> */ mp_greater_or_equal_operation, /* operation code for |>=| */ mp_equal_operation, /* operation code for \.= */ mp_unequal_operation, /* operation code for |<>| */ mp_concat_operation, /* operation code for \.\& */ mp_just_append_operation, /* operation code for \.\&\& */ mp_tolerant_concat_operation, /* operation code for \.\&\&\& */ mp_tolerant_append_operation, /* operation code for \.\&\&\&\& */ mp_rotated_operation, /* operation code for |rotated| */ mp_slanted_operation, /* operation code for |slanted| */ mp_scaled_operation, /* operation code for |scaled| */ mp_shifted_operation, /* operation code for |shifted| */ mp_transformed_operation, /* operation code for |transformed| */ mp_x_scaled_operation, /* operation code for |xscaled| */ mp_y_scaled_operation, /* operation code for |yscaled| */ mp_z_scaled_operation, /* operation code for |zscaled| */ mp_xy_scaled_operation, /* operation code for |xyscaled| */ mp_uncycled_operation, /* operation code for |uncycled| */ mp_intertimes_operation, /* operation code for |intersectiontimes| */ mp_intertimes_list_operation, /* operation code for |intersectiontimeslist| */ mp_double_dot_operation, /* operation code for improper |..| */ /* the |of| operations: */ mp_substring_operation, /* operation code for |substring| */ mp_subpath_operation, /* operation code for |subpath| */ mp_segment_operation, /* operation code for |subpath| */ mp_direction_time_operation, /* operation code for |directiontime| */ mp_point_operation, /* operation code for |point| */ mp_precontrol_operation, /* operation code for |precontrol| */ mp_postcontrol_operation, /* operation code for |postcontrol| */ mp_direction_operation, /* operation code for |direction| */ mp_path_point_operation, /* operation code for |pathpoint| */ mp_path_precontrol_operation, /* operation code for |pathprecontrol| */ mp_path_postcontrol_operation, /* operation code for |pathpostcontrol| */ mp_path_direction_operation, /* operation code for |pathdirection| */ mp_path_state_operation, /* operation code for |pathstate| */ mp_path_index_operation, /* operation code for |pathindex| */ mp_path_lastindex_operation, /* operation code for |pathlastindex| */ mp_path_length_operation, /* operation code for |pathlength| */ mp_path_first_operation, /* operation code for |pathfirst| */ mp_path_last_operation, /* operation code for |pathlast| */ mp_pen_offset_operation, /* operation code for |penoffset| */ mp_arc_time_operation, /* operation code for |arctime| */ mp_arc_point_operation, /* operation code for |arcpoint| */ mp_arc_point_list_operation, /* operation code for |arcpointlist| */ mp_subarc_length_operation, /* operation code for |subarclength| */ mp_version_operation, /* operation code for |mpversion| */ mp_envelope_operation, /* operation code for |envelope| */ mp_boundingpath_operation, /* operation code for |boundingpath| */ mp_bytemap_value_operation, mp_bytemap_found_operation, mp_bytemap_path_operation, mp_bytemap_bounds_operation, } mp_name_type_type; # define mp_min_of_operation mp_substring_operation typedef enum mp_class_codes { mp_digit_class = 0, /* the class number of |0123456789| */ mp_period_class = 1, /* the class number of |.| */ mp_space_class = 2, /* the class number of spaces and nonstandard characters */ mp_percent_class = 3, /* the class number of `\.\%' */ mp_string_class = 4, /* the class number of |"| */ mp_comma_class = 5, /* the , */ mp_semicolon_class = 6, /* the ; */ mp_left_parenthesis_class = 7, /* the class number of |(| */ mp_right_parenthesis_class = 8, /* the class number of |)| */ mp_letter_class = 9, /* letters and the underline character */ mp_suffix_class = 15, mp_left_bracket_class = 17, /* |[| */ mp_right_bracket_class = 18, /* |]| */ mp_brace_class = 19, mp_invalid_class = 20, /* bad character in the input */ mp_max_class = 20, /* the largest class number */ } mp_class_codes; typedef enum mp_text_codes { mp_forever_text, /* |token_type| code for loop texts */ mp_loop_text, /* |token_type| code for loop texts */ mp_parameter_text, /* |token_type| code for parameter texts */ mp_backed_up_text, /* |token_type| code for texts to be reread */ mp_inserted_text, /* |token_type| code for inserted texts */ mp_macro_text, /* |token_type| code for macro replacement texts */ mp_file_bottom_text, /* lowest file code */ } mp_text_codes; typedef enum mp_scanner_states { mp_normal_state, /* |scanner_status| at \quote {quiet times} */ mp_skipping_state, /* |scanner_status| when false conditional text is being skipped */ mp_flushing_state, /* |scanner_status| when junk after a statement is being ignored */ mp_absorbing_state, /* |scanner_status| when a |text| parameter is being scanned */ mp_var_defining_state, /* |scanner_status| when a |vardef| is being scanned */ mp_op_defining_state, /* |scanner_status| when a macro |def| is being scanned */ mp_loop_defining_state, /* |scanner_status| when a |for| loop is being scanned */ mp_tex_flushing_state, } mp_scanner_states; typedef enum mp_verbatim_codes { mp_btex_code, mp_verbatim_code, } mp_verbatim_codes; typedef enum mp_def_codes { mp_end_def_code, /* command modifier for |enddef| */ mp_def_code, /* command modifier for |def| */ mp_var_def_code, /* command modifier for |vardef| */ mp_primary_def_code, /* command modifier for |primarydef| */ mp_secondary_def_code, /* command modifier for |secondarydef| */ mp_tertiary_def_code, /* command modifier for |tertiarydef| */ } mp_def_codes; typedef enum mp_only_set_codes { mp_random_seed_code, mp_max_knot_pool_code, } mp_only_set_codes; typedef enum mp_bytemap_codes { mp_bytemap_set_byte_code, mp_bytemap_set_offset_code, mp_bytemap_copy_code, mp_bytemap_new_code, mp_bytemap_set_code, mp_bytemap_clip_code, mp_bytemap_reduce_code, mp_bytemap_set_options_code, mp_bytemap_reset_code, mp_bytemap_reset_all_code, } mp_bytemap_codes; typedef enum mp_for_codes { mp_end_for_code, /* command modifier for |endfor| */ mp_start_forever_code, /* command modifier for |forever| */ mp_start_for_code, /* command modifier for |for| */ mp_start_forsuffixes_code, /* command modifier for |forsuffixes| */ } mp_for_codes; typedef enum mp_macro_fix_codes { mp_macro_quote_code, /* |macro_special| modifier for |quote| */ mp_macro_prefix_code, /* |macro_special| modifier for |\#\AT!| */ mp_macro_at_code, /* |macro_special| modifier for |\AT!| */ mp_macro_suffix_code, /* |macro_special| modifier for |\AT!\#| */ } mp_macro_fix_codes; typedef enum mp_controls_codes { mp_both_controls_code, mp_first_control_code, mp_second_control_code, } mp_controls_codes; typedef enum mp_if_codes { mp_no_if_code, mp_if_code, /* code for |if| being evaluated */ mp_fi_code, /* code for |fi| */ mp_else_code, /* code for |else| */ mp_else_if_code, /* code for |elseif| */ } mp_if_codes; typedef enum mp_show_codes { mp_show_token_code, /* show the meaning of a single token */ mp_show_stats_code, /* show current memory and string usage */ mp_show_code, /* show a list of expressions */ mp_show_var_code, /* show a variable and its descendents */ mp_show_dependencies_code, /* show dependent variables in terms of independents */ } mp_show_codes; typedef enum mp_with_codes { mp_with_pen_code, mp_with_dashed_code, mp_with_pre_script_code, mp_with_post_script_code, mp_with_nested_pre_script_code, mp_with_nested_post_script_code, mp_with_stacking_code, mp_with_no_model_code, mp_with_grey_model_code, mp_with_uninitialized_model_code, mp_with_rgb_model_code, mp_with_cmyk_model_code, mp_with_linecap_code, mp_with_linejoin_code, mp_with_miterlimit_code, mp_with_curvature_code, mp_with_bytemap_code, mp_with_nothing_code, /* quits scanning of a with, avoids lookahead */ } mp_with_codes; typedef enum mp_add_codes { mp_add_double_path_code, /* command modifier for |doublepath| */ mp_add_contour_code, /* command modifier for |contour| */ mp_add_also_code, /* command modifier for |also| */ } mp_add_codes ; typedef enum mp_message_codes { mp_normal_message_code, mp_error_message_code, mp_error_help_code, } mp_message_codes; typedef enum mp_protection_codes { mp_inner_protection_code, mp_outer_protection_code, } mp_protection_codes; typedef enum mp_input_codes { mp_input_code, mp_end_input_code, } mp_input_codes; typedef enum mp_stop_codes { mp_end_code, mp_dump_code, } mp_stop_codes; /* types in the outer block */ typedef void (*convert_func) (mp_number *r); typedef void (*m_log_func) (MP mp, mp_number *r, mp_number *a); typedef void (*m_exp_func) (MP mp, mp_number *r, mp_number *a); typedef void (*m_unif_rand_func) (MP mp, mp_number *ret, mp_number *x_orig); typedef void (*m_norm_rand_func) (MP mp, mp_number *ret); typedef void (*pyth_add_func) (MP mp, mp_number *r, mp_number *a, mp_number *b); typedef void (*pyth_sub_func) (MP mp, mp_number *r, mp_number *a, mp_number *b); typedef void (*power_of_func) (MP mp, mp_number *r, mp_number *a, mp_number *b); typedef void (*n_arg_func) (MP mp, mp_number *r, mp_number *a, mp_number *b); typedef void (*velocity_func) (MP mp, mp_number *r, mp_number *a, mp_number *b, mp_number *c, mp_number *d, mp_number *e); typedef int (*ab_vs_cd_func) (mp_number *a, mp_number *b, mp_number *c, mp_number *d); typedef void (*crossing_point_func) (MP mp, mp_number *r, mp_number *a, mp_number *b, mp_number *c); typedef void (*number_from_int_func) (mp_number *A, int B); typedef void (*number_from_boolean_func) (mp_number *A, int B); typedef void (*number_from_scaled_func) (mp_number *A, int B); typedef void (*number_from_double_func) (mp_number *A, double B); typedef void (*number_from_addition_func) (mp_number *A, mp_number *B, mp_number *C); typedef void (*number_half_from_addition_func) (mp_number *A, mp_number *B, mp_number *C); typedef void (*number_from_subtraction_func) (mp_number *A, mp_number *B, mp_number *C); typedef void (*number_half_from_subtraction_func) (mp_number *A, mp_number *B, mp_number *C); typedef void (*number_from_div_func) (mp_number *A, mp_number *B, mp_number *C); typedef void (*number_from_mul_func) (mp_number *A, mp_number *B, mp_number *C); typedef void (*number_from_int_div_func) (mp_number *A, mp_number *B, int C); typedef void (*number_from_int_mul_func) (mp_number *A, mp_number *B, int C); typedef void (*number_from_of_the_way_func) (MP mp, mp_number *A, mp_number *t, mp_number *B, mp_number *C); typedef void (*number_negate_func) (mp_number *A); typedef void (*number_add_func) (mp_number *A, mp_number *B); typedef void (*number_subtract_func) (mp_number *A, mp_number *B); typedef void (*number_modulo_func) (mp_number *A, mp_number *B); typedef void (*number_half_func) (mp_number *A); typedef void (*number_double_func) (mp_number *A); typedef void (*number_abs_func) (mp_number *A); typedef void (*number_clone_func) (mp_number *A, mp_number *B); typedef void (*number_negated_clone_func) (mp_number *A, mp_number *B); typedef void (*number_abs_clone_func) (mp_number *A, mp_number *B); typedef void (*number_swap_func) (mp_number *A, mp_number *B); typedef void (*number_add_scaled_func) (mp_number *A, int b); typedef void (*number_multiply_int_func) (mp_number *A, int b); typedef void (*number_divide_int_func) (mp_number *A, int b); typedef int (*number_to_int_func) (mp_number *A); typedef int (*number_to_boolean_func) (mp_number *A); typedef int (*number_to_scaled_func) (mp_number *A); typedef int (*number_round_func) (mp_number *A); typedef void (*number_floor_func) (mp_number *A); typedef double (*number_to_double_func) (mp_number *A); typedef int (*number_odd_func) (mp_number *A); typedef int (*number_equal_func) (mp_number *A, mp_number *B); typedef int (*number_less_func) (mp_number *A, mp_number *B); typedef int (*number_greater_func) (mp_number *A, mp_number *B); typedef int (*number_non_equal_abs_func) (mp_number *A, mp_number *B); typedef void (*make_scaled_func) (MP mp, mp_number *ret, mp_number *A, mp_number *B); typedef void (*make_fraction_func) (MP mp, mp_number *ret, mp_number *A, mp_number *B); typedef void (*take_fraction_func) (MP mp, mp_number *ret, mp_number *A, mp_number *B); typedef void (*take_scaled_func) (MP mp, mp_number *ret, mp_number *A, mp_number *B); typedef void (*sin_cos_func) (MP mp, mp_number *A, mp_number *S, mp_number *C); typedef void (*slow_add_func) (MP mp, mp_number *A, mp_number *S, mp_number *C); typedef void (*sqrt_func) (MP mp, mp_number *ret, mp_number *A); typedef void (*init_randoms_func) (MP mp, int seed); typedef void (*allocate_number_func) (MP mp, mp_number *A, mp_number_type t); typedef void (*allocate_number_clone_func) (MP mp, mp_number *A, mp_number_type t, mp_number *B); typedef void (*allocate_number_abs_func) (MP mp, mp_number *A, mp_number_type t, mp_number *B); typedef void (*allocate_number_div_func) (MP mp, mp_number *A, mp_number_type t, mp_number *B, mp_number *C); typedef void (*allocate_number_mul_func) (MP mp, mp_number *A, mp_number_type t, mp_number *B, mp_number *C); typedef void (*allocate_number_add_func) (MP mp, mp_number *A, mp_number_type t, mp_number *B, mp_number *C); typedef void (*allocate_number_sub_func) (MP mp, mp_number *A, mp_number_type t, mp_number *B, mp_number *C); typedef void (*allocate_number_double_func) (MP mp, mp_number *A, double B); typedef void (*free_number_func) (MP mp, mp_number *n); typedef void (*fraction_to_round_scaled_func) (mp_number *n); typedef void (*print_func) (MP mp, mp_number *A); typedef char *(*tostring_func) (MP mp, mp_number *A); typedef void (*scan_func) (MP mp, int A); typedef void (*mp_free_func) (MP mp); typedef void (*set_precision_func) (MP mp); /*tex We use a prefix |md_| so that we don't get complaints about recursive macro definitions. This is cleaner than redefining the macros. */ typedef struct math_data { mp_number md_precision_default; mp_number md_precision_max; mp_number md_precision_min; mp_number md_epsilon_t; mp_number md_inf_t; mp_number md_negative_inf_t; mp_number md_one_third_inf_t; mp_number md_zero_t; mp_number md_unity_t; mp_number md_two_t; mp_number md_three_t; mp_number md_half_unit_t; mp_number md_three_quarter_unit_t; mp_number md_fraction_one_t; mp_number md_fraction_half_t; mp_number md_fraction_three_t; mp_number md_fraction_four_t; mp_number md_one_eighty_deg_t; mp_number md_negative_one_eighty_deg_t; mp_number md_three_sixty_deg_t; mp_number md_one_k; mp_number md_sqrt_8_e_k; mp_number md_twelve_ln_2_k; mp_number md_coef_bound_k; mp_number md_coef_bound_minus_1; mp_number md_twelvebits_3; mp_number md_arc_tol_k; mp_number md_twentysixbits_sqrt2_t; mp_number md_twentyeightbits_d_t; mp_number md_twentysevenbits_sqrt2_d_t; mp_number md_fraction_threshold_t; mp_number md_half_fraction_threshold_t; mp_number md_scaled_threshold_t; mp_number md_half_scaled_threshold_t; mp_number md_near_zero_angle_t; mp_number md_p_over_v_threshold_t; mp_number md_equation_threshold_t; mp_number md_warning_limit_t; allocate_number_func md_allocate; allocate_number_clone_func md_allocate_clone; allocate_number_abs_func md_allocate_abs; allocate_number_div_func md_allocate_div; allocate_number_mul_func md_allocate_mul; allocate_number_add_func md_allocate_add; allocate_number_sub_func md_allocate_sub; allocate_number_double_func md_allocate_double; free_number_func md_free; number_from_int_func md_from_int; number_from_boolean_func md_from_boolean; number_from_scaled_func md_from_scaled; number_from_double_func md_from_double; number_from_addition_func md_from_addition; number_half_from_addition_func md_half_from_addition; number_from_subtraction_func md_from_subtraction; number_half_from_subtraction_func md_half_from_subtraction; number_from_div_func md_from_div; number_from_mul_func md_from_mul; number_from_int_div_func md_from_int_div; number_from_int_mul_func md_from_int_mul; number_from_of_the_way_func md_from_of_the_way; number_negate_func md_negate; number_add_func md_add; number_subtract_func md_subtract; number_half_func md_half; number_modulo_func md_modulo; number_double_func md_do_double; number_abs_func md_abs; number_clone_func md_clone; number_negated_clone_func md_negated_clone; number_abs_clone_func md_abs_clone; number_swap_func md_swap; number_add_scaled_func md_add_scaled; number_multiply_int_func md_multiply_int; number_divide_int_func md_divide_int; number_to_int_func md_to_int; number_to_boolean_func md_to_boolean; number_to_scaled_func md_to_scaled; number_to_double_func md_to_double; number_odd_func md_odd; number_equal_func md_equal; number_less_func md_less; number_greater_func md_greater; number_non_equal_abs_func md_non_equal_abs; number_round_func md_round_unscaled; number_floor_func md_floor_scaled; make_scaled_func md_make_scaled; make_fraction_func md_make_fraction; take_fraction_func md_take_fraction; take_scaled_func md_take_scaled; velocity_func md_velocity; ab_vs_cd_func md_ab_vs_cd; crossing_point_func md_crossing_point; n_arg_func md_n_arg; m_log_func md_m_log; m_exp_func md_m_exp; m_unif_rand_func md_m_unif_rand; m_norm_rand_func md_m_norm_rand; pyth_add_func md_pyth_add; pyth_sub_func md_pyth_sub; power_of_func md_power_of; fraction_to_round_scaled_func md_fraction_to_round_scaled; convert_func md_fraction_to_scaled; convert_func md_scaled_to_fraction; convert_func md_scaled_to_angle; convert_func md_angle_to_scaled; init_randoms_func md_init_randoms; sin_cos_func md_sin_cos; sqrt_func md_sqrt; slow_add_func md_slow_add; print_func md_print; tostring_func md_tostring; scan_func md_scan_numeric; scan_func md_scan_fractional; mp_free_func md_free_math; set_precision_func md_set_precision; } math_data; typedef unsigned short quarterword; /* 1/4 of a 64 bit word */ typedef int halfword; /* 1/2 of a 64 bit word */ /*tex It is more convenient toi have these in one place. The records are defined later. Some nodes are for housekeeping, others concern graphics. We also encounter export related objects. Some nodes are mized in linked lists to then we cast them in away that the common fields overlap. */ typedef struct mp_value_node_data *mp_value_node; typedef struct mp_node_data *mp_node; typedef struct mp_symbol_data *mp_symbol; typedef struct mp_subst_data *mp_subst_node; /* will become mp_subst */ typedef struct mp_save_data *mp_save; typedef struct mp_loop_data *mp_loop_node; /* will become mp_loop */ typedef struct mp_if_data *mp_if_node; /* will become mp_if */ typedef struct mp_node_data *mp_symbolic_node; typedef struct mp_node_data *mp_token_node; typedef struct mp_pair_node_data *mp_pair_node; typedef struct mp_transform_node_data *mp_transform_node; typedef struct mp_color_node_data *mp_color_node; typedef struct mp_shape_node_data *mp_shape_node; typedef struct mp_start_node_data *mp_start_node; typedef struct mp_stop_node_data *mp_stop_node; typedef struct mp_dash_node_data *mp_dash_node; typedef struct mp_independent_data { union { int serial; /* only for |indep_value|, used together with |scale| */ int equivalent; }; int scale; /* only for |indep_scale|, used together with |serial| */ } mp_independent_data; typedef struct mp_value_data { mp_independent_data indep; mp_number n; mp_string str; mp_symbol sym; mp_node node; mp_knot p; } mp_value_data; typedef struct mp_value { mp_variable_type type; mp_value_data data; } mp_value; /*tex \MP\ also has a bunch of internal parameters that a user might want to fuss with. Every such parameter has an identifying code number, defined here. */ typedef enum mp_given_internal { mp_number_system_internal = 1, /* the number system as set up by |numbersystem| */ mp_number_precision_internal, /* the number system precision as set up by |numberprecision| */ mp_job_name_internal, /* the jobname as set up from the options stucture */ mp_tracing_titles_internal, /* show titles online when they appear */ mp_tracing_equations_internal, /* show each variable when it becomes known */ mp_tracing_capsules_internal, /* show capsules too */ mp_tracing_dependencies_internal,/* show dependencies (de)allocation */ mp_tracing_choices_internal, /* show the control points chosen for paths */ mp_tracing_specs_internal, /* show path subdivision prior to filling with polygonal a pen */ mp_tracing_commands_internal, /* show commands and operations before they are performed */ mp_tracing_restores_internal, /* show when a variable or internal is restored */ mp_tracing_macros_internal, /* show macros before they are expanded */ mp_tracing_output_internal, /* dummy */ mp_tracing_stats_internal, /* show memory usage at end of job */ /* now a dummy */ mp_tracing_online_internal, /* show long diagnostics on terminal and in the log file */ mp_year_internal, /* the current year (e.g., 1984) */ mp_month_internal, /* the current month (e.g., 3 $\equiv$ March) */ mp_day_internal, /* the current day of the month */ mp_time_internal, /* the number of minutes past midnight when this job started */ mp_hour_internal, /* the number of hours past midnight when this job started */ mp_minute_internal, /* the number of minutes in that hour when this job started */ mp_char_code_internal, /* the number of the next character to be output */ mp_char_wd_internal, /* the width of the next character to be output */ mp_char_ht_internal, /* the height of the next character to be output */ mp_char_dp_internal, /* the depth of the next character to be output */ mp_char_ic_internal, /* the italic correction of the next character to be output */ mp_pausing_internal, /* dummy */ mp_showstopping_internal, /* positive to stop after each |show| command */ mp_texscriptmode_internal, /* controls spacing in texmode */ mp_overloadmode_internal, mp_linejoin_internal, /* as in \ps: 0 for mitered, 1 for round, 2 for beveled */ mp_linecap_internal, /* as in \ps: 0 for butt, 1 for round, 2 for square */ mp_stacking_internal, mp_miterlimit_internal, /* controls miter length as in \ps */ mp_warning_check_internal, /* controls error message when variable value is large */ mp_default_zero_angle_internal, mp_true_corners_internal, /* positive to make |llcorner| etc. ignore |setbounds| */ mp_default_color_model_internal, /* the default color model for unspecified items */ mp_restore_clip_color_internal, mp_less_digits_internal, mp_intersection_precision_internal, mp_join_tolerance_internal, } mp_given_internal; # define max_given_internal mp_join_tolerance_internal typedef struct mp_internal { mp_value v; char *intname; int run; int padding; } mp_internal; typedef enum mp_bytemap_options { mp_bytemap_option_persistent = 1, mp_bytemap_option_posit = 2, } mp_bytemap_options; typedef struct mp_bytemap { unsigned char *data; int nx; int ny; int nz; int ox; int oy; int options; } mp_bytemap; typedef struct mp_symbol_data { int type; int property; /* we had padding room anyway */ mp_value v; mp_string text; void *parent; /* can be MP */ } mp_symbol_data; typedef enum mp_macro_info { mp_general_macro, /* preface to a macro defined with a parameter list */ mp_primary_macro, /* preface to a macro with a |primary| parameter */ mp_secondary_macro, /* preface to a macro with a |secondary| parameter */ mp_tertiary_macro, /* preface to a macro with a |tertiary| parameter */ mp_expr_macro, /* preface to a macro with an undelimited |expr| parameter */ mp_of_macro, /* preface to a macro with undelimited `|expr| |x| |of|~|y|' parameters */ mp_suffix_macro, /* preface to a macro with an undelimited |suffix| parameter */ mp_text_macro, /* preface to a macro with an undelimited |text| parameter */ mp_expr_parameter, /* used by |expr| primitive */ mp_suffix_parameter, /* used by |suffix| primitive */ mp_text_parameter /* used by |text| primitive */ } mp_macro_info; typedef struct mp_save_data { int type; int padding; mp_internal value; struct mp_save_data *link; } mp_save_data; enum mp_bb_code { mp_x_code, /* index for |minx| and |maxx| */ mp_y_code /* index for |miny| and |maxy| */ }; typedef struct mp_in_state_record { int start_field; int loc_field; int limit_field; int index_field; mp_node nstart_field; mp_node nloc_field; mp_string name_field; } mp_in_state_record; typedef struct mp_subst_data { mp_name_type_type info_mod; int value_mod; int value_data; int padding; mp_symbol info; mp_subst_node link; } mp_subst_data; typedef struct mp_loop_data { mp_symbol var ; /* the var of the loop */ mp_node info; /* iterative text of this loop */ mp_node type; /* the special type of this loop, or a pointer into mem */ mp_node list; /* the remaining list elements */ mp_node list_start; /* head fo the list of elements */ mp_number old_value; /* previous value of current arithmetic value */ mp_number value; /* current arithmetic value */ mp_number step_size; /* arithmetic step size */ mp_number final_value; /* end arithmetic value */ struct mp_loop_data *link; /* the enclosing loop, if any */ mp_knot point; } mp_loop_data; typedef struct File { FILE *f; } File; typedef struct mp_if_data { mp_variable_type type; mp_name_type_type name_type; struct mp_if_data *link; // int hasnumber; int if_line_field; } mp_if_data; /*tex The user's terminal acts essentially like other files of text, except that it is used both for input and for output. When the terminal is considered an input file, the file variable is called |term_in|, and when it is considered an output file the file variable is |term_out|. Sometimes it is necessary to synchronize the input/output mixture that happens on the user's terminal, and three system-dependent procedures are used for this purpose. The first of these, |update_terminal|, is called when we want to make sure that everything we have output to the terminal so far has actually left the computer's internal buffers and been sent. The second, |clear_terminal|, is called when we wish to cancel any input that the user may have typed ahead (since we are about to issue an unexpected error message). The third, |wake_up_terminal|, is supposed to revive the terminal if the user has disabled it by some instruction to the operating system. The following macros show how these operations can be specified:The global variable |loc| should be set so that the character to be read next by \MP\ is in |buffer [loc]|. This character should not be blank, and we should have |loc < last|. */ // # define update_terminal() mp_print_nl_only(mp); /* empty the terminal output buffer */ // # define clear_terminal() /* clear the terminal input buffer */ // # define wake_up_terminal() mp_print_nl_only(mp); /* cancel the user's cancellation of output */ typedef enum mp_selectors { mp_new_string_selector, /* printing is deflected to the string pool */ mp_no_print_selector, /* |selector| setting that makes data disappear */ mp_term_only_selector, /* printing is destined for the terminal only */ mp_log_only_selector, /* printing is destined for the transcript file only */ mp_term_and_log_selector, /* normal |selector| setting */ mp_first_file_selector, /* first write file selector */ } mp_selectors; typedef enum mp_logging_targets { mp_void_logging_target, mp_term_logging_target, mp_file_logging_target, mp_both_logging_target, mp_error_logging_target, } mp_logging_targets; # define mp_fputs(b,f) (mp->write_file)(mp, f, b) # define mp_log_string(target,s) (mp->run_logger)(mp, target, s, strlen(s)) # define mp_log_mpstr(target,s,l) (mp->run_logger)(mp, target, s, l) # define mp_log_cr(target) (mp->run_logger)(mp, target, "\n", 1) # define mp_log_chr(target,s) { unsigned char ss[2] = { s, 0 }; (mp->run_logger)(mp, target, (const char *) ss, 1); } # define mp_log_error(s) (mp->run_logger)(mp, mp_error_logging_target, s, strlen(s)) typedef struct mp_node_data { union { mp_command_code command; mp_variable_type type; }; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int padding; /* specific */ mp_value_data data; } mp_node_data; typedef enum mp_linecap_codes { mp_butt_linecap_code, mp_rounded_linecap_code, mp_squared_linecap_code, /* see below */ mp_weird_linecap_code, } mp_linecap_codes; typedef enum mp_linejoin_codes { mp_mitered_linejoin_code, mp_rounded_linejoin_code, mp_beveled_linejoin_code, /* we see this value being used */ mp_weird_linejoin_code, } mp_linejoin_codes; typedef enum mp_curvature_codes { mp_default_curvature_code, mp_always_curvature_code, /* we see this value being used */ mp_weird_curvature_code, } mp_curvature_codes; # define internal_value(A) mp->internal[(A)].v.data.n # define internal_string(A) mp->internal[A].v.data.str # define set_internal_string(A,B) mp->internal[(A)].v.data.str=(B) # define internal_name(A) mp->internal[(A)].intname # define set_internal_name(A,B) mp->internal[(A)].intname=(B) # define internal_type(A) mp->internal[A].v.type # define set_internal_type(A,B) mp->internal[(A)].v.type=(B) # define internal_run(A) mp->internal[(A)].run # define set_internal_run(A,B) mp->internal[(A)].run=(B) typedef struct mp_value_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int padding; /* specific */ mp_value_data data; mp_number subscript; mp_symbol hashloc; mp_node parent; mp_node attr_head; mp_node subscr_head; } mp_value_node_data; typedef struct mp_pair_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int padding; /* specific */ mp_node x_part; mp_node y_part; } mp_pair_node_data; typedef struct mp_transform_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int padding; /* specific */ mp_node tx_part; mp_node ty_part; mp_node xx_part; mp_node yx_part; mp_node xy_part; mp_node yy_part; } mp_transform_node_data; typedef struct mp_color_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int padding; /* specific */ union { mp_node red_part; mp_node cyan_part; mp_node x_part; }; union { mp_node green_part; mp_node magenta_part; mp_node y_part; }; union { mp_node blue_part; mp_node yellow_part; mp_node z_part; }; union { mp_node grey_part; mp_node black_part; mp_node w_part; }; } mp_color_node_data; typedef struct mp_shape_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_shape_node_data *link; // int hasnumber; // int stacking; /*common */ int stacking; mp_string pre_script; mp_string post_script; union { mp_number red; mp_number cyan; }; union { mp_number green; mp_number magenta; }; union { mp_number blue; mp_number yellow; }; union { mp_number black; mp_number grey; }; /* specific to paths */ mp_knot path; mp_knot pen; mp_node dash; mp_number dashscale; mp_number miterlimit; unsigned char color_model; unsigned char linejoin; unsigned char linecap; unsigned char pen_type; unsigned char curvature; unsigned char padding_1; short bytemap; } mp_shape_node_data; typedef struct mp_start_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int stacking; /* specific */ int stacking; mp_string pre_script; mp_string post_script; mp_knot path; } mp_start_node_data; typedef struct mp_stop_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int stacking; /* specific */ int stacking; } mp_stop_node_data; typedef struct mp_dash_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_dash_node_data *link; // int hasnumber; // int padding; /* specific */ mp_number start_x; /* the starting $x$~coordinate in a dash node */ mp_number stop_x; /* the ending $x$~coordinate in a dash node */ mp_number dash_y; /* $y$ value for the dash list in an edge header */ mp_node dash_info; } mp_dash_node_data; typedef struct mp_edge_header_node_data { mp_variable_type type; mp_name_type_type name_type; struct mp_node_data *link; // int hasnumber; // int padding; /* specific */ mp_number start_x; mp_number stop_x; mp_number dash_y; mp_node dash_info; mp_number minx; mp_number miny; mp_number maxx; mp_number maxy; mp_node bblast; int bbtype; /* tells how bounding box data depends on |truecorners| */ int ref_count; mp_node list; mp_node obj_tail; } mp_edge_header_node_data; typedef struct mp_edge_header_node_data *mp_edge_header_node; typedef enum mp_bound_codes { mp_no_bounds_code, /* |bbtype| value when bounding box data is valid for all |truecorners| values */ mp_bounds_set_code, /* |bbtype| value when bounding box data is for |truecorners|${}\le 0$ */ mp_bounds_unset_code, /* |bbtype| value when bounding box data is for |truecorners|${}>0$ */ } mp_bound_codes; typedef enum mp_expression_scan_types { mp_expression_scan_code, mp_primary_scan_code, mp_secondary_scan_code, mp_tertiary_scan_code, } mp_expression_scan_types; typedef enum mp_internal_action_types { mp_initialize_internal_code, mp_save_internal_code, mp_restore_internal_code, // mp_tracing_internal_code, } mp_internal_action_types; typedef struct mp_memory_pool_data { void *list; /* head of available list */ int used; /* currently used */ int max; /* maximum used */ int pool; /* size of pool */ union { int kept; /* kept in reserve */ int step; /* step up when full */ }; union { size_t size; /* size or record */ size_t count; /* allocated bytes */ }; int state; } mp_memory_pool_data; typedef enum mp_memory_pool_states { mp_pool_uknown, mp_pool_counted, mp_pool_pooled, mp_pool_persistent, } mp_memory_pool_states; typedef enum mp_memory_pool_types { mp_token_pool, mp_symbol_pool, /* not a pool, just statistics */ mp_pair_pool, mp_color_pool, mp_transform_pool, mp_dash_pool, mp_knot_pool, mp_shape_pool, mp_start_pool, mp_stop_pool, mp_edge_header_pool, mp_value_pool, mp_symbolic_pool, mp_save_pool, mp_if_pool, mp_loop_pool, mp_subst_pool, mp_edge_object_pool, mp_dash_object_pool, mp_knot_object_pool, mp_shape_object_pool, mp_start_object_pool, mp_stop_object_pool, mp_identifiers_pool, mp_internals_pool, mp_bytemaps_pool, mp_bytemap_data_pool, mp_max_pool, } mp_memory_pool_types; /* The size of stack for bisection algorithms; it should probably be left at this value. */ # define bistack_size 1500 /*tex Constants and variables per instance: */ typedef struct MP_instance { /* */ void *userdata; /* this allows the calling application to setup local (e.g. L for Lua) */ char *banner; /* the banner that is printed to the screen and log */ int utf8_mode; int text_mode; int show_mode; int halt_on_error; /* do we quit at the first error? */ /* */ mp_file_finder find_file; mp_script_runner run_script; mp_internal_runner run_internal; mp_log_runner run_logger; mp_overload_runner run_overload; mp_error_runner run_error; mp_warning_runner run_warning; mp_status_runner run_status; mp_text_maker make_text; mp_file_opener open_file; mp_file_closer close_file; mp_file_reader read_file; mp_file_writer write_file; int find_file_id; int run_script_id; int run_internal_id; int run_logger_id; int run_overload_id; int run_error_id; int run_warning_id; int run_status_id; int make_text_id; int open_file_id; /* */ int less_digits; int interaction; int random_seed; int math_mode; /* */ char *job_name; /* */ mp_backend_writer shipout_backend; /* */ math_data *math; /* */ int max_in_open; /* maximum number of input files and error insertions that can be going on simultaneously */ /* */ char *name_of_file; /* the name of a system file */ /* */ size_t buf_size; /* maximum number of characters simultaneously present in current lines of open files */ unsigned char *buffer; /* lines of characters being read */ size_t first; /* the first unused position in |buffer| */ size_t last; /* end of the line just input to |buffer| */ size_t max_buf_stack; /* largest index used in |buffer| */ /* */ void *term_in; /* the terminal as an input file */ /* */ avl_tree strings; /* string avl tree */ unsigned char *cur_string; /* current string buffer */ size_t cur_length; /* current index in that buffer */ size_t cur_string_size; /* malloced size of |cur_string| */ /* */ int pool_in_use; /* total number of string bytes actually in use */ int max_pool_used; /* maximum |pool_in_use| so far */ int strings_in_use; /* total number of strings actually in use */ int max_strings_used; /* maximum |strs_in_use| so far */ /* */ unsigned int selector; /* where to print a message */ unsigned int term_offset; /* the number of characters on the current terminal line */ unsigned int file_offset; /* the number of characters on the current file line */ /* */ int history; /* has the source input been clean so far? */ int error_count; /* the number of scrolled errors since the last statement ended */ mp_string error_help; /* a string set up by |errhelp| */ int long_help_seen; /* has the long |\\errmessage| help been used? */ /* */ jmp_buf *jump_buffer; /* */ int run_state; /* are we processing input ? */ int finished; /* set true by |close_files_and_terminate| */ /* */ int arithmic_error; /* */ mp_number randoms[55]; /* the last 55 random values generated */ int j_random; /* the number of unused |randoms| */ /* */ mp_memory_pool_data memory_pool[mp_max_pool]; /* */ mp_dash_node null_dash; mp_value_node dep_head; mp_node inf_val; mp_node zero_val; mp_node temp_val; mp_node end_attr; mp_node bad_vardef; mp_node temp_head; mp_node hold_head; mp_node spec_head; /* */ mp_internal *internal; /* the values of internal quantities */ /* */ mp_bytemap *bytemaps; /* */ unsigned int old_selector; /* */ int char_class[256]; /* */ avl_tree symbols; /* avl tree of symbolic tokens */ avl_tree frozen_symbols; /* avl tree of frozen symbolic tokens */ avl_iterator symbol_iterator; mp_symbol frozen_bad_vardef; mp_symbol frozen_colon; mp_symbol frozen_end_def; mp_symbol frozen_end_for; mp_symbol frozen_end_group; mp_symbol frozen_etex; mp_symbol frozen_fi; mp_symbol frozen_inaccessible; mp_symbol frozen_left_bracket; mp_symbol frozen_repeat_loop; mp_symbol frozen_right_delimiter; mp_symbol frozen_semicolon; mp_symbol frozen_slash; mp_symbol frozen_undefined; mp_symbol frozen_dump; /* */ mp_symbol id_lookup_test; /* */ mp_save_data *save_ptr; /* the most recently saved item */ /* */ mp_knot path_tail; /* the node that links to the beginning of a path */ /* */ int path_size; /* maximum number of knots between breakpoints of a path */ int path_padding; /* be nice */ mp_number *delta_x; mp_number *delta_y; mp_number *delta; /* knot differences */ mp_number *psi; /* turning angles */ /* */ mp_number *theta; /* values of $\theta_k$ */ mp_number *uu; /* values of $u_k$ */ mp_number *vv; /* values of $v_k$ */ mp_number *ww; /* values of $w_k$ */ /* */ mp_number st; mp_number ct; mp_number sf; mp_number cf; /* sines and cosines */ /* */ mp_number bbmin[2]; mp_number bbmax[2]; /* */ mp_number half_cos[8]; /* ${1\over2}\cos(45k)$ */ mp_number d_cos[8]; /* a magic constant times $\cos(45k)$ */ /* */ mp_number cur_x; mp_number cur_y; /* all-purpose return value registers */ /* */ int spec_offset; /* number of pen edges between |h| and the initial offset */ int spec_padding; /* be nice */ /* */ mp_knot spec_p1; mp_knot spec_p2; /* pointers to distinguished knots */ /* */ unsigned int tol_step; /* either 0 or 3, usually */ /* */ mp_number *bisect_stack; int bisect_ptr; /* */ mp_number cur_t; mp_number cur_tt; /* controls and results of |cubic_intersection| */ int time_to_go; /* this many backtracks before giving up */ mp_number max_t; /* maximum of $2^{l+1}$ so far achieved */ /* */ mp_number delx; mp_number dely; /* the components of $\Delta=2^l(w_0-z_0)$ */ int tol; /* bound on the uncertainty in the overlap test */ int uv; int xy; /* pointers to the current packets of interest */ int three_l; /* |tol_step| times the bisection level */ mp_number appr_t; mp_number appr_tt; /* best approximations known to the answers */ /* */ int serial_no; /* the most recent serial number */ /* */ int fix_needed; /* does at least one |independent| variable need scaling? */ int watch_coefs; /* should we scale coefficients that exceed |coef_bound|? */ mp_value_node dep_final; /* location of the constant term and final link */ /* */ mp_node cur_mod_; /* current command, symbol, and its operands */ /* */ mp_in_state_record *input_stack; int input_ptr; /* first unused location of |input_stack| */ int max_input_stack; /* largest value of |input_ptr| when pushing */ mp_in_state_record cur_input; /* the \quote {top} input state */ int stack_size; /* maximum number of simultaneous input sources */ /* */ int in_open; /* the number of lines in the buffer, less one */ int in_open_max; /* highest value of |in_open| ever seen */ unsigned int open_parens; /* the number of open text files */ void **input_files; int *input_lines; /* the line number for each file */ /* */ mp_node *parameter_stack; /* token list pointers for parameters */ int parameter_ptr; /* first unused entry in |parameter_stack| */ int max_parameter_stack; /* largest value of |parameter_ptr| */ int parameter_size; /* maximum number of simultaneous macro parameters */ /* */ int file_ptr; /* shallowest level shown by |show_context| */ /* */ int scanner_status; /* are we scanning at high speed? */ mp_symbol warning_info; /* if so, what else do we need to know, in case an error occurs? */ int warning_line; mp_node warning_info_node; /* */ int force_eof; /* should the next |input| be aborted early? */ /* */ mp_symbol bg_loc; mp_symbol eg_loc; /* hash addresses of |begingroup| and |endgroup| */ /* */ int expand_depth_count; /* current expansion depth */ int expand_depth; /* current expansion depth */ /* */ mp_if_node cond_ptr; /* top of the condition stack */ int if_limit; /* upper bound on |fi_or_else| codes */ int cur_if; /* type of conditional being worked on */ int if_line; /* line where that conditional began */ /* */ mp_loop_data *loop_ptr; /* top of the loop-control-node stack */ /* */ char *cur_name; /* name of file just scanned */ /* */ int quoted_filename; /* whether the filename is wrapped in " markers */ /* */ int max_read_files; /* maximum number of simultaneously open |readfrom| files */ int n_of_read_files; /* number of valid entries in the above arrays */ void **read_filehandles; /* |readfrom| files */ char **read_filenames; /* corresponding file name or 0 if file not open */ /* */ int max_write_files; /* maximum number of simultaneously open |write| */ int n_of_write_files; /* number of valid entries in the above arrays */ void **write_filehandles; /* |write| files */ char **write_filenames; /* corresponding file name or 0 if file not open */ /* */ mp_value cur_exp; /* the value of the expression just found */ /* */ mp_number max_c [mp_proto_dependent_type + 1]; /* max coefficient magnitude */ mp_value_node max_ptr [mp_proto_dependent_type + 1]; /* where |p| occurs with |max_c| */ mp_value_node max_link[mp_proto_dependent_type + 1]; /* other occurrences of |p| */ /* */ int var_flag; /* command that wants a variable */ /* */ mp_string eof_line; mp_string eof_file; /* */ mp_number txx; /* current transform coefficients */ mp_number txy; mp_number tyx; mp_number tyy; mp_number tx; mp_number ty; /* */ mp_run_data run_data; /* */ int last_add_type; /* command modifier that identifies the last |addto| command */ /* */ mp_symbol every_job_sym; /* */ int ten_pow[10]; /* $10^0..10^9$ */ int scaled_out; /* amount of |scaled| that was taken out in |divide_scaled| */ /* */ } MP_instance; /* mp header stuff */ extern void mp_print_e_str (MP mp, const char *s); // void mp_print_e_chr (MP mp, unsigned char k); extern void mp_show_context (MP mp); extern void mp_error (MP mp, const char *msg, const char *hlp); extern void mp_warn (MP mp, const char *msg); extern void mp_fatal_error (MP mp, const char *s); extern void mp_confusion (MP mp, const char *s); extern int mp_initialize_symbol_traverse (MP mp); extern void mp_kill_symbol_traverse (MP mp); extern void *mp_fetch_symbol_traverse (MP mp); extern void *mp_fetch_symbol (MP mp, char *s); extern int mp_close_path_cycle (MP mp, mp_knot p, mp_knot q); extern int mp_close_path (MP mp, mp_knot q, mp_knot first); extern mp_knot mp_create_knot (MP mp); extern mp_knot mp_append_knot (MP mp, mp_knot p, double x, double y); extern mp_knot mp_append_knot_xy (MP mp, mp_knot p, double x, double y); extern int mp_set_knot_curl (MP mp, mp_knot q, double value); extern int mp_set_knot_left_curl (MP mp, mp_knot q, double value); extern int mp_set_knot_right_curl (MP mp, mp_knot q, double value); extern int mp_set_knot_simple_curl (MP mp, mp_knot q); extern int mp_set_knotpair_curls (MP mp, mp_knot p, mp_knot q, double t1, double t2) ; extern int mp_set_knotpair_tensions (MP mp, mp_knot p, mp_knot q, double t1, double t2) ; extern int mp_set_knot_left_tension (MP mp, mp_knot p, double t1); extern int mp_set_knot_right_tension (MP mp, mp_knot p, double t1); extern int mp_set_knot_left_control (MP mp, mp_knot p, double t1, double t2); extern int mp_set_knot_right_control (MP mp, mp_knot p, double t1, double t2); extern int mp_set_knotpair_controls (MP mp, mp_knot p, mp_knot q, double x1, double y1, double x2, double y2); extern int mp_set_knot_direction (MP mp, mp_knot q, double x, double y) ; extern int mp_set_knotpair_directions (MP mp, mp_knot p, mp_knot q, double x1, double y1, double x2, double y2); extern int mp_solve_path (MP mp, mp_knot first); extern void mp_free_path (MP mp, mp_knot p); extern double mp_number_as_double (MP mp, mp_number n); extern void mp_set_internal (MP mp, char *n, char *v, int isstring); extern int mp_skip_token_value (MP mp, int token); extern void mp_scan_next_value (MP mp, int keep, int *token, int *mode, int *kind); extern void mp_scan_expr_value (MP mp, int keep, int *kind); extern void mp_scan_token_value (MP mp, int keep, int *token, int *mode, int *kind); extern void mp_scan_symbol_value (MP mp, int keep, char **s, int expand); extern void mp_scan_property_value (MP mp, int keep, int *kind, char **s, int *property, int *detail); extern void mp_scan_numeric_value (MP mp, int primary, double *d); extern void mp_scan_boolean_value (MP mp, int primary, int *b); extern void mp_scan_string_value (MP mp, int primary, char **s, size_t *l); extern void mp_scan_pair_value (MP mp, int primary, double *x, double *y); extern void mp_scan_color_value (MP mp, int primary, double *r, double *g, double *b); extern void mp_scan_cmykcolor_value (MP mp, int primary, double *c, double *m, double *y, double *k); extern void mp_scan_transform_value (MP mp, int primary, double *x, double *y, double *xx, double *xy, double *yx, double *yy); extern void mp_scan_path_value (MP mp, int primary, mp_knot *k); extern void mp_push_numeric_value (MP mp, double n); extern void mp_push_integer_value (MP mp, int i); extern void mp_push_boolean_value (MP mp, int b); extern void mp_push_string_value (MP mp, const char *s, int l); extern void mp_push_pair_value (MP mp, double x, double y); extern void mp_push_color_value (MP mp, double r, double g, double b); extern void mp_push_cmykcolor_value (MP mp, double c, double m, double y, double k); extern void mp_push_transform_value (MP mp, double x, double y, double xx, double xy, double yx, double yy); extern void mp_push_path_value (MP mp, mp_knot k); extern void mp_new_randoms (MP mp); /* library interfaces */ extern MP mp_initialize (MP_options *opt); extern int mp_run (MP mp); extern int mp_execute (MP mp, const char *s, size_t l); extern int mp_finish (MP mp); extern char *mp_metapost_version (void); extern mp_run_data *mp_rundata (MP mp); extern MP_options *mp_options (void); extern void *mp_userdata (MP mp); extern int mp_status (MP mp); extern int mp_finished (MP mp); extern void mplib_shipout_backend (MP mp, void *h); extern mp_bytemap *mp_bytemap_get_by_index (MP mp, int index); extern int mp_bytemap_new_by_index (MP mp, int index, int nx, int ny, int nz, unsigned char *data); extern void mp_graphic_toss_object (MP mp, mp_graphic_object_node p); extern void mp_graphic_toss_objects (MP mp, mp_edge_object_node p); /* memory management header stuff */ extern void *mp_memory_allocate (size_t size); extern void *mp_memory_clear_allocate (size_t size); extern void *mp_memory_reallocate (void *p, size_t size); extern void mp_memory_free (void *p); # endif