<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
	<title>הבלוג של ארתיום :: icode‏‏Un</title>
	<link>http://art-blog.no-ip.info/newpress/blog</link>
	<description>בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!</description>
	<atom:link 
		href="http://art-blog.no-ip.info/newpress/blog/rss" 
		rel="self" type="application/rss+xml" />
	
		
		<item>
			<title>תכירו Boost.Locale</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/239</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/239</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;אחרי תהיות עמוקות על תמיכה בלוקליזציה ב־C++‎, הבנתי שלא ניתן יהיה ללכת איתה רחוק. לקחתי ICU והתחלתי לעטוף אותו בסביבה ידידותית לתכנות C++‎ מודרני.&lt;/p&gt;

&lt;p&gt;אחרי הרבה עבודה הבנתי&amp;hellip; כל מה שאני עושה יהיה שימושי הרבה מעבר ל־CppCMS ולכן החלטתי להכין ספריה נפרדת שמטפלת בלוקליזציה במטרה לשלב אותה ב־Boost. כך נולד Boost.Locale שנותנת כלים פשוטים וחזקים לעבודה עם לוקליזציה.&lt;/p&gt;

&lt;p&gt;דוגמה פשוטה שתבהיר את החשיבותה ועוצמתה. הנה קטע קוד שמציג למשל את תאריך המאמר באתר:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;out &amp;lt;&amp;lt; format(translate(&quot;{1}, posted  at {2,date} on {2,time} by {3}&quot;))
          % title % date % author;
&lt;/pre&gt;

&lt;p&gt;ועכשיו המתרגם יכול לתרגם את המשפט לצורה הבאה:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&quot;{1}, פורסם ב{2,locale=he_IL@calendar=hebrew,date} ‏(לועזי {2,date}) ב־{2,time} ע&quot;י {3}&quot;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;מה קרה כאן? התצוגה באנגלית תהיה&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;‎Some article was published at 11/8/2009 on 10:30 PM by somebody&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;כאשר התצוגה בעברית תהיה&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;מאמר מסוים פורסם בכ&quot;א בחשון התש&quot;ע (לועזי 08/11/2009) ב־22:30 ע&quot;י מישהו&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;למעשה, בלי שימוש ב־libhdate, בלי לעבוד קשה מידי, קיבלתי אפשרות להציג את התאריך העברי והלועזי לפי הלוקל העברי, רק בגלל ש־ICU תומך בלוח־השנה העברי.&lt;/p&gt;

&lt;p&gt;למעשה, עבזרת Boost.Locale ניתן לעשות המון דברים בצורה פשוטה. למשל:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;cout &amp;lt;&amp;lt; as::spellout &amp;lt;&amp;lt; 123 &amp;lt;&amp;lt;endl;
&lt;/pre&gt;

&lt;p&gt;יידפיס בלוקל עברי&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;מאה עשרים ושלוש&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;יאפשר לחלק מילה &quot;שָלוֹם&quot; לארבעה תווים בהתחשב בניקוד: &quot;שָ&quot;, &quot;ל&quot;, &quot;וֹ&quot; ו־&quot;ם&quot; ועוד. למיין טקסט בצורה נכונה ועוד עשרות פעולות חשובות שניתנות ע&quot;י ICU רק בצורה נוחה וטבעית ל־C++‎.&lt;/p&gt;

&lt;p&gt;תכירו Boost.Locale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;תיעוד &lt;a href=&quot;http://cppcms.sourceforge.net/boost_locale/docs/&quot;&gt;http://cppcms.sourceforge.net/boost_locale/docs/&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;תיעוד מפורט של פונקציות ומחלקות: &lt;a href=&quot;http://cppcms.sourceforge.net/boost_locale/docs/doxy/html/&quot;&gt;http://cppcms.sourceforge.net/boost_locale/docs/doxy/html/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;קוד מקור (דרך svn)‏ &lt;a href=&quot;https://cppcms.svn.sourceforge.net/svnroot/cppcms/boost_locale/trunk&quot;&gt;https://cppcms.svn.sourceforge.net/svnroot/cppcms/boost_locale/trunk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;תהנו, אשמח גם לתגובות.&lt;/p&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/239"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>על תמיכה בלוקליזציה ב־C++‎ ועל תקן שבור</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/238</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/238</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;ככל שעובד הזמן אנחנו מתקרבים יותר ויותר לתקן C++‎ החדש שבהחלט מעשיר את השפה בהרבה כלים חיוניים &amp;ndash; הן מבחינת ליבת השפה והן לבחינת הספריה הסטנדרטית.&lt;/p&gt;

&lt;p&gt;אבל נשאר מקום אחד שבו C++0x כמעט ולא נגע, אפילו שהתקן שבור לחלוטין &amp;ndash; לוקליזציה&amp;hellip;&lt;/p&gt;

&lt;p&gt;לצורך הדגמה בואו נכתוב תכנה טרוייואלית שמדפיסה מספר לקובץ טקסט number.txt:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;fstream&amp;gt;
#include &amp;lt;locale&amp;gt;


int main()
{
        // Set global locale to system default;
        std::locale::global(std::locale(&quot;&quot;));

        // open file &quot;number.txt&quot;
        std::ofstream number(&quot;number.txt&quot;);

        // write a number to file and close it
        number&amp;lt;&amp;lt;13456&amp;lt;&amp;lt;std::endl;
}
&lt;/pre&gt;

&lt;p&gt;תכנה פשוטה אפילו טריוויאלית. עכשיו בואו נעשה אותו דבר ב־C.&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;locale.h&amp;gt;

int main()
{
        setlocale(LC_ALL,&quot;&quot;);
        FILE *f=fopen(&quot;number.txt&quot;,&quot;w&quot;);
        fprintf(f,&quot;%'i\n&quot;,13456);
        fclose(f);
        return 0;
}
&lt;/pre&gt;

&lt;p&gt;גם פשוט ביותר.&lt;/p&gt;

&lt;p&gt;בואו נריץ את התכנות כאשר הלוקל הוא &lt;code&gt;en_US.UTF-8&lt;/code&gt;&amp;hellip; ונקבל בקובץ number.txt את המספר: 13,456, עכשיו נעשה אותו דבר, רק נגדיר לוקל נפוץ אחר &lt;code&gt;ru_RU.UTF-8‏&lt;/code&gt;: כך &lt;code&gt;LC_ALL=ru_RU.UTF-8 ./a.out&lt;/code&gt; ונקבל:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt; ‎13&amp;lt;?&amp;gt;456
&lt;/pre&gt;

&lt;p&gt;כאשר אם נריץ תכנה ב־C נקבל דווקא משהו נכון: ‎13 456&lt;/p&gt;

&lt;p&gt;אופס&amp;hellip; מה קרה כאן? כשאני עושה את אותו הדבר דרך C ודרך C++‎ אני מקבל תוצאה שונה, יותר מזה, הפלט של תכנה שכתובה ב־C++‎ מצביעה על טקסט UTF-8 לא תקין! (אפשר לבדוק בקלות עם iconv).&lt;/p&gt;

&lt;p&gt;מה בעצם קראה כאן?&lt;/p&gt;

&lt;p&gt;לפי הגדרות הלוקל הרוסי. התו שמפריד בין אלפים ומאות הוא תו U2002 &amp;ndash; ‏ EN SPACE &amp;ndash; סוג של רווח שונה מרווח ASCII רגיל U0020. כלומר בגלל שמדובר בתו Unicode שהוא לא בתחום ASCII הוא צריך להיות מקודד כמחרוזת ארוכה מבית 1.&lt;/p&gt;

&lt;p&gt;אז למה ספריית C מתמודדת יפה מאוד עם בעיה זו וספריית C++‎ לא?&lt;/p&gt;

&lt;p&gt;עכשיו בואו נסתכל בהגדרות הסביבה להצגת מספרים: המחלקה &lt;a href=&quot;http://www.cplusplus.com/reference/std/locale/numpunct/&quot;&gt;‏std::numpunct&lt;char&gt;‎&lt;/a&gt; מייצגת את סימון ההפרדה &lt;a href=&quot;http://www.cplusplus.com/reference/std/locale/numpunct/thousands_sep/&quot;&gt;thousands_sep‏&lt;/a&gt; כבית בודד! לכן אין שום סיכוי לייצג תו Unicode U2002, לעומת זאת, ספריית C, &lt;a href=&quot;http://linux.die.net/man/7/locale&quot;&gt;מייצגת&lt;/a&gt; את סימון ההפרדה כמחרוזת ולא כתו בודד. מכאן, אין שום בעיה לייצר מספרים.&lt;/p&gt;

&lt;p&gt;זאת הייתה דוגמה של בעיוה הטריוויאלית לשחזור. קיימים עוד בעיות עקרוניות רבות כאלה בתקן לוקליזציה הקיים ב־C++‎ היום. חבל שהוועדה שמטפלת ב־C++0x כלל לא התייחסת לנושא זה &amp;mdash; אולי הגיע זמן להעלות את הנושא?&lt;/p&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/238"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>ייסורי בינאום ולוקליזציה בשנת 2009</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/237</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/237</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;מה יותר פשוט מאשר להציג תאריך ושעה בהתאם למקובל באיזור? בארה&quot;ב תכתוב ‎6/15/2008 8:30 PM ובישראל תכתוב 15/6/2008 20:30. לא מסובך, נכון? כמובן ‎&lt;a href=&quot;http://www.cplusplus.com/reference/clibrary/ctime/strftime/&quot;&gt;strftime&lt;/a&gt;‎ עושה את העבודה הנאמנה בצורה טובה. אכן, יש אופציות ‎&quot;%x&quot;‎ ו־‎&quot;%X&quot;‎ להצגת תאריך ושעה בהתאם ללוקל מקומי.&lt;/p&gt;

&lt;p&gt;עכשיו בואו נעשה את הדרך ההפוכה: יש לנו טופס HTML בו אנחנו רוצים להציג תאריך ולתת למשתמש אפשרות לערוך אותו? במילים אחרות אני רוצה אופציה של פענוח תאריך ושעה לפי התבנית המקובלת לאיזור ובשפה הספציפיים&amp;hellip; ואכן, יש פונקציה הפוכה ל־strftime ‏&amp;mdash; strptime. שעושה את העבודה ההפוכה.&lt;/p&gt;

&lt;p&gt;כמובן גם ב־C++‎ יש מקבילות &lt;code&gt;std::facet&lt;/code&gt; מסוג: &lt;code&gt;std::time_put&lt;/code&gt; ו־&lt;code&gt;std::time_get&lt;/code&gt; עושות את העבודה וגם מאפשרות להשתמש ביותר מ־locale אחד בתהליך, שמאפשר, למשל לייצר טקסט שונה למשתמשים שונים בחוטים שונים. ב־C ובשירותי מערכת ההפעלה הסטנדרטיים אין כלי כזה, יש רק &lt;code&gt;strftime_l&lt;/code&gt; ו־&lt;code&gt;strptime_l&lt;/code&gt; הלא מתועדים ולא מוגדרים לפי סטנדרט שעושים את העבודה.&lt;/p&gt;

&lt;p&gt;מכאן, הכל פשוט&amp;hellip; על הנייר. במציאות המצב הרבה יותר מסובך:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;הגדרות סטנדרט C++‎ של &lt;code&gt;std::time_get&lt;/code&gt; מכילות באג לוגי שמקשה מאוד על יצירת כלים לפענוח תאריך ושעה בצורה נכונה וגם כשעובדים, הם עושים זאת בצורה חלקית &amp;mdash; כי אין מקבילה של strptime המלאה של C.&lt;/li&gt;
&lt;li&gt;גם API של C, מסתבר כלא תמיד עובד כמו שצריך.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;לצורך ההשוואה, בניתי תכנה פשוטה, שמייצרת מחרוזת עם תאריך ושעה בעזרת כלֵי C,‏ C++‎ וספריית ICU. ולאחר מכן מפענחת אותה אם אותם הכלים. בדקתי את זה עבור מספר לוקלים. בטבלה למטה מוצגים: לוקל, שעה ותאריך כפי שמייוצרים ע&quot;י כלים שונים והפענוח של אותם תאריך ושעה המוצגים בפורמט בינלאומי.&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;    en_US.UTF-8
    strftime        10/05/2009 11:36:38 PM to 2009-10-05 23:36:38
    std::facet      10/05/2009 11:36:38 PM to 2009-10-05 00:00:00
    icu::DateFormat Oct 5, 2009 11:36:38 PM to 2009-10-05 23:36:38
    he_IL.UTF-8
    strftime        05/10/09 23:36:38 to 2009-10-05 23:36:38
    std::facet      05/10/09 23:36:38 to 1909-10-05 23:36:38
    icu::DateFormat 23:36:38 05/10/2009 to 2009-10-05 23:36:38
    de_DE.UTF-8
    strftime        05.10.2009 23:36:38 to 2009-10-05 23:36:38
    std::facet      05.10.2009 23:36:38 to 2009-10-05 23:36:38
    icu::DateFormat 05.10.2009 23:36:38 to 2009-10-05 23:36:38
    en_GB.UTF-8
    strftime        05/10/09 23:36:38 to 2009-10-05 23:36:38
    std::facet      05/10/09 23:36:38 to 1909-10-05 23:36:38
    icu::DateFormat 5 Oct 2009 23:36:38 to 2009-10-05 23:36:38
    ja_JP.UTF-8
    strftime        2009年10月05日 23時36分38秒 to 2009-10-05 23:36:38
    std::facet      2009年10月05日 23時36分38秒 to 2009-10-05 23:36:38
    icu::DateFormat 2009/10/05 23:36:38 to 2009-10-05 23:36:38
    ar_EG.UTF-8
    strftime        05 أكت, 2009 IST 11:36:38  to 2009-10-05 00:00:00
    std::facet      05 أكت, 2009 IST 11:36:38  to 2009-10-05 11:36:38
    icu::DateFormat ٠٥/١٠/٢٠٠٩ ١١:٣٦:٣٨ م to 2009-10-05 23:36:38
    tr_TR.UTF-8
    strftime        05-10-2009 23:36:38 to 2009-10-05 23:36:38
    std::facet      05-10-2009 23:36:38 to 2009-10-05 23:36:38
    icu::DateFormat 05.Eki.2009 23:36:38 to 2009-10-05 23:36:38
    ru_RU.UTF-8
    strftime        05.10.2009 23:36:38 to 2009-10-05 23:36:38
    std::facet      05.10.2009 23:36:38 to 2009-10-05 23:36:38
    icu::DateFormat 05.10.2009 23:36:38 to 2009-10-05 23:36:38
    zh_CN.UTF-8
    strftime        2009年10月05日 23时36分38秒 to 2009-10-05 23:36:38
    std::facet      2009年10月05日 23时36分38秒 to 2009-10-05 23:36:38
    icu::DateFormat 2009-10-5 下午11:36:38 to 2009-10-05 23:36:38
&lt;/pre&gt;

&lt;p&gt;כפי שניתן לראות:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;std::facet לא מתמודד עם שעון של 12 שעות המכיל ציון AM/PM.‏&lt;/li&gt;
&lt;li&gt;std::facet לא מוסוגל לשחזר שנה בעזרת שתי ספרות בלבד וזורק אותנו משנת 2009 ל־1909 ב־2 מתוך 9 דוגמאות.&lt;/li&gt;
&lt;li&gt;strptime לא מצליח לשחזר שעה בכלל ו־std::facet וטועה ב־12 שעות בלוקל מצרי.יש לציין שזה באג בייצוג locale כי הפורמט המוגדר הוא ‎&quot;%Z %I:%M:%S&quot;‎ במקום ‎&quot;%p %I:%M:%S&quot;‎ &amp;mdash; להציג איזור זמן במקום סימון AM/PM המתאים (م).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;במילים אחרות&amp;hellip; מימוש של std::facet גרוע, יש בעיות בייצוג locale באופן כללי.&lt;/p&gt;

&lt;p&gt;עצוב שזה המצב בשנת 2009&amp;hellip;&lt;/p&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/237"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>לרגל שחרורו של gcc-4.4... חידושים ושיפורים.</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/223</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/223</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;לפני כחודש שוחררה גרסה חדשה של gcc:‏ 4.4. אחד הדברים המעניינים זה התקדמות בתמיכה בתקן C++‎ החדש C++0x. הנה כמה תכונות מאוד מעניינות שכבר מזמן חיכיתי להן:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;סוף־סוף, הגיע אחת התכונות &lt;a href=&quot;http://stackoverflow.com/questions/137812/whats-your-favorite-c0x-feature&quot;&gt;הנחשקות ביותר&lt;/a&gt; &amp;mdash; תמיכה ב־&lt;strong&gt;auto&lt;/strong&gt;, שחוסכת המון הקלדה מיותר ומקלה בצורה משמעותית על כתיבת קוד בלתי תלוי בקונטיינרים. לדוגמה, היום כך כותבים לולאה שמדפיסה איברי הרשימה:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;for(list&amp;lt;int&amp;gt;::contst_iterator p=numbers.begin();p!=numbers.end();++p)
{
    cout&amp;lt;&amp;lt; *p &amp;lt;&amp;lt;endl;
}
&lt;/pre&gt;

&lt;p&gt;ואם רוצים לשנות את סוג הקונטיינר מ־list ל־vector צריך לשנות את &lt;code&gt;list&lt;/code&gt; ל־&lt;code&gt;vector&lt;/code&gt; בלולאה. עם טיפוס auto זה מתקצר בצורה משמעותית:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;for(auto p=numbers.begin();p!=numbers.end();++p)
{
    cout&amp;lt;&amp;lt; *p &amp;lt;&amp;lt;endl;
}
&lt;/pre&gt;

ובנוסף ל&quot;קיצור&quot; הכתיבה, אין שום אזכור של סוג הקונטיינר בלולאת for.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;טיפוסי תווים חדשים&lt;/strong&gt;. בסטנדרט הנוכחי יש בעיה משמעותית בהגדרת תווי unicode, או ליתר דיוק העדר הגדרה ראויה שלהם. כך &lt;code&gt;wchar_t&lt;/code&gt; למעשה יכול להיות בגודל של 32 ביטים, 16 ביטים ואפילו 8 ביטים. למעשה, בסביבת Windows, ‏&lt;code&gt;wchar_t&lt;/code&gt; הוא בגודל של שני בתים ומייצג utf-16 (או ucs-2), כאשר בכל סביבות ה־UNIX, ‏&lt;code&gt;wchar_t&lt;/code&gt; מייצג נקודת קידוד בודדת והוא בגודל של 32 ביט. זה יוצר לא מעט בעיות בטיפול במחרוזות unicode. כי הקידוד של std::wstring לא ברור.&lt;/p&gt;

&lt;p&gt;התקן החדש הגדיר שני טיפוסי תווים חדשים: &lt;code&gt;char16_t&lt;/code&gt; ו־&lt;code&gt;char32_t&lt;/code&gt; שמונעים את האי בהירות בנושא. כך שהעבודה עם std::u16string ו־std::u32string הופכת להרבה יותר שקופה. כך, בנוסף הוגדר ייצוג חדש למחרוזות:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;std::string normal=&quot;שלום&quot;; // encoded as 8 bit
std::wstring wide=L&quot;שלום&quot;; // utf16 or utf32 depending on your OS
std::u16string utf16=u&quot;שלום&quot;; // utf16 encoded
std::u32string utf32=U&quot;שלום&quot;; // utf32 encoded
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;כמובן, לא צריך לשכוח את התמיכה ב־&lt;strong&gt;Variadic templates&lt;/strong&gt; שהתווספה ב־gcc-4.3, המאפשרת לבנות פונקציות typesafe עם מספר משתנה של פרמטרים בצורה בטוחה, קצרה ומהירה. התמיכה בהן מקצרת בצורה בסדר גודל את זמן הקומפילציה של תבניות כמו std::function או std::bind.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;מבחינתי, יש עוד מספר תכונות שאני מחכה להן:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;תמיכה בביטויי למבדא.&lt;/li&gt;
&lt;li&gt;תמיכה ב־delegating and inheriting constructors שמקצרת בצורה משמעותית את הכתיבה של overloaded constructors.&lt;/li&gt;
&lt;li&gt;תמיכה ב־Concepts שייאפשר לספק פלט שגיאות הרבה יותר ידידותי.&lt;/li&gt;
&lt;li&gt;תמיכה מלאה ב־STL החדש, כולל regular expressions.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;אני מקווה שזה לא ייקח הרבה זמן&amp;hellip;&lt;/p&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/223"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>האם אתה מוכן לבינאום ולוקליזציה?</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/218</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/218</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;הכנתי שאלון קצת שמאפשר לכם לבדוק&amp;hellip; האם אתם מוכנים לכתיבת תכנה שתהיה מוכנה להתאמה לתרבויות שונות?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;אני רוצה לייצג מחרוזת, כ־&lt;code&gt;char *some_text&lt;/code&gt;. מהו המידע שחסר לי?&lt;/li&gt;
&lt;li&gt;יש לי מחרוזת &lt;code&gt;wchar_t *text&lt;/code&gt; או &lt;code&gt;String text&lt;/code&gt; ב־Java, אני רוצה לקחת את התו הראשון שלה:

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt; wchar_t c=text[0]; // C
 Char c=text.charAt(0); // Java
&lt;/pre&gt;

האם זהו קוד נכון?&lt;/li&gt;
&lt;li&gt;אני כותב את הקוד הבא:

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt; if n==1:
     print translate(&quot;You have one aplle&quot;)
 else:
     print translate(&quot;You have %d apples&quot;) % n
&lt;/pre&gt;

 מה לא בסדר בקוד הזה?&lt;/li&gt;
&lt;li&gt;מה לא בסדר בקוד הבא:

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt; #include &amp;lt;stdio.h&amp;gt;
 #include &amp;lt;time.h&amp;gt;

int main()
{
        time_t now_t=time(NULL);
        struct tm *now=localtime(&amp;amp;now_t);
        char str_time[32];
        strftime(str_time,sizeof(str_time),&quot;%d/%m/%y&quot;,now);
        printf(&quot;Today is %s\n&quot;,str_time);
        return 0;
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;מהו גודל הזכרון הנדרש לשמירת תו unicode בודד?&lt;/li&gt;
&lt;li&gt;מהו גודל של wchar_t? (למתכנתי C++/C)‏?&lt;/li&gt;
&lt;li&gt;מהי גודל של תו unicode בשפת התכנות שאתה אוהב?&lt;/li&gt;
&lt;li&gt;מהו קידוד של מחרוזת (unicode) בשפת התכנות/toolkit שאתה אוהב?&lt;/li&gt;
&lt;li&gt;מה הבדל בין utf-8,‏ utf-16, ‏utf-32?‏&lt;/li&gt;
&lt;li&gt;מהו אורך התו הארוך ביותר ב־utf8?‏&lt;/li&gt;
&lt;li&gt;בניתי ספרייה עם שתי פונקציות בלבד. מה לא בסדר בקוד הבא (שתי בעיות לפחות)?

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;extern Char32 to_upper_char(Char32);
void to_upper(String str)
{
        for(int i=0;i&amp;lt;str.size();i++)
                str[i]=to_upper(str[i]);
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;מה לא בסדר בקוד הבא:

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;def print_error_message(message):
    print translate(&quot;Error occured: &quot;)+&quot;“&quot;+translate(message)+&quot;”&quot;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;מה לא בסדר בקוד הזה:

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;&amp;lt;?php $rtl_langs=array(&quot;he&quot;,&quot;ar&quot;,&quot;pa&quot;); ?&amp;gt;
...
&amp;lt;div &amp;lt;?php if(in_array($lang,$rtl_langs) echo 'dir=&quot;rtl&quot;'; ?&amp;gt; &amp;gt;
...
&amp;lt;/div&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;אני רוצה לחתוך את הטקסט בצורה יפה, כך שזה לא ייחתך באמצע המילה: מה לא בסדר בקוד הבא:

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;// Cut nice pice of text
wstring cut_nicely(wstring const &amp;amp;orig,int n)
{
   if(orig.size()&amp;lt;=n) return orig;
   return orig.substr(orig.find_first_of(L&quot; \r\n\t\f&quot;,n));
}
&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;


			&lt;p&gt;
			&lt;a href="/newpress/blog/post/218"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>Unicode ב־C++‎ תיקון טעות.</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/217</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/217</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;עדכון קטן על תמיכה ב־Unicode ב־C++‎. למעשה, כשאמרתי ב&lt;a href=&quot;http://art-blog.no-ip.info/newpress/blog/post/216&quot;&gt;כתבה קודמת&lt;/a&gt; שאין כל תמיכה ב־Unicode, טעיתי. דווקא יש תמיכה אם כי היא לא מתקרבת למה ש־ICU נותן.&lt;/p&gt;

&lt;p&gt;std::locale נותן מספר ממשקים בפרט: std::ctype&amp;lt;&gt;‎ שמאפשר המרה של case והמרת קידוד בין קידוד מקומי כמו utf-8 או cp1255 למחרוזות של wchar_t. הוא מצליח להמודד עם מקרים יחסית פשוטים כמו המרת &quot;Артём&quot; (השם הפרטי שלי ברוסית) לאותיות גדולות וקטנות בצורה נכונה: АРТЁМ. דבר שכל הכלים, אפילו פחות מוצלחים כמו Python ו־qt3 מצליחים לבצע ללא בעיה.&lt;/p&gt;

&lt;p&gt;אבל תמיכה מובנית עדיין לא מצליחה להתמודד עם מקרים מסובכים יותר כמו ß הגרמנית ו־Σ היוונית.&lt;/p&gt;

&lt;p&gt;כך שלצרכים הבסיסיים, ניתן להסתפק ב־API של C++‎ כפישהו, אבל כמובן זאת לא תמיכה מלאה (כמו גם בשפות אחרות, משל Python).&lt;/p&gt;

&lt;p&gt;לדוגמה toupper‏:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;cpp&quot; &gt;// Set global locale
locale::global(locale(&quot;en_US.UTF-8&quot;));

// Now we can use locale for various purposes
wchar_t str[]=L&quot;Артём&quot;;
use_facet&amp;lt;ctype&amp;lt;wchar_t&amp;gt; &amp;gt;(locale()).toupper(str,str+5);
&lt;/pre&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/217"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>ייסורי Unicode ב־2009, או תמיכה ב־unicode בסביבות שונות.</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/216</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/216</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;אחד הדברים החסרים ביותר ב־C++‎, מבחינתי, זה העדר תמיכה טובה ב־Unicode. למרות ש־std::wstring ו־std::locale קיימים הם לא נותנים מענה על כל דרישות העבודה עם Unicode.&lt;/p&gt;

&lt;p&gt;יש שפות תכנות כמו Python ו־Java בהן התמיכה הזו נחשבת ל&quot;טבעית&quot;. אז החלטתי לעשות בדיקה ולבדוק מספר דברים חיוניים בעיבוד טקסט טבעי: החלפה בין אותיות גדולות וקטנות וכן מציאת גבולות המילים. דברים שנראים טריוויאליים עבור אנגלית למעשה הופכים לכלל לא טריויאליים כאשר מדובר בשפות אחרות:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;שינוי אות קטנה לגדולה: ß גרמנית צריכה להפוך ל־SS (שתי אותיות).&lt;/li&gt;
&lt;li&gt;שינוי אות גדולה לקטנה: Σ היוונית הופכת ל־σ במרכז המילה ול־ς בסופה.&lt;/li&gt;
&lt;li&gt;הפרדת מילים לצורך חיתוך הטקסט: 中文 אלה שתי מילים ולא מילה אחת.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;בדקתי 6 כלים: ספריית ICU עם API במספר שפות, ספריית glib יחד עם pango עבור C, ספריות Qt3 ו־Qt4  עבור C++‎, וגם כלים טבעיים של Java, ‏C++‎ ושל Python.&lt;/p&gt;

&lt;p&gt;אקדים ואומר, המקרים הפשוטים כמו המרת: &quot;Артём&quot; (השם הפרטי שלי ברוסית) ל&quot;АРТЁМ&quot; עבדו בכל הכלים ושפות, אבל במקרים יותר מורכבים התוצאות היו כלל לא מעודדות:&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;כלי&lt;/th&gt;&lt;th&gt;לאותיות גדולות&lt;/th&gt;&lt;th&gt;לאותיות קטנות&lt;/th&gt;&lt;th&gt;גבולות המילים&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;C++‎&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;td&gt;אין תמיכה&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;C++/ICU‎&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;C++/Qt4‎&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;C++/Qt3‎&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;td&gt;אין תמיכה&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;C/glib+pango&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Java/JDK&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Java/ICU4j&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;td&gt;נכשל&lt;/td&gt;&lt;td&gt;אין תמיכה&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Python/PyICU‎&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;td&gt;הצליח&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;


&lt;h3&gt; עכשיו פרטים&lt;/h3&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/216"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>מתיאוריה למציאות, או עד כמה UTF-16 באמת בעייתי</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/170</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/170</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;בהמשך ל&lt;a href=&quot;http://art-blog.no-ip.info/newpress/blog/post/169&quot;&gt;פוסט הקודם&lt;/a&gt;, החלטתי לעשות סקירה קצרה: &quot;האם באמת תכנות שכתובות עם utf-16 לא עובדות כמו שצריך עם קידודים כפולים ומה קורה עם תכנות שמשתמשות בייצוג פנימי ב־utf-8/utf-32?&quot;&lt;/p&gt;

&lt;p&gt;לקחתי תו &lt;span style=&quot;font-size:150%&quot;&gt;&quot;𠂊&quot;&lt;/span&gt; או U+2008A וניסיתי להציג אותו ביישומים שונים מבוססים על toolkitים שונים. התו הזה מתייחס ל־&lt;a href=&quot;http://en.wikipedia.org/wiki/Template:Unicode_chart_CJK_Unified_Ideographs_Extension_B&quot;&gt;CJK Unified Ideographs Extension B‏&lt;/a&gt; ולא לא יכול להיות מיוצג ב־utf-16 בעזרת איבר אחד (שני בתים) אלא דורש צירוף של שני איברים (ארבעה בתים).  אם אתם לא רואים את התו הזה, או רואים אותו כריבוע בדפדפן שלכם, אפשר להתקין גופן חופשי: AR PL ShanHeiSun Uni, בעלי דביאן יכולים להתקין חבילה ttf-arphic-uming.‏ חייב לציין, אין מי מושג מה התו או המילה האלה אומרים, כך שמתנצל מראש.&lt;/p&gt;

&lt;p&gt;קודם כל: היישומים שעובדים עם utf-16 שהתמודדו אתו בצורה יפה ונכונה (או פשוט לא מצאתי באגים ב־2 דקות ששיחקתי איתם) הם:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenOffice שעובד עם icu (אם כי, אני לא בטוח שהוא משתמש בו בייצוג פנימי)&lt;/li&gt;
&lt;li&gt;Microsoft Word עבד ללא בעיות ועובד עם Windows API המבוסס על utf16‏.&lt;/li&gt;
&lt;li&gt;FreeMind שכתוב ב־Java הצליח להציג את התו ולערוך טקסט בצורה מסודרת. (Java משתמשת ב־utf-16 במחרוזות שלה).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;אבל פה פחות או יותר נגמרו היישומים שעובדים עם utf-16 וגם מסתדרים עם התו הבעייתי. נתחיל:&lt;/p&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/170"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
		<item>
			<title>UTF-8, UTF-16, Unicode וכל מה שביניהם.</title>
			<link>http://art-blog.no-ip.info/newpress/blog/post/169</link>
			<guid>http://art-blog.no-ip.info/newpress/blog/post/169</guid>
			<description>
			&lt;div style=&quot;direction:rtl&quot;&gt;
			&lt;p&gt;היו היה בית, בתקופה של תחילת עידן המחשבים הוא היה מסוגל לשמור תו בודד. אבל אנושות הלכה והתפתח ויום אחד התברר שהוא לא מספיק. יש צרפתים, יש רוסים, יש סינים ולא ניתן לדחוף את הכל התווים הידועים לבית אחד מסכן. אז התאספו אנשים חכמים ובסוף שנות ה־80 &amp;mdash; תחילת 90 החליטו לבנות תקן אחיד שיכסה את כל השפות האפשריות &amp;mdash; Unicode.&lt;/p&gt;

&lt;p&gt;האנשים האלה חשבו וחישבו ששני בתים יספיקו לכסות את כל השפות אפשריות. כך נולד קידוד של Unicode בשני בתים. בתחילת ה־90, יצרתי UNIX הגדולים גם חשבו ובנו UTF-8 שכדי להבטיח תאימות לאחור עם כל התכנה הקיימת &amp;mdash; כך נולד קידוד בעל אורך משתנה.&lt;/p&gt;

&lt;p&gt;עבר הזמן, יצרני תכנה שונים הולכו בשני כיוונים: אחד להציג כל תו בשני בתים והשני להמשיך להשתמש ב־ANSI C String ולעבוד עם תווים בעלי ייצוג באורך שונה. אבל, באמצע שנות ה־90 כבר היה ברור ששני בתים לא יספיקו כדי לכסות את כל השפות האפשריות. ולכן התקן הורחב כך שהוא כלל ערכים מ־0 ועד ל־0x10FFFF.&lt;/p&gt;

			&lt;p&gt;
			&lt;a href="/newpress/blog/post/169"&gt;המשך...&lt;/a&gt;
			&lt;/p&gt;
			&lt;/div&gt;
			</description>
		</item>
		
	
</channel>
</rss>
