[Aptitude-svn-commit] r3423 - in branches/aptitude-0.3/aptitude: . src/vscreen
Daniel Burrows
dburrows@costa.debian.org
Sat, 25 Jun 2005 17:16:24 +0000
Author: dburrows
Date: Sat Jun 25 17:16:21 2005
New Revision: 3423
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc
branches/aptitude-0.3/aptitude/src/vscreen/fragment.h
branches/aptitude-0.3/aptitude/src/vscreen/fragment_contents.h
Log:
Use wide character strings internally to format text fragments, and require explicit conversion of std::strings.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Sat Jun 25 17:16:21 2005
@@ -1,5 +1,10 @@
2005-06-25 Daniel Burrows <dburrows@debian.org>
+ * src/vscreen/fragment.cc, src/vscreen/fragment.h, src/vscreen/fragment_contents.h:
+
+ Use wide character strings internally to format text fragments,
+ and require explicit conversion of std::strings.
+
* src/vscreen/curses++.h:
Add a convenience constructor to build a wchstring by repeating
Modified: branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc Sat Jun 25 17:16:21 2005
@@ -3,6 +3,7 @@
// Copyright 2004 Daniel Burrows
#include "fragment.h"
+#include "transcode.h"
#include "config/colors.h"
@@ -10,6 +11,8 @@
#include <algorithm>
+#include <wctype.h>
+
using namespace std;
fragment::~fragment()
@@ -22,13 +25,13 @@
class _text_fragment:public fragment
{
public:
- _text_fragment(const string &_s):s(_s) {}
+ _text_fragment(const wstring &_s):s(_s) {}
fragment_contents layout(size_t firstw, size_t restw,
const style &st)
{
fragment_contents rval;
- rval.push_back(chstring(s, st));
+ rval.push_back(fragment_line(s, st));
return rval;
}
@@ -49,15 +52,41 @@
return false;
}
private:
- string s;
+ wstring s;
};
-fragment *text_fragment(const string &s) { return new _text_fragment(s); }
-fragment *text_fragment(const string &s,
- const style &style)
+fragment *text_fragment(const wstring &s) { return new _text_fragment(s); }
+fragment *text_fragment(const wstring &s,
+ const style &st)
{
return style_fragment(text_fragment(s),
- style);
+ st);
+}
+
+fragment *transcode_fragment(const string &s,
+ const char *encoding)
+{
+ wstring decoded;
+
+ // The error code is not translated, because that would require an
+ // additional decoding step and could result in infinite loops and
+ // other bad stuff. Besides, something is very wrong if it appears;
+ // better to just output a diagnostic message that can be cut+paste.
+ if(!transcode(s.c_str(), decoded, encoding))
+ return sequence_fragment(text_fragment(decoded),
+ text_fragment(L"Error decoding multibyte string",
+ get_style("Error")),
+ NULL);
+ else
+ return text_fragment(decoded);
+}
+
+fragment *transcode_fragment(const string &s,
+ const style &st,
+ const char *encoding)
+{
+ return style_fragment(transcode_fragment(s, encoding),
+ st);
}
/** This fragment just expands to a newline. */
@@ -217,7 +246,7 @@
{
fragment_contents rval;
- rval.push_back(string(""));
+ rval.push_back(fragment_line(L""));
for(vector<fragment*>::const_iterator i=contents.begin();
i!=contents.end(); ++i)
@@ -246,7 +275,7 @@
if(lines.size()==0)
{
if(rval.get_final_nl() && lines.get_final_nl())
- rval.push_back(chstring(""));
+ rval.push_back(fragment_line(L""));
rval.set_final_nl(rval.get_final_nl() || lines.get_final_nl());
}
@@ -349,7 +378,7 @@
// Fall back on sequence_fragment [for now?]
fragment *join_fragments(const vector<fragment *> &fragments,
- const string &between)
+ const wstring &between)
{
vector<fragment*> rval;
@@ -383,7 +412,7 @@
for(fragment_contents::const_iterator i=lines.begin();
i!=lines.end(); ++i)
{
- chstring s=*i;
+ fragment_line s=*i;
// Make sure we at least advance the cursor for every line read.
//
@@ -396,7 +425,7 @@
while(first<s.size())
{
// Strip leading whitespace.
- while(first<s.size() && isspace(s[first]&A_CHARTEXT))
+ while(first<s.size() && iswspace(s[first].ch))
++first;
if(first==s.size())
@@ -406,7 +435,7 @@
// line, do that.
if(s.size()-first<=firstw)
{
- rval.push_back(chstring(s, first, s.size()-first));
+ rval.push_back(fragment_line(s, first, s.size()-first));
firstw=restw;
first=s.size();
output_something=true;
@@ -415,13 +444,13 @@
{
size_t amt=firstw;
- while(amt>0 && !isspace(s[first+amt]&A_CHARTEXT))
+ while(amt>0 && !iswspace(s[first+amt].ch))
--amt;
// Oops, there's a word that's longer than the current line.
if(amt==0)
{
- rval.push_back(chstring(s, first, firstw));
+ rval.push_back(fragment_line(s, first, firstw));
first+=firstw;
firstw=restw;
output_something=true;
@@ -430,11 +459,11 @@
{
// Eh, strip trailing whitespace.
while(amt>0 &&
- isspace(s[first+amt]&A_CHARTEXT) &&
- isspace(s[first+amt-1]&A_CHARTEXT))
+ isspace(s[first+amt].ch) &&
+ isspace(s[first+amt-1].ch))
--amt;
- rval.push_back(chstring(s, first, amt));
+ rval.push_back(fragment_line(s, first, amt));
firstw=restw;
first+=amt;
output_something=true;
@@ -444,7 +473,7 @@
if(!output_something)
{
- rval.push_back(chstring(""));
+ rval.push_back(fragment_line(L""));
firstw=restw;
}
@@ -499,27 +528,27 @@
for(fragment_contents::const_iterator i=lines.begin();
i!=lines.end(); ++i)
{
- chstring s=*i;
+ fragment_line s=*i;
size_t first=0;
// Build a list of words on the current line.
- vector<chstring> words;
+ vector<fragment_line> words;
bool output_something=false;
while(first<s.size())
{
// Strip leading whitespace.
- while(first<s.size() && isspace(s[first]&A_CHARTEXT))
+ while(first<s.size() && iswspace(s[first].ch))
++first;
size_t amt=0;
- while(first+amt<s.size() && !isspace(s[first+amt]&A_CHARTEXT))
+ while(first+amt<s.size() && !iswspace(s[first+amt].ch))
++amt;
if(amt>0)
- words.push_back(chstring(s, first, amt));
+ words.push_back(fragment_line(s, first, amt));
first+=amt;
}
@@ -545,8 +574,8 @@
if(nwords==0)
{
// Split a single word: just chop the beginning off.
- rval.push_back(chstring(words[word_start], 0, firstw));
- words[word_start]=chstring(words[word_start], firstw);
+ rval.push_back(fragment_line(words[word_start], 0, firstw));
+ words[word_start]=fragment_line(words[word_start], firstw);
firstw=restw;
output_something=true;
}
@@ -563,7 +592,7 @@
// Now spit the words into an output string, filled
// left and right.
- chstring final("");
+ fragment_line final(L"");
// This is similar to the famous algorithm for drawing
// a line. The idea is to add diff/(words-1) spaces
@@ -583,7 +612,7 @@
size_t nspaces=1+extra_spaces/(nwords-1);
extra_spaces%=nwords-1;
- final+=chstring(nspaces, ' ');
+ final+=fragment_line(nspaces, L' ', st.get_attrs());
}
final+=words[word+word_start];
@@ -599,7 +628,7 @@
if(!output_something)
{
- rval.push_back(chstring(""));
+ rval.push_back(fragment_line(L""));
firstw=restw;
}
}
@@ -656,24 +685,24 @@
{
if(i->empty())
{
- rval.push_back(chstring(""));
+ rval.push_back(fragment_line(L""));
firstw=restw;
}
else
{
- chstring s=*i;
- chstring::size_type start=0;
+ fragment_line s=*i;
+ fragment_line::size_type start=0;
while(s.size()-start>firstw)
{
- rval.push_back(chstring(s, start, firstw));
+ rval.push_back(fragment_line(s, start, firstw));
start+=firstw;
firstw=restw;
}
if(start<s.size())
{
- rval.push_back(chstring(s, start));
+ rval.push_back(fragment_line(s, start));
firstw=restw;
}
}
@@ -724,7 +753,7 @@
if(i->size()<=firstw)
rval.push_back(*i);
else
- rval.push_back(chstring(*i, 0, firstw));
+ rval.push_back(fragment_line(*i, 0, firstw));
firstw=restw;
}
@@ -773,8 +802,8 @@
if(restw<=restindent)
return fragment_contents();
- fragment_line firstprepend(firstindent, ' ');
- fragment_line restprepend(restindent, ' ');
+ fragment_line firstprepend(firstindent, L' ', st.get_attrs());
+ fragment_line restprepend(restindent, L' ', st.get_attrs());
firstprepend.apply_style(st);
restprepend.apply_style(st);
@@ -788,7 +817,7 @@
for(fragment_contents::const_iterator i=lines.begin(); i!=lines.end(); ++i)
{
- chstring l=((i==lines.begin())?firstprepend:restprepend)+*i;
+ fragment_line l=((i==lines.begin())?firstprepend:restprepend)+*i;
rval.push_back(l);
}
Modified: branches/aptitude-0.3/aptitude/src/vscreen/fragment.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/fragment.h (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/fragment.h Sat Jun 25 17:16:21 2005
@@ -81,7 +81,7 @@
*
* \return the new fragment
*/
-fragment *text_fragment(const std::string &s);
+fragment *text_fragment(const std::wstring &s);
/** Create a fragment from a string of text. The text will simply be
* formatted as a single line without clipping.
@@ -95,6 +95,24 @@
fragment *text_fragment(const std::string &s,
const style &st);
+/** Create a fragment from a string of multibyte-encoded text.
+ *
+ * \param s the text to use
+ * \param encoding the text's encoding; if this is \b null or
+ * unspecified, LC_CTYPE will be used.
+ *
+ * \return the new fragment
+ */
+fragment *transcode_fragment(const std::string &s,
+ const char *encoding=NULL);
+
+/** Create a fragment from a string of multibyte-encoded text,
+ * wrapping an implicit style_fragment around it.
+ */
+fragment *transcode_fragment(const std::string &s,
+ const style &st,
+ const char *encoding=NULL);
+
/** Create a fragment from a string of text. The text will simply be
* formatted as a single line without clipping.
*
@@ -158,7 +176,7 @@
* \param between a string to place between adjacent items in the input list
*/
fragment *join_fragments(const std::vector<fragment *> &fragments,
- const std::string &between);
+ const std::wstring &between);
/** Create a flowbox.
*
@@ -237,6 +255,7 @@
*
* - %F: substitutes a fragment into the sequence being built
* - %s: substitutes a const char * into the sequence being built
+ * with transcoding according to LC_CTYPE
* - %n: substitutes a newline fragment into the sequence being built
* - %%: inserts a literal %
* - %B/%b: toggle the bold character attribute
Modified: branches/aptitude-0.3/aptitude/src/vscreen/fragment_contents.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/fragment_contents.h (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/fragment_contents.h Sat Jun 25 17:16:21 2005
@@ -15,7 +15,7 @@
* worthwhile to change this to a rope<chtype> if this class is
* used to format larger pieces of text.
*/
-typedef chstring fragment_line;
+typedef wchstring fragment_line;
/** This class represents the formatted contents of a fragment.
*