/* * This file part of sdcv - console version of Stardict program * http://sdcv.sourceforge.net * Copyright (C) 2005-2006 Evgeniy * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "utils.hpp" #include "libwrapper.hpp" static std::string xdxf2text(const char *p) { std::string res; for (; *p; ++p) { if (*p!='<') { if (g_str_has_prefix(p, ">")) { res+=">"; p+=3; } else if (g_str_has_prefix(p, "<")) { res+="<"; p+=3; } else if (g_str_has_prefix(p, "&")) { res+="&"; p+=4; } else if (g_str_has_prefix(p, """)) { res+="\""; p+=5; } else res+=*p; continue; } const char *next=strchr(p, '>'); if (!next) continue; std::string name(p+1, next-p-1); if (name=="abr") res+=""; else if (name=="/abr") res+=""; else if (name=="k") { const char *begin=next; if ((next=strstr(begin, ""))!=NULL) next+=sizeof("")-1-1; else next=begin; } else if (name=="b") res+=""; else if (name=="/b") res+=""; else if (name=="i") res+=""; else if (name=="/i") res+=""; else if (name=="tr") res+="["; else if (name=="/tr") res+="]"; else if (name=="ex") res+=""; else if (name=="/ex") res+=""; else if (!name.empty() && name[0]=='c' && name!="co") { std::string::size_type pos=name.find("code"); if (pos!=std::string::size_type(-1)) { pos+=sizeof("code=\"")-1; std::string::size_type end_pos=name.find("\""); std::string color(name, pos, end_pos-pos); res+=""; } else { res+=""; } } else if (name=="/c") res+=""; p=next; } return res; } static string parse_data(const gchar *data) { if (!data) return ""; string res; guint32 data_size, sec_size=0; gchar *m_str; const gchar *p=data; data_size=*((guint32 *)p); p+=sizeof(guint32); while (guint32(p - data) match_res((MAX_MATCH_ITEM_PER_LIB) * ndicts()); gint nfound=Libs::LookupWithRule(str.c_str(), &match_res[0]); if (!nfound) return; for (gint i=0; i > drl(ndicts()); if (!Libs::LookupData(str.c_str(), &drl[0])) return; for (int idict=0; idict::size_type j=0; j%s\n-->%s\n%s\n\n", utf8_output ? res.bookname.c_str() : loc_bookname.c_str(), utf8_output ? res.def.c_str() : loc_def.c_str(), utf8_output ? res.exp.c_str() : loc_exp.c_str()); } class sdcv_pager { public: sdcv_pager(bool ignore_env=false) { output=stdout; if (ignore_env) return; const gchar *pager=g_getenv("SDCV_PAGER"); if (pager && (output=popen(pager, "w"))==NULL) { perror(_("popen failed")); output=stdout; } } ~sdcv_pager() { if (output!=stdout) fclose(output); } FILE *get_stream() { return output; } private: FILE *output; }; bool Library::process_phrase(const char *loc_str, read_line &io, bool force) { if (NULL==loc_str) return true; std::string query; analyze_query(loc_str, query); if (!query.empty()) io.add_to_history(query.c_str()); gsize bytes_read; gsize bytes_written; GError *err=NULL; char *str=NULL; if (!utf8_input) str=g_locale_to_utf8(loc_str, -1, &bytes_read, &bytes_written, &err); else str=g_strdup(loc_str); if (NULL==str) { fprintf(stderr, _("Can not convert %s to utf8.\n"), loc_str); fprintf(stderr, "%s\n", err->message); g_error_free(err); return false; } if (str[0]=='\0') return true; TSearchResultList res_list; switch (analyze_query(str, query)) { case qtFUZZY: LookupWithFuzzy(query, res_list); break; case qtREGEXP: LookupWithRule(query, res_list); break; case qtSIMPLE: SimpleLookup(str, res_list); if (res_list.empty()) LookupWithFuzzy(str, res_list); break; case qtDATA: LookupData(query, res_list); break; default: /*nothing*/; } if (!res_list.empty()) { /* try to be more clever, if there are one or zero results per dictionary show all */ bool show_all_results=true; typedef std::map< string, int, std::less > DictResMap; if (!force) { DictResMap res_per_dict; for(TSearchResultList::iterator ptr=res_list.begin(); ptr!=res_list.end(); ++ptr){ std::pair r = res_per_dict.equal_range(ptr->bookname); DictResMap tmp(r.first, r.second); if (tmp.empty()) //there are no yet such bookname in map res_per_dict.insert(DictResMap::value_type(ptr->bookname, 1)); else { ++((tmp.begin())->second); if (tmp.begin()->second>1) { show_all_results=false; break; } } } }//if (!force) if (!show_all_results && !force) { printf(_("Found %zu items, similar to %s.\n"), res_list.size(), utf8_output ? str : utf8_to_locale_ign_err(str).c_str()); for (size_t i=0; i%s\n", i, utf8_output ? res_list[i].bookname.c_str() : loc_bookname.c_str(), utf8_output ? res_list[i].def.c_str() : loc_def.c_str()); } int choise; std::auto_ptr choice_readline(create_readline_object()); for (;;) { string str_choise; choice_readline->read(_("Your choice[-1 to abort]: "), str_choise); sscanf(str_choise.c_str(), "%d", &choise); if (choise>=0 && choise