void html_ul(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *al; /* dump_html_stack(html_context); */ par_format.list_level++; par_format.list_number = 0; par_format.flags = P_DISC; al = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp); if (al) { if (!c_strcasecmp((const char *)al, "disc")) par_format.flags = P_DISC; else if (!c_strcasecmp((const char *)al, "circle")) par_format.flags = P_O; else if (!c_strcasecmp((const char *)al, "square")) par_format.flags = P_SQUARE; mem_free(al); } par_format.leftmargin += 2 + (par_format.list_level > 1); if (!html_context->table_level) int_upper_bound(&par_format.leftmargin, par_format.width / 2); par_format.align = ALIGN_LEFT; html_top->type = ELEMENT_DONT_KILL; }
/* Returns the encoding specified by ENCODING, which must be in one of the forms described at the top of encoding-guesser.h. The returned string might be ENCODING itself or a suffix of it, or it might be a statically allocated string. */ const char * encoding_guess_parse_encoding (const char *encoding) { if (encoding == NULL || !c_strcasecmp (encoding, "auto") || !c_strcasecmp (encoding, "auto,locale") || !c_strcasecmp (encoding, "locale")) return locale_charset (); else if (!c_strncasecmp (encoding, "auto,", 5)) return encoding + 5; else return encoding; }
void html_button(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *al; struct form_control *fc; enum form_type type = FC_SUBMIT; int cp = html_context->doc_cp; html_focusable(html_context, a); al = get_attr_val(a, (unsigned char *)"type", cp); if (!al) goto no_type_attr; if (!c_strcasecmp((const char *)al, "button")) { type = FC_BUTTON; } else if (!c_strcasecmp((const char *)al, "reset")) { type = FC_RESET; } else if (c_strcasecmp((const char *)al, "submit")) { /* unknown type */ mem_free(al); return; } mem_free(al); no_type_attr: fc = init_form_control(type, a, html_context); if (!fc) return; fc->id = get_attr_val(a, (unsigned char *)"id", cp); fc->name = get_attr_val(a, (unsigned char *)"name", cp); fc->default_value = get_attr_val(a, (unsigned char *)"value", cp); if (!fc->default_value) { if (fc->type == FC_SUBMIT) fc->default_value = stracpy((const unsigned char *)"Submit"); else if (fc->type == FC_RESET) fc->default_value = stracpy((const unsigned char *)"Reset"); else if (fc->type == FC_BUTTON) fc->default_value = stracpy((const unsigned char *)"Button"); } if (!fc->default_value) fc->default_value = stracpy((const unsigned char *)""); html_context->special_f(html_context, SP_CONTROL, fc); format.form = fc; format.style.attr |= AT_BOLD; }
/* Canonicalize an encoding name. */ const char * po_charset_canonicalize (const char *charset) { /* The list of charsets supported by glibc's iconv() and by the portable iconv() across platforms. Taken from intl/config.charset. */ static const char *standard_charsets[] = { ascii, "ANSI_X3.4-1968", "US-ASCII", /* i = 0..2 */ "ISO-8859-1", "ISO_8859-1", /* i = 3, 4 */ "ISO-8859-2", "ISO_8859-2", "ISO-8859-3", "ISO_8859-3", "ISO-8859-4", "ISO_8859-4", "ISO-8859-5", "ISO_8859-5", "ISO-8859-6", "ISO_8859-6", "ISO-8859-7", "ISO_8859-7", "ISO-8859-8", "ISO_8859-8", "ISO-8859-9", "ISO_8859-9", "ISO-8859-13", "ISO_8859-13", "ISO-8859-14", "ISO_8859-14", "ISO-8859-15", "ISO_8859-15", /* i = 25, 26 */ "KOI8-R", "KOI8-U", "KOI8-T", "CP850", "CP866", "CP874", "CP932", "CP949", "CP950", "CP1250", "CP1251", "CP1252", "CP1253", "CP1254", "CP1255", "CP1256", "CP1257", "GB2312", "EUC-JP", "EUC-KR", "EUC-TW", "BIG5", "BIG5-HKSCS", "GBK", "GB18030", "SHIFT_JIS", "JOHAB", "TIS-620", "VISCII", "GEORGIAN-PS", utf8 }; size_t i; for (i = 0; i < SIZEOF (standard_charsets); i++) if (c_strcasecmp (charset, standard_charsets[i]) == 0) return standard_charsets[i < 3 ? 0 : i < 27 ? ((i - 3) & ~1) + 3 : i]; return NULL; }
void html_linebrk(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *al = get_attr_val(a, (unsigned char *)"align", html_context->doc_cp); if (al) { if (!c_strcasecmp((const char *)al, "left")) par_format.align = ALIGN_LEFT; else if (!c_strcasecmp((const char *)al, "right")) par_format.align = ALIGN_RIGHT; else if (!c_strcasecmp((const char *)al, "center")) { par_format.align = ALIGN_CENTER; if (!html_context->table_level) par_format.leftmargin = par_format.rightmargin = 0; } else if (!c_strcasecmp((const char *)al, "justify")) par_format.align = ALIGN_JUSTIFY; mem_free(al); } }
static widget_creation_function find_in_table (const char *type, const widget_creation_entry *table) { const widget_creation_entry* cur; for (cur = table; cur->type; cur++) if (!c_strcasecmp (type, cur->type)) return cur->function; return NULL; }
/* Parse a link and return results in @link. * It tries to identify known types. */ static int html_link_parse(struct html_context *html_context, unsigned char *a, struct hlink *link) { int i; assert(a && link); memset(link, 0, sizeof(*link)); link->href = get_url_val(a, (unsigned char *)"href", html_context->doc_cp); if (!link->href) return 0; link->lang = get_attr_val(a, (unsigned char *)"lang", html_context->doc_cp); link->hreflang = get_attr_val(a, (unsigned char *)"hreflang", html_context->doc_cp); link->title = get_attr_val(a, (unsigned char *)"title", html_context->doc_cp); link->content_type = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp); link->media = get_attr_val(a, (unsigned char *)"media", html_context->doc_cp); link->name = get_attr_val(a, (unsigned char *)"rel", html_context->doc_cp); if (link->name) { link->direction = LD_REL; } else { link->name = get_attr_val(a, (unsigned char *)"rev", html_context->doc_cp); if (link->name) link->direction = LD_REV; } if (!link->name) return 1; /* TODO: fastfind */ for (i = 0; lt_names[i].str; i++) if (!c_strcasecmp((const char *)link->name, (const char *)lt_names[i].str)) { link->type = lt_names[i].type; return 1; } if (c_strcasestr((const char *)link->name, "icon") || (link->content_type && c_strcasestr((const char *)link->content_type, "icon"))) { link->type = LT_ICON; } else if (c_strcasestr((const char *)link->name, "alternate")) { link->type = LT_ALTERNATE; if (link->lang) link->type = LT_ALTERNATE_LANG; else if (c_strcasestr((const char *)link->name, "stylesheet") || (link->content_type && c_strcasestr((const char *)link->content_type, "css"))) link->type = LT_ALTERNATE_STYLESHEET; else if (link->media) link->type = LT_ALTERNATE_MEDIA; } else if (link->content_type && c_strcasestr((const char *)link->content_type, "css")) { link->type = LT_STYLESHEET; } return 1; }
int name_to_language(const unsigned char *name) { int i; for (i = 0; languages[i].name; i++) { if (c_strcasecmp(languages[i].name, name)) continue; return i; } return 1; }
int compare_opt(struct document_options *o1, struct document_options *o2) { return memcmp(o1, o2, offsetof(struct document_options, framename)) || c_strcasecmp(o1->framename, o2->framename) || (o1->box.x != o2->box.x) || (o1->box.y != o2->box.y) || ((o1->needs_height || o2->needs_height) && o1->box.height != o2->box.height) || ((o1->needs_width || o2->needs_width) && o1->box.width != o2->box.width); }
char * str_iconveha (const char *src, const char *from_codeset, const char *to_codeset, bool transliterate, enum iconv_ilseq_handler handler) { if (*src == '\0' || c_strcasecmp (from_codeset, to_codeset) == 0) { char *result = strdup (src); if (result == NULL) errno = ENOMEM; return result; } /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, we want to use transliteration. */ #if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \ && !defined __UCLIBC__) \ || _LIBICONV_VERSION >= 0x0105 if (transliterate) { char *result; size_t len = strlen (to_codeset); char *to_codeset_suffixed = (char *) malloca (len + 10 + 1); memcpy (to_codeset_suffixed, to_codeset, len); memcpy (to_codeset_suffixed + len, "//TRANSLIT", 10 + 1); result = str_iconveha_notranslit (src, from_codeset, to_codeset_suffixed, handler); freea (to_codeset_suffixed); return result; } else #endif return str_iconveha_notranslit (src, from_codeset, to_codeset, handler); }
/* ToUnicode(). May realloc() utf8in. Will free utf8in unconditionally. */ static int idna_to_unicode_internal (char *utf8in, uint32_t * out, size_t * outlen, int flags) { int rc; char tmpout[64]; size_t utf8len = strlen (utf8in) + 1; size_t addlen = 0; /* * ToUnicode consists of the following steps: * * 1. If the sequence contains any code points outside the ASCII range * (0..7F) then proceed to step 2, otherwise skip to step 3. */ { size_t i; int inasciirange; inasciirange = 1; for (i = 0; utf8in[i]; i++) if (utf8in[i] & ~0x7F) inasciirange = 0; if (inasciirange) goto step3; } /* * 2. Perform the steps specified in [NAMEPREP] and fail if there is an * error. (If step 3 of ToASCII is also performed here, it will not * affect the overall behavior of ToUnicode, but it is not * necessary.) The AllowUnassigned flag is used in [NAMEPREP]. */ do { char *newp = realloc (utf8in, utf8len + addlen); if (newp == NULL) { free (utf8in); return IDNA_MALLOC_ERROR; } utf8in = newp; if (flags & IDNA_ALLOW_UNASSIGNED) rc = stringprep_nameprep (utf8in, utf8len + addlen); else rc = stringprep_nameprep_no_unassigned (utf8in, utf8len + addlen); addlen += 1; } while (rc == STRINGPREP_TOO_SMALL_BUFFER); if (rc != STRINGPREP_OK) { free (utf8in); return IDNA_STRINGPREP_ERROR; } /* 3. Verify that the sequence begins with the ACE prefix, and save a * copy of the sequence. * ... The ToASCII and ToUnicode operations MUST recognize the ACE prefix in a case-insensitive manner. */ step3: if (c_strncasecmp (utf8in, IDNA_ACE_PREFIX, strlen (IDNA_ACE_PREFIX)) != 0) { free (utf8in); return IDNA_NO_ACE_PREFIX; } /* 4. Remove the ACE prefix. */ memmove (utf8in, &utf8in[strlen (IDNA_ACE_PREFIX)], strlen (utf8in) - strlen (IDNA_ACE_PREFIX) + 1); /* 5. Decode the sequence using the decoding algorithm in [PUNYCODE] * and fail if there is an error. Save a copy of the result of * this step. */ (*outlen)--; /* reserve one for the zero */ rc = punycode_decode (strlen (utf8in), utf8in, outlen, out, NULL); if (rc != PUNYCODE_SUCCESS) { free (utf8in); return IDNA_PUNYCODE_ERROR; } out[*outlen] = 0; /* add zero */ /* 6. Apply ToASCII. */ rc = idna_to_ascii_4i (out, *outlen, tmpout, flags); if (rc != IDNA_SUCCESS) { free (utf8in); return rc; } /* 7. Verify that the result of step 6 matches the saved copy from * step 3, using a case-insensitive ASCII comparison. */ if (c_strcasecmp (utf8in, tmpout + strlen (IDNA_ACE_PREFIX)) != 0) { free (utf8in); return IDNA_ROUNDTRIP_VERIFY_ERROR; } /* 8. Return the saved copy from step 5. */ free (utf8in); return IDNA_SUCCESS; }
char * str_iconv (const char *src, const char *from_codeset, const char *to_codeset) { if (*src == '\0' || c_strcasecmp (from_codeset, to_codeset) == 0) { char *result = strdup (src); if (result == NULL) errno = ENOMEM; return result; } else { #if HAVE_ICONV iconv_t cd; char *result; /* Avoid glibc-2.1 bug with EUC-KR. */ # if (__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) && !defined _LIBICONV_VERSION if (c_strcasecmp (from_codeset, "EUC-KR") == 0 || c_strcasecmp (to_codeset, "EUC-KR") == 0) { errno = EINVAL; return NULL; } # endif cd = iconv_open (to_codeset, from_codeset); if (cd == (iconv_t) -1) return NULL; result = str_cd_iconv (src, cd); if (result == NULL) { /* Close cd, but preserve the errno from str_cd_iconv. */ int saved_errno = errno; iconv_close (cd); errno = saved_errno; } else { if (iconv_close (cd) < 0) { /* Return NULL, but free the allocated memory, and while doing that, preserve the errno from iconv_close. */ int saved_errno = errno; free (result); errno = saved_errno; return NULL; } } return result; #else /* This is a different error code than if iconv_open existed but didn't support from_codeset and to_codeset, so that the caller can emit an error message such as "iconv() is not supported. Installing GNU libiconv and then reinstalling this package would fix this." */ errno = ENOSYS; return NULL; #endif } }
static int cmp_names(const void *item, void *data) { return c_strcasecmp(item, data); }
const char * proper_name_utf8 (const char *name_ascii, const char *name_utf8) { /* See whether there is a translation. */ const char *translation = gettext (name_ascii); /* Try to convert NAME_UTF8 to the locale encoding. */ const char *locale_code = locale_charset (); char *alloc_name_converted = NULL; char *alloc_name_converted_translit = NULL; const char *name_converted = NULL; const char *name_converted_translit = NULL; const char *name; if (c_strcasecmp (locale_code, "UTF-8") != 0) { #if HAVE_ICONV name_converted = alloc_name_converted = xstr_iconv (name_utf8, "UTF-8", locale_code); # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ || _LIBICONV_VERSION >= 0x0105 { size_t len = strlen (locale_code); char *locale_code_translit = (char *) xmalloc (len + 10 + 1); memcpy (locale_code_translit, locale_code, len); memcpy (locale_code_translit + len, "//TRANSLIT", 10 + 1); name_converted_translit = alloc_name_converted_translit = xstr_iconv (name_utf8, "UTF-8", locale_code_translit); free (locale_code_translit); } # endif #endif } else { name_converted = name_utf8; name_converted_translit = name_utf8; } /* The name in locale encoding. */ name = (name_converted != NULL ? name_converted : name_converted_translit != NULL ? name_converted_translit : name_ascii); if (translation != name_ascii) { /* See whether the translation contains the original name. A multibyte-aware strstr() is not absolutely necessary here. */ if (c_strstr (translation, name_ascii) != NULL || (name_converted != NULL && strstr (translation, name_converted) != NULL) || (name_converted_translit != NULL && strstr (translation, name_converted_translit) != NULL)) { if (alloc_name_converted != NULL) free (alloc_name_converted); if (alloc_name_converted_translit != NULL) free (alloc_name_converted_translit); return translation; } else { /* Return "TRANSLATION (NAME)". */ char *result = (char *) xmalloc (strlen (translation) + 2 + strlen (name) + 1 + 1); sprintf (result, "%s (%s)", translation, name); if (alloc_name_converted != NULL) free (alloc_name_converted); if (alloc_name_converted_translit != NULL) free (alloc_name_converted_translit); return result; } } else { if (alloc_name_converted != NULL && alloc_name_converted != name) free (alloc_name_converted); if (alloc_name_converted_translit != NULL && alloc_name_converted_translit != name) free (alloc_name_converted_translit); return name; } }
static bool is_encoding_utf32 (const char *encoding) { return (!c_strcasecmp (encoding, "utf-32") || !c_strcasecmp (encoding, "utf32")); }
int iconveh_open (const char *to_codeset, const char *from_codeset, iconveh_t *cdp) { iconv_t cd; iconv_t cd1; iconv_t cd2; /* Avoid glibc-2.1 bug with EUC-KR. */ # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ <= 1) && !defined __UCLIBC__) \ && !defined _LIBICONV_VERSION if (c_strcasecmp (from_codeset, "EUC-KR") == 0 || c_strcasecmp (to_codeset, "EUC-KR") == 0) { errno = EINVAL; return -1; } # endif cd = iconv_open (to_codeset, from_codeset); if (STRCASEEQ (from_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0)) cd1 = (iconv_t)(-1); else { cd1 = iconv_open ("UTF-8", from_codeset); if (cd1 == (iconv_t)(-1)) { int saved_errno = errno; if (cd != (iconv_t)(-1)) iconv_close (cdp->cd); errno = saved_errno; return -1; } } if (STRCASEEQ (to_codeset, "UTF-8", 'U','T','F','-','8',0,0,0,0) # if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \ && !defined __UCLIBC__) \ || _LIBICONV_VERSION >= 0x0105 || c_strcasecmp (to_codeset, "UTF-8//TRANSLIT") == 0 # endif ) cd2 = (iconv_t)(-1); else { cd2 = iconv_open (to_codeset, "UTF-8"); if (cd2 == (iconv_t)(-1)) { int saved_errno = errno; if (cd1 != (iconv_t)(-1)) iconv_close (cd1); if (cd != (iconv_t)(-1)) iconv_close (cd); errno = saved_errno; return -1; } } cdp->cd = cd; cdp->cd1 = cd1; cdp->cd2 = cd2; return 0; }
/* Parse all the aggregate functions. */ static bool parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict, struct agr_proc *agr) { struct agr_var *tail; /* Tail of linked list starting at agr->vars. */ /* Parse everything. */ tail = NULL; for (;;) { char **dest; char **dest_label; size_t n_dest; struct string function_name; enum mv_class exclude; const struct agr_func *function; int func_index; union agr_argument arg[2]; const struct variable **src; size_t n_src; size_t i; dest = NULL; dest_label = NULL; n_dest = 0; src = NULL; function = NULL; n_src = 0; arg[0].c = NULL; arg[1].c = NULL; ds_init_empty (&function_name); /* Parse the list of target variables. */ while (!lex_match (lexer, T_EQUALS)) { size_t n_dest_prev = n_dest; if (!parse_DATA_LIST_vars (lexer, dict, &dest, &n_dest, (PV_APPEND | PV_SINGLE | PV_NO_SCRATCH | PV_NO_DUPLICATE))) goto error; /* Assign empty labels. */ { int j; dest_label = xnrealloc (dest_label, n_dest, sizeof *dest_label); for (j = n_dest_prev; j < n_dest; j++) dest_label[j] = NULL; } if (lex_is_string (lexer)) { dest_label[n_dest - 1] = xstrdup (lex_tokcstr (lexer)); lex_get (lexer); } } /* Get the name of the aggregation function. */ if (lex_token (lexer) != T_ID) { lex_error (lexer, _("expecting aggregation function")); goto error; } ds_assign_substring (&function_name, lex_tokss (lexer)); exclude = ds_chomp_byte (&function_name, '.') ? MV_SYSTEM : MV_ANY; for (function = agr_func_tab; function->name; function++) if (!c_strcasecmp (function->name, ds_cstr (&function_name))) break; if (NULL == function->name) { msg (SE, _("Unknown aggregation function %s."), ds_cstr (&function_name)); goto error; } ds_destroy (&function_name); func_index = function - agr_func_tab; lex_get (lexer); /* Check for leading lparen. */ if (!lex_match (lexer, T_LPAREN)) { if (function->src_vars == AGR_SV_YES) { lex_force_match (lexer, T_LPAREN); goto error; } } else { /* Parse list of source variables. */ { int pv_opts = PV_NO_SCRATCH; if (func_index == SUM || func_index == MEAN || func_index == SD) pv_opts |= PV_NUMERIC; else if (function->n_args) pv_opts |= PV_SAME_TYPE; if (!parse_variables_const (lexer, dict, &src, &n_src, pv_opts)) goto error; } /* Parse function arguments, for those functions that require arguments. */ if (function->n_args != 0) for (i = 0; i < function->n_args; i++) { int type; lex_match (lexer, T_COMMA); if (lex_is_string (lexer)) { arg[i].c = recode_string (dict_get_encoding (agr->dict), "UTF-8", lex_tokcstr (lexer), -1); type = VAL_STRING; } else if (lex_is_number (lexer)) { arg[i].f = lex_tokval (lexer); type = VAL_NUMERIC; } else { msg (SE, _("Missing argument %zu to %s."), i + 1, function->name); goto error; } lex_get (lexer); if (type != var_get_type (src[0])) { msg (SE, _("Arguments to %s must be of same type as " "source variables."), function->name); goto error; } } /* Trailing rparen. */ if (!lex_force_match (lexer, T_RPAREN)) goto error; /* Now check that the number of source variables match the number of target variables. If we check earlier than this, the user can get very misleading error message, i.e. `AGGREGATE x=SUM(y t).' will get this error message when a proper message would be more like `unknown variable t'. */ if (n_src != n_dest) { msg (SE, _("Number of source variables (%zu) does not match " "number of target variables (%zu)."), n_src, n_dest); goto error; } if ((func_index == PIN || func_index == POUT || func_index == FIN || func_index == FOUT) && (var_is_numeric (src[0]) ? arg[0].f > arg[1].f : str_compare_rpad (arg[0].c, arg[1].c) > 0)) { union agr_argument t = arg[0]; arg[0] = arg[1]; arg[1] = t; msg (SW, _("The value arguments passed to the %s function " "are out-of-order. They will be treated as if " "they had been specified in the correct order."), function->name); } } /* Finally add these to the linked list of aggregation variables. */ for (i = 0; i < n_dest; i++) { struct agr_var *v = xzalloc (sizeof *v); /* Add variable to chain. */ if (agr->agr_vars != NULL) tail->next = v; else agr->agr_vars = v; tail = v; tail->next = NULL; v->moments = NULL; /* Create the target variable in the aggregate dictionary. */ { struct variable *destvar; v->function = func_index; if (src) { v->src = src[i]; if (var_is_alpha (src[i])) { v->function |= FSTRING; v->string = xmalloc (var_get_width (src[i])); } if (function->alpha_type == VAL_STRING) destvar = dict_clone_var_as (agr->dict, v->src, dest[i]); else { assert (var_is_numeric (v->src) || function->alpha_type == VAL_NUMERIC); destvar = dict_create_var (agr->dict, dest[i], 0); if (destvar != NULL) { struct fmt_spec f; if ((func_index == N || func_index == NMISS) && dict_get_weight (dict) != NULL) f = fmt_for_output (FMT_F, 8, 2); else f = function->format; var_set_both_formats (destvar, &f); } } } else { struct fmt_spec f; v->src = NULL; destvar = dict_create_var (agr->dict, dest[i], 0); if (destvar != NULL) { if ((func_index == N || func_index == NMISS) && dict_get_weight (dict) != NULL) f = fmt_for_output (FMT_F, 8, 2); else f = function->format; var_set_both_formats (destvar, &f); } } if (!destvar) { msg (SE, _("Variable name %s is not unique within the " "aggregate file dictionary, which contains " "the aggregate variables and the break " "variables."), dest[i]); goto error; } free (dest[i]); if (dest_label[i]) var_set_label (destvar, dest_label[i]); v->dest = destvar; } v->exclude = exclude; if (v->src != NULL) { int j; if (var_is_numeric (v->src)) for (j = 0; j < function->n_args; j++) v->arg[j].f = arg[j].f; else for (j = 0; j < function->n_args; j++) v->arg[j].c = xstrdup (arg[j].c); } } if (src != NULL && var_is_alpha (src[0])) for (i = 0; i < function->n_args; i++) { free (arg[i].c); arg[i].c = NULL; } free (src); free (dest); free (dest_label); if (!lex_match (lexer, T_SLASH)) { if (lex_token (lexer) == T_ENDCMD) return true; lex_error (lexer, "expecting end of command"); return false; } continue; error: ds_destroy (&function_name); for (i = 0; i < n_dest; i++) { free (dest[i]); free (dest_label[i]); } free (dest); free (dest_label); free (arg[0].c); free (arg[1].c); if (src && n_src && var_is_alpha (src[0])) for (i = 0; i < function->n_args; i++) { free (arg[i].c); arg[i].c = NULL; } free (src); return false; } }
void html_input(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *al; struct form_control *fc; int cp = html_context->doc_cp; fc = init_form_control(FC_TEXT, a, html_context); if (!fc) return; al = get_attr_val(a, (unsigned char *)"type", cp); if (al) { if (!c_strcasecmp((const char *)al, "text")) fc->type = FC_TEXT; else if (!c_strcasecmp((const char *)al, "hidden")) fc->type = FC_HIDDEN; else if (!c_strcasecmp((const char *)al, "button")) fc->type = FC_BUTTON; else if (!c_strcasecmp((const char *)al, "checkbox")) fc->type = FC_CHECKBOX; else if (!c_strcasecmp((const char *)al, "radio")) fc->type = FC_RADIO; else if (!c_strcasecmp((const char *)al, "password")) fc->type = FC_PASSWORD; else if (!c_strcasecmp((const char *)al, "submit")) fc->type = FC_SUBMIT; else if (!c_strcasecmp((const char *)al, "reset")) fc->type = FC_RESET; else if (!c_strcasecmp((const char *)al, "file")) fc->type = FC_FILE; else if (!c_strcasecmp((const char *)al, "image")) fc->type = FC_IMAGE; /* else unknown type, let it default to FC_TEXT. */ mem_free(al); } if (fc->type == FC_HIDDEN) fc->default_value = get_lit_attr_val(a, (unsigned char *)"value", cp); else if (fc->type != FC_FILE) fc->default_value = get_attr_val(a, (unsigned char *)"value", cp); if (!fc->default_value) { if (fc->type == FC_CHECKBOX) fc->default_value = stracpy((const unsigned char *)"on"); else if (fc->type == FC_SUBMIT) fc->default_value = stracpy((const unsigned char *)"Submit"); else if (fc->type == FC_RESET) fc->default_value = stracpy((const unsigned char *)"Reset"); else if (fc->type == FC_BUTTON) fc->default_value = stracpy((const unsigned char *)"Button"); } if (!fc->default_value) fc->default_value = stracpy((const unsigned char *)""); fc->id = get_attr_val(a, (unsigned char *)"id", cp); fc->name = get_attr_val(a, (unsigned char *)"name", cp); fc->size = get_num(a, (unsigned char *)"size", cp); if (fc->size == -1) fc->size = html_context->options->default_form_input_size; fc->size++; if (fc->size > html_context->options->box.width) fc->size = html_context->options->box.width; fc->maxlength = get_num(a, (unsigned char *)"maxlength", cp); if (fc->maxlength == -1) fc->maxlength = INT_MAX; if (fc->type == FC_CHECKBOX || fc->type == FC_RADIO) fc->default_state = has_attr(a, (unsigned char *)"checked", cp); if (fc->type == FC_IMAGE) fc->alt = get_attr_val(a, (unsigned char *)"alt", cp); if (fc->type != FC_HIDDEN) { html_input_format(html_context, a, fc); } html_context->special_f(html_context, SP_CONTROL, fc); }
static int alias_compare(const struct alias_map *map1, const struct alias_map *map2) { return c_strcasecmp(map1->alias, map2->alias); }
void html_textarea(struct html_context *html_context, unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end) { struct form_control *fc; unsigned char *p, *t_name, *wrap_attr; int t_namelen; int cols, rows; int i; html_focusable(html_context, attr); while (html < eof && (*html == '\n' || *html == '\r')) html++; p = html; while (p < eof && *p != '<') { pp: p++; } if (p >= eof) { *end = eof; return; } if (parse_element(p, eof, &t_name, &t_namelen, NULL, end)) goto pp; if (c_strlcasecmp(t_name, t_namelen, (const unsigned char *)"/TEXTAREA", 9)) goto pp; fc = init_form_control(FC_TEXTAREA, attr, html_context); if (!fc) return; fc->id = get_attr_val(attr, (unsigned char *)"id", html_context->doc_cp); fc->name = get_attr_val(attr, (unsigned char *)"name", html_context->doc_cp); fc->default_value = convert_string(NULL, html, p - html, html_context->doc_cp, CSM_DEFAULT, NULL, NULL, NULL); for (p = fc->default_value; p && p[0]; p++) { /* FIXME: We don't cope well with entities here. Bugzilla uses * inside of textarea and we fail miserably upon that * one. --pasky */ if (p[0] == '\r') { if (p[1] == '\n' || (p > fc->default_value && p[-1] == '\n')) { memmove(p, p + 1, strlen((const char *)p)); p--; } else { p[0] = '\n'; } } } cols = get_num(attr, (unsigned char *)"cols", html_context->doc_cp); if (cols <= 0) cols = html_context->options->default_form_input_size; cols++; /* Add 1 column, other browsers may have different behavior here (mozilla adds 2) --Zas */ if (cols > html_context->options->box.width) cols = html_context->options->box.width; fc->cols = cols; rows = get_num(attr, (unsigned char *)"rows", html_context->doc_cp); if (rows <= 0) rows = 1; if (rows > html_context->options->box.height) rows = html_context->options->box.height; fc->rows = rows; html_context->options->needs_height = 1; wrap_attr = get_attr_val(attr, (unsigned char *)"wrap", html_context->doc_cp); if (wrap_attr) { if (!c_strcasecmp((const char *)wrap_attr, "hard") || !c_strcasecmp((const char *)wrap_attr, "physical")) { fc->wrap = FORM_WRAP_HARD; } else if (!c_strcasecmp((const char *)wrap_attr, "soft") || !c_strcasecmp((const char *)wrap_attr, "virtual")) { fc->wrap = FORM_WRAP_SOFT; } else if (!c_strcasecmp((const char *)wrap_attr, "none") || !c_strcasecmp((const char *)wrap_attr, "off")) { fc->wrap = FORM_WRAP_NONE; } mem_free(wrap_attr); } else if (has_attr(attr, (unsigned char *)"nowrap", html_context->doc_cp)) { fc->wrap = FORM_WRAP_NONE; } else { fc->wrap = FORM_WRAP_SOFT; } fc->maxlength = get_num(attr, (unsigned char *)"maxlength", html_context->doc_cp); if (fc->maxlength == -1) fc->maxlength = INT_MAX; if (rows > 1) ln_break(html_context, 1); else put_chrs(html_context, (unsigned char *)" ", 1); html_stack_dup(html_context, ELEMENT_KILLABLE); format.form = fc; format.style.attr |= AT_BOLD; for (i = 0; i < rows; i++) { int j; for (j = 0; j < cols; j++) put_chrs(html_context, (unsigned char *)"_", 1); if (i < rows - 1) ln_break(html_context, 1); } pop_html_element(html_context); if (rows > 1) ln_break(html_context, 1); else put_chrs(html_context, (unsigned char *)" ", 1); html_context->special_f(html_context, SP_CONTROL, fc); }
void html_form(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { unsigned char *al; struct form *form; html_context->was_br = 1; form = init_form(); if (!form) return; form->method = FORM_METHOD_GET; form->form_num = a - html_context->startf; al = get_attr_val(a, (unsigned char *)"method", html_context->doc_cp); if (al) { if (!c_strcasecmp((const char *)al, "post")) { unsigned char *enctype; enctype = get_attr_val(a, (unsigned char *)"enctype", html_context->doc_cp); form->method = FORM_METHOD_POST; if (enctype) { if (!c_strcasecmp((const char *)enctype, "multipart/form-data")) form->method = FORM_METHOD_POST_MP; else if (!c_strcasecmp((const char *)enctype, "text/plain")) form->method = FORM_METHOD_POST_TEXT_PLAIN; mem_free(enctype); } } mem_free(al); } form->onsubmit = get_attr_val(a, (unsigned char *)"onsubmit", html_context->doc_cp); al = get_attr_val(a, (unsigned char *)"name", html_context->doc_cp); if (al) form->name = al; al = get_attr_val(a, (unsigned char *)"action", html_context->doc_cp); /* The HTML specification at * http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.3 states * that the behavior of an empty action attribute should be undefined. * Mozilla handles action="" as action="<current-URI>" which seems * reasonable. (bug 615) */ if (al && *al) { form->action = join_urls(html_context->base_href, trim_chars(al, ' ', NULL)); mem_free(al); } else { enum uri_component components = URI_ORIGINAL; mem_free_if(al); /* We have to do following for GET method, because we would end * up with two '?' otherwise. */ if (form->method == FORM_METHOD_GET) components = URI_FORM_GET; form->action = get_uri_string(html_context->base_href, components); /* No action URI should contain post data */ assert(!form->action || !strchr((char *)form->action, POST_CHAR)); /* GET method URIs should not have '?'. */ assert(!form->action || form->method != FORM_METHOD_GET || !strchr((char *)form->action, '?')); } al = get_target(html_context->options, a); form->target = al ? al : stracpy(html_context->base_target); html_context->special_f(html_context, SP_FORM, form); }
int main (int argc, char *argv[]) { if (argc > 1) { /* configure should already have checked that the locale is supported. */ if (setlocale (LC_ALL, "") == NULL) return 1; } ASSERT (c_strcasecmp ("paragraph", "Paragraph") == 0); ASSERT (c_strcasecmp ("paragrapH", "parAgRaph") == 0); ASSERT (c_strcasecmp ("paragraph", "paraLyzed") < 0); ASSERT (c_strcasecmp ("paraLyzed", "paragraph") > 0); ASSERT (c_strcasecmp ("para", "paragraph") < 0); ASSERT (c_strcasecmp ("paragraph", "para") > 0); /* The following tests shows how c_strcasecmp() is different from strcasecmp(). */ ASSERT (c_strcasecmp ("\311mile", "\351mile") < 0); ASSERT (c_strcasecmp ("\351mile", "\311mile") > 0); /* The following tests shows how c_strcasecmp() is different from mbscasecmp(). */ ASSERT (c_strcasecmp ("\303\266zg\303\274r", "\303\226ZG\303\234R") > 0); /* özgür */ ASSERT (c_strcasecmp ("\303\226ZG\303\234R", "\303\266zg\303\274r") < 0); /* özgür */ /* This test shows how strings of different size cannot compare equal. */ ASSERT (c_strcasecmp ("turkish", "TURK\304\260SH") < 0); ASSERT (c_strcasecmp ("TURK\304\260SH", "turkish") > 0); return 0; }
void html_link(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { int link_display = html_context->options->meta_link_display; unsigned char *name; struct hlink link; struct string text; int name_neq_title = 0; int first = 1; #ifndef CONFIG_CSS if (!link_display) return; #endif if (!html_link_parse(html_context, a, &link)) return; if (!link.href) goto free_and_return; #ifdef CONFIG_CSS if (link.type == LT_STYLESHEET && supports_html_media_attr(link.media)) { int len = strlen((const char *)link.href); import_css_stylesheet(&html_context->css_styles, html_context->base_href, link.href, len); } if (!link_display) goto free_and_return; #endif /* Ignore few annoying links.. */ if (link_display < 5 && (link.type == LT_ICON || link.type == LT_AUTHOR || link.type == LT_STYLESHEET || link.type == LT_ALTERNATE_STYLESHEET)) goto free_and_return; if (!link.name || link.type != LT_UNKNOWN) /* Give preference to our default names for known types. */ name = get_lt_default_name(&link); else name = link.name; if (!name) goto free_and_return; if (!init_string(&text)) goto free_and_return; html_focusable(html_context, a); if (link.title) { add_to_string(&text, link.title); name_neq_title = strcmp((const char *)link.title, (const char *)name); } else add_to_string(&text, name); if (link_display == 1) goto put_link_line; /* Only title */ #define APPEND(what) do { \ add_to_string(&text, first ? (const unsigned char *)" (" : (const unsigned char *)", "); \ add_to_string(&text, (what)); \ first = 0; \ } while (0) if (name_neq_title) { APPEND(name); } if (link_display >= 3 && link.hreflang) { APPEND(link.hreflang); } if (link_display >= 4 && link.content_type) { APPEND(link.content_type); } if (link.lang && link.type == LT_ALTERNATE_LANG && (link_display < 3 || (link.hreflang && c_strcasecmp((const char *)link.hreflang, (const char *)link.lang)))) { APPEND(link.lang); } if (link.media) { APPEND(link.media); } #undef APPEND if (!first) add_char_to_string(&text, ')'); put_link_line: { unsigned char *prefix = (link.direction == LD_REL) ? (unsigned char *)"Link: " : (unsigned char *)"Reverse link: "; unsigned char *link_name = (text.length) ? text.source : name; put_link_line(prefix, link_name, link.href, html_context->base_target, html_context); if (text.source) done_string(&text); } free_and_return: html_link_clear(&link); }
iconv_t rpl_iconv_open (const char *tocode, const char *fromcode) #undef iconv_open { char fromcode_upper[32]; char tocode_upper[32]; char *fromcode_upper_end; char *tocode_upper_end; #if REPLACE_ICONV_UTF /* Special handling of conversion between UTF-8 and UTF-{16,32}{BE,LE}. Do this here, before calling the real iconv_open(), because OSF/1 5.1 iconv() to these encoding inserts a BOM, which is wrong. We do not need to handle conversion between arbitrary encodings and UTF-{16,32}{BE,LE}, because the 'striconveh' module implements two-step conversion through UTF-8. The _ICONV_* constants are chosen to be disjoint from any iconv_t returned by the system's iconv_open() functions. Recall that iconv_t is a scalar type. */ if (c_toupper (fromcode[0]) == 'U' && c_toupper (fromcode[1]) == 'T' && c_toupper (fromcode[2]) == 'F' && fromcode[3] == '-') { if (c_toupper (tocode[0]) == 'U' && c_toupper (tocode[1]) == 'T' && c_toupper (tocode[2]) == 'F' && tocode[3] == '-') { if (strcmp (fromcode + 4, "8") == 0) { if (c_strcasecmp (tocode + 4, "16BE") == 0) return _ICONV_UTF8_UTF16BE; if (c_strcasecmp (tocode + 4, "16LE") == 0) return _ICONV_UTF8_UTF16LE; if (c_strcasecmp (tocode + 4, "32BE") == 0) return _ICONV_UTF8_UTF32BE; if (c_strcasecmp (tocode + 4, "32LE") == 0) return _ICONV_UTF8_UTF32LE; } else if (strcmp (tocode + 4, "8") == 0) { if (c_strcasecmp (fromcode + 4, "16BE") == 0) return _ICONV_UTF16BE_UTF8; if (c_strcasecmp (fromcode + 4, "16LE") == 0) return _ICONV_UTF16LE_UTF8; if (c_strcasecmp (fromcode + 4, "32BE") == 0) return _ICONV_UTF32BE_UTF8; if (c_strcasecmp (fromcode + 4, "32LE") == 0) return _ICONV_UTF32LE_UTF8; } } } #endif /* Do *not* add special support for 8-bit encodings like ASCII or ISO-8859-1 here. This would lead to programs that work in some locales (such as the "C" or "en_US" locales) but do not work in East Asian locales. It is better if programmers make their programs depend on GNU libiconv (except on glibc systems), e.g. by using the AM_ICONV macro and documenting the dependency in an INSTALL or DEPENDENCIES file. */ /* Try with the original names first. This covers the case when fromcode or tocode is a lowercase encoding name that is understood by the system's iconv_open but not listed in our mappings table. */ { iconv_t cd = iconv_open (tocode, fromcode); if (cd != (iconv_t)(-1)) return cd; } /* Convert the encodings to upper case, because 1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case matters, 2. it makes searching in the table faster. */ { const char *p = fromcode; char *q = fromcode_upper; while ((*q = c_toupper (*p)) != '\0') { p++; q++; if (q == &fromcode_upper[SIZEOF (fromcode_upper)]) { errno = EINVAL; return (iconv_t)(-1); } } fromcode_upper_end = q; } { const char *p = tocode; char *q = tocode_upper; while ((*q = c_toupper (*p)) != '\0') { p++; q++; if (q == &tocode_upper[SIZEOF (tocode_upper)]) { errno = EINVAL; return (iconv_t)(-1); } } tocode_upper_end = q; } #ifdef ICONV_FLAVOR /* Apply the mappings. */ { const struct mapping *m = mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper); fromcode = (m != NULL ? m->vendor_name : fromcode_upper); } { const struct mapping *m = mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper); tocode = (m != NULL ? m->vendor_name : tocode_upper); } #else fromcode = fromcode_upper; tocode = tocode_upper; #endif return iconv_open (tocode, fromcode); }
void html_script(struct html_context *html_context, unsigned char *a, unsigned char *html, unsigned char *eof, unsigned char **end) { #ifdef CONFIG_ECMASCRIPT /* TODO: <noscript> processing. Well, same considerations apply as to * CSS property display: none processing. */ /* TODO: Charsets for external scripts. */ unsigned char *type, *language, *src; int in_comment = 0; #endif html_skip(html_context, a); #ifdef CONFIG_ECMASCRIPT /* We try to process nested <script> if we didn't process the parent * one. That's why's all the fuzz. */ /* Ref: * http://www.ietf.org/internet-drafts/draft-hoehrmann-script-types-03.txt */ type = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp); if (type) { unsigned char *pos = type; if (!c_strncasecmp((const char *)type, "text/", 5)) { pos += 5; } else if (!c_strncasecmp((const char *)type, "application/", 12)) { pos += 12; } else { mem_free(type); not_processed: /* Permit nested scripts and retreat. */ html_top->invisible++; return; } if (!c_strncasecmp((const char *)pos, "javascript", 10)) { int len = strlen((const char *)pos); if (len > 10 && !isdigit(pos[10])) { mem_free(type); goto not_processed; } } else if (c_strcasecmp((const char *)pos, "ecmascript") && c_strcasecmp((const char *)pos, "jscript") && c_strcasecmp((const char *)pos, "livescript") && c_strcasecmp((const char *)pos, "x-javascript") && c_strcasecmp((const char *)pos, "x-ecmascript")) { mem_free(type); goto not_processed; } mem_free(type); } /* Check that the script content is ecmascript. The value of the * language attribute can be JavaScript with optional version digits * postfixed (like: ``JavaScript1.1''). * That attribute is deprecated in favor of type by HTML 4.01 */ language = get_attr_val(a, (unsigned char *)"language", html_context->doc_cp); if (language) { int languagelen = strlen((const char *)language); if (languagelen < 10 || (languagelen > 10 && !isdigit(language[10])) || c_strncasecmp((const char *)language, "javascript", 10)) { mem_free(language); html_top->invisible++; return; //goto not_processed; } mem_free(language); } if (html_context->part->document && (src = get_attr_val(a, (unsigned char *)"src", html_context->doc_cp))) { /* External reference. */ unsigned char *import_url; struct uri *uri; if (!get_opt_bool((const unsigned char *)"ecmascript.enable", NULL)) { mem_free(src); html_top->invisible++; return; //goto not_processed; } /* HTML <head> urls should already be fine but we can.t detect them. */ import_url = join_urls(html_context->base_href, src); mem_free(src); if (!import_url) goto imported; uri = get_uri(import_url, URI_BASE); if (!uri) goto imported; /* Request the imported script as part of the document ... */ html_context->special_f(html_context, SP_SCRIPT, uri); done_uri(uri); /* Create URL reference onload snippet. */ insert_in_string(&import_url, 0, (const unsigned char *)"^", 1); add_to_string_list(&html_context->part->document->onload_snippets, import_url, -1); imported: /* Retreat. Do not permit nested scripts, tho'. */ if (import_url) mem_free(import_url); return; } /* Positive, grab the rest and interpret it. */ /* First position to the real script start. */ while (html < eof && *html <= ' ') html++; if (eof - html > 4 && !strncmp((const char *)html, "<!--", 4)) { in_comment = 1; /* We either skip to the end of line or to -->. */ for (; *html != '\n' && *html != '\r' && eof - html >= 3; html++) { if (!strncmp((const char *)html, "-->", 3)) { /* This means the document is probably broken. * We will now try to process the rest of * <script> contents, which is however likely * to be empty. Should we try to process the * comment too? Currently it seems safer but * less tolerant to broken pages, if there are * any like this. */ html += 3; in_comment = 0; break; } } } *end = html; /* Now look ahead for the script end. The <script> contents is raw * CDATA, so we just look for the ending tag and need not care for * any quote marks counting etc - YET, we are more tolerant and permit * </script> stuff inside of the script if the whole <script> element * contents is wrapped in a comment. See i.e. Mozilla bug 26857 for fun * reading regarding this. */ for (; *end < eof; (*end)++) { unsigned char *name; int namelen; if (in_comment) { /* TODO: If we ever get some standards-quirk mode * distinction, this should be disabled in the * standards mode (and we should just look for CDATA * end, which is "</"). --pasky */ if (eof - *end >= 3 && !strncmp((const char *)*end, "-->", 3)) { /* Next iteration will jump passed the ending '>' */ (*end) += 2; in_comment = 0; } continue; /* XXX: Scan for another comment? That's admittelly * already stretching things a little bit to an * extreme ;-). */ } if (**end != '<') continue; /* We want to land before the closing element, that's why we * don't pass @end also as the appropriate parse_element() * argument. */ if (parse_element(*end, eof, &name, &namelen, NULL, NULL)) continue; if (c_strlcasecmp(name, namelen, (const unsigned char *)"/script", 7)) continue; /* We have won! */ break; } if (*end >= eof) { /* Either the document is not completely loaded yet or it's * broken. At any rate, run away screaming. */ *end = eof; /* Just for sanity. */ return; } if (html_context->part->document && *html != '^') { add_to_string_list(&html_context->part->document->onload_snippets, html, *end - html); } #endif }