Exemplo n.º 1
0
/********************************************************************
 * FUNCTION find_alias
 * 
 * Find the alias record
 *
 * INPUTS:
 *   name == alias name to find (not assumed to be z-terminated
 *   namelen == length of name string
 * RETURNS:
 *   alias record; NULL if not found
 *********************************************************************/
static alias_cb_t *
    find_alias (const xmlChar *name,
                uint32 namelen)
{
    dlq_hdr_t  *aliasQ = get_aliasQ();
    alias_cb_t *curalias;

    if (aliasQ == NULL) {
        SET_ERROR(ERR_INTERNAL_VAL);
        return NULL;
    }

    for (curalias = (alias_cb_t *)dlq_firstEntry(aliasQ);
         curalias != NULL;
         curalias = (alias_cb_t *)dlq_nextEntry(curalias)) {

        uint32 curlen = xml_strlen(curalias->name);
        int ret = xml_strncmp(curalias->name, name, namelen);

        if (ret == 0) {
            if (curlen == namelen) {
                return curalias;
            }
        } else if (ret > 0) {
            /* already past where this name should be sorted */
            return NULL;
        }
    }

    return NULL;

}  /* find_alias */
Exemplo n.º 2
0
/********************************************************************
 * FUNCTION do_unset (local RPC)
 * 
 * unset def
 *
 * Handle the unset command; remove the specified alias
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the unset command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
extern status_t
    do_unset (server_cb_t *server_cb,
              obj_template_t *rpc,
              const xmlChar *line,
              uint32  len)
{
    val_value_t        *valset, *parm;
    status_t            res = NO_ERR;

    valset = get_valset(server_cb, rpc, &line[len], &res);

    if (res == NO_ERR && valset) {
        parm = val_find_child(valset, YANGCLI_MOD, NCX_EL_NAME);
        if (parm) {
            const xmlChar *varstr = VAL_STR(parm);
            alias_cb_t *alias = find_alias(varstr, xml_strlen(varstr));
            if (alias) {
                dlq_remove(alias);
                free_alias(alias);
                log_info("\nDeleted alias '%s'\n", varstr);
            } else {
                res = ERR_NCX_INVALID_VALUE;
                log_error("\nError: unknown alias '%s'\n", varstr);
            }
        }  /* else missing parameter already reported */
    } /* else no valset already reported */

    if (valset) {
        val_free_value(valset);
    }

    return res;

}  /* do_unset */
Exemplo n.º 3
0
/********************************************************************
* FUNCTION read_txid_file
*
* Read the transaction ID file and return the current ID value found
*
* INPUTS:
*    txidfile == full filespec of the transaction ID file
*    curid == address of return ID
*
* OUTPUTS:
*    *curid == return current ID (if return NO_ERR
*
* RETURNS:
*    status
*********************************************************************/
static status_t
    read_txid_file (const xmlChar *txidfile,
                    cfg_transaction_id_t *curid)
{

    assert( txidfile && "txidfile is NULL" );
    assert( curid && "curid is NULL" );

    *curid = 0;
    status_t res = NO_ERR;
    FILE *fil = fopen((const char *)txidfile, "r");
    if (!fil) {
        res = errno_to_status();
        log_error("\nError: Open txid file for read failed (%s)", 
                  get_error_string(res));
        return res;
    } 

    char buffer [128];
    if (fgets(buffer, sizeof buffer, fil)) {
        /* expecting just 1 line containing the ASCII encoding of
         * the transaction ID  */
        log_debug4("\nRead transaction ID line '%s'", buffer);

        uint32 len = xml_strlen((const xmlChar *)buffer);
        if (len > 1) {
            /* strip ending newline */
            buffer[len-1] = 0;

            ncx_num_t num;
            ncx_init_num(&num);
            res = ncx_convert_num((xmlChar *)buffer, NCX_NF_DEC, NCX_BT_UINT64,
                                  &num);
            if (res == NO_ERR) {
                agt_cfg_txid = num.ul;
                *curid = num.ul;
                log_debug3("\nGot transaction ID line '%llu'", 
                           (unsigned long long)num.ul);
            } else {
                log_error("\nError: txid is not valid (%s)",
                          get_error_string(res));
            }
            ncx_clean_num(NCX_BT_UINT64, &num);
        } else {
            res = ERR_NCX_INVALID_NUM;
            log_error("\nError: txid is not valid (%s)",
                      get_error_string(res));
        }
    } else {
        res = errno_to_status();
        log_error("\nError: Read txid file failed (%s)", 
                  get_error_string(res));
    }

    fclose(fil);

    return res;

} /* read_txid_file */
Exemplo n.º 4
0
/********************************************************************
 * build a prefix map using the xmplns directives in a message.
 *
 * \param msg the message in progrss
 * \param attrs the the top-level attrs list (e;g, rpc_in_attrs)
 * \return status
 *********************************************************************/
static status_t build_prefix_map_from_xmlns_directives( xml_msg_hdr_t* msg,
        xml_attrs_t* attrs )
{
    xmlns_id_t invid = xmlns_inv_id();
    xml_attr_t *attr = (xml_attr_t *)xml_first_attr(attrs);

    for ( ; attr;  attr = (xml_attr_t *)xml_next_attr(attr)) {

        /* make sure this is an XMLNS attribute with or wo a prefix */
        if (xml_strncmp(XMLNS, attr->attr_qname, XMLNS_LEN)) {
            continue;
        }

        /* find the namespace associated with the prefix
           note: it is not an error to have extra xmlns decls in the <rpc>elem;
           still need to make sure not to reuse the prefix anyway */
        xmlns_t *nsrec = def_reg_find_ns(attr->attr_val);

        /* check if this attribute has a prefix */
        if (attr->attr_qname == attr->attr_name) {
            /* no prefix in the name so this must be the default namespace */
            if ( !nsrec ) {
                /* the default namespace is not one of ours, so it will not be
                 * used in the reply */
                attr->attr_xmlns_ns = invid;
            } else {
                attr->attr_xmlns_ns = nsrec->ns_id;
            }
            continue;
        }

        /* there is a prefix, so get the prefix len.
         * The entire prefix was saved as the attr_name */
        uint32 plen = xml_strlen(attr->attr_name);

        /* get a new prefix map */
        xmlns_pmap_t *newpmap = xmlns_new_pmap(plen+1);
        if (!newpmap) {
            return ERR_INTERNAL_MEM;
        }

        /* save the prefix and the xmlns ID */
        xml_strncpy(newpmap->nm_pfix, attr->attr_name, plen);
        if ( !nsrec ) {
            newpmap->nm_id = invid;
            attr->attr_xmlns_ns = invid;
        } else {
            newpmap->nm_id = nsrec->ns_id;
            attr->attr_xmlns_ns = nsrec->ns_id;
        }
        newpmap->nm_topattr = TRUE;
        add_pmap(msg, newpmap);
    }

    return NO_ERR;
}
Exemplo n.º 5
0
/********************************************************************
* FUNCTION xml_msg_clean_defns_attr
*
* Get rid of an xmlns=foo default attribute
*
* INPUTS:
*    attrs == xmlns_attrs_t Q to process
*
* OUTPUTS:
*   *attrs will be cleaned as needed,
*
* RETURNS:
*   status
*********************************************************************/
status_t
xml_msg_clean_defns_attr (xml_attrs_t *attrs)
{
    xml_attr_t  *attr, *nextattr;
    uint32       len, len2;

#ifdef DEBUG
    if (!attrs) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

    len = xml_strlen(XMLNS);

    for (attr = (xml_attr_t *)xml_first_attr(attrs);
            attr != NULL;
            attr = nextattr) {


        nextattr = (xml_attr_t *)xml_next_attr(attr);

        len2 = xml_strlen(attr->attr_qname);
        if (len2 >= len) {
            if (!xml_strncmp(attr->attr_qname, XMLNS, len)) {
                if (len == len2) {
                    /* this xmlns=foo is getting toosed so
                     * the netconf NSID can be the default
                     */
                    dlq_remove(attr);
                    xml_free_attr(attr);
                    return NO_ERR;
                } /* else xmlns:foo=bar found */
            }  /* else not xmlns */
        }  /* else not 'xmlns' */
    }

    return NO_ERR;

}  /* xml_msg_clean_defns_attr */
Exemplo n.º 6
0
/********************************************************************
 * FUNCTION set_alias
 * 
 * Set an alias value field
 *
 * INPUTS:
 *    alias == alias record to use
 *    valstr == value string to use
 *
 * RETURNS:
 *    status
 *********************************************************************/
static status_t
    set_alias (alias_cb_t *alias,
               const xmlChar *valstr)
{
    status_t  res = NO_ERR;

    if (alias->value) {
        m__free(alias->value);
        alias->value = NULL;
    }
    alias->quotes = 0;
    if (valstr) {
        if (*valstr == '"' || *valstr == '\'') {
            /* preseve quotes used */
            alias->quotes = (*valstr == '"') ? 2 : 1;

            /* check trim quoted string */
            uint32 len = xml_strlen(valstr);
            if (len > 2) {
                const xmlChar *endstr = &valstr[len-1];
                if (*endstr == *valstr) {
                    /* remove paired quotes */
                    alias->value = xml_strndup(valstr+1, len-2);
                    if (alias->value == NULL) {
                        res = ERR_INTERNAL_MEM;
                    }
                } else {
                    /* improper string; unmatched quotes */
                    res = ERR_NCX_INVALID_VALUE;
                }
            } else {
                /* else got just a quote char */
                res = ERR_NCX_INVALID_VALUE;
            }
        } else {
            alias->value = xml_strdup(valstr);
            if (alias->value == NULL) {
                res = ERR_INTERNAL_MEM;
            }
        }
    } /* else cleared value if not already */


    return res;

}  /* set_alias */
Exemplo n.º 7
0
/********************************************************************
* FUNCTION find_feature_entry
* 
* Find a feature_entry_t
*
* INPUTS:
*   featstr == feature string parm to use
*   featQ == Q of feature_entry_t to use
*
* RETURNS:
*   pointer to found entry or NULL if not found
*********************************************************************/
static feature_entry_t *
    find_feature_entry (const xmlChar *featstr,
                        dlq_hdr_t  *featQ)
{
    uint32 len = 0;
    boolean splitdone = FALSE;
    status_t res = split_feature_string(featstr, &len);
    if (res == NO_ERR) {
        splitdone = TRUE;
    }

    feature_entry_t  *feature_entry = (feature_entry_t *)dlq_firstEntry(featQ);
    for (; feature_entry != NULL;
         feature_entry = (feature_entry_t *)dlq_nextEntry(feature_entry)) {

        if (splitdone && feature_entry->modname) {
            /* match the module name */
            uint32 len2 = xml_strlen(feature_entry->modname);
            if (len != len2) {
                continue;
            }
            if (xml_strncmp(feature_entry->modname, featstr, len)) {
                continue;
            }
        }

        /* match the feature name */
        if (splitdone) {
            if (xml_strcmp(feature_entry->feature, &featstr[len+1])) {
                continue;
            }
        } else {
            if (xml_strcmp(feature_entry->feature, featstr)) {
                continue;
            }
        }

        return feature_entry;
    }

    return NULL;

}  /* find_feature_entry */
static void func_parse_start_element(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
{
	std::string res;
	if (strcmp(element_name, "基本词义")==0 || strcmp(element_name, "CY")==0) {
		if (((PwUserData*)user_data)->first_jbcy) {
			((PwUserData*)user_data)->first_jbcy = false;
		} else {
			res="\n<span foreground=\"blue\">&lt;基本词义&gt;</span>";
		}
	// ToDo: These need to fix!
	} else if (strcmp(element_name, "继承用法")==0) {
		res="\n<span foreground=\"blue\">&lt;继承用法&gt;</span>";
	} else if (strcmp(element_name, "习惯用语")==0) {
		res="\n<span foreground=\"blue\">&lt;习惯用语&gt;</span>";
	} else if (strcmp(element_name, "词性变化")==0) {
		res="\n<span foreground=\"blue\">&lt;词性变化&gt;</span>";
	} else if (strcmp(element_name, "特殊用法")==0) {
		res="\n<span foreground=\"blue\">&lt;特殊用法&gt;</span>";
	} else if (strcmp(element_name, "参考词汇")==0) {
		res="\n<span foreground=\"blue\">&lt;参考词汇&gt;</span>";
	} else if (strcmp(element_name, "常用词组")==0) {
		res="\n<span foreground=\"blue\">&lt;常用词组&gt;</span>";
	} else if (strcmp(element_name, "语源")==0) {
		res="\n<span foreground=\"blue\">&lt;语源&gt;</span>";
	} else if (strcmp(element_name, "派生")==0) {
		res="\n<span foreground=\"blue\">&lt;派生&gt;</span>";
	} else if (strcmp(element_name, "用法")==0) {
		res="\n<span foreground=\"blue\">&lt;用法&gt;</span>";
	} else if (strcmp(element_name, "注释")==0) {
		res="\n<span foreground=\"blue\">&lt;注释&gt;</span>";
	}
	if (!res.empty()) {
		*(((PwUserData*)user_data)->pango) += res;
		((PwUserData*)user_data)->cur_pos += xml_strlen(res.c_str());
	}
}
Exemplo n.º 9
0
/********************************************************************
 * FUNCTION show_alias
 * 
 * Output 1 alias by name
 *
 * INPUTS:
 *    name == name of alias to show
 *********************************************************************/
void
    show_alias (const xmlChar *name)
{
    show_alias_name(name, xml_strlen(name));

}  /* show_alias */
Exemplo n.º 10
0
/********************************************************************
 * FUNCTION do_aliases (local RPC)
 * 
 * aliases
 * aliases clear
 * aliases show
 * aliases load[=filespec]
 * aliases save[=filespec]
 *
 * Handle the aliases command, based on the parameter
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the aliases command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_aliases (server_cb_t *server_cb,
              obj_template_t *rpc,
              const xmlChar *line,
              uint32  len)
{
    val_value_t   *valset;
    status_t       res = NO_ERR;

    valset = get_valset(server_cb, rpc, &line[len], &res);

    if (res == NO_ERR && valset) {
        /* get the 1 of N 'alias-action' choice */
        val_value_t *parm;
        const xmlChar *parmval = NULL;
        boolean done = FALSE;
        
        /* aliases show */
        parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_SHOW);
        if (parm) {
            show_aliases();
            done = TRUE;
        }

        /* aliases clear */
        if (!done) {
            parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_CLEAR);
            if (parm) {
                dlq_hdr_t *aliasQ = get_aliasQ();
                if (!dlq_empty(aliasQ)) {
                    free_aliases();
                    log_info("\nDeleted all aliases from memory\n");
                    update_yangcli_param_change_flag (ALIASES_FILE, TRUE);
                }else {
                    log_info("\nNo aliases found\n");
                }
                done = TRUE;
            }
        }

        /* aliases load */
        if (!done) {
            parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_LOAD);
            if (parm) {
                if (xml_strlen(VAL_STR(parm))) {
                    parmval = VAL_STR(parm);
                } else {
                    parmval = get_aliases_file();
                }
                res = load_aliases(parmval, !val_set_by_default(parm));
                if (res == NO_ERR) {
                    log_info("\nLoaded aliases OK from '%s'\n", parmval);
                } else {
                    log_error("\nLoad aliases from '%s' failed (%s)\n", 
                              parmval, get_error_string(res));
                }
                done = TRUE;
            }
        }

        /* aliases save */
        if (!done) {
            parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_SAVE);
            if (parm) {
                if (xml_strlen(VAL_STR(parm))) {
                    parmval = VAL_STR(parm);
                } else {
                    parmval = get_aliases_file();
                }
                res = save_aliases(parmval);
                if (res == NO_ERR) {
                    log_info("\nSaved aliases OK to '%s'\n", parmval);
                } else if (res != ERR_NCX_CANCELED) {
                    log_error("\nSave aliases to '%s' failed (%s)\n", 
                              parmval, get_error_string(res));
                }
                done = TRUE;
            }
        }

        if (!done) {
            /* no parameters; show all aliases */
            show_aliases();
        }
    }

    if (valset) {
        val_free_value(valset);
    }

    return res;

}  /* do_aliases */
Exemplo n.º 11
0
/********************************************************************
* FUNCTION tstamp_convert_to_utctime
*
* Check if the specified string is a valid dateTime or 
* date-and-time string is valid and if so, convert it
* to 
*
* INPUTS:
*   buff == pointer to buffer to check
*   isNegative == address of return negative date flag
*   res == address of return status
*
* OUTPUTS:
*   *isNegative == TRUE if a negative dateTime string is given
*                  FALSE if no starting '-' sign found
*   *res == return status
*
* RETURNS:
*   malloced pointer to converted date time string
*   or NULL if some error
*********************************************************************/
xmlChar *
    tstamp_convert_to_utctime (const xmlChar *timestr,
                               boolean *isNegative,
                               status_t *res)
{
    assert(timestr && "timestr is NULL!");
    assert(isNegative && "isNegative is NULL!");
    assert(res && "res is NULL!");

    *res = NO_ERR;

    struct tm convertedtime;
    memset(&convertedtime, 0x0, sizeof(struct tm));

    if (*timestr == '-') {
        *isNegative = TRUE;
        timestr++;
    } else {
        *isNegative = FALSE;
    }

    xmlChar *buffer = NULL;
    const char *retptr = NULL;

    uint32 len = xml_strlen(timestr);
    if (len == 20) {
        /* could be in canonical form */
        retptr = strptime((const char *)timestr, "%FT%TZ", &convertedtime);
        if (retptr && *retptr == '\0') {
            buffer = xml_strdup(timestr);
            if (!buffer) {
                *res = ERR_INTERNAL_MEM;
                return NULL;
            } else {
                return buffer;
            }
        } else {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }
    } else if (len > 20) {
        retptr = strptime((const char *)timestr, "%FT%T", &convertedtime);
        if (retptr == NULL || *retptr == '\0') {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }

        /* check is frac-seconds entered, and skip it */
        if (*retptr == '.') {
            retptr++;
            if (!isdigit((int)*retptr)) {
                *res = ERR_NCX_INVALID_VALUE;
                return NULL;
            }

            retptr++;  /* got a start digit */
            while (isdigit((int)*retptr)) {
                retptr++;
            }
        }

        /* check if a timezone offset is present */
        retptr = strptime(retptr, "%z", &convertedtime);
        if (retptr == NULL) {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }

        /* check where retptr ended up */
        if (*retptr == '\0') {
            /* OK read all the bytes */
            ;
        } else if (*retptr == ':') {
            if (strcmp(retptr, ":00")) {
                /* the linux strptime function does
                 * not process the 'time-minute' field in the
                 * time string; since this is so rare
                 * just treat as a special error
                 */
                *res = ERR_NCX_OPERATION_NOT_SUPPORTED;
                return NULL;
            } /* else time-minute field == '00' and no error */
        } else {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }

        buffer = m__getMem(TSTAMP_MIN_SIZE);
        if (!buffer) {
            *res = ERR_INTERNAL_MEM;
            return NULL;
        }

        time_t utime = mktime(&convertedtime);
        if (utime == (utime)-1) {
            *res = ERR_NCX_INVALID_VALUE;
            m__free(buffer);
            return NULL;
        }

        struct tm *curtime = gmtime(&utime);
        time_to_string(curtime, buffer);
        return buffer;
    } else {
        /* improper length */
        *res = ERR_NCX_INVALID_VALUE;
        return NULL;
    }
    
} /* tstamp_convert_to_utctime */
Exemplo n.º 12
0
/********************************************************************
* FUNCTION set_initial_transaction_id
*
* Set the last_transaction_id for the running config
* Will check for sys:transaction-id leaf in config->root
*
* RETURNS:
*    status
*********************************************************************/
static status_t
    set_initial_transaction_id (void)
{
    cfg_template_t *cfg = cfg_get_config_id(NCX_CFGID_RUNNING);
    if (cfg == NULL) {
        return ERR_NCX_CFG_NOT_FOUND;
    }
    if (cfg->root == NULL) {
        return ERR_NCX_EMPTY_VAL;
    }

    agt_profile_t *profile = agt_get_profile();
    status_t res = NO_ERR;
    boolean  foundfile = FALSE;

    /* figure out which transaction ID file to use */
    if (profile->agt_startup_txid_file == NULL) {
        /* search for the default startup-cfg.xml filename */
        xmlChar *fname = ncxmod_find_data_file(NCX_DEF_STARTUP_TXID_FILE, 
                                               FALSE, &res);
        if (fname == NULL || res != NO_ERR || *fname == 0) {
            /* need to set the default startup transaction ID file name */
            log_debug("\nSetting initial transaction ID file to default");
            if (fname) {
                m__free(fname);
            }
            res = NO_ERR;
            fname = agt_get_startup_filespec(&res);
            if (fname == NULL || res != NO_ERR) {
                if (res == NO_ERR) {
                    res = ERR_NCX_OPERATION_FAILED;
                }
                log_error("\nFailed to set initial transaction ID file (%s)",
                          get_error_string(res));
                if (fname) {
                    m__free(fname);
                }
                return res;
            }
            /* get dir part and append the TXID file name to it */
            uint32 fnamelen = xml_strlen(fname);
            xmlChar *str = &fname[fnamelen - 1];
            while (str >= fname && *str && *str != NCX_PATHSEP_CH) {
                str--;
            }
            if (*str != NCX_PATHSEP_CH) {
                log_error("\nFailed to set initial transaction ID file");
                m__free(fname);
                return ERR_NCX_INVALID_VALUE;
            }

            /* copy base filespec + 1 for the path-sep-ch */
            uint32 baselen = (uint32)(str - fname) + 1;
            uint32 newlen =  baselen + xml_strlen(NCX_DEF_STARTUP_TXID_FILE);
            xmlChar *newstr = m__getMem(newlen + 1);
            if (newstr == NULL) {
                m__free(fname);
                return ERR_INTERNAL_MEM;
            }
            str = newstr;
            str += xml_strncpy(str, fname, baselen);
            xml_strcpy(str, NCX_DEF_STARTUP_TXID_FILE);
            m__free(fname);
            profile->agt_startup_txid_file = newstr; // pass off memory here
        } else {
            foundfile = TRUE;
            profile->agt_startup_txid_file = fname; // pass off memory here
        }
    }

    /* initialize the starting transaction ID in the config module */
    res = agt_cfg_init_transactions(profile->agt_startup_txid_file, foundfile);
    if (res != NO_ERR) {
        log_error("\nError: cfg-init transaction ID failed (%s)",
                  get_error_string(res));
    }
    return res;

} /* set_initial_transaction_id */
static void func_parse_passthrough(GMarkupParseContext *context, const gchar *passthrough_text, gsize text_len, gpointer user_data, GError **error)
{
	if (!g_str_has_prefix(passthrough_text, "<![CDATA["))
		return;
	const gchar *element = g_markup_parse_context_get_element(context);
	if (!element)
		return;
	const gchar *text = passthrough_text+9;
	gsize len = text_len-9-3;
	while (g_ascii_isspace(*text)) {
		text++;
		len--;
	}
	while (len>0 && g_ascii_isspace(*(text+len-1))) {
		len--;
	}
	if (len==0)
		return;
	std::string *pango = ((PwUserData*)user_data)->pango;
	std::string::size_type &cur_pos = ((PwUserData*)user_data)->cur_pos;
	if (strcmp(element, "词典音标")==0 || strcmp(element, "CB")==0) {
		if (!pango->empty()) {
			*pango+='\n';
			cur_pos++;
		}
		*pango+="[<span foreground=\"blue\">";
		cur_pos++;
		gchar *str = toUtfPhonetic(text, len);
		*pango+=str;
		cur_pos+=xml_strlen(str);
		g_free(str);
		*pango+="</span>]";
		cur_pos++;
	} else if (strcmp(element, "单词原型")==0 || strcmp(element, "YX")==0) {
		const gchar *oword = ((PwUserData*)user_data)->oword;
		if (strncmp(oword, text, len)) {
			if (!pango->empty()) {
				*pango+='\n';
				cur_pos++;
			}
			*pango+="<b>";
			gchar *str = g_markup_escape_text(text, len);
			pango->append(str);
			cur_pos+=xml_strlen(str);
			g_free(str);
			*pango+="</b>";
		}
	} else if (strcmp(element, "单词词性")==0 || strcmp(element, "DX")==0) {
		if (!pango->empty()) {
			*pango+='\n';
			cur_pos++;
		}
		*pango+="<i>";
		powerword_markup_add_text(text, len, pango, cur_pos, ((PwUserData*)user_data)->links_list);
		*pango+="</i>";
	} else if (strcmp(element, "汉语拼音")==0 || strcmp(element, "PY")==0) {
		if (!pango->empty()) {
			*pango+='\n';
			cur_pos++;
		}
		*pango+="<span foreground=\"blue\" underline=\"single\">";
		powerword_markup_add_text(text, len, pango, cur_pos, ((PwUserData*)user_data)->links_list);
		*pango+="</span>";
	} else if (strcmp(element, "例句原型")==0 || strcmp(element, "LY")==0) {
		if (!pango->empty()) {
			*pango+='\n';
			cur_pos++;
		}
		*pango+="<span foreground=\"#008080\">";
		powerword_markup_add_text(text, len, pango, cur_pos, ((PwUserData*)user_data)->links_list);
		*pango+="</span>";
	} else if (strcmp(element, "例句解释")==0 || strcmp(element, "LS")==0) {
		if (!pango->empty()) {
			*pango+='\n';
			cur_pos++;
		}
		*pango+="<span foreground=\"#01259A\">";
		powerword_markup_add_text(text, len, pango, cur_pos, ((PwUserData*)user_data)->links_list);
		*pango+="</span>";
	/*} else if (strcmp(element, "相关词")==0) {
		if (!res->empty())
			*res+='\n';
		std::string tabstr;
		tabstr+=text[0];
		for (gsize i=1;i<len;i++) {
			if (text[i]=='&')
				tabstr+="\t&";
			else
				tabstr+=text[i];
		}
		gchar *str = powerword_markup_escape_text(tabstr.c_str(), tabstr.length());
		res->append(str);
		g_free(str);*/
	} else
	/*} else if (
	strcmp(element, "解释项")==0 ||
	strcmp(element, "跟随解释")==0 ||
	strcmp(element, "相关词")==0 ||
	strcmp(element, "预解释")==0 ||
	strcmp(element, "繁体写法")==0 ||
	strcmp(element, "台湾音标")==0 ||
	strcmp(element, "图片名称")==0 ||
	strcmp(element, "跟随注释")==0 ||
	strcmp(element, "音节分段")==0 ||
	strcmp(element, "AHD音标")==0 ||
	strcmp(element, "国际音标")==0 ||
	strcmp(element, "美国音标")==0 ||
	strcmp(element, "子解释项")==0 ||
	strcmp(element, "同义词")==0 ||
	strcmp(element, "日文发音")==0 ||
	strcmp(element, "惯用型原型")==0 ||
	strcmp(element, "惯用型解释")==0 ||
	strcmp(element, "另见")==0
	) {*/
	{
		if (!pango->empty()) {
			*pango+='\n';
			cur_pos++;
		}
		powerword_markup_add_text(text, len, pango, cur_pos, ((PwUserData*)user_data)->links_list);
	}
}
static void powerword_markup_add_text(const gchar *text, gssize length, std::string *pango, std::string::size_type &cur_pos, LinksPosList *links_list)
{
	const gchar *p;
	const gchar *end;
	p = text;
	end = text + length;

	GString *str;
	str = g_string_sized_new (length);

	const gchar *n;
	bool find;
	bool previous_islink = false;
	std::string marktags;
	guint currentmarktag = 0;
	while (p != end) {
		const gchar *next;
		next = g_utf8_next_char (p);
		switch (*p) {
			case '}':
				if (currentmarktag==0) {
					g_string_append (str, "}");
					previous_islink = false;
				}
				else {
					currentmarktag--;
					switch (marktags[currentmarktag]) {
						case 'b':
						case 'B':
							g_string_append (str, "</b>");
							previous_islink = false;
							break;
						case 'I':
							g_string_append (str, "</i>");
							previous_islink = false;
							break;
						case '+':
							g_string_append (str, "</sup>");
							previous_islink = false;
							break;
						case '-':
							g_string_append (str, "</sub>");
							previous_islink = false;
							break;
						case 'x':
							g_string_append (str, "</span>");
							previous_islink = false;
							break;
						case 'l':
						case 'D':
						case 'L':
						case 'U':
							g_string_append (str, "</span>");
							previous_islink = true;
							break;
						default:
							previous_islink = false;
							break;
					}
				}
				break;
			case '&':
				find = false;
				if (next!=end) {
					n = g_utf8_next_char(next);
					if (n!=end && *n == '{') {
						find=true;
						currentmarktag++;
						if (marktags.length()<currentmarktag)
							marktags+=*next;
						else
							marktags[currentmarktag-1]=*next;
						switch (*next) {
							case 'b':
							case 'B':
								g_string_append (str, "<b>");
								next = n+1;
								break;
							case 'I':
								g_string_append (str, "<i>");
								next = n+1;
								break;
							case '+':
								g_string_append (str, "<sup>");
								next = n+1;
								break;
							case '-':
								g_string_append (str, "<sub>");
								next = n+1;
								break;
							case 'x':
								g_string_append (str, "<span foreground=\"blue\" underline=\"single\">");
								next = n+1;
								break;
							case 'X':
							case '2':
								{
								const gchar *tag_end = n+1;
								while (tag_end!=end) {
									if (*tag_end=='}')
										break;
									else
										tag_end++;
								}
								g_string_append (str, "<span foreground=\"blue\">");
								gchar *tag_str;
								if (*next == 'X') {
									tag_str = toUtfPhonetic(n+1, tag_end - (n+1));
								} else {
									tag_str = toUtfPhonetic2(n+1, tag_end - (n+1));
								}
								g_string_append (str, tag_str);
								g_free(tag_str);
								g_string_append (str, "</span>");
								currentmarktag--;
								if (tag_end!=end)
									next = tag_end+1;
								else
									next = end;
								previous_islink = false;
								break;
								}
							case 'l':
							case 'D':
							case 'L':
							case 'U':
								if (previous_islink)
									g_string_append (str, "\t");
								if (*next == 'l' || *next == 'D')
									g_string_append (str, "<span foreground=\"blue\" underline=\"single\">");
								else
									g_string_append (str, "<span foreground=\"#008080\" underline=\"single\">");
								*pango += str->str;
								cur_pos += xml_strlen(str->str);
								g_string_erase(str, 0, -1);
								{
								const gchar *tag_end = n+1;
								while (tag_end!=end) {
									if (*tag_end=='}')
										break;
									else
										tag_end++;
								}
								char *tmpstr = g_markup_escape_text(n+1, tag_end - (n+1));
								size_t xml_len = xml_strlen(tmpstr);
								std::string link("query://");
								link.append(n+1, tag_end - (n+1));
								links_list->push_back(LinkDesc(cur_pos, xml_len, link));
								*pango += tmpstr;
								cur_pos += xml_len;
								g_free(tmpstr);
								g_string_append (str, "</span>");
								currentmarktag--;
								if (tag_end!=end)
									next = tag_end+1;
								else
									next = end;
								previous_islink = true;
								break;
								}
							/*case ' ':
							case '9':
							case 'S':*/
							default:
								next = n+1;
								break;
						}
					}
				}
				if (!find) {
					previous_islink = false;
					g_string_append (str, "&amp;");
				}
				break;
			case '<':
				previous_islink = false;
				g_string_append (str, "&lt;");
				break;
			case '>':
				previous_islink = false;
				g_string_append (str, "&gt;");
				break;
			case '\'':
				previous_islink = false;
				g_string_append (str, "&apos;");
				break;
			case '"':
				previous_islink = false;
				g_string_append (str, "&quot;");
				break;
			default:
				previous_islink = false;
				g_string_append_len (str, p, next - p);
				break;
		}
		p = next;
	}
	if (currentmarktag>0) {
		do {
			currentmarktag--;
			switch (marktags[currentmarktag]) {
				case 'b':
				case 'B':
					g_string_append (str, "</b>");
					break;
				case 'I':
					g_string_append (str, "</i>");
					break;
				case '+':
					g_string_append (str, "</sup>");
					break;
				case '-':
					g_string_append (str, "</sub>");
					break;
				case 'x':
				case 'l':
				case 'D':
				case 'L':
				case 'U':
					g_string_append (str, "</span>");
					break;
				default:
					break;
			}
		} while (currentmarktag>0);
	}
	*pango += str->str;
	cur_pos += xml_strlen(str->str);
	g_string_free (str, TRUE);
}
Exemplo n.º 15
0
/********************************************************************
* FUNCTION xml_msg_gen_new_prefix
*
* Generate a new namespace prefix
*
* INPUTS:
*    msg  == message to search and generate a prefix for
*    nsid == namespace ID to generate prefix for
*    retbuff == address of return buffer
*    buffsize == buffer size
* OUTPUTS:
*   if *retbuff is NULL it will be created
*   else *retbuff is filled in with the new prefix if NO_ERR
*
* RETURNS:
*    status
*********************************************************************/
status_t
xml_msg_gen_new_prefix (xml_msg_hdr_t *msg,
                        xmlns_id_t  nsid,
                        xmlChar **retbuff,
                        uint32 buffsize)
{
    const xmlChar      *defpfix;
    xmlChar             startch;
    int32               nlen, i;
    xmlChar             numbuff[NCX_MAX_NUMLEN], *buff;
    xmlns_id_t          testid;

#ifdef DEBUG
    if (!msg || !retbuff) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

    if (*retbuff) {
        buff = *retbuff;
    } else {
        buff = m__getMem(NCX_MAX_NUMLEN+1);
        if (!buff) {
            return ERR_INTERNAL_MEM;
        } else {
            buffsize = NCX_MAX_NUMLEN+1;
            *retbuff = buff;
        }
    }

    /* first see if a default prefix was registered with the namespace
     * and use it if not already in the prefix map
     */
    defpfix = xmlns_get_ns_prefix(nsid);
    if (defpfix && *defpfix) {
        testid = find_prefix_val(msg, defpfix);
        if (testid == 0 || testid==nsid) {
            if (xml_strlen(defpfix) < buffsize) {
                xml_strcpy(buff, defpfix);
                return NO_ERR;
            } else {
                return ERR_BUFF_OVFL;
            }
        }
    }

    /* default already in use for something else so generate a prefix */
    nlen = snprintf((char *)numbuff, NCX_MAX_NUMLEN, "%u", (uint32)nsid);
    if (nlen < 0) {
        return ERR_NCX_INVALID_NUM;
    }

    if ((uint32)(nlen+2) >= buffsize) {
        return ERR_BUFF_OVFL;
    }

    /* copy the number to the prefix buffer w/ trailing zero */
    for (i=0; i<=nlen; i++) {
        buff[i+1] = numbuff[i];
    }

    /* set the start letter in the prefix buffer */
    startch = 'n';

    /* try to generate a unique prefix */
    for (i=0; i<=MAX_PREFIX_TRIES; i++) {
        /* adjust the label value */
        buff[0] = startch++;
        if (startch > 'z') {
            startch = 'a';
        }

        /* check if the prefix is in use */
        if (!find_prefix_val(msg, buff)) {
            return NO_ERR;
        }
    }

    return ERR_NCX_OPERATION_FAILED;

}  /* xml_msg_gen_new_prefix */
Exemplo n.º 16
0
/********************************************************************
 * FUNCTION load_aliases
 * 
 * Load the aliases from the specified filespec
 *
 * INPUT:
 *   fspec == input filespec to use (NULL == default)
 *   file_error == TRUE if the file must be found
 *                 FALSE if finding the default file and it
 *                 is not required to be present
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    load_aliases (const xmlChar *fspec,
                  boolean file_error)
{
    FILE      *fp;
    xmlChar   *fullspec, *buffer;
    status_t   res = NO_ERR;
    
    buffer = m__getMem(NCX_MAX_LINELEN+1);
    if (buffer == NULL) {
        log_error("\nError: malloc failed\n");
        return ERR_INTERNAL_MEM;
    }

    if (fspec == NULL) {
        fspec = get_aliases_file();
    }

    fullspec = ncx_get_source(fspec, &res);
    if (res == NO_ERR && fullspec) {
        fp = fopen((const char *)fullspec, "r");
        if (fp) {
#define MAX_ALIAS_ERRORS 5
            boolean done = FALSE;
            uint32 errorcnt = 0;
            while (!done) {
                char *retstr = fgets((char *)buffer, NCX_MAX_LINELEN+1, fp);
                if (retstr) {
                    uint32 len = xml_strlen(buffer);
                    if (len) {
                        if (*buffer != '#' && *buffer != '\n') {
                            if (buffer[len-1] == '\n') {
                                buffer[len-1] = 0;
                            } 
                            res = handle_alias_parm(buffer, TRUE, FALSE);
                            if (res != NO_ERR) {
                                if (++errorcnt == MAX_ALIAS_ERRORS) {
                                    log_error("\nError: skipping aliases; "
                                              "too many errors\n");
                                    done = TRUE;
                                }
                            }
                        }  // else skip a newline or comment line
                    } // else skip empty line
                } else {
                    done = TRUE;
                }
            }
            fclose(fp);
            /* Save mtime of this aliases file */
            res = update_def_yangcli_file_mtime (ALIASES_FILE, fullspec);
        } else if (file_error) {
            log_error("\nError: Aliases file '%s' could not be opened\n",
                      fullspec);
            res = ERR_FIL_OPEN;
        } else if (LOGDEBUG) {
            log_debug("\nAliases file '%s' could not be opened\n", fullspec);
        }
    } else {
        log_error("\nError: Expand source '%s' failed (%s)",
                  fspec, get_error_string(res));
    }

    if (fullspec) {
        m__free(fullspec);
    }

    if (buffer) {
        m__free(buffer);
    }
    return res;

}  /* load_aliases */
Exemplo n.º 17
0
/********************************************************************
 * 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 */
Exemplo n.º 18
0
/********************************************************************
* FUNCTION consume_node
* 
* Internal consume XML node function
* see agt_xml_consume_node for details.
*
* EXTRA INPUTS:
*   eoferr == TRUE if an End of File error should be generated
*          == FALSE if not
*    nserr == TRUE if bad namespace should be checked
*          == FALSE if not
*    clean == TRUE is a string should be cleaned before returned 
*          == FALSE if a string node should be returned as-is
*
* RETURNS:
*   status of the operation
*   Try to fail on fatal errors only
*********************************************************************/
static status_t 
    consume_node (ses_cb_t *scb,
                  boolean advance,
                  xml_node_t *node,
                  ncx_layer_t layer,
                  xml_msg_hdr_t *msghdr,
                  boolean eoferr,
                  boolean nserr,
                  boolean clean)
{
    int             ret, nodetyp;
    const xmlChar  *badns;
    xmlChar        *valstr, *namestr;
    uint32          len;
    status_t        res, res2;
    boolean         done;

    /* init local vars */
    done = FALSE;
    res = NO_ERR;
    res2 = NO_ERR;
    badns = NULL;

    /* loop past any unused xmlTextReader node types */
    while (!done) {
        /* check if a new node should be read */
        if (advance) {
            /* advance the node pointer */
            ret = xmlTextReaderRead(scb->reader);
            if (ret != 1) {
                /* do not treat this as an internal error */
                res = ERR_XML_READER_EOF;
                if (msghdr && eoferr) {
                    /* generate an operation-failed error */
                    agt_record_error(scb, 
                                     msghdr, 
                                     layer, 
                                     res, 
                                     NULL, 
                                     NCX_NT_NONE,
                                     NULL, 
                                     NCX_NT_NONE,
                                     NULL);
                }
                return res;
            }
        }

        /* get the node depth to match the end node correctly */
        node->depth = xmlTextReaderDepth(scb->reader);
        if (node->depth == -1) {
            /* this never actaully happens */
            SET_ERROR(ERR_XML_READER_INTERNAL);
            node->depth = 0;
        }

        /* get the internal nodetype, check it and convert it */
        nodetyp = xmlTextReaderNodeType(scb->reader);
        switch (nodetyp) {
        case XML_ELEMENT_NODE:
            /* classify element as empty or start */
            if (xmlTextReaderIsEmptyElement(scb->reader)) {
                node->nodetyp = XML_NT_EMPTY;
            } else {
                node->nodetyp = XML_NT_START;
            }
            done = TRUE;
            break;
        case XML_ELEMENT_DECL:
            node->nodetyp = XML_NT_END;
            done = TRUE;
            break;
        case XML_TEXT_NODE:
     /* case XML_DTD_NODE: */
            node->nodetyp = XML_NT_STRING;
            done = TRUE;
            break;
        default:
            /* unused node type -- keep trying */
            if (LOGDEBUG3) {
                log_debug3("\nxml_consume_node: skip unused node (%s)",
                           xml_get_node_name(nodetyp));
            }
            advance = TRUE;
        }
    }

    /* finish the node, depending on its type */
    switch (node->nodetyp) {
    case XML_NT_START:
    case XML_NT_END:
    case XML_NT_EMPTY:
        /* get the element QName */
        namestr = xml_strdup(xmlTextReaderConstName(scb->reader));
        if (!namestr) {
            res = ERR_INTERNAL_MEM;
        } else {
            node->qname = namestr;

            /* check for namespace prefix in the name 
             * only error returned is unknown-namespace 
             */
            len = 0;
            res = xml_check_ns(scb->reader, 
                               namestr, 
                               &node->nsid, 
                               &len, 
                               &badns);
            if (!nserr && res != NO_ERR) {
                node->nsid = xmlns_inv_id();
                len = 0;
                res = NO_ERR;
            }
            
            /* set the element name to the char after the prefix, if any */
            node->elname = (const xmlChar *)(namestr+len);
        
            /* get all the attributes, except for XML_NT_END */
            if (res == NO_ERR && node->nodetyp != XML_NT_END) {
                res2 = get_all_attrs(scb, 
                                     node,
                                     &node->attrs, 
                                     layer, 
                                     msghdr, 
                                     nserr);
            }

            /* Set the node module */
            if (res == NO_ERR) {
                if (node->nsid) {
                    node->module = xmlns_get_module(node->nsid);
                } else {
                    /* no entry, use the default module (ncx) */
                    node->module = NCX_DEF_MODULE;
                }
            }
        }
        break;
    case XML_NT_STRING:
        /* get the text value -- this is a malloced string */
        node->simval = NULL;
        valstr = xmlTextReaderValue(scb->reader);
        if (valstr) {
            if (clean) {
                node->simfree = xml_copy_clean_string(valstr);
            } else {
                node->simfree = xml_strdup(valstr);
            }
            if (node->simfree) {
                node->simlen = xml_strlen(node->simfree);
                node->simval = (const xmlChar *)node->simfree;
            }

            /* see if this is a QName string; if so save the NSID */
            xml_check_qname_content(scb->reader, node);

            xmlFree(valstr);
        }
        if (!node->simval) {
            /* prevent a NULL ptr reference */
            node->simval = EMPTY_STRING;
            node->simlen = 0;
            node->simfree = NULL;
        }
        break;
    default:
        break;
    }

    if ((res != NO_ERR) && msghdr) {
        if (badns) {
            /* generate an operation-failed error */
            agt_record_error(scb,
                             msghdr,
                             layer, 
                             res, 
                             node,
                             NCX_NT_STRING, 
                             badns, 
                             NCX_NT_NONE, 
                             NULL);
        } else {
            agt_record_error(scb,
                             msghdr,
                             layer,
                             res, 
                             node,
                             NCX_NT_NONE,
                             NULL, 
                             NCX_NT_NONE, 
                             NULL);
        }
    }

    if (LOGDEBUG4) {
        log_debug4("\nxml_consume_node: return (%d)", 
                   (res==NO_ERR) ? res2 : res);
        if (scb->state != SES_ST_INIT) {
            xml_dump_node(node);
        }
    }

    /* return general error first, then attribute error 
     * It doesn't really matter since the caller will 
     * assume all error reports have been queued upon return
     */
    return (res==NO_ERR) ? res2 : res;

}  /* consume_node */