/******************************************************************** * FUNCTION parse_alias * * Parse a string into its components * * INPUTS: * parmstr == parameter string to parse * namelen == address of return name length * valstr == address of return value string pointer * * OUTPUTS: * *namelen == return name length * *valstr == return value string pointer (NULL if no value) * * RETURNS: * status *********************************************************************/ static status_t parse_alias (const xmlChar *parmstr, uint32 *namelen, const xmlChar **valstr) { const xmlChar *p; boolean done; *namelen = 0; *valstr = NULL; /* check string for OK chars */ p = parmstr; while (*p) { if (*p == '\n' || *p == '\t') { ; // just skip this char; TBD: config param for this } else if (!isprint((int)*p)) { return ERR_NCX_INVALID_VALUE; } p++; } /* look for end of name */ p = parmstr; if (!ncx_valid_fname_ch(*p++)) { return ERR_NCX_INVALID_NAME; } done = FALSE; while (*p && !done) { if (*p == '=') { done = TRUE; } else if (!ncx_valid_name_ch(*p)) { return ERR_NCX_INVALID_NAME; } else { p++; } } /* set output parms */ *namelen = (uint32)(p - parmstr); if (done) { /* stopped at equals sign; check next char OK */ if (p[1] == 0 || xml_isspace(p[1])) { return ERR_NCX_INVALID_VALUE; } *valstr = &p[1]; } /* else stopped at end of valid name string */ return NO_ERR; } /* parse_alias */
/******************************************************************** * FUNCTION expand_alias * * Check if the first token is an alias name * If so, construct a new command line with the alias contents * * INPUT: * line == command line to check and possibly convert * res == address of return status * * OUTPUTS: * *res == return status (ERR_NCX_SKIPPED if nothing done) * * RETURNS: * pointer to malloced command string if *res==NO_ERR * NULL if *res==ERR_NCX_SKIPPED or some real error *********************************************************************/ xmlChar * expand_alias (xmlChar *line, status_t *res) { xmlChar *start, *p = line, *newline; alias_cb_t *alias; uint32 namelen, newlen; boolean done = FALSE; /* skip any leading whitespace; not expected from yangcli */ while (*p && xml_isspace(*p)) { p++; } if (*p == 0) { *res = ERR_NCX_SKIPPED; return NULL; } /* look for end of name */ start = p; if (!ncx_valid_fname_ch(*p++)) { *res = ERR_NCX_SKIPPED; return NULL; } while (*p && !done) { if (xml_isspace(*p)) { done = TRUE; } else if (!ncx_valid_name_ch(*p)) { *res = ERR_NCX_SKIPPED; return NULL; } else { p++; } } /* look for the alias */ namelen = (uint32)(p - start); alias = find_alias(start, namelen); if (alias == NULL) { *res = ERR_NCX_SKIPPED; return NULL; } /* replace the alias name with its contents and make a new string */ if (alias->value) { newlen = xml_strlen(p) + xml_strlen(alias->value); } else { newlen = xml_strlen(p); } newline = m__getMem(newlen + 1); if (newline == NULL) { *res = ERR_INTERNAL_MEM; return NULL; } start = newline; if (alias->value) { start += xml_strcpy(start, alias->value); } xml_strcpy(start, p); if (LOGDEBUG2) { log_debug2("\nExpanded alias '%s'; new line: '%s'", alias->name, newline); } *res = NO_ERR; return newline; } /* expand_alias */
/** * pango_parse_markup: * @markup_text: markup to parse (see <link linkend="PangoMarkupFormat">markup format</link>) * @length: length of @markup_text, or -1 if nul-terminated * @accel_marker: character that precedes an accelerator, or 0 for none * @attr_list: address of return location for a #PangoAttrList, or %NULL * @text: address of return location for text with tags stripped, or %NULL * @accel_char: address of return location for accelerator char, or %NULL * @error: address of return location for errors, or %NULL * * Parses marked-up text (see * <link linkend="PangoMarkupFormat">markup format</link>) to create * a plain-text string and an attribute list. * * If @accel_marker is nonzero, the given character will mark the * character following it as an accelerator. For example, @accel_marker * might be an ampersand or underscore. All characters marked * as an accelerator will receive a %PANGO_UNDERLINE_LOW attribute, * and the first character so marked will be returned in @accel_char. * Two @accel_marker characters following each other produce a single * literal @accel_marker character. * * If any error happens, none of the output arguments are touched except * for @error. * * Return value: %FALSE if @error is set, otherwise %TRUE **/ gboolean pango_parse_markup (const char *markup_text, int length, gunichar accel_marker, PangoAttrList **attr_list, char **text, gunichar *accel_char, GError **error) { GMarkupParseContext *context = NULL; MarkupData *md = NULL; gboolean needs_root = TRUE; GSList *tmp_list; const char *p; const char *end; g_return_val_if_fail (markup_text != NULL, FALSE); md = g_slice_new (MarkupData); /* Don't bother creating these if they weren't requested; * might be useful e.g. if you just want to validate * some markup. */ if (attr_list) md->attr_list = pango_attr_list_new (); else md->attr_list = NULL; md->text = g_string_new (NULL); if (accel_char) *accel_char = 0; md->accel_marker = accel_marker; md->accel_char = 0; md->index = 0; md->tag_stack = NULL; md->to_apply = NULL; context = g_markup_parse_context_new (&pango_markup_parser, 0, md, NULL); if (length < 0) length = strlen (markup_text); p = markup_text; end = markup_text + length; while (p != end && xml_isspace (*p)) ++p; if (end - p >= 8 && strncmp (p, "<markup>", 8) == 0) needs_root = FALSE; if (needs_root) if (!g_markup_parse_context_parse (context, "<markup>", -1, error)) goto error; if (!g_markup_parse_context_parse (context, markup_text, length, error)) goto error; if (needs_root) if (!g_markup_parse_context_parse (context, "</markup>", -1, error)) goto error; if (!g_markup_parse_context_end_parse (context, error)) goto error; g_markup_parse_context_free (context); if (md->attr_list) { /* The apply list has the most-recently-closed tags first; * we want to apply the least-recently-closed tag last. */ tmp_list = md->to_apply; while (tmp_list != NULL) { PangoAttribute *attr = tmp_list->data; /* Innermost tags before outermost */ pango_attr_list_insert (md->attr_list, attr); tmp_list = g_slist_next (tmp_list); } g_slist_free (md->to_apply); md->to_apply = NULL; } if (attr_list) *attr_list = md->attr_list; if (text) *text = g_string_free (md->text, FALSE); else g_string_free (md->text, TRUE); if (accel_char) *accel_char = md->accel_char; g_assert (md->tag_stack == NULL); g_slice_free (MarkupData, md); return TRUE; error: g_slist_foreach (md->tag_stack, (GFunc) open_tag_free, NULL); g_slist_free (md->tag_stack); g_slist_foreach (md->to_apply, (GFunc) pango_attribute_destroy, NULL); g_slist_free (md->to_apply); g_string_free (md->text, TRUE); if (md->attr_list) pango_attr_list_unref (md->attr_list); g_slice_free (MarkupData, md); if (context) g_markup_parse_context_free (context); return FALSE; }