diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2009-03-27 15:30:55 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2009-03-27 15:30:55 +0000 |
commit | 178de0871d690556af74f3768c11bc812b07f347 (patch) | |
tree | a939c31adc90d6207848effaec87dd78ec00e658 /Build/source/texk/web2c/luatexdir/lang | |
parent | 4865b23b5199697829e4e6633f2f697b4634c462 (diff) |
Import of luatex 0.37.0 (autoreconf has not been run yet!)
git-svn-id: svn://tug.org/texlive/trunk@12529 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lang')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/lang/hyphen.c | 48 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/lang/texlang.c | 1498 |
2 files changed, 883 insertions, 663 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lang/hyphen.c b/Build/source/texk/web2c/luatexdir/lang/hyphen.c index 049210d3d71..56d745809ae 100644 --- a/Build/source/texk/web2c/luatexdir/lang/hyphen.c +++ b/Build/source/texk/web2c/luatexdir/lang/hyphen.c @@ -53,6 +53,9 @@ #include "hnjalloc.h" #include "hyphen.h" +static const char _svn_version[] = + "$Id: hyphen.c 1696 2008-12-28 21:02:34Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $"; + /* SHOULD BE MOVED TO SEPARATE LIBRARY */ static unsigned char * hnj_strdup( const unsigned char *s @@ -283,7 +286,15 @@ static void hyppat_insert( i = hnj_string_hash (key) % HASH_SIZE; for (e = hashtab->entries[i]; e; e=e->next) { if (strcmp((char*)e->key,(char*)key)==0) { - if (e->u.hyppat) hnj_free(e->u.hyppat); + if (e->u.hyppat) { + if (hyppat && strcmp((char*)e->u.hyppat,(char*)hyppat)!=0) { + int s = maketexstring("Conflicting pattern ignored"); + do_print_err(s); + error(); + flush_str(s); + } + hnj_free(e->u.hyppat); + } e->u.hyppat = hyppat; hnj_free(key); return; @@ -418,7 +429,7 @@ static const unsigned char* next_pattern( size_t* length, const unsigned char **buf ) { - const unsigned char *rover = *buf, *here; + const unsigned char *here, *rover = *buf; while (*rover && isspace(*rover)) rover++; here = rover; while (*rover) { @@ -598,10 +609,10 @@ void hnj_hyphen_load( const unsigned char* format; const unsigned char* begin = f; + unsigned char *pat; + char *org; while((format = next_pattern(&l,&f))!=NULL) { int i,j,e; - unsigned char *pat; - char *org; /* printf("%s\n",format); char* repl = strnchr(format, '/',l); @@ -630,10 +641,11 @@ void hnj_hyphen_load( if (is_utf8_follow(format[i])) e++; } /* l-e => number of _characters_ not _bytes_*/ + /* l-j => number of pattern bytes */ /* l-e-j => number of pattern characters*/ pat = (unsigned char*) malloc(1+l-j); org = ( char*) malloc(2+l-e-j); - /* remove hyphenation encoders (digits) from pat*/ + /* remove hyphenation encoders (digits) from pat*/ org[0] = '0'; for (i=0,j=0,e=0; (unsigned)i<l; i++) { unsigned char c = format[i]; @@ -659,15 +671,15 @@ void hnj_hyphen_load( for (l=1; l<=wordsize; l++) { if (is_utf8_follow(word[l])) continue; /* Do not clip an utf8 sequence*/ for (j=1; j<=l; j++) { - int i = l-j; char *subpat_pat; + int i = l-j; if (is_utf8_follow(word[i])) continue; /* Do not start halfway an utf8 sequence*/ if ((subpat_pat = hyppat_lookup(dict->patterns,word+i,j))!=NULL) { char* newpat_pat; if ((newpat_pat = hyppat_lookup(dict->merged,word,l))==NULL) { + char *neworg; unsigned char *newword=(unsigned char*)malloc(l+1); int e=0; - char *neworg; strncpy((char*)newword, (char*)word,l); newword[l]=0; for (i=0; i<l; i++) if (is_utf8_follow(newword[i])) e++; neworg = malloc(l+2-e); @@ -700,7 +712,8 @@ void hnj_hyphen_load( last_state = state_num; ch = word[j]; if (ch>=0x80) { - int i=1, m; + int m; + int i=1; while (is_utf8_follow(word[j-i])) i++; ch = word[j-i] & mask[i]; m = j-i; @@ -757,14 +770,14 @@ void hnj_hyphen_hyphenate( halfword right, lang_variables *lan ) { + int char_num; + halfword here; + int state = 0; /* +2 for dots at each end, +1 for points /outside/ characters*/ int ext_word_len = length+2; int hyphen_len = ext_word_len+1; /*char *hyphens = hnj_malloc((hyphen_len*2)+1); */ /* LATER */ char *hyphens = hnj_malloc(hyphen_len+1); - int char_num; - int state = 0; - halfword here; /* Add a '.' to beginning and end to facilitate matching*/ set_vlink(begin_point,first); @@ -780,18 +793,21 @@ void hnj_hyphen_hyphenate( hyphens[hyphen_len] = 0; /* now, run the finite state machine */ - for (char_num=0, here=begin_point; here!=end_point; here=get_vlink(here)) { - - int ch = get_lc_code(get_character(here)); + for (char_num=0, here=begin_point; here!=get_vlink(end_point); here=get_vlink(here)) { + int ch; + if (here == begin_point || here == end_point) + ch='.'; + else + ch = get_lc_code(get_character(here)); while (state!=-1) { /* printf("%*s%s%c",char_num-strlen(get_state_str(state)),"",get_state_str(state),(char)ch);*/ HyphenState *hstate = &dict->states[state]; int k; for (k = 0; k < hstate->num_trans; k++) { if (hstate->trans[k].uni_ch == ch) { - char *match; - state = hstate->trans[k].new_state; + char *match; + state = hstate->trans[k].new_state; /* printf(" state %d\n",state);*/ match = dict->states[state].match; if (match) { diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.c b/Build/source/texk/web2c/luatexdir/lang/texlang.c index 1f847f5c643..c37350f146f 100644 --- a/Build/source/texk/web2c/luatexdir/lang/texlang.c +++ b/Build/source/texk/web2c/luatexdir/lang/texlang.c @@ -1,24 +1,21 @@ -/* -Copyright (c) 2007 Taco Hoekwater <taco@latex.org> +/* texlang.c + + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of luatex. + This file is part of LuaTeX. -luatex is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -luatex is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with luatex; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -This is texlang.c -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ #include "luatex-api.h" #include <ptexlib.h> @@ -26,464 +23,648 @@ This is texlang.c #include <string.h> #include "nodes.h" +#include "font/texfont.h" #include "hyphen.h" +static const char _svn_version[] = + "$Id: texlang.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $"; + /* functions from the fontforge unicode library */ -extern unsigned int *utf82u_strcpy(unsigned int *ubuf,const char *utf8buf); +#if 0 +extern unsigned int *utf82u_strcpy(unsigned int *ubuf, const char *utf8buf); extern unsigned int u_strlen(unsigned int *ubuf); -extern char *utf8_idpb(char *w,unsigned int i); +extern char *utf8_idpb(char *w, unsigned int i); +#else + +typedef unsigned int unichar_t; +typedef unsigned char uint8; +typedef unsigned int uint32; + +static unichar_t *utf82u_strcpy(unichar_t * ubuf, const char *utf8buf) +{ + int len = strlen(utf8buf) + 1; + unichar_t *upt = ubuf, *uend = ubuf + len - 1; + const uint8 *pt = (const uint8 *) utf8buf, *end = pt + strlen(utf8buf); + int w, w2; + + while (pt < end && *pt != '\0' && upt < uend) { + if (*pt <= 127) + *upt = *pt++; + else if (*pt <= 0xdf) { + *upt = ((*pt & 0x1f) << 6) | (pt[1] & 0x3f); + pt += 2; + } else if (*pt <= 0xef) { + *upt = ((*pt & 0xf) << 12) | ((pt[1] & 0x3f) << 6) | (pt[2] & 0x3f); + pt += 3; + } else { + w = (((*pt & 0x7) << 2) | ((pt[1] & 0x30) >> 4)) - 1; + w = (w << 6) | ((pt[1] & 0xf) << 2) | ((pt[2] & 0x30) >> 4); + w2 = ((pt[2] & 0xf) << 6) | (pt[3] & 0x3f); + *upt = w * 0x400 + w2 + 0x10000; + pt += 4; + } + ++upt; + } + *upt = '\0'; + return (ubuf); +} + +static char *utf8_idpb(char *utf8_text, uint32 ch) +{ + /* Increment and deposit character */ + if (ch >= 17 * 65536) + return (utf8_text); + + if (ch <= 127) + *utf8_text++ = ch; + else if (ch <= 0x7ff) { + *utf8_text++ = 0xc0 | (ch >> 6); + *utf8_text++ = 0x80 | (ch & 0x3f); + } else if (ch <= 0xffff) { + *utf8_text++ = 0xe0 | (ch >> 12); + *utf8_text++ = 0x80 | ((ch >> 6) & 0x3f); + *utf8_text++ = 0x80 | (ch & 0x3f); + } else { + uint32 val = ch - 0x10000; + int u = ((val & 0xf0000) >> 16) + 1, z = (val & 0x0f000) >> 12, y = + (val & 0x00fc0) >> 6, x = val & 0x0003f; + *utf8_text++ = 0xf0 | (u >> 2); + *utf8_text++ = 0x80 | ((u & 3) << 4) | z; + *utf8_text++ = 0x80 | y; + *utf8_text++ = 0x80 | x; + } + return (utf8_text); +} + +static int u_strlen(register unichar_t * str) +{ + register int len = 0; + while (*str++ != '\0') + ++len; + return (len); +} + +#endif #define noVERBOSE -#define MAX_TEX_LANGUAGES 32767 +#define MAX_TEX_LANGUAGES 32768 -static struct tex_language *tex_languages[MAX_TEX_LANGUAGES] = {NULL}; +static struct tex_language *tex_languages[MAX_TEX_LANGUAGES] = { NULL }; static int next_lang_id = 0; -struct tex_language * -new_language (void) { - struct tex_language* lang; - if (next_lang_id<MAX_TEX_LANGUAGES) { - lang = xmalloc(sizeof(struct tex_language)); - tex_languages[next_lang_id] = lang; - lang->id = next_lang_id++; - lang->exceptions = 0; - lang->patterns = NULL; - lang->pre_hyphen_char = '-'; - lang->post_hyphen_char = 0; - return lang; - } else { - return NULL; - } +struct tex_language *new_language(int n) +{ + struct tex_language *lang; + unsigned l; + if (n >= 0) { + l = (unsigned) n; + if (l != (MAX_TEX_LANGUAGES - 1)) + if (next_lang_id <= n) + next_lang_id = n + 1; + } else { + while (tex_languages[next_lang_id] != NULL) + next_lang_id++; + l = next_lang_id++; + } + if (l < (MAX_TEX_LANGUAGES - 1) && tex_languages[l] == NULL) { + lang = xmalloc(sizeof(struct tex_language)); + tex_languages[l] = lang; + lang->id = l; + lang->exceptions = 0; + lang->patterns = NULL; + lang->pre_hyphen_char = '-'; + lang->post_hyphen_char = 0; + lang->pre_exhyphen_char = 0; + lang->post_exhyphen_char = 0; + return lang; + } else { + return NULL; + } } -struct tex_language * -get_language (int n) { - if (n>=0 && n<MAX_TEX_LANGUAGES ) { - if (tex_languages[n]!=NULL) { - return tex_languages[n]; +struct tex_language *get_language(int n) +{ + if (n >= 0 && n < MAX_TEX_LANGUAGES) { + if (tex_languages[n] != NULL) { + return tex_languages[n]; + } else { + return new_language(n); + } } else { - return new_language(); + return NULL; } - } else { - return NULL; - } } -void -set_pre_hyphen_char (integer n, integer v) { - struct tex_language *l = get_language((int)n); - if (l!=NULL) - l->pre_hyphen_char = (int)v; +void set_pre_hyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->pre_hyphen_char = (int) v; } -void -set_post_hyphen_char (integer n, integer v) { - struct tex_language *l = get_language((int)n); - if (l!=NULL) - l->post_hyphen_char = (int)v; +void set_post_hyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->post_hyphen_char = (int) v; } -integer -get_pre_hyphen_char (integer n) { - struct tex_language *l = get_language((int)n); - if (l==NULL) return -1; - return (integer)l->pre_hyphen_char; + +void set_pre_exhyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->pre_exhyphen_char = (int) v; } -integer -get_post_hyphen_char (integer n) { - struct tex_language *l = get_language((int)n); - if (l==NULL) return -1; - return (integer)l->post_hyphen_char; +void set_post_exhyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->post_exhyphen_char = (int) v; } -void -load_patterns (struct tex_language *lang, unsigned char *buffer) { - if (lang==NULL) - return; - if (lang->patterns==NULL) { - lang->patterns = hnj_hyphen_new(); - } - hnj_hyphen_load (lang->patterns,buffer); + + +integer get_pre_hyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->pre_hyphen_char; } -void -clear_patterns (struct tex_language *lang) { - if (lang==NULL) - return; - if (lang->patterns!=NULL) { - hnj_hyphen_clear(lang->patterns); - } +integer get_post_hyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->post_hyphen_char; } -void -load_tex_patterns(int curlang, halfword head) { - char *s = tokenlist_to_cstring (head,1, NULL); - load_patterns(get_language(curlang),(unsigned char *)s); + +integer get_pre_exhyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->pre_exhyphen_char; +} + +integer get_post_exhyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->post_exhyphen_char; +} + +void load_patterns(struct tex_language *lang, unsigned char *buffer) +{ + if (lang == NULL) + return; + if (lang->patterns == NULL) { + lang->patterns = hnj_hyphen_new(); + } + hnj_hyphen_load(lang->patterns, buffer); +} + +void clear_patterns(struct tex_language *lang) +{ + if (lang == NULL) + return; + if (lang->patterns != NULL) { + hnj_hyphen_clear(lang->patterns); + } +} + +void load_tex_patterns(int curlang, halfword head) +{ + char *s = tokenlist_to_cstring(head, 1, NULL); + load_patterns(get_language(curlang), (unsigned char *) s); } #define STORE_CHAR(x) { word[w] = x ; if (w<MAX_WORD_LEN) w++; } - + /* todo change this! */ -char * -clean_hyphenation (char *buffer, char **cleaned) { - int items; - unsigned char word [MAX_WORD_LEN+1]; - int w = 0; - char *s = buffer; - while (*s && !isspace(*s)) { - if (*s == '-') { /* skip */ - } else if (*s == '=') { - STORE_CHAR('-'); - } else if (*s == '{') { - s++; - items=0; - while (*s && *s!='}') { s++; } - if (*s=='}') { items++; s++; } - while (*s && *s!='}') { s++; } - if (*s=='}') { items++; s++; } - if (*s=='{') { s++; } - while (*s && *s!='}') {STORE_CHAR(*s); s++; } - if (*s=='}') { items++; } else { s--; } - if (items!=3) { /* syntax error */ - *cleaned = NULL; - while (*s && !isspace(*s)) { s++; } - return s; - } - } else { - STORE_CHAR(*s); +char *clean_hyphenation(char *buffer, char **cleaned) +{ + int items; + unsigned char word[MAX_WORD_LEN + 1]; + int w = 0; + char *s = buffer; + while (*s && !isspace(*s)) { + if (*s == '-') { /* skip */ + } else if (*s == '=') { + STORE_CHAR('-'); + } else if (*s == '{') { + s++; + items = 0; + while (*s && *s != '}') { + s++; + } + if (*s == '}') { + items++; + s++; + } + while (*s && *s != '}') { + s++; + } + if (*s == '}') { + items++; + s++; + } + if (*s == '{') { + s++; + } + while (*s && *s != '}') { + STORE_CHAR(*s); + s++; + } + if (*s == '}') { + items++; + } else { + s--; + } + if (items != 3) { /* syntax error */ + *cleaned = NULL; + while (*s && !isspace(*s)) { + s++; + } + return s; + } + } else { + STORE_CHAR(*s); + } + s++; } - s++; - } - word[w] = 0; - *cleaned = xstrdup((char *)word); - return s; -} - -void -load_hyphenation (struct tex_language *lang, unsigned char *buffer) { - char *s, *value, *cleaned; - lua_State *L = Luas[0]; - if (lang==NULL) - return; - if (lang->exceptions==0) { - lua_newtable(L); - lang->exceptions = luaL_ref(L,LUA_REGISTRYINDEX); - } - lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions); - s = (char *)buffer; - while (*s) { - while (isspace(*s)) s++; - if (*s) { - value = s; - s = clean_hyphenation(s, &cleaned); - if (cleaned!=NULL) { - if ((s-value)>0) { - lua_pushstring(L,cleaned); - lua_pushlstring(L,value,(s-value)); - lua_rawset(L,-3); - } - free(cleaned); - } else { + word[w] = 0; + *cleaned = xstrdup((char *) word); + return s; +} + +void load_hyphenation(struct tex_language *lang, unsigned char *buffer) +{ + char *s, *value, *cleaned; + lua_State *L = Luas; + if (lang == NULL) + return; + if (lang->exceptions == 0) { + lua_newtable(L); + lang->exceptions = luaL_ref(L, LUA_REGISTRYINDEX); + } + lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions); + s = (char *) buffer; + while (*s) { + while (isspace(*s)) + s++; + if (*s) { + value = s; + s = clean_hyphenation(s, &cleaned); + if (cleaned != NULL) { + if ((s - value) > 0) { + lua_pushstring(L, cleaned); + lua_pushlstring(L, value, (s - value)); + lua_rawset(L, -3); + } + free(cleaned); + } else { #ifdef VERBOSE - fprintf(stderr,"skipping invalid hyphenation exception: %s\n",value); + fprintf(stderr, "skipping invalid hyphenation exception: %s\n", + value); #endif - } + } + } } - } } -void -clear_hyphenation (struct tex_language *lang) { - if (lang==NULL) - return; - if (lang->exceptions!=0) { - luaL_unref(Luas[0],LUA_REGISTRYINDEX,lang->exceptions); - lang->exceptions = 0; - } +void clear_hyphenation(struct tex_language *lang) +{ + if (lang == NULL) + return; + if (lang->exceptions != 0) { + luaL_unref(Luas, LUA_REGISTRYINDEX, lang->exceptions); + lang->exceptions = 0; + } } -void -load_tex_hyphenation(int curlang, halfword head) { - char *s = tokenlist_to_cstring (head,1, NULL); - load_hyphenation(get_language(curlang),(unsigned char *)s); +void load_tex_hyphenation(int curlang, halfword head) +{ + char *s = tokenlist_to_cstring(head, 1, NULL); + load_hyphenation(get_language(curlang), (unsigned char *) s); } /* TODO: clean this up. The delete_attribute_ref() statements are not very nice, but needed. Also, in the post-break, it would be nicer to get the attribute list from vlink(n). No rush, as it is currently not used much. */ -halfword insert_discretionary ( halfword t, halfword pre, halfword post, halfword replace) { - halfword g, n; - n = new_node(disc_node,syllable_disc); - try_couple_nodes(n,vlink(t)); - couple_nodes(t,n); - for (g=pre;g!=null;g=vlink(g)) { - font(g)=font(replace); - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; +halfword insert_discretionary(halfword t, halfword pre, halfword post, + halfword replace) +{ + halfword g, n; + int f; + n = new_node(disc_node, syllable_disc); + try_couple_nodes(n, vlink(t)); + couple_nodes(t, n); + if (replace != null) + f = font(replace); + else + f = get_cur_font(); /* for compound words following explicit hyphens */ + for (g = pre; g != null; g = vlink(g)) { + font(g) = f; + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(g)); + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } } - } - for (g=post;g!=null;g =vlink(g)) { - font(g)=font(replace); - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; + for (g = post; g != null; g = vlink(g)) { + font(g) = f; + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(g)); + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } } - } - for (g=replace;g!=null;g =vlink(g)) { - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; + for (g = replace; g != null; g = vlink(g)) { + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(g)); + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } } - } - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(vlink(t))); - node_attr(vlink(t)) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; - } - t = vlink(t); - set_disc_field(pre_break(t),pre); - set_disc_field(post_break(t),post); - set_disc_field(no_break(t),replace); - return t; -} - -halfword -insert_syllable_discretionary ( halfword t, lang_variables *lan) { - halfword g, n; - n = new_node(disc_node,syllable_disc); - couple_nodes(n,vlink(t)); - couple_nodes(t,n); - delete_attribute_ref(node_attr(n)); - if (node_attr(t)!=null) { - node_attr(n) = node_attr(t); - attr_list_ref(node_attr(t))++ ; - } else { - node_attr(n) = null; - } - if (lan->pre_hyphen_char >0) { - g = raw_glyph_node(); - set_to_character(g); - character(g)=lan->pre_hyphen_char; - font(g)=font(t); - lang_data(g)=lang_data(t); - if (node_attr(t)!=null) { - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) ++; - } - set_disc_field(pre_break(n),g); - } + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(vlink(t))); + node_attr(vlink(t)) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } + t = vlink(t); + set_disc_field(pre_break(t), pre); + set_disc_field(post_break(t), post); + set_disc_field(no_break(t), replace); + return t; +} - if (lan->post_hyphen_char >0) { - t = vlink(n); - g = raw_glyph_node(); - set_to_character(g); - character(g)=lan->post_hyphen_char; - font(g)=font(t); - lang_data(g)=lang_data(t); - if (node_attr(t)!=null) { - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; - } - set_disc_field(post_break(n),g); - } - return n; +halfword insert_syllable_discretionary(halfword t, lang_variables * lan) +{ + halfword g, n; + n = new_node(disc_node, syllable_disc); + couple_nodes(n, vlink(t)); + couple_nodes(t, n); + delete_attribute_ref(node_attr(n)); + if (node_attr(t) != null) { + node_attr(n) = node_attr(t); + attr_list_ref(node_attr(t))++; + } else { + node_attr(n) = null; + } + if (lan->pre_hyphen_char > 0) { + g = raw_glyph_node(); + set_to_character(g); + character(g) = lan->pre_hyphen_char; + font(g) = font(t); + lang_data(g) = lang_data(t); + if (node_attr(t) != null) { + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t))++; + } + set_disc_field(pre_break(n), g); + } + + if (lan->post_hyphen_char > 0) { + t = vlink(n); + g = raw_glyph_node(); + set_to_character(g); + character(g) = lan->post_hyphen_char; + font(g) = font(t); + lang_data(g) = lang_data(t); + if (node_attr(t) != null) { + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } + set_disc_field(post_break(n), g); + } + return n; } -halfword insert_word_discretionary ( halfword t, lang_variables *lan) { - halfword pre = null, pos = null; - if (lan->pre_hyphen_char >0) pre = insert_character ( null, lan->pre_hyphen_char); - if (lan->post_hyphen_char>0) pos = insert_character ( null, lan->post_hyphen_char); - return insert_discretionary ( t, pre, pos, null); +halfword insert_word_discretionary(halfword t, lang_variables * lan) +{ + halfword pre = null, pos = null; + if (lan->pre_exhyphen_char > 0) + pre = insert_character(null, lan->pre_exhyphen_char); + if (lan->post_exhyphen_char > 0) + pos = insert_character(null, lan->post_exhyphen_char); + return insert_discretionary(t, pre, pos, null); } -halfword insert_complex_discretionary ( halfword t, lang_variables *lan, - halfword pre, halfword pos, halfword replace) { - return insert_discretionary ( t, pre, pos, replace); +halfword compound_word_break(halfword t, int clang) +{ + int disc; + lang_variables langdata; + langdata.pre_exhyphen_char = get_pre_exhyphen_char(clang); + langdata.post_exhyphen_char = get_post_exhyphen_char(clang); + disc = insert_word_discretionary(t, &langdata); + return disc; } -halfword insert_character ( halfword t, int c) { - halfword p; - p=new_node(glyph_node,0); - set_to_character(p); - character(p)=c; - if (t!=null) { - couple_nodes(t,p); - } - return p; +halfword insert_complex_discretionary(halfword t, lang_variables * lan, + halfword pre, halfword pos, + halfword replace) +{ + (void) lan; + return insert_discretionary(t, pre, pos, replace); } -void -set_disc_field (halfword f, halfword t) { - if (t!=null) { - couple_nodes(f,t); - tlink(f) = tail_of_list(t); - } +halfword insert_character(halfword t, int c) +{ + halfword p; + p = new_node(glyph_node, 0); + set_to_character(p); + character(p) = c; + if (t != null) { + couple_nodes(t, p); + } + return p; +} + + +void set_disc_field(halfword f, halfword t) +{ + if (t != null) { + couple_nodes(f, t); + tlink(f) = tail_of_list(t); + } else { + vlink(f) = null; + tlink(f) = null; + } } -char *hyphenation_exception(int exceptions, char *w) { - char *ret = NULL; - lua_State *L = Luas[0]; - lua_checkstack(L,2); - lua_rawgeti(L,LUA_REGISTRYINDEX,exceptions); - if (lua_istable(L,-1)) { /* ?? */ - lua_pushstring(L,w); /* word table */ - lua_rawget(L,-2); - if (lua_isstring(L,-1)) { - ret = xstrdup((char *)lua_tostring(L,-1)); +char *hyphenation_exception(int exceptions, char *w) +{ + char *ret = NULL; + lua_State *L = Luas; + lua_checkstack(L, 2); + lua_rawgeti(L, LUA_REGISTRYINDEX, exceptions); + if (lua_istable(L, -1)) { /* ?? */ + lua_pushstring(L, w); /* word table */ + lua_rawget(L, -2); + if (lua_isstring(L, -1)) { + ret = xstrdup((char *) lua_tostring(L, -1)); + } + lua_pop(L, 2); + } else { + lua_pop(L, 1); } - lua_pop(L,2); - } else { - lua_pop(L,1); - } - return ret; -} - - -char *exception_strings(struct tex_language *lang) { - char *value; - size_t size = 0, current =0; - size_t l =0; - char *ret = NULL; - lua_State *L = Luas[0]; - if (lang->exceptions==0) - return NULL; - lua_checkstack(L,2); - lua_rawgeti(L,LUA_REGISTRYINDEX,lang->exceptions); - if (lua_istable(L,-1)) { - /* iterate and join */ - lua_pushnil(L); /* first key */ - while (lua_next(L,-2) != 0) { - value = (char *)lua_tolstring(L, -1, &l); - if (current + 2 + l > size ) { - ret = xrealloc(ret, (1.2*size)+current+l+1024); - size = (1.2*size)+current+l+1024; - } - *(ret+current) = ' '; - strcpy(ret+current+1,value); - current += l+1; - lua_pop(L, 1); + return ret; +} + + +char *exception_strings(struct tex_language *lang) +{ + char *value; + size_t size = 0, current = 0; + size_t l = 0; + char *ret = NULL; + lua_State *L = Luas; + if (lang->exceptions == 0) + return NULL; + lua_checkstack(L, 2); + lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions); + if (lua_istable(L, -1)) { + /* iterate and join */ + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + value = (char *) lua_tolstring(L, -1, &l); + if (current + 2 + l > size) { + ret = xrealloc(ret, (1.2 * size) + current + l + 1024); + size = (1.2 * size) + current + l + 1024; + } + *(ret + current) = ' '; + strcpy(ret + current + 1, value); + current += l + 1; + lua_pop(L, 1); + } } - } - return ret; + return ret; } /* the sequence from |wordstart| to |r| can contain only normal characters */ /* it could be faster to modify a halfword pointer and return an integer */ -halfword find_exception_part(unsigned int *j, int *uword, int len) { - halfword g = null, gg = null; - register int i = *j; - i++; /* this puts uword[i] on the '{' */ - while (i<len && uword[i+1] != '}') { - if (g==null) { - gg = new_char(0,uword[i+1]); - g = gg; - } else { - halfword s = new_char(0,uword[i+1]); - couple_nodes(g,s); - g = vlink(g); +halfword find_exception_part(unsigned int *j, int *uword, int len) +{ + halfword g = null, gg = null; + register int i = *j; + i++; /* this puts uword[i] on the '{' */ + while (i < len && uword[i + 1] != '}') { + if (g == null) { + gg = new_char(0, uword[i + 1]); + g = gg; + } else { + halfword s = new_char(0, uword[i + 1]); + couple_nodes(g, s); + g = vlink(g); + } + i++; } - i++; - } - *j = ++i; - return gg; + *j = ++i; + return gg; } -int count_exception_part(unsigned int *j, int *uword, int len) { - int ret=0; - register int i = *j; - i++; /* this puts uword[i] on the '{' */ - while (i<len && uword[i+1] != '}') { - ret++; - i++; - } - *j = ++i; - return ret; -} - - -static char *PAT_ERROR[] = { - "Exception discretionaries should contain three pairs of braced items.", - "No intervening spaces are allowed.", - NULL }; - -void do_exception (halfword wordstart, halfword r, char *replacement) { - unsigned i; - halfword t; - unsigned len; - int clang; - lang_variables langdata; - int uword[MAX_WORD_LEN+1] = {0}; - (void)utf82u_strcpy((unsigned int *)uword,replacement); - len = u_strlen((unsigned int *)uword); - i = 0; - t=wordstart; - clang = char_lang(wordstart); - langdata.pre_hyphen_char = get_pre_hyphen_char(clang); - langdata.post_hyphen_char = get_post_hyphen_char(clang); - - for (i=0;i<len;i++) { - if (uword[i+1] == '-') { /* a hyphen follows */ - while (vlink(t)!=r && (type(t)!=glyph_node || !is_simple_character(t))) - t = vlink(t); - if (vlink(t)==r) - break; - insert_syllable_discretionary(t, &langdata); - t = vlink(t); /* skip the new disc */ - } else if (uword[i+1] == '=') { - /* do nothing ? */ - t = vlink(t); - } else if (uword[i+1] == '{') { - halfword gg, hh, replace = null; - int repl; - gg = find_exception_part(&i,uword,len); - if (i==len || uword[i+1] != '{') { - tex_error ("broken pattern 1", PAT_ERROR); - } - hh = find_exception_part(&i,uword,len); - if (i==len || uword[i+1] != '{') { - tex_error ("broken pattern 2", PAT_ERROR); - } - repl = count_exception_part(&i,uword,len); - if (i==len) { - tex_error ("broken pattern 3", PAT_ERROR); - } - /*i++; */ /* jump over the last right brace */ - if (vlink(t)==r) - break; - if (repl>0) { - halfword q = t; - replace = vlink(q); - while(repl>0 && q!=null) { - q=vlink(q); - if (type(q)==glyph_node) { - repl--; - } - } - try_couple_nodes(t,vlink(q)); - vlink(q)=null; - } - t = insert_discretionary(t,gg,hh,replace); - } else { - t = vlink(t); +int count_exception_part(unsigned int *j, int *uword, int len) +{ + int ret = 0; + register int i = *j; + i++; /* this puts uword[i] on the '{' */ + while (i < len && uword[i + 1] != '}') { + ret++; + i++; + } + *j = ++i; + return ret; +} + + +static char *PAT_ERROR[] = { + "Exception discretionaries should contain three pairs of braced items.", + "No intervening spaces are allowed.", + NULL +}; + +void do_exception(halfword wordstart, halfword r, char *replacement) +{ + unsigned i; + halfword t; + unsigned len; + int clang; + lang_variables langdata; + int uword[MAX_WORD_LEN + 1] = { 0 }; + (void) utf82u_strcpy((unsigned int *) uword, replacement); + len = u_strlen((unsigned int *) uword); + i = 0; + t = wordstart; + clang = char_lang(wordstart); + langdata.pre_hyphen_char = get_pre_hyphen_char(clang); + langdata.post_hyphen_char = get_post_hyphen_char(clang); + + for (i = 0; i < len; i++) { + if (uword[i + 1] == '-') { /* a hyphen follows */ + while (vlink(t) != r + && (type(t) != glyph_node || !is_simple_character(t))) + t = vlink(t); + if (vlink(t) == r) + break; + insert_syllable_discretionary(t, &langdata); + t = vlink(t); /* skip the new disc */ + } else if (uword[i + 1] == '=') { + /* do nothing ? */ + t = vlink(t); + } else if (uword[i + 1] == '{') { + halfword gg, hh, replace = null; + int repl; + gg = find_exception_part(&i, uword, len); + if (i == len || uword[i + 1] != '{') { + tex_error("broken pattern 1", PAT_ERROR); + } + hh = find_exception_part(&i, uword, len); + if (i == len || uword[i + 1] != '{') { + tex_error("broken pattern 2", PAT_ERROR); + } + repl = count_exception_part(&i, uword, len); + if (i == len) { + tex_error("broken pattern 3", PAT_ERROR); + } + /*i++; *//* jump over the last right brace */ + if (vlink(t) == r) + break; + if (repl > 0) { + halfword q = t; + replace = vlink(q); + while (repl > 0 && q != null) { + q = vlink(q); + if (type(q) == glyph_node) { + repl--; + } + } + try_couple_nodes(t, vlink(q)); + vlink(q) = null; + } + t = insert_discretionary(t, gg, hh, replace); + t = vlink(t); /* skip the new disc */ + } else { + t = vlink(t); + } } - } } /* This is a documentation section from the pascal web file. It is not @@ -554,276 +735,299 @@ using an algorithm due to Frank~M. Liang. /* * This is incompatible with TEX because the first word of a paragraph * can be hyphenated, but most european users seem to agree that - * prohibiting hyphenation there was not a the best idea ever. + * prohibiting hyphenation there was not the best idea ever. */ -halfword find_next_wordstart(halfword r) { - register int l; - register int start_ok = 1; - int mathlevel = 1; - while (r!=null) { - switch (type(r)) { - case glue_node: - start_ok = 1; - break; - case math_node: - while (mathlevel>0 ){ - r = vlink(r); - if (r==null) - return r; - if (type(r)==math_node) { - if (subtype(r)==before) { - mathlevel++; - } else { - mathlevel--; - } - } - } - break; - case glyph_node: - if (start_ok && - is_simple_character(r) && - (l = get_lc_code(character(r)))>0 && - (char_uchyph(r) || l == character(r))) - return r; - /* fall through */ - default: - start_ok = 0; - break; - } - r = vlink(r); - } - return r; -} - -int valid_wordend( halfword s) { - register halfword r = s; - register int clang = char_lang(s); - if (r==null) - return 1; - while ((r!=null) && - ((type(r)==glyph_node && is_simple_character(r) && clang == char_lang(r)) || - (type(r)==kern_node && subtype(r)==normal))) { - r = vlink(r); - } - if (r==null || - (type(r)==glyph_node && is_simple_character(r) && clang != char_lang(r)) || - type(r)==glue_node || - type(r)==whatsit_node || - type(r)==ins_node || - type(r)==adjust_node || - type(r)==penalty_node || - (type(r)==kern_node && subtype(r)==explicit)) - return 1; - return 0; -} - -void -hnj_hyphenation (halfword head, halfword tail) { - int lchar, i; - struct tex_language* lang; - lang_variables langdata; - char utf8word[(4*MAX_WORD_LEN)+1] = {0}; - int wordlen = 0; - char *hy = utf8word; - char *replacement = NULL; - halfword s, r = head, wordstart = null, save_tail = null, left = null, right = null; - - /* this first movement assures two things: - * a) that we won't waste lots of time on something that has been - * handled already (in that case, none of the glyphs match |simple_character|). - * b) that the first word can be hyphenated. if the movement was - * not explicit, then the indentation at the start of a paragraph - * list would make find_next_wordstart() look too far ahead. - */ - - while (r!=null && (type(r)!=glyph_node || !is_simple_character(r))) - r =vlink(r); - /* this will make |r| a glyph node with subtype_character */ - r = find_next_wordstart(r); - if (r==null) - return; - - assert (tail!=null); - save_tail = vlink(tail); - s = new_penalty(0); - couple_nodes(tail, s); - - while (r!=null) { /* could be while(1), but let's be paranoid */ - int clang, lhmin, rhmin; - wordstart = r; - assert (is_simple_character(wordstart)); - clang = char_lang(wordstart); - lhmin = char_lhmin(wordstart); - rhmin = char_rhmin(wordstart); - langdata.pre_hyphen_char = get_pre_hyphen_char(clang); - langdata.post_hyphen_char = get_post_hyphen_char(clang); - while (r!=null && - type(r)==glyph_node && - is_simple_character(r) && - clang == char_lang(r) && - (lchar = get_lc_code(character(r)))>0) { - wordlen++; - hy = utf8_idpb(hy,character(r)); - /* this should not be needed any more */ - /*if (vlink(r)!=null) alink(vlink(r))=r;*/ - r = vlink(r); - } - if (valid_wordend(r) && wordlen>=lhmin+rhmin && (lang=tex_languages[clang])!=NULL) { - *hy=0; - if (lang->exceptions!=0 && - (replacement = hyphenation_exception(lang->exceptions,utf8word))!=NULL) { +halfword find_next_wordstart(halfword r) +{ + register int l; + register int start_ok = 1; + int mathlevel = 1; + while (r != null) { + switch (type(r)) { + case glue_node: + start_ok = 1; + break; + case math_node: + while (mathlevel > 0) { + r = vlink(r); + if (r == null) + return r; + if (type(r) == math_node) { + if (subtype(r) == before) { + mathlevel++; + } else { + mathlevel--; + } + } + } + break; + case glyph_node: + if (start_ok && + is_simple_character(r) && + (l = get_lc_code(character(r))) > 0 && + (char_uchyph(r) || l == character(r))) + return r; + break; + default: + start_ok = 0; + break; + } + r = vlink(r); + } + return r; +} + +int valid_wordend(halfword s) +{ + register halfword r = s; + register int clang = char_lang(s); + if (r == null) + return 1; + while ((r != null) && ((type(r) == glyph_node && is_simple_character(r) + && clang == char_lang(r)) || (type(r) == kern_node + && subtype(r) == + normal))) { + r = vlink(r); + } + if (r == null || (type(r) == glyph_node && is_simple_character(r) + && clang != char_lang(r)) || type(r) == glue_node + || type(r) == whatsit_node || type(r) == ins_node + || type(r) == adjust_node || type(r) == penalty_node + || (type(r) == kern_node && subtype(r) == explicit)) + return 1; + return 0; +} + +void hnj_hyphenation(halfword head, halfword tail) +{ + int lchar, i; + struct tex_language *lang; + lang_variables langdata; + char utf8word[(4 * MAX_WORD_LEN) + 1] = { 0 }; + int wordlen = 0; + char *hy = utf8word; + char *replacement = NULL; + halfword s, r = head, wordstart = null, save_tail = null, left = + null, right = null; + + /* this first movement assures two things: + * a) that we won't waste lots of time on something that has been + * handled already (in that case, none of the glyphs match |simple_character|). + * b) that the first word can be hyphenated. if the movement was + * not explicit, then the indentation at the start of a paragraph + * list would make find_next_wordstart() look too far ahead. + */ + + while (r != null && (type(r) != glyph_node || !is_simple_character(r))) { + r = vlink(r); + } + /* this will make |r| a glyph node with subtype_character */ + r = find_next_wordstart(r); + if (r == null) + return; + + assert(tail != null); + save_tail = vlink(tail); + s = new_penalty(0); + couple_nodes(tail, s); + + while (r != null) { /* could be while(1), but let's be paranoid */ + int clang, lhmin, rhmin; + halfword hyf_font; + halfword end_word = r; + wordstart = r; + assert(is_simple_character(wordstart)); + hyf_font = font(wordstart); + if (hyphen_char(hyf_font)<0) /* for backward compat */ + hyf_font = 0; + clang = char_lang(wordstart); + lhmin = char_lhmin(wordstart); + rhmin = char_rhmin(wordstart); + langdata.pre_hyphen_char = get_pre_hyphen_char(clang); + langdata.post_hyphen_char = get_post_hyphen_char(clang); + while (r != null && + type(r) == glyph_node && + is_simple_character(r) && + clang == char_lang(r) && + (lchar = get_lc_code(character(r))) > 0) { + wordlen++; + hy = utf8_idpb(hy, character(r)); + /* this should not be needed any more */ + /*if (vlink(r)!=null) alink(vlink(r))=r; */ + end_word = r; + r = vlink(r); + } + if (valid_wordend(r) && wordlen >= lhmin + rhmin + && (hyf_font != 0) && (lang = tex_languages[clang]) != NULL) { + *hy = 0; + if (lang->exceptions != 0 && + (replacement = + hyphenation_exception(lang->exceptions, utf8word)) != NULL) { #ifdef VERBOSE - fprintf(stderr,"replacing %s (c=%d) by %s\n",utf8word,clang,replacement); -#endif - do_exception(wordstart,r,replacement); - free(replacement); - } else if (lang->patterns!=NULL) { - - left = wordstart; - for (i=lhmin;i>1;i--) { - left = vlink(left); - while (!is_simple_character(left)) - left = vlink(left); - } - right = r; - for (i=rhmin;i>0;i--) { - right = alink(right); - while (!is_simple_character(right)) - right = alink(right); - } - + fprintf(stderr, "replacing %s (c=%d) by %s\n", utf8word, clang, + replacement); +#endif + do_exception(wordstart, r, replacement); + free(replacement); + } else if (lang->patterns != NULL) { + + left = wordstart; + for (i = lhmin; i > 1; i--) { + left = vlink(left); + while (!is_simple_character(left)) + left = vlink(left); + } + right = r; + for (i = rhmin; i > 0; i--) { + right = alink(right); + while (!is_simple_character(right)) + right = alink(right); + } + #ifdef VERBOSE - fprintf(stderr,"hyphenate %s (c=%d,l=%d,r=%d) from %c to %c\n",utf8word, - clang,lhmin,rhmin, - character(left), character(right)); -#endif - (void)hnj_hyphen_hyphenate(lang->patterns,wordstart,r,wordlen,left,right, &langdata); - } - } - wordlen = 0; - hy = utf8word; - if (r==null) - break; - r = find_next_wordstart(r); - } - flush_node(vlink(tail)); - vlink(tail) = save_tail; -} - - -void -new_hyphenation (halfword head, halfword tail) { - register int callback_id = 0; - if (head==null || vlink(head)==null) - return; - fix_node_list (head); /* TODO: use couple_nodes() in append_tail()!*/ - callback_id = callback_defined(hyphenate_callback); - if (callback_id>0) { - lua_State *L = Luas[0]; - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1, callback_id); - if (!lua_isfunction(L,-1)) { - lua_pop(L,2); - return; - } - nodelist_to_lua(L,head); - nodelist_to_lua(L,tail); - if (lua_pcall(L,2,0,0) != 0) { - fprintf(stdout,"error: %s\n",lua_tostring(L,-1)); - lua_pop(L,2); - lua_error(L); - return; - } - lua_pop(L,1); - } else { - hnj_hyphenation(head,tail); - } + fprintf(stderr, "hyphenate %s (c=%d,l=%d,r=%d) from %c to %c\n", + utf8word, clang, lhmin, rhmin, character(left), + character(right)); +#endif + (void) hnj_hyphen_hyphenate(lang->patterns, wordstart, end_word, + wordlen, left, right, &langdata); + } + } + wordlen = 0; + hy = utf8word; + if (r == null) + break; + r = find_next_wordstart(r); + } + flush_node(vlink(tail)); + vlink(tail) = save_tail; +} + + +void new_hyphenation(halfword head, halfword tail) +{ + register int callback_id = 0; + if (head == null || vlink(head) == null) + return; + fix_node_list(head); /* TODO: use couple_nodes() in append_tail()! */ + callback_id = callback_defined(hyphenate_callback); + if (callback_id > 0) { + lua_State *L = Luas; + if (!get_callback(L, callback_id)) { + lua_pop(L, 2); + return; + } + nodelist_to_lua(L, head); + nodelist_to_lua(L, tail); + if (lua_pcall(L, 2, 0, 0) != 0) { + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 2); + lua_error(L); + return; + } + lua_pop(L, 1); + } else { + hnj_hyphenation(head, tail); + } } /* dumping and undumping fonts */ -#define dump_string(a) \ - if (a!=NULL) { \ - x = strlen(a)+1; \ - dump_int(x); dump_things(*a, x); \ - } else { \ - x = 0; dump_int(x); \ +#define dump_string(a) \ + if (a!=NULL) { \ + x = strlen(a)+1; \ + dump_int(x); dump_things(*a, x); \ + } else { \ + x = 0; dump_int(x); \ } -void dump_one_language (int i) { - char *s = NULL; - unsigned x = 0; - struct tex_language *lang; - lang = tex_languages[i]; - dump_int(lang->id); - dump_int(lang->pre_hyphen_char); - dump_int(lang->post_hyphen_char); - if (lang->patterns!=NULL) { - s = (char *)hnj_serialize(lang->patterns); - } - dump_string(s); - if (s!=NULL) { - free(s); - s = NULL; - } - if (lang->exceptions!=0) - s = exception_strings(lang); - dump_string(s); - if (s!=NULL) { - free(s); - } - free (lang); +void dump_one_language(int i) +{ + char *s = NULL; + unsigned x = 0; + struct tex_language *lang; + lang = tex_languages[i]; + dump_int(lang->id); + dump_int(lang->pre_hyphen_char); + dump_int(lang->post_hyphen_char); + dump_int(lang->pre_exhyphen_char); + dump_int(lang->post_exhyphen_char); + if (lang->patterns != NULL) { + s = (char *) hnj_serialize(lang->patterns); + } + dump_string(s); + if (s != NULL) { + free(s); + s = NULL; + } + if (lang->exceptions != 0) + s = exception_strings(lang); + dump_string(s); + if (s != NULL) { + free(s); + } + free(lang); } -void dump_language_data (void) { - int i; - dump_int(next_lang_id); - for (i=0;i<next_lang_id;i++) { - if (tex_languages[i]) { - dump_int(1); - dump_one_language(i); - } else { - dump_int(0); +void dump_language_data(void) +{ + int i; + dump_int(next_lang_id); + for (i = 0; i < next_lang_id; i++) { + if (tex_languages[i]) { + dump_int(1); + dump_one_language(i); + } else { + dump_int(0); + } } - } } -void undump_one_language (int i) { - char *s = NULL; - unsigned x = 0; - struct tex_language *lang = get_language(i); - undump_int(x); lang->id = x; - undump_int(x); lang->pre_hyphen_char = x; - undump_int(x); lang->post_hyphen_char = x; - /* patterns */ - undump_int (x); - if (x>0) { - s = xmalloc(x); - undump_things(*s,x); - load_patterns(lang,(unsigned char *)s); - free(s); - } - /* exceptions */ - undump_int (x); - if (x>0) { - s = xmalloc(x); - undump_things(*s,x); - load_hyphenation(lang,(unsigned char *)s); - free(s); - } -} - -void undump_language_data (void) { - unsigned i, x, numlangs; - undump_int(numlangs); - for (i=0;i<numlangs;i++) { +void undump_one_language(int i) +{ + char *s = NULL; + unsigned x = 0; + struct tex_language *lang = get_language(i); + undump_int(x); + lang->id = x; + undump_int(x); + lang->pre_hyphen_char = x; undump_int(x); - if (x==1) { - undump_one_language(i); + lang->post_hyphen_char = x; + undump_int(x); + lang->pre_exhyphen_char = x; + undump_int(x); + lang->post_exhyphen_char = x; + /* patterns */ + undump_int(x); + if (x > 0) { + s = xmalloc(x); + undump_things(*s, x); + load_patterns(lang, (unsigned char *) s); + free(s); + } + /* exceptions */ + undump_int(x); + if (x > 0) { + s = xmalloc(x); + undump_things(*s, x); + load_hyphenation(lang, (unsigned char *) s); + free(s); } - } } +void undump_language_data(void) +{ + unsigned i, x, numlangs; + undump_int(numlangs); + next_lang_id = numlangs; + for (i = 0; i < numlangs; i++) { + undump_int(x); + if (x == 1) { + undump_one_language(i); + } + } +} |