• Patch: Elm ME+ 2.5 PLalpha62 -> Elm ME+ 2.5 PLalpha63 [5/7] (2/7)

    From Kari Hurtta@21:1/5 to All on Wed Jan 3 13:52:43 2024
    [continued from previous message]

    + } else {
    + DPRINT(Debug,14,(&Debug,
    + " - at end (alternatives_count=%zu)",
    + walk->alternatives_count));
    +
    + pos = walk->alternatives_count;
    + }
    +
    + DPRINT(Debug,14,(&Debug," pos=%zu\n",pos));
    +
    +
    + newcount = walk->alternatives_count+1;
    + walk->alternatives = safe_array_realloc(walk->alternatives,
    + newcount,
    + sizeof (walk->alternatives[0]));
    + walk->alternatives[walk->alternatives_count] = NULL;
    +
    + for (z = walk->alternatives_count; z > pos; z--) {
    + walk->alternatives[z] = walk->alternatives[z-1];
    + walk->alternatives[z-1] = NULL;
    + }
    +
    + if (z != pos)
    + mime_panic(__FILE__,__LINE__,"advance_walk",
    + "Loop error");
    +
    + if (walk->alternatives[pos])
    + mime_panic(__FILE__,__LINE__,"advance_walk",
    + "pos not empty");
    +
    + walk->alternatives[pos] =
    + malloc_name_entity_walk(ents,u);
    +
    + walk->alternatives_count = newcount;
    + res = walk->alternatives[pos];
    + break;
    + }
    +
    + } else {
    + DPRINT(Debug,14,(&Debug,"advance_walk: u=x%04x not entity_character\n",u));
    +
    + }
    +
    + if (res) {
    +
    + found:
    + DPRINT(Debug,14,(&Debug,"advance_walk=%p (found or created)\n",res));
    +
    + inc_name_entity_walk_refcount(res);
    + } else {
    + DPRINT(Debug,14,(&Debug,"advance_walk=NULL (not found or created)\n")); + }
    +
    + return res;
    + }
    +
    + /* Increment refcount */
    + static struct name_entity_walk * walk_reference_key P_((struct tagfilter_entities * entity_type,
    + struct string * reference_key,
    + int have_semicolon));
    + static struct name_entity_walk * walk_reference_key(entity_type,
    + reference_key,
    + have_semicolon)
    + struct tagfilter_entities * entity_type;
    + struct string * reference_key;
    + int have_semicolon;
    + {
    + struct name_entity_walk *walk = NULL;
    + int len = string_len(reference_key);
    + int idx;
    +
    + for (idx = 0; idx < len; idx++) {
    + uint16 code = give_unicode_from_string(reference_key,idx);
    +
    + if (0 == idx && 0x0026 /* & */ == code) {
    + if (TAGFILTER_ENTITIES_magic != entity_type->magic)
    + mime_panic(__FILE__,__LINE__,"walk_reference_key",
    + "Bad magic number (tagfilter_entities)");
    +
    + if (! entity_type->ampersand)
    + entity_type->ampersand = malloc_name_entity_walk(entity_type,code);
    +
    + walk = entity_type->ampersand;
    +
    + inc_name_entity_walk_refcount(walk);
    +
    + } else if (idx == len-1 && 0x003B /* ; */ == code && have_semicolon) { + goto found;
    + } else if (walk) {
    + struct name_entity_walk *tmp = advance_walk(walk,code,walk_create, + entity_type);
    +
    + free_name_entity_walk(&walk);
    +
    + walk = tmp;
    + }
    +
    + if (!walk) {
    + DPRINT(Debug,14,(&Debug,
    + "walk_reference_key: \"%S\" failed at %d code=x%04x\n",
    + reference_key,idx,code));
    + break;
    + }
    + }
    +
    + found:
    + if (!walk) {
    + DPRINT(Debug,14,(&Debug,
    + "walk_reference_key: Failed to create node for \"%S\"",
    + reference_key));
    + }
    +
    + return walk;
    + }
    +
    + /* Increment refcount */
    + static struct name_entity_walk * walk_reference_ascii P_((struct tagfilter_entities * entity_type,
    + const unsigned char * ascii_key,
    + int have_semicolon)); + static struct name_entity_walk * walk_reference_ascii(entity_type,
    + ascii_key,
    + have_semicolon)
    + struct tagfilter_entities * entity_type;
    + const unsigned char * ascii_key;
    + int have_semicolon;
    + {
    + struct name_entity_walk *walk = NULL;
    + int idx;
    +
    + DPRINT(Debug,14,(&Debug,
    + "walk_reference_ascii: ascii_key=%Q - %s \n",
    + ascii_key,
    + have_semicolon ? " have semicolon" : " no semicolon"));
    +
    +
    + for (idx = 0; ascii_key[idx]; idx++) {
    + DPRINT(Debug,14,(&Debug,
    + "walk_reference_ascii: #%d '%c' ",
    + idx,ascii_key[idx]));
    + if (walk) {
    + if (NAME_ENTITY_WALK_magic != walk->magic)
    + mime_panic(__FILE__,__LINE__,"name_entity_walk",
    + "Bad magic number (tagfilter_entities)");
    +
    + DPRINT(Debug,14,(&Debug,"walk => x%04x",walk->code));
    + }
    + DPRINT(Debug,14,(&Debug,"\n"));
    +
    + if (0 == idx && '&' == ascii_key[idx]) {
    + if (TAGFILTER_ENTITIES_magic != entity_type->magic)
    + mime_panic(__FILE__,__LINE__,"walk_reference_ascii",
    + "Bad magic number (tagfilter_entities)");
    +
    + if (! entity_type->ampersand)
    + entity_type->ampersand = malloc_name_entity_walk(entity_type,ascii_key[idx]);
    +
    + walk = entity_type->ampersand;
    +
    + inc_name_entity_walk_refcount(walk);
    +
    + } else if (!ascii_key[idx+1] && ';' == ascii_key[idx] && have_semicolon) {
    + goto found;
    + } else if (walk) {
    + struct name_entity_walk *tmp = advance_walk(walk,
    + ascii_key[idx],walk_create,
    + entity_type);
    + free_name_entity_walk(&walk);
    +
    + walk = tmp;
    + }
    +
    + if (!walk) {
    + DPRINT(Debug,1,(&Debug,
    + "walk_reference_ascii: %Q failed at %d char=%d\n", + ascii_key,idx,ascii_key[idx]));
    + break;
    + }
    + }
    +
    + found:
    + if (!walk) {
    + DPRINT(Debug,1,(&Debug,
    + "walk_reference_ascii: Failed to create node for %Q",
    + ascii_key));
    + }
    +
    + return walk;
    + }
    +
    + static void inc_name_entity_match_refcount P_((struct name_entity_match *ptr));
    +
    + static void link_name_entity_walk P_((struct name_entity_walk * walk,
    + struct name_entity_match * result,
    + int *errors));
    + static void link_name_entity_walk(walk,result,errors)
    + struct name_entity_walk * walk;
    + struct name_entity_match * result;
    + int * errors;
    + {
    + int ok = 0;
    + struct tagfilter_entities_conf *conf = NULL;
    + char * filename = "<builtin>";
    +
    + if (NAME_ENTITY_MATCH_magic != result->magic)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_walk",
    + "Bad magic number (name_entity_match)");
    +
    + if (NAME_ENTITY_WALK_magic != walk->magic)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_walk",
    + "Bad magic number");
    +
    + if (result-> linked_walk &&
    + result-> linked_walk != walk)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_walk",
    + "Result already used for elsewhere");
    +
    + if (result->conf) {
    + struct tagfilter_entities_conf *conf = result->conf;
    +
    + if (TAGFILTER_ENTITIES_CONF_magic != conf->magic)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_match",
    + "Bad magic number");
    +
    + filename = conf->filename;
    + }
    +
    + if (walk->results) {
    + size_t i;
    +
    + for (i = 0; i < walk->results_count; i++) {
    +
    + if (walk->results[i] == result) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "link_name_entity_walk: walk(%p)->results[%zu] == result(%p) -- already done\n",
    + walk,i,result));
    + goto found;
    + }
    + }
    +
    + if (ison(result->flags,ne_match_IGNORE)) {
    + DPRINT(Debug,14,(&Debug,
    + "link_name_entity_walk: walk(%p) skipping result(%p)\n",
    + walk,result));
    + goto skipping;
    + }
    +
    + for (i = 0; i < walk->results_count; i++) {
    +
    + if (walk->results[i]) {
    + if (NAME_ENTITY_MATCH_magic != walk->results[i]->magic)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_walk",
    + "Bad magic number (name_entity_match)");
    +
    +
    + if (conf == walk->results[i]->conf &&
    + result->flags == walk->results[i]->flags) {
    +
    + if (result->unicode_value == walk->results[i]->unicode_value &&
    + ! result->entity_value &&
    + ! walk->results[i]->entity_value) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "link_name_entity_walk: walk(%p) skipping duplicate result(%p)\n",
    + walk,result));
    +
    + setit(result->flags,ne_match_IGNORE);
    +
    + goto skipping;
    + }
    +
    +
    + if (errors) {
    + lib_error(CATGETS(elm_msg_cat, MeSet,
    + MeEntityDuplicate2,
    + "%s: %d: Duplicate entity - already given on line %d"),
    + filename,result->lineno,
    + walk->results[i]->lineno);
    + (*errors)++;
    + }
    +
    + DPRINT(Debug,14,(&Debug,
    + "link_name_entity_walk: walk(%p) skipping duplicate result(%p)\n",
    + walk,result));
    +
    + setit(result->flags,ne_match_IGNORE);
    +
    +
    + goto skipping;
    + }
    + }
    + }
    + }
    +
    + ok = 1;
    +
    + walk->results = safe_array_realloc(walk->results,
    + walk->results_count+1,
    + sizeof (walk->results[0]));
    +
    + walk->results[walk->results_count] = result;
    + inc_name_entity_match_refcount(walk->results[walk->results_count]);
    +
    + DPRINT(Debug,14,(&Debug,
    + "link_name_entity_walk: walk(%p)->results[%zu] == result(%p) -- added\n",
    + walk,walk->results_count,result));
    +
    + walk->results_count++;
    +
    +
    + skipping:
    + if (ok) {
    +
    + found:
    + result-> linked_walk = walk;
    +
    + DPRINT(Debug,14,(&Debug,
    + "link_name_entity_walk: walk(%p) linked with result(%p)\n",
    + walk,result));
    +
    + }
    + }
    +
    + static void tagfilter_generate_defaults P_((struct tagfilter_entities *ents));
    + static void tagfilter_generate_defaults(ents)
    + struct tagfilter_entities *ents;
    + {
    + if (TAGFILTER_ENTITIES_magic != ents->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_generate_defaults",
    + "Bad magic number");
    +
    + ents->builtin_generated = 1;
    +
    + if (ents->default_entities) {
    + size_t i;
    +
    + DPRINT(Debug,14,(&Debug,
    + "tagfilter_generate_defaults: %zu default entities\n", + ents->default_entities_count));
    +
    + for (i = 0; i < ents->default_entities_count; i++) {
    +
    + struct name_entity_walk * walk;
    + int have_semicolon = 0;
    +
    + if (NAME_ENTITY_MATCH_magic != ents->default_entities[i].static_result->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_generate_defaults",
    + "Bad magic number (name_entity_match)");
    +
    + have_semicolon = ison(ents->default_entities[i].static_result->flags,
    + ne_match_SEMICOLON);
    +
    + DPRINT(Debug,14,(&Debug,
    + "tagfilter_generate_defaults: #%zu: %Q %s\n",
    + i,ents->default_entities[i].ascii_entity,
    + have_semicolon ? "(have semicolon)" : "(no semicolon)"));
    +
    + walk = walk_reference_ascii(ents,
    + cs2us(ents->default_entities[i].ascii_entity),
    + have_semicolon);
    + if (!walk)
    + mime_panic(__FILE__,__LINE__,"tagfilter_generate_defaults",
    + "Linking failed");
    +
    + if (! ents->default_entities[i].static_result->linked_walk) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "tagfilter_generate_defaults: #%zu %s linking\n",
    + i,ents->default_entities[i].ascii_entity));
    +
    + link_name_entity_walk(walk,ents->default_entities[i].static_result,NULL);
    +
    + } else if (ents->default_entities[i].static_result->linked_walk == walk) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "tagfilter_generate_defaults: #%zu %s already linked\n",
    + i,ents->default_entities[i].ascii_entity));
    + } else {
    + mime_panic(__FILE__,__LINE__,"tagfilter_generate_defaults",
    + "Bad linking");
    + }
    +
    + free_name_entity_walk(&walk);
    + }
    +
    + }
    + }
    +
    +
    + static void link_name_entity_match P_((struct name_entity_match * result,
    + struct tagfilter_entities * entity_type, + struct string * reference_key,
    + int * errors));
    + static void link_name_entity_match(result,entity_type,reference_key,errors)
    + struct name_entity_match * result;
    + struct tagfilter_entities * entity_type; /* Root of linked tree */
    + struct string * reference_key;
    + int * errors;
    + {
    + int have_semicolon;
    +
    + struct name_entity_walk * walk;
    +
    + if (NAME_ENTITY_MATCH_magic != result->magic)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_match",
    + "Bad magic number (name_entity_match)");
    +
    + if (TAGFILTER_ENTITIES_magic != entity_type->magic)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_match",
    + "Bad magic number (tagfilter_entities)");
    +
    +
    + have_semicolon = ison(result->flags,ne_match_SEMICOLON);
    +
    + /* Increment refcount */
    + walk = walk_reference_key(entity_type,
    + reference_key,
    + have_semicolon);
    +
    +
    + if (walk) {
    +
    + if (! result->linked_walk) {
    +
    + link_name_entity_walk(walk,result,errors);
    +
    + } else {
    + /* just verify */
    +
    + if (walk != result->linked_walk)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_match",
    + "Bad linking");
    + }
    +
    + free_name_entity_walk(&walk);
    +
    + } else {
    +
    + if (result->linked_walk)
    + mime_panic(__FILE__,__LINE__,"link_name_entity_match",
    + "Bad linking / reference_key");
    +
    + mime_panic(__FILE__,__LINE__,"link_name_entity_match",
    + "Can not link given reference_key");
    +
    + }
    + }
    +
    + void link_tagfilter_entities(conf,errors)
    + struct tagfilter_entities_conf *conf;
    + int * errors;
    + {
    + if (TAGFILTER_ENTITIES_CONF_magic != conf->magic)
    + mime_panic(__FILE__,__LINE__,"link_tagfilter_entities",
    + "Bad magic number");
    +
    + conf->linked = 1;
    +
    + if (conf->root) {
    + size_t map_len = sort_list_len(conf->root);
    + size_t i;
    +
    + for (i = 0; i < map_len; i++) {
    +
    + union sort_item res;
    +
    + res.entity = NULL;
    +
    + /* Increments refcount */
    + get_sort_list_item(conf->root,sort_list_get_normal,i,&res);
    +
    + if (res.entity) {
    + struct entity_sort_item * entity_item = res.entity;
    +
    + if (ENTITY_SORT_ITEM_magic != entity_item->magic)
    + mime_panic(__FILE__,__LINE__,"link_tagfilter_entities",
    + "Bad magic number (entity_sort_item)");
    +
    + if (entity_item->entities) {
    + size_t j;
    +
    + for (j = 0; j < entity_item->entities_count; j++) {
    +
    + if (entity_item->entities[j].entity_type &&
    + entity_item->entities[j].result) {
    +
    + if (TAGFILTER_ENTITIES_magic !=
    + entity_item->entities[j].entity_type->magic)
    + mime_panic(__FILE__,__LINE__,"link_tagfilter_entities",
    + "Bad magic number (tagfilter_entities)");
    +
    + if (NAME_ENTITY_MATCH_magic !=
    + entity_item->entities[j].result->magic)
    + mime_panic(__FILE__,__LINE__,"link_tagfilter_entities",
    + "Bad magic number (name_entity_match)");
    +
    + if (conf != entity_item->entities[j].result->conf) + mime_panic(__FILE__,__LINE__,"link_tagfilter_entities",
    + "Bad conf (name_entity_match)");
    +
    + link_name_entity_match(entity_item->entities[j].result,
    + entity_item->entities[j].entity_type,
    + entity_item->reference_key, + errors
    + );
    +
    + }
    +
    + }
    + }
    +
    + free_entity_sort_item(&res);
    + }
    + }
    + }
    + }
    +
    +
    + static void unlink_name_entity_walk P_((struct name_entity_walk **walk,
    + struct tagfilter_entities * ents));
    +
    + static void unlink_name_entity_walk(walk,ents)
    + struct name_entity_walk **walk;
    + struct tagfilter_entities * ents;
    + {
    + struct name_entity_walk ** worklist = NULL;
    + size_t worklist_len = 0;
    + size_t idx= 0;
    +
    + if (NAME_ENTITY_WALK_magic != (*walk)->magic)
    + mime_panic(__FILE__,__LINE__,"unlink_name_entity_walk",
    + "Bad magic number");
    +
    + if (TAGFILTER_ENTITIES_magic != ents->magic)
    + mime_panic(__FILE__,__LINE__,"unlink_name_entity_walk",
    + "Bad magic number");
    +
    + worklist = safe_zero_alloc(sizeof (worklist[0]));
    + worklist[0] = *walk;
    + worklist_len = 1;
    + *walk = NULL;
    +
    + /* Flatten */
    +
    + while (idx < worklist_len) {
    + if (NAME_ENTITY_WALK_magic != worklist[idx]->magic)
    + mime_panic(__FILE__,__LINE__,"unlink_name_entity_walk",
    + "Bad magic number");
    +
    + if (ents != worklist[idx]->ents)
    + mime_panic(__FILE__,__LINE__,"unlink_name_entity_walk",
    + "Bad backlink (struct tagfilter_entities * ents)");
    +
    + /* Remove only tree part */
    +
    + if (worklist[idx]->alternatives) {
    + size_t newlen = worklist_len + worklist[idx]->alternatives_count;
    + size_t i;
    +
    + worklist = safe_array_realloc(worklist,newlen,sizeof (worklist[0]));
    +
    + for (i = 0; i < worklist[idx]->alternatives_count && worklist_len < newlen; i++) {
    + if (worklist[idx]->alternatives[i]) {
    + worklist[worklist_len++] = worklist[idx]->alternatives[i];
    + worklist[idx]->alternatives[i] = NULL;
    + }
    + }
    +
    +
    + free(worklist[idx]->alternatives);
    + worklist[idx]->alternatives = NULL;
    + }
    + worklist[idx]->alternatives_count = 0;
    +
    + worklist[idx]->ents = NULL;
    + idx++;
    + }
    +
    + /* Release */
    + for (idx = 0; idx < worklist_len; idx++) {
    + free_name_entity_walk(& worklist[idx]);
    + }
    +
    + free(worklist);
    + worklist = NULL;
    + }
    +
    +
    + static struct tagfilter_entities * entity_types[] = {
    + &HTML_entities
    + };
    + static const size_t entity_types_count = (sizeof entity_types) / sizeof (entity_types[0]);
    +
    +
    + void unlink_tagfilter_entities()
    + {
    + size_t y;
    +
    + for (y = 0; y < entity_types_count; y++) {
    + if (TAGFILTER_ENTITIES_magic != entity_types[y]->magic)
    + mime_panic(__FILE__,__LINE__,"unlink_tagfilter_entities",
    + "Bad magic number (tagfilter_entities)");
    +
    +
    + DPRINT(Debug,14,(&Debug,
    + "unlink_tagfilter_entities: %zu: unlinking %s\n",
    + y,entity_types[y]->type_tag));
    +
    + if (entity_types[y]->ampersand)
    + unlink_name_entity_walk(& (entity_types[y]->ampersand),
    + entity_types[y]);
    +
    + entity_types[y]->builtin_generated = 0;
    +
    +
    + }
    + }
    +
    +
    + struct tagfilter_entities_conf * new_tagfilter_entities_conf(rc,filename)
    + enum record_mode rc;
    + const char *filename;
    + {
    + /* Just dummy */
    +
    + return malloc_tagfilter_entities_conf(rc,filename,1);
    + }
    +
    + int dump_tagfilter_entities(f,conf,commentfile,actor,version_buff,fileset,
    + propline,rc,errno_res)
    + FILE *f;
    + struct tagfilter_entities_conf *conf;
    + FILE *commentfile;
    + const char *actor;
    + char *version_buff;
    + charset_t fileset;
    + const struct editor_propline *propline;
    + enum record_mode rc /* SYSTEM_RC = 0, LOCAL_RC = 1 */;
    + int * errno_res;
    + {
    + int ret = 0;
    + const char * sysnam = NULL;
    +
    + enum editor_propline_v propline_mode =
    + give_dt_enumerate_as_int(&editor_tfent_propline);
    +
    + int r;
    +
    + if (errno_res)
    + *errno_res = 0;
    +
    + if (!conf)
    + return 0;
    +
    + if (TAGFILTER_ENTITIES_CONF_magic != conf->magic)
    + mime_panic(__FILE__,__LINE__,"dump_tagfilter_entities",
    + "Bad magic number (tagfilter_entities_conf)");
    +
    + if (!fileset) {
    + DPRINT(Debug,10,(&Debug,
    + "dump_tagfilter_entities: File charset is not set, using system charset\n"));
    + fileset = system_charset;
    + }
    +
    + sysnam = get_charset_MIME_name(fileset);
    +
    + /* Must have first line */
    + if (propline_mode != editor_propline_ignore)
    + write_editor_propline(propline,propline_mode,
    + f,"# ","\n",fileset);
    +
    + if (sysnam) {
    + /* Store used character set */
    +
    + elm_fprintf(f,
    + CATGETS(elm_msg_cat,MeSet, MeCharsetExplain,
    + "# Character set used on this file\n"));
    +
    + fprintf(f,"@charset = %s\n",sysnam);
    + }
    +
    + insert_commentfile(f,ELMTAGFILENT_INFO,commentfile,
    + actor,version_buff);
    +
    + if (conf->root) {
    + size_t map_len = sort_list_len(conf->root);
    + size_t i;
    + int need_delete = 0;
    +
    + DPRINT(Debug,14,(&Debug,
    + "dump_tagfilter_entities: %zu names\n",
    + map_len));
    +
    +
    + for (i = 0; i < map_len; i++) {
    +
    + union sort_item res;
    +
    + res.entity = NULL;
    +
    + /* Increments refcount */
    + get_sort_list_item(conf->root,sort_list_get_normal,i,&res);
    +
    + if (res.entity) {
    + struct entity_sort_item * entity_item = res.entity;
    + int failcount = 0;
    + struct string * S1 = NULL;
    +
    + char * S1_res = NULL;
    + int S1_len = 0;
    +
    + if (ENTITY_SORT_ITEM_magic != entity_item->magic)
    + mime_panic(__FILE__,__LINE__,"dump_tagfilter_entities",
    + "Bad magic number (entity_sort_item)");
    +
    + S1 = convert_string2(fileset,entity_item->reference_key,&failcount);
    +
    +
    + DPRINT(Debug,14,(&Debug,"dump_tagfilter_entities: entity %zu = \"%S\"",
    + i,entity_item->reference_key));
    +
    + if (failcount > 0 || ! S1) {
    + DPRINT(Debug,14,(&Debug,", can't convert to %s\n",
    + sysnam ? sysnam : "<no MIME name>"));
    + goto failentity;
    + }
    +
    +
    +
    +
    + bytestream_from_string(S1,&S1_res,&S1_len);
    +
    + if (entity_item->entities) {
    + size_t j;
    + size_t width = 8;
    +
    + DPRINT(Debug,14,(&Debug," -- count %zu\n",
    + entity_item->entities_count));
    +
    + for (j = 0; j < entity_item->entities_count; j++) {
    + const char * type = "???";
    +
    + struct string * S2 = NULL;
    + int failS2count = 0;
    + char * S2_res = NULL;
    + int S2_len = 0;
    +
    + if (entity_item->entities[j].entity_type) {
    + if (TAGFILTER_ENTITIES_magic !=
    + entity_item->entities[j].entity_type->magic)
    + mime_panic(__FILE__,__LINE__,"dump_tagfilter_entities",
    + "Bad magic number (tagfilter_entities)");
    + type = entity_item->entities[j].entity_type->type_tag;
    +
    + } else {
    + DPRINT(Debug,14,(&Debug," : %zu -- skipping\n",
    + j));
    + continue;
    + }
    +
    + DPRINT(Debug,14,(&Debug," : %zu %s",
    + j,type));
    +
    + if (entity_item->entities[j].delete) {
    + DPRINT(Debug,14,(&Debug,", marked for delete -- skipping\n"));
    +
    + need_delete++;
    + continue;
    + }
    +
    + if (entity_item->entities[j].result) {
    +
    + if (NAME_ENTITY_MATCH_magic != entity_item->entities[j].result->magic)
    + mime_panic(__FILE__,__LINE__,"dump_tagfilter_entities",
    + "Bad magic number (name_entity_match)");
    +
    +
    + if (ison(entity_item->entities[j].result->flags,ne_match_IGNORE)) {
    + DPRINT(Debug,14,(&Debug,", marked for ignore -- skipping\n"));
    +
    + entity_item->entities[j].delete = 1;
    + need_delete++;
    + continue;
    + }
    +
    + if (entity_item->entities[j].result->entity_value) {
    +
    + S2 = convert_string2(fileset,
    + entity_item->entities[j].result->entity_value,
    + &failS2count);
    +
    + if (!S2 || failS2count > 0) {
    + DPRINT(Debug,14,(&Debug,
    + ", failed to convert value \"%S\" to %s\n",
    + entity_item->entities[j].result->entity_value,
    + sysnam ? sysnam : "<no MIME name>"));
    + goto failedresult;
    + }
    +
    + bytestream_from_string(S2,&S2_res,&S2_len);
    +
    + }
    +
    + entity_item->entities[j].old = 1;
    +
    + fwrite(S1_res,1,S1_len,f);
    +
    + if (S1_len < width) {
    + size_t zz = S1_len;
    +
    + /* Pad with space */
    + while (zz < width) {
    + putc(' ',f);
    + zz++; /* Ascii compatible assumed */
    + }
    + } else if (S1_len < 20 && S1_len/8 > width/8) {
    + width = S1_len;
    + }
    +
    + putc('\t',f); /* Ascii compatible assumed */
    + fputs(type,f); /* Ascii compatible assumed */
    + putc('\t',f); /* Ascii compatible assumed */
    +
    + if (S2) {
    + putc('"',f); /* Ascii compatible assumed */ + fwrite(S2_res,1,S2_len,f);
    + putc('"',f); /* Ascii compatible assumed */ + } else {
    + fprintf(f,"x%04x",
    + entity_item->entities[j].result->unicode_value);
    + /* Ascii compatible assumed */
    + }
    +
    + putc('\n',f);
    +
    + } else {
    + DPRINT(Debug,14,(&Debug," -- skipping\n"));
    + }
    +
    + if (S2_res) {
    + free(S2_res);
    + S2_res = NULL;
    + }
    + failedresult:
    + if (S2)
    + free_string(&S2);
    +
    +
    + }
    + } else {
    + need_delete ++;
    +
    + DPRINT(Debug,14,(&Debug," -- empty (need delete)\n"));
    + }
    +
    + if (S1_res) {
    + free(S1_res);
    + S1_res = NULL;
    + }
    +
    + failentity:
    + if (S1)
    + free_string(&S1);
    +
    + free_entity_sort_item(&res);
    + }
    + }
    +
    + if (need_delete) {
    + DPRINT(Debug,14,(&Debug,
    + "dump_tagfilter_entities: %d entities need to be delete (total %zu names)\n",
    + need_delete,map_len));
    +
    + if (map_len > 0) {
    +
    + size_t i = map_len -1;
    + size_t deleted = 0;
    +
    + while (1) {
    + union sort_item res;
    +
    + res.aliases = NULL;
    +
    + /* Increments refcount */
    + get_sort_list_item(conf->root,sort_list_get_normal,i,&res); +
    + if (res.entity) {
    + struct entity_sort_item * entity_item = res.entity;
    + int have_names = 0;
    +
    + if (ENTITY_SORT_ITEM_magic != entity_item->magic)
    + mime_panic(__FILE__,__LINE__,"dump_tagfilter_entities",
    + "Bad magic number (entity_sort_item)"); +
    + DPRINT(Debug,14,(&Debug,"dump_tagfilter_entities: entity %zu = \"%S\"",
    + i,entity_item->reference_key));
    +
    + if (entity_item->entities) {
    + size_t j;
    + size_t t;
    +
    + DPRINT(Debug,14,(&Debug," -- count %zu\n",
    + entity_item->entities_count));
    +
    + for (j = 0, t = 0; j < entity_item->entities_count; j++) {
    + const char * type UNUSED_VAROK = "???";
    +
    +
    + if (entity_item->entities[j].entity_type) {
    + if (TAGFILTER_ENTITIES_magic !=
    + entity_item->entities[j].entity_type->magic)
    + mime_panic(__FILE__,__LINE__,"dumo_tagfilter_entities",
    + "Bad magic number (tagfilter_entities)");
    + type = entity_item->entities[j].entity_type->type_tag;
    + }
    +
    + DPRINT(Debug,14,(&Debug," : %zu %s",
    + j,type));
    +
    + if (entity_item->entities[j].delete) {
    + DPRINT(Debug,14,(&Debug,", marked for delete\n"));
    +
    + free_entity_item_data(& (entity_item->entities[j]));
    +
    + } else {
    +
    + if (t != i) {
    + DPRINT(Debug,14,(&Debug,", => %zu (move)"));
    +
    + entity_item->entities[t] = entity_item->entities[j];
    + t++;
    +
    + bzero(&(entity_item->entities[j]),
    + sizeof (entity_item->entities[j]));
    + }
    +
    + DPRINT(Debug,14,(&Debug,"\n"));
    + have_names = 1;
    + }
    + }
    +
    + if (t < entity_item->entities_count) {
    + DPRINT(Debug,14,(&Debug,
    + "dump_tagfilter_entities: entity %zu = \"%S\" - count=%zu => %zu\n",
    + i,entity_item->reference_key,entity_item->entities_count,t));
    +
    + entity_item->entities_count = t;
    + }
    +
    + } else {
    + DPRINT(Debug,14,(&Debug," -- empty, deleting\n")); + }
    +
    + if (!have_names) {
    + entity_item = NULL;
    +
    + DPRINT(Debug,14,(&Debug,
    + "dump_tagfilter_entities: entity %zu = \"%S\" -- deleting\n",
    + i,entity_item->reference_key));
    +
    + free_entity_sort_item(&res);
    +
    +
    + /* Increments refcount */
    + get_sort_list_item(conf->root,sort_list_get_remove,i,&res);
    +
    + if (res.entity) {
    + entity_item = res.entity;
    +
    + if (ENTITY_SORT_ITEM_magic != entity_item->magic)
    + mime_panic(__FILE__,__LINE__,"dump_tagfilter_entities",
    + "Bad magic number (entity_sort_item)");
    +
    + DPRINT(Debug,14,(&Debug,"dump_tagfilter_entities: entity %zu = \"%S\" deleted\n",
    + i,entity_item->reference_key));
    +
    + }
    + }
    +
    + free_entity_sort_item(&res);
    + }
    +
    + if (i > 0)
    + i--;
    + else
    + break;
    +
    + }
    +
    + if (deleted) {
    + map_len = sort_list_len(conf->root);
    +
    +
    + DPRINT(Debug,14,(&Debug,
    + "dump_tagfilter_entities: %zu enitites deleted, %zu names left\n",
    + deleted,map_len));
    +
    + }
    +
    + }
    + }
    + }
    +
    + r = fflush(f);
    +
    + switch (r) {
    + int err;
    +
    + case 0:
    + ret = 1;
    +
    + break;
    + case EOF:
    + err = errno;
    +
    + DPRINT(Debug,14,(&Debug,
    + "dump_tagfilter_entities: fflush: %s\n",
    + strerror(err)));
    +
    + if (errno_res)
    + *errno_res = err;
    +
    + break;
    + }
    +
    + DPRINT(Debug,14,(&Debug,
    + "dump_tagfilter_entities=%d",ret));
    + if (errno_res && *errno_res) {
    + DPRINT(Debug,14,(&Debug,"; error %s",
    + strerror(*errno_res)));
    + }
    + DPRINT(Debug,14,(&Debug,"\n"));
    +
    +
    + return ret;
    + }
    +
    + static int read_tagfilter_entities P_((const char * filename,
    + FILE * f,
    + struct tagfilter_entities_conf ** conf, + int * errors,
    + charset_t * fileset,
    + struct editor_propline ** propline,
    + enum record_mode rc /* SYSTEM_RC = 0,
    + LOCAL_RC = 1 */, + int * need_rewrite));
    +
    +
    +
    + /* XXXXX same as hashmark_is_printableln() */
    + static int tagfilter_is_printableln P_((const char *filename,
    + int lineno,
    + const struct string * rest_S));
    +
    + static int tagfilter_is_printableln(filename,lineno,rest_S)
    + const char *filename;
    + int lineno;
    + const struct string * rest_S;
    + {
    + int L = string_len(rest_S);
    + int idx;
    +
    + for (idx = 0; idx < L; idx++) {
    + uint16 ucode = 0;
    + unsigned char bcode = 0;
    + int gchar_flags = give_character_from_string(rest_S,idx,
    + &ucode,&bcode);
    +
    + if (0 != (gchar_flags & GCHAR_unicode) &&
    + 0x0009 /* HT '\t' (horizontal tab) */ == ucode) {
    +
    + /* Allow tabulator */
    +
    + } else if (0 == (gchar_flags & GCHAR_unicode ) ||
    + 0 == unicode_ch(ucode,UOP_printable)) {
    + char ubuffer[8], * ub = "";
    + char bbuffer[5], * bb = "";
    +
    + if (0 != (gchar_flags & GCHAR_unicode)) {
    + elm_sfprintf(ubuffer,sizeof ubuffer,
    + FRM(" u%04X"),
    + ucode);
    + ub = ubuffer;
    + }
    + if (0 != (gchar_flags & GCHAR_bytecode)) {
    + elm_sfprintf(bbuffer,sizeof bbuffer,
    + FRM(" x%02X"),
    + bcode);
    + bb = bbuffer;
    + }
    +
    + lib_error(CATGETS(elm_msg_cat, MeSet,
    + MeNonPrintableCharOnLine,
    + "%s: %d: Non-printable character%s%s on line"),
    + filename,lineno,ub,bb);
    + return 0;
    + }
    + }
    +
    + return 1;
    + }
    +
    + enum change_mode {
    + read_entities = 0,
    + merge_entities
    + };
    +
    +
    + static int set_tagfilter_entity P_((const char * filename,
    + struct tagfilter_entities_conf * conf,
    + struct string * named_reference,
    + struct tagfilter_entities * enttyp,
    + struct string * entity_value,
    + uint16 unicode_value,
    + int lineno,
    + unsigned ne_match_flags,
    + enum change_mode merged_entity,
    + size_t * res_idx_p /* append mode */,
    + int * append_need_rewrite_p,
    + int * errors,
    + struct string * rest_S,
    + struct string * entity_type,
    + int set_old
    + ));
    + static int set_tagfilter_entity(filename,conf,named_reference,
    + enttyp,entity_value, unicode_value,
    + lineno,ne_match_flags, merged_entity,
    + res_idx_p,
    + append_need_rewrite_p,
    + errors,rest_S, entity_type,set_old)
    + const char * filename;
    + struct tagfilter_entities_conf * conf;
    + struct string * named_reference;

    [continued in next message]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)