Patch: Elm ME+ 2.5 PLalpha62 -> Elm ME+ 2.5 PLalpha63 [5/7] (3/7)
From
Kari Hurtta@21:1/5 to
All on Wed Jan 3 13:52:43 2024
[continued from previous message]
+ 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;
+ {
+ int r = 1;
+
+ union sort_key key;
+ union sort_item_default def;
+ union sort_item res;
+
+ struct string_sort * search_key = NULL;
+
+ if (TAGFILTER_ENTITIES_CONF_magic != conf->magic)
+ mime_panic(__FILE__,__LINE__," set_tagfilter_entity",
+ "Bad magic number (tagfilter_entities_conf)");
+
+
+ /* Shares named_reference and increments refcount */
+ search_key = new_string_sort(named_reference);
+
+ key.string_sort = search_key;
+ def.dummy = NULL;
+ res.dummy = NULL;
+
+ /* Increments refcount, returns 1 if found or created */
+ if (search_sort_list_item(conf->root,
+ sort_list_insert_hint /* sequential append mode, + uses res_idx
+ */
+ /* sort_list_search_create <-- when random order */
+ ,key,def,
+ &res,res_idx_p,append_need_rewrite_p)) {
+
+ DPRINT(Debug,14,(&Debug,
+ "set_tagfilter_entity: search_sort_list_item found or created item #%zu\n",
+ *res_idx_p));
+
+ if (res.entity) {
+ struct entity_sort_item * entity_item = res.entity;
+ size_t newpos = 0;
+ int merged = 0;
+
+ if (ENTITY_SORT_ITEM_magic != entity_item->magic)
+ mime_panic(__FILE__,__LINE__,"set_tagfilter_entity",
+ "Bad magic number (entity_sort_item)");
+
+ if (entity_item->entities) {
+ size_t a;
+
+ for (a = 0; a < entity_item->entities_count; a++) {
+
+ if (enttyp == entity_item->entities[a].entity_type) {
+
+ if (! entity_item->entities[a].result) {
+
+ newpos = a;
+ goto found1;
+ }
+
+ if (NAME_ENTITY_MATCH_magic !=
+ entity_item->entities[a].result->magic)
+ mime_panic(__FILE__,__LINE__,"set_tagfilter_entity",
+ "Bad magic number (name_entity_match)"); +
+ if (conf != entity_item->entities[a].result->conf)
+ mime_panic(__FILE__,__LINE__,"set_tagfilter_entities",
+ "Bad conf (name_entity_match)");
+
+
+ switch (merged_entity) {
+ case read_entities:
+ /* Is this merge */
+ if (entity_item->entities[a].need_on_disk) {
+
+ newpos = a;
+ merged = 1;
+
+ goto found1;
+ }
+ break;
+ case merge_entities:
+ newpos = a;
+ merged = 1;
+
+ goto found1;
+ }
+
+ if (rest_S && entity_type) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityDuplicate,
+ "%s: %d: Duplicate entity %S with type %S - already given on line %d: %S"),
+ filename,lineno,
+ named_reference,entity_type,
+ entity_item->entities[a].result->lineno,
+ rest_S);
+ }
+
+ (*errors) ++;
+ goto fail2;
+
+ }
+ }
+ }
+
+ entity_item->entities =
+ safe_array_realloc(entity_item->entities,
+ entity_item->entities_count+1,
+ sizeof (entity_item->entities[0]));
+
+ newpos = entity_item->entities_count++;
+
+ /* bzero is defined on hdrs/defs.h */
+ bzero((void *)&(entity_item->entities[newpos]),
+ sizeof ((entity_item->entities[newpos])));
+
+ entity_item->entities[newpos].entity_type = enttyp;
+ entity_item->entities[newpos].result = NULL;
+ entity_item->entities[newpos].old = set_old;
+
+
+ found1:
+
+ if (newpos >= entity_item->entities_count)
+ mime_panic(__FILE__,__LINE__,"set_tagfilter_entity",
+ "Bad newpos");
+
+ if (entity_item->entities[newpos].entity_type != enttyp)
+ mime_panic(__FILE__,__LINE__,"set_tagfilter_entity",
+ "Bad type on newpos");
+
+ entity_item->entities[newpos].need_on_disk = 0;
+ entity_item->entities[newpos].delete = 0;
+
+ if (entity_item->entities[newpos].result) {
+ if (NAME_ENTITY_MATCH_magic !=
+ entity_item->entities[newpos].result->magic)
+ mime_panic(__FILE__,__LINE__,"set_tagfilter_entity",
+ "Bad magic number (name_entity_match)");
+
+ if (conf != entity_item->entities[newpos].result->conf)
+ mime_panic(__FILE__,__LINE__,"set_tagfilter_entity",
+ "Bad conf ((name_entity_match)");
+
+ if (!merged) {
+ if (rest_S && entity_type) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityDuplicate,
+ "%s: %d: Duplicate entity %S with type %S - already given on line %d: %S"),
+ filename,lineno,
+ named_reference,entity_type,
+ entity_item->entities[newpos].result->lineno,
+ rest_S);
+ }
+ (*errors) ++;
+ }
+
+ entity_item->entities[newpos].result->lineno = lineno;
+
+ if (entity_item->entities[newpos].result->entity_value)
+ free_string(& (entity_item->entities[newpos].result->
+ entity_value));
+ if (entity_value)
+ entity_item->entities[newpos].result->entity_value =
+ dup_string(entity_value);
+
+ entity_item->entities[newpos].result->unicode_value = unicode_value;
+ entity_item->entities[newpos].result->flags = ne_match_flags;
+
+ } else
+ entity_item->entities[newpos].result =
+ malloc_name_entity_match(entity_value,unicode_value,
+ conf,lineno,ne_match_flags);
+
+ if (conf->linked)
+ link_name_entity_match(entity_item->entities[newpos].result,
+ entity_item->entities[newpos].entity_type,
+ entity_item->reference_key,
+ errors);
+
+ free_entity_sort_item(&res); /* Decrement refcount */
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "set_tagfilter_entity: search_sort_list_item did not set entity\n"));
+ r = 0;
+ }
+
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "set_tagfilter_entity: search_sort_list_item failed to create entry\n"));
+
+ r = 0;
+ }
+
+ fail2:
+ if (search_key)
+ free_string_sort(&search_key);
+
+
+ return r;
+ }
+
+
+
+
+ int change_tagfilter_entities(conf,new,rc,filename,errors)
+ struct tagfilter_entities_conf **conf;
+ struct tagfilter_entities_conf * new;
+ enum record_mode rc /* SYSTEM_RC = 0,
+ LOCAL_RC = 1 */;
+ const char * filename;
+ int * errors;
+ {
+ int ret = 1;
+
+ if (*conf) {
+
+ if (TAGFILTER_ENTITIES_CONF_magic != (*conf)->magic)
+ mime_panic(__FILE__,__LINE__,"change_tagfilter_entities",
+ "Bad magic number (tagfilter_entities_conf, *conf)");
+
+ }
+
+ if (TAGFILTER_ENTITIES_CONF_magic != new->magic)
+ mime_panic(__FILE__,__LINE__,"change_tagfilter_entities",
+ "Bad magic number (tagfilter_entities_conf, new");
+
+ if (new->root) {
+ size_t count = sort_list_len(new->root);
+ size_t i;
+ size_t new_idx = 0;
+ int append_need_rewrite = 0;
+
+ if (!*conf) {
+
+ DPRINT(Debug,14,(&Debug,
+ "change_tagfilter_entities: Creating config, count=%zu entities for %s\n",
+ count,filename));
+
+ *conf = malloc_tagfilter_entities_conf(rc,filename,count);
+ } else {
+
+ if ((*conf)->root) {
+ size_t old_count = sort_list_len((*conf)->root);
+
+ DPRINT(Debug,14,(&Debug,
+ "change_tagfilter_entities: %zu entires already on %s\n",
+ old_count,(*conf)->filename));
+ } else {
+ (*conf)->root = alloc_sort_list(&entity_map_operation,count);
+ }
+
+ (*conf)->rc = rc;
+ if ((*conf)->filename != filename) {
+ DPRINT(Debug,14,(&Debug,
+ "change_tagfilter_entities: filename %s => %s\n",
+ (*conf)->filename,filename));
+ (*conf)->filename = strmcpy((*conf)->filename,filename);
+ }
+ }
+
+ /* merge request from elmtagfilterents */
+
+ for (i = 0; i < count; i++) {
+
+ union sort_item res;
+
+ res.entity = NULL;
+
+ /* Increments refcount */
+ get_sort_list_item(new->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__,"change_tagfilter_entities",
+ "Bad magic number (entity_sort_item)");
+
+ DPRINT(Debug,14,(&Debug,"change_tagfilter_entities: entity %zu = \"%S\"\n",
+ i,entity_item->reference_key));
+
+
+ if (entity_item->entities) {
+ size_t j;
+
+ for (j = 0; j < entity_item->entities_count; j++) {
+ const char * type = "???";
+
+ if (! entity_item->entities[j].entity_type ||
+ ! entity_item->entities[j].result)
+ continue;
+
+ if (TAGFILTER_ENTITIES_magic !=
+ entity_item->entities[j].entity_type->magic)
+ mime_panic(__FILE__,__LINE__,"change_tagfilter_entities",
+ "Bad magic number (tagfilter_entities)");
+ type = entity_item->entities[j].entity_type->type_tag; +
+ DPRINT(Debug,14,(&Debug," : %zu %s\n",
+ j,type));
+
+ if (NAME_ENTITY_MATCH_magic != entity_item->entities[j].result->magic)
+ mime_panic(__FILE__,__LINE__,"change_tagfilter_entities",
+ "Bad magic number (name_entity_match)"); +
+
+
+
+ if (set_tagfilter_entity(filename,*conf,entity_item->reference_key,
+ entity_item->entities[j].entity_type,
+ entity_item->entities[j].result->entity_value,
+ entity_item->entities[j].result->unicode_value,
+
+ /* Not really correct */
+ entity_item->entities[j].result->lineno,
+
+ entity_item->entities[j].result->flags,
+ merge_entities,
+ &new_idx,
+ &append_need_rewrite,
+ errors,NULL,NULL,0
+ )) {
+
+ DPRINT(Debug,14,(&Debug," - %zu %s => %zu\n",
+ j,type,new_idx));
+
+ } else {
+ DPRINT(Debug,14,(&Debug," - %zu %s => failed\n",
+ j,type));
+
+ ret = 0;
+ }
+ }
+ }
+
+ free_entity_sort_item(&res);
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ int merge_tagfilter_entities(filename,f,conf,errors,fileset,propline,rc,need_rewrite)
+ 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;
+ {
+ int r;
+
+ r = read_tagfilter_entities(filename,f,&conf,errors,fileset,propline,
+ rc, need_rewrite);
+
+ return r;
+ }
+
+ static int read_tagfilter_entities(filename,f,conf,errors,fileset,propline,rc,need_rewrite)
+ 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;
+ {
+ charset_t cs = system_charset;
+ const char * csn = get_charset_MIME_name(cs);
+
+ size_t res_idx = 0; /* Append mode position */
+ char * buf = NULL;
+ int c;
+ size_t count = 0;
+ int last_c = '\n';
+ int lineno = 0;
+
+ int append_need_rewrite = 0;
+
+ int fail_it = 0;
+ size_t pos = 0;
+ enum syscall_status r;
+
+ int ret_status = 0;
+ int set_old = 0;
+
+ if (fileset && *fileset) {
+ csn = get_charset_MIME_name(*fileset);
+
+ cs = *fileset;
+
+ if (csn) {
+ DPRINT(Debug,2,(&Debug,
+ "read_tagfilter_entities: %s: default charset: %s\n",
+ filename,csn));
+ }
+ }
+
+ /* Look for editor property line */
+
+ if (propline) {
+ enum editor_propline_v propline_mode =
+ give_dt_enumerate_as_int(&editor_tfent_propline);
+
+ /* Nothing detected yet */
+
+ if (*propline)
+ free_editor_propline(propline);
+
+ if (propline_mode != editor_propline_ignore) {
+ int i;
+
+ for (i = 0; i < 3 && !*propline; i++) {
+ int l1;
+
+ c = fgetc(f);
+
+ if (EOF == c)
+ goto propline_failure;
+ if ('\n' == c)
+ continue;
+
+ ungetc(c,f);
+
+ if ('#' != c)
+ break;
+
+ l1 = malloc_gets(&buf,LONG_STRING,f);
+ if (l1 > 1) {
+
+ if ('#' != buf[0])
+ goto propline_failure;
+
+ *propline =
+ detect_editor_propline(propline_mode,
+ buf,l1,filename,i,&cs);
+
+ csn = get_charset_MIME_name(cs);
+
+ } else { /* something wrong? */
+ propline_failure:
+
+ rewind(f);
+ break;
+ }
+ }
+ }
+
+ pos = ftell(f);
+ }
+
+
+ if (*conf) {
+
+ if (TAGFILTER_ENTITIES_CONF_magic != (*conf)->magic)
+ mime_panic(__FILE__,__LINE__,"read_tagfilter_entities",
+ "Bad magic number (tagfilter_entities_conf)");
+
+ if ((*conf)->root) {
+ size_t map_len = sort_list_len((*conf)->root);
+ size_t i;
+ size_t old_count = 0;
+
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: %zu items on tagfilter_entities_conf already\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;
+
+ if (ENTITY_SORT_ITEM_magic != entity_item->magic)
+ mime_panic(__FILE__,__LINE__,"read_tagfilter_entities", + "Bad magic number (entity_sort_item)");
+
+ DPRINT(Debug,14,(&Debug,"read_tagfilter_entities: entity %zu = \"%S\"\n",
+ i,entity_item->reference_key));
+
+ if (entity_item->entities) {
+ size_t j;
+
+ for (j = 0; j < entity_item->entities_count; j++) {
+ const char * type = "???";
+
+ if (entity_item->entities[j].entity_type) {
+ if (TAGFILTER_ENTITIES_magic !=
+ entity_item->entities[j].entity_type->magic)
+ mime_panic(__FILE__,__LINE__,"read_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"));
+ } else if (entity_item->entities[j].old) {
+ entity_item->entities[j].need_on_disk = 1;
+ DPRINT(Debug,14,(&Debug,", old -- marked need_on_disk"));
+ old_count++;
+ } else if (entity_item->entities[j].need_on_disk) { + entity_item->entities[j].need_on_disk = 0;
+ DPRINT(Debug,14,(&Debug,", clearing need_on_disk"));
+ }
+ DPRINT(Debug,14,(&Debug,"\n"));
+
+ }
+ }
+
+ free_entity_sort_item(&res);
+ }
+
+ if (old_count) {
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: %zu old entities marked need_on_disk\n",
+ old_count));
+ }
+ }
+ }
+ } else {
+ set_old = 1; /* When later merged, need found from disk */
+ }
+
+ if (!*conf || ! ((*conf)->root)) {
+
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: counting entity lines from offset %ld at %s\n",
+ pos,filename));
+
+ while(EOF != (c = fgetc(f))) {
+ /* Rough guess about &entity lines */
+
+ if (last_c == '\n' &&
+ c == '&')
+ count++;
+ last_c = c;
+ }
+
+ r = fseek(f,pos,SEEK_SET);
+ switch (r) {
+ int err;
+ case syscall_success:
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: Reading again from offset %ld at %s\n",
+ pos,filename));
+ break;
+ case syscall_error:
+ err = errno;
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: Failed to seek to offset %ld at %s: %s\n",
+ pos,filename,strerror(err)));
+
+ return 0;
+ }
+
+
+ if (!*conf) {
+
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: Creating config, count=%zu entity lines on %s\n",
+ count,filename));
+
+ *conf = malloc_tagfilter_entities_conf(rc,filename,count);
+ } else if (! ((*conf)->root)) {
+ (*conf)->root = alloc_sort_list(&entity_map_operation,count);
+ }
+ }
+
+ while(!feof(f) && !ferror(f) && !fail_it) {
+ int l1 = malloc_gets(&buf,LONG_STRING,f);
+ struct string * rest_S = NULL;
+ char * cx = buf;
+ int restlen = 0;
+ int ERRORS = 0;
+ int rs;
+ int L;
+
+ if (-1 == l1) {
+ lib_error(CATGETS(elm_msg_cat, MeSet, MeTooLongLineNo,
+ "%s: %d: Too long line: %.30s..."),
+ filename,lineno+1,buf);
+ (*errors) ++;
+
+ DPRINT(Debug,9,(&Debug,
+ "read_tagfilter_entities: %s: %d: failed to parse line, too long line\n",
+ filename,lineno+1));
+
+
+ break;
+ } else if (l1 < 0) {
+ DPRINT(Debug,9,(&Debug,
+ "read_tagfilter_entities: %s: %d: read error or EOF\n",
+ filename,lineno+1));
+ break;
+ }
+
+ lineno++;
+
+ if (l1 == 0)
+ continue;
+
+ l1 = trim_whitespace_from_end(buf,l1);
+
+ if (read_charset_tag(buf,l1,
+ filename,lineno,
+ errors,&cs,&csn))
+ continue;
+
+ cx = buf;
+ while (*cx && whitespace (*cx)) /* skip leading whitespace */
+ cx++;
+ if ('#' == *cx)
+ continue;
+
+ if (!*cx) {
+
+ if (cx < buf + l1) {
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeNULcharacterOnLine,
+ "%s: %d: NUL character on line."),
+ filename,lineno);
+ (*errors) ++;
+
+ DPRINT(Debug,9,(&Debug,
+ "read_tagfilter_entities: %s: %d: failed to parse line (NUL character)\n",
+ filename,lineno));
+
+
+ }
+
+ }
+
+ rest_S = new_string(cs);
+ restlen = (buf + l1) - cx;
+ rs = add_streambytes_to_string(rest_S,restlen,
+ cs2us(cx),&ERRORS);
+ if (rs < restlen) {
+ lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFailedAsCharset,
+ "Failed to parse line %d as charset %s in \"%s\" file"),
+ lineno, csn ? csn : "<no MIME name>",filename);
+
+ (*errors) ++;
+
+ DPRINT(Debug,9,(&Debug,
+ "read_tagfilter_entities: %s: %d: failed to parse line\n",
+ filename,lineno));
+
+ goto fail;
+ }
+
+ if (ERRORS) {
+ lib_error(CATGETS(elm_msg_cat, ElmSet, ElmFileAsCharsetErrors,
+ "There is %d errors when parsing line %d as charset %s in \"%s\" file"),
+ ERRORS,lineno,
+ csn ? csn : "<no MIME name>",filename);
+
+ (*errors) ++;
+
+ DPRINT(Debug,9,(&Debug,
+ "read_tagfilter_entities: %s: %d: failed to parse line (%d character errors)\n",
+ filename,lineno, ERRORS));
+
+
+ goto fail;
+ }
+
+ L = string_len(rest_S);
+ if (L > 0) {
+ uint16 code = give_unicode_from_string(rest_S,0);
+ struct string * named_reference = NULL;
+ struct string * entity_type = NULL;
+ struct string * entity_value = NULL;
+
+ if (0x0026 /* & */ == code) {
+
+ int x;
+ int seen_semicolon = 0;
+ int X = 0;
+ int rs;
+ uint16 found_delim = 0;
+
+ enum value_mode {
+ null_value = 0,
+ quoted_string,
+ octal_value = 8,
+ decimal_value = 10,
+ hexdecimal_value = 16,
+
+ } mode = null_value;
+ uint32 value = 0;
+
+ int start_x = 0;
+ int end_x = 0;
+
+ size_t y;
+
+ struct tagfilter_entities * enttyp = NULL;
+ int ne_match_flags;
+
+
+
+ for (x = 1; x < L; x++) {
+ code = give_unicode_from_string(rest_S,x);
+
+
+ if (0x003B /* ; */ == code) {
+ seen_semicolon = 1;
+ x++;
+ break;
+ } else if (0x0009 /* HT '\t' (horizontal tab) */ == code ||
+ 0x0020 /* SPACE */ == code) {
+ break;
+ } else if (tagfilter_entity_character(code,NULL)) {
+ /* OK */
+ } else {
+ goto badline;
+ }
+ }
+
+ if (x < 2 || ( seen_semicolon && x < 3)) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityNotGiven,
+ "%s: %d: Entity name not given: %S"), + filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+ }
+
+ named_reference = clip_from_string(rest_S,&X,x);
+
+ rs = get_word_from_string(rest_S,&entity_type,&X,
+ GWF_lowercase,cs2us(" \t"),
+ &found_delim);
+
+ if (rs < 1 || !entity_type || string_len(entity_type) < 1) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityTypeNotGiven,
+ "%s: %d: Entity type not given: %S"), + filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+ }
+
+ for (x = X; x < L; x++) {
+ code = give_unicode_from_string(rest_S,x);
+
+ if (0x0031 /* 1 */ <= code && code <= 0x0039 /* 9 */) {
+ mode = decimal_value;
+ break;
+ } else if (0x0078 /* x */ == code ||
+ 0x0058 /* X */ == code) {
+ x++;
+ mode = hexdecimal_value;
+ break;
+ } else if (0x0022 /* " */ == code) {
+ x++;
+ mode = quoted_string;
+ break;
+ } else if (0x0030 /* 0 */ == code) {
+ mode = octal_value;
+ break;
+ } else if (0x0009 /* HT '\t' (horizontal tab) */ == code ||
+ 0x0020 /* SPACE */ == code) {
+ /* Skip */
+ } else {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityValNotOK,
+ "%s: %d: Entity value is not number or quoted string: %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+
+ }
+ }
+
+ switch (mode) {
+ case null_value: goto badline;
+ case quoted_string:
+ start_x = x;
+
+ for (x = start_x; x < L; x++) {
+ code = give_unicode_from_string(rest_S,x);
+
+ if (0x0022 /* " */ == code) {
+ end_x = x;
+ x++;
+ break;
+ } else if (0x005C /* \ */ == code) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityValNotBackSlash,
+ "%s: %d: Entity value does not allow backslash (\\): %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+ }
+ }
+
+ if (end_x < start_x) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityValNotQuoteEnd,
+ "%s: %d: Entity value does not does not end with quote (\"): %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+ }
+
+ X = start_x;
+ entity_value = clip_from_string(rest_S,&X,end_x-start_x);
+ X++;
+
+ break;
+ case octal_value:
+ case decimal_value:
+ case hexdecimal_value:
+ start_x = x;
+
+ for (x = start_x; x < L; x++) {
+ unsigned char v = 0;
+
+ code = give_unicode_from_string(rest_S,x);
+
+
+
+ if (0x0030 /* 0 */ <= code && code <= 0x0039 /* 9 */) { + v = code - 0x0030 /* 0 */;
+ } else if (0x0041 /* A */ <= code && code <= 0x005A /* Z */) {
+ v = code - 0x0041 /* A */ + 10;
+ } else if (0x0061 /* a */ <= code && code <= 0x007A /* z */) {
+ v = code - 0x0061 /* a */ + 10;
+
+ } else if (0x0009 /* HT '\t' (horizontal tab) */ == code ||
+ 0x0020 /* SPACE */ == code) {
+
+ break;
+
+ } else {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityValNotValidNumber,
+ "%s: %d: Entity value is not valid number: %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+ }
+
+ if (v >= mode) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityValNotValidNumber,
+ "%s: %d: Entity value is not valid number: %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+ }
+
+ value *= mode;
+ value += v;
+
+ if (value > 0xFFFF) {
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityValTooBig,
+ "%s: %d: Entity value is too big: %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+
+ }
+ }
+
+ X = x;
+ break;
+
+ }
+
+ for (x = X; x < L; x++) {
+ code = give_unicode_from_string(rest_S,x);
+
+ if (0x0009 /* HT '\t' (horizontal tab) */ == code ||
+ 0x0020 /* SPACE */ == code) {
+
+ /* OK */
+ } else if (0x0023 /* # */ == code) {
+ break;
+ } else {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityValTarilinData,
+ "%s: %d: Entity value have trailing data: %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+ goto fail2;
+
+ }
+ }
+
+ for (y = 0; y < entity_types_count; y++) {
+ if (TAGFILTER_ENTITIES_magic != entity_types[y]->magic)
+ mime_panic(__FILE__,__LINE__,"read_tagfilter_entities", + "Bad magic number (tagfilter_entities)");
+
+ if (string_matches_ascii(entity_type,
+ cs2us(entity_types[y]->type_tag),0,
+ SMA_op_normal)) {
+ enttyp = entity_types[y];
+ break;
+ }
+ }
+
+ if (!enttyp) {
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeEntityTypeNotSup,
+ "%s: %d: Entity type %S not supported: %S"),
+ filename,lineno,entity_type,rest_S);
+ (*errors) ++;
+ goto fail2;
+ }
+
+ if (mode < octal_value && !value)
+ value = UNICODE_BAD_CHAR; /* REPLACEMENT CHARACTER */
+
+
+ ne_match_flags =
+ seen_semicolon ? ne_match_SEMICOLON : 0;
+
+ if (set_tagfilter_entity(filename,*conf,
+ named_reference,enttyp, entity_value, value,
+ lineno,ne_match_flags,read_entities,
+ &res_idx,&append_need_rewrite,
+ errors,rest_S,entity_type,set_old
+ )) {
+
+ /* Nothing */
+
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: set_tagfilter_entity failed\n"));
+ fail_it = 1;
+ }
+
+ if (append_need_rewrite && need_rewrite && !*need_rewrite) {
+ DPRINT(Debug,14,(&Debug,
+ "read_tagfilter_entities: Setting *need_rewrite\n"));
+ *need_rewrite = 1;
+ }
+
+ } else {
+ badline:
+
+
+ if (tagfilter_is_printableln(filename,lineno,rest_S))
+ lib_error(CATGETS(elm_msg_cat, MeSet,
+ MeUnsupportedLineS,
+ "%s: %d: Unsupported line: %S"),
+ filename,lineno,rest_S);
+ (*errors) ++;
+
+ DPRINT(Debug,9,(&Debug,
+ "read_tagfilter_entities: %s: %d: failed to parse line\n",
+ filename,lineno));
+ }
+
+ fail2:
+
+ if (entity_value)
+ free_string(&entity_value);
+ if (named_reference)
+ free_string(&named_reference);
+ if (entity_type)
+ free_string(&entity_type);
+ }
+
+ fail:
+
+ free_string(&rest_S);
+ }
+
+ if (buf)
+ free(buf);
+
+ if (fail_it)
+ ret_status = 0;
+ else if (feof(f) && (*conf)->root) {
+ size_t i;
+ size_t map_len = sort_list_len((*conf)->root);
+
+
+ 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__,"read_tagfilter_entities",
+ "Bad magic number (entity_sort_item)");
+
+ DPRINT(Debug,14,(&Debug,"read_tagfilter_entities: entity %zu = \"%S\"\n",
+ i,res.entity->reference_key));
+
+
+ if (res.entity->entities) {
+ size_t j;
+
+ for (j = 0; j < res.entity->entities_count; j++) {
+ const char * type = "???";
+
+ if (res.entity->entities[j].entity_type) {
+ if (TAGFILTER_ENTITIES_magic !=
+ res.entity->entities[j].entity_type->magic)
+ mime_panic(__FILE__,__LINE__,"read_tagfilter_entities",
+ "Bad magic number (tagfilter_entities)");
+ type = res.entity->entities[j].entity_type->type_tag;
+ }
+
+ DPRINT(Debug,14,(&Debug," : %zu %s",
+ j,type));
+
+ if (res.entity->entities[j].old) {
+ DPRINT(Debug,14,(&Debug,", old"));
+ }
+
+ if (res.entity->entities[j].delete) {
+ DPRINT(Debug,14,(&Debug,", marked for delete"));
+ }
+
+ if (res.entity->entities[j].need_on_disk) {
+ DPRINT(Debug,14,(&Debug,", not seen on disk"));
+
+ if (! res.entity->entities[j].need_on_disk) {
+ DPRINT(Debug,14,(&Debug," (marking for delete)"));
+
+ res.entity->entities[j].delete = 1;
+ }
+ }
+
+ DPRINT(Debug,14,(&Debug,"\n"));
+ }
+ }
+
+ free_entity_sort_item(&res);
+ }
+ }
+
+ ret_status = 1;
+ }
+
+ return ret_status;
+ }
+
+
+ struct tagfilter_entities_conf * parse_tagfilter_entities(filename,errors,fileset,propline,rc,
+ need_rewrite
+ )
+ const char *filename;
+ int *errors;
+ charset_t *fileset;
+ struct editor_propline **propline;
+ enum record_mode rc /* SYSTEM_RC = 0,
+ LOCAL_RC = 1 */;
+ int *need_rewrite;
+ {
+ struct tagfilter_entities_conf * ret = NULL;
+
+ int err = can_open(filename,"r");
+ FILE * f;
+
+ if (err) {
+ DPRINT(Debug,2,(&Debug,
+ "parse_tagfilter_entities=NULL: %s: %s (can_open)\n",
+ filename,strerror(err)));
+ return NULL;
+ }
+
+ f = fopen(filename,"r");
+ if (!f) {
+ err = errno;
+ DPRINT(Debug,2,(&Debug,
+ "parse_tagfilter_entities=NULL: %s: %s\n",
+ filename,strerror(err)));
+ return NULL;
+ }
+
+ if (read_tagfilter_entities(filename,f,&ret,
+ errors,fileset,propline,rc,need_rewrite)) {
+ fclose(f);
+
+ return ret;
+ }
+
+ if (ret)
+ free_tagfilter_entities_conf(&ret);
+
+ return ret;
+ }
+
+ static struct tagfilter_entities_conf * malloc_tagfilter_entities_conf(rc,filename,
+ alloc_size)
+ enum record_mode rc;
+ const char * filename;
+ size_t alloc_size;
+ {
+ struct tagfilter_entities_conf * ret = safe_zero_alloc(sizeof(*ret));
+
+ ret->magic = TAGFILTER_ENTITIES_CONF_magic;
+ ret->rc = rc;
+
+ ret->filename = NULL;
+ if (filename)
+ ret->filename = safe_strdup(filename);
+
+ ret->root = alloc_sort_list(&entity_map_operation,alloc_size);
+
+ ret->linked = 0;
+
+ return ret;
+ }
+
+ void free_tagfilter_entities_conf(ptr)
+ struct tagfilter_entities_conf **ptr;
+ {
+ if (TAGFILTER_ENTITIES_CONF_magic != (*ptr)->magic)
+ mime_panic(__FILE__,__LINE__,"free_tagfilter_entities_conf",
[continued in next message]
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)