מאמרים בנושא ‏תכנה ומחשבים‏.

לשרוד פיתוח תואם "Windows" בעידן Unicode...

ב־יום ראשון, 13 ביוני 2010, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, C++‎‏, Unicode, Boost‏; ‏8 תגובות

אם פיתחתם מעט עבור Windows אתם בוודאי מכירים את המושג שנקרא Wide-API. קרי לכל פונקציית המערכת יש שתי גרסאות: "ANSI" ו־"Wide", למשל: DeleteFileA ו־DeleteFileW, כאשר אחת מהן מקבלת char const *‎ והשניה wchar_t const *‎.

נחמד לא? יש לך שני סוגי API שנוח לך, או לעבוד עם המחרוזות הפשוטות או לעבוד עם מחרוזות מבוססות "תווים־רחבים". אבל, לא בדיוק.

למעשה, לפי מדיניות של Microsoft, כדי לגשת לכל הכוח של מערכת ההפעלה אתה חייב להשתמש ב־Wide API אחרת... אתה אפילו לא תוכל ליצור קובץ "שלום.txt". נחמד, לא?

הבעיה שלא C99 ולא, C++‎, וגם לא C++0x לא מכירים במושג העמעום של wide-path ולמעשה, לפי התקן אין, דרך לפתוח קובץ שהשם לו הוא "שלום.txt" מקודד כמחרוזת של wchar_t (רק char). כמובן חבר'ה ב־MS הם "ידידותיים" למפתחים והם הציע API חילופי: ‎_wfopen(wchar_t const *,wchar_t const *);‎ וגם הוסיפו הרחבה לסטנדרט ב־Visual Studio‏: std::fstream::open(wchar_t const *,...);‎ הכל לטובת המפתח (הם כנראה לא שמעו בכלל על UTF-8)...

כאן, מתחיל הסיוט, למעשה למפתח יש שתי אופציות:

  • להתעלם מהטמטום של Wide-API ולעבוד רק עם "ANSI-API" ו... התוכנה תפסיק לעבוד באופן אקראי על קבצים אקראיים, והמשתמשים המסכנים ישברו את הראש מה לא עובד.
  • להתחיל לשכפל את כל הקוד שלך למקרה wide ולמקרה נורמלי.

סיוט. לא פלא, שרבים בורחים באופציה הראשונה, ולכן בשנת 2010, אנחנו נתקלים יישומים כמו Thunderbird, שלא עובד כשתיקיית המשתמש שלך בחלונות מכילה תוים עבריים.

כך גם, אני כשהתחלתי תמיכה בחלונות ב־CppCMS החלטתי להתעלם מהעובדה ש־fopen או std::fstream::open לא יעבדו לי. אבל בסוף ייסורי מצפון הזיזו את כף־המאזניים: מספיק לכתוב קוד גרוע... והכנתי ספריית עזר קטנה, קראתי לה booster::nowide. כל מה שהיא עושה זה: להעביר ל־namespace שלך את הכלים סטנדרטיים שקיימים ב־stdio וב־STL בכל מערכות ההפעלה נורמליות. ובחלונות, היא פשוט עוטפת אתה API‏ ‎_w*‎ עם פונקציות משלה שממירות UTF-8 ל־UTF-16 ואז קוראות לפונקציות המתאימות.

בנוסף יצרתי מחלקות תואמות ל־std::fstream שעובדות מעל stdio (ועל הדרך סוף־סוף הבנתי כיצד לממש streambuf משלך).

התוצאה? אם אתה מתכוון לתמוך בחלונו, במקום לכתוב

std::ofstream f("שלום.txt")

שמייצרת ג'יבריש במקרה הטוב אתה כותב:

booster::nowide::ofstream f("שלום.txt")

וזה עובד בצורה שקופה, כנ"ל, std::fopen, std::freopen, std::remove, std::rename - רק החלף std::‎ ב־booster::nowide::‎.

במילים אחרות: no-more-wide-crap!

הספרייה היא חלק מ־booster של CppCMS ומופצת תחת רישיון Boost (משהו סגנון MIT). אם מישהו ירצה ספריה בלתי תלויה ב־booster, אז תגידו ואני אגזור אחת (לא מסובך בכלל).

קריאה נוספת: "Should UTF-16 be considered harmful?‎‏"

גרסת הספרית nowide התלויה בקומפיילר C++‎ לבלבד ניתנת להורדה כאן:
http://art-blog.no-ip.info/files/nowide.zip

אם מישהו יגיד לי כמה CMake נפלא וכמה autotools גרוע אני...

ב־יום ראשון, 6 ביוני 2010, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, ‏CMake‏; ‏2 תגובות

לאחרונה אני סבלתי מבעיות בניה מוזרות, פתאום אחרי עריכת כמה קבצים היו לי כשלונות בבניה. בהתחלה לא הבנתי מדוע זה קורה לי. חשבתי אולי משהו השתנה ב־svn והוא לא מעדכן נכון את ה־timestamp או אולי אני עשיתי איזושהי שטות.

היום סוף סוף הבנתי מה הבעיה ועוד פעם, כמה אני שונא CMake.

"למזלי", התקנתי שלשום CMake 2.8.1 מקוד מקור, כדי לדבג בעיה קומפיליצה ששברה את הבניה שלי (שעבדה יפה עם 2.6, אגב גם באג או ליתר דיוק שינוי מדיניות).

אז נתחיל בקצרה:

זה פלט של הפקודה בעבודה עם CMake 2.6

$ grep application.h CMakeFiles/cppcms.dir/depend.make
CMakeFiles/cppcms.dir/src/application.cpp.o: /usr/include/cppcms/application.h
CMakeFiles/cppcms.dir/src/applications_pool.cpp.o: /usr/include/cppcms/application.h
CMakeFiles/cppcms.dir/src/http_context.cpp.o: /usr/include/cppcms/application.h
CMakeFiles/cppcms.dir/src/internal_file_server.cpp.o: /usr/include/cppcms/application.h
CMakeFiles/cppcms.dir/src/rpc_json.cpp.o: /usr/include/cppcms/application.h
CMakeFiles/cppcms.dir/src/service.cpp.o: /usr/include/cppcms/application.h
CMakeFiles/cppcms.dir/src/url_dispatcher.cpp.o: /usr/include/cppcms/application.h

וזה פלט של אותה פקודה לגמרה בעבודה עם CMake 2.8

$ grep application.h CMakeFiles/cppcms.dir/depend.make
CMakeFiles/cppcms.dir/src/application.cpp.o: ../cppcms/application.h
CMakeFiles/cppcms.dir/src/applications_pool.cpp.o: ../cppcms/application.h
CMakeFiles/cppcms.dir/src/http_context.cpp.o: ../cppcms/application.h
CMakeFiles/cppcms.dir/src/internal_file_server.cpp.o: ../cppcms/application.h
CMakeFiles/cppcms.dir/src/rpc_json.cpp.o: ../cppcms/application.h
CMakeFiles/cppcms.dir/src/service.cpp.o: ../cppcms/application.h
CMakeFiles/cppcms.dir/src/url_dispatcher.cpp.o: ../cppcms/application.h

ההבדל ברור? אם לא, אני אסביר.

למרות שדגלוני הקומפיילר אומרים באופן מפורש להסתכל בתיקיה ".." "בודק התלויות" של CMake (במרכאות כפולות ומכופלות) מתעקש להסתכל על ספריות המערכת למרות שזה לא נכון בעליל.

האמת? אני לא מבין כיצד KDE אימצו כלי כזה? אני מבין שיש ל־CMake לא מעט יתרונות, רק שהבעיה שאני יותר נלחם בו מאשר נעזר בו. האם תמיכה ב־MSVC שווה את זה?

אגב, autotools משתמש בקומפיילר עצמו כדי לבנות תלויות כך שהתלויות יוצאות מדויקות לגמרי.

טוב, נו... מספיק להתבכיין, נראה לי אצטרך לשדרג את ה־CMake שלי לגרסה האחרונה.

נ.ב.: ik_5, אפילו אל תגיב... אני יודע מראש מה אתה תרצה לומר

Wikipp רץ על CppCMS 1.x.x !

ב־יום שלישי, 25 במאי 2010, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, CppCMS, C++‎‏; ‏0 תגובות

בשעה טובה, המרתי את Wikipp‏ לגרסת אלפה של CppCMS 1.x.x והיא רצה סוף־סוף ב"ייצור".

עוד שלב חשוב לשחרור גרסת בטא של CppCMS 1.x.x - שבו תוכננו מחדש ושוכתבתו מחצית מהרכיבים פנימיים שלו.

עדכנו אותי אם אתם נתקלים בבעיות.

ספריית Boost.Locale הוגשה לביקורת רשימית

ב־יום שני, 24 במאי 2010, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, C++‎‏, Unicode, Boost‏; ‏0 תגובות

בשעה טובה, הגשתי את הספריית לוקליזציה Boost.Locale‏ לביקורת רשמית (formal review) של קהילת ה־Boost. אם היא תעבור אותה היא תתקבל כחלק רשמי של Boost.

קישורים:

אעדכן אתכם על התפתחויות בהמשך.

עדכון: זה רשמי -- Boost.Locale התווספה לרשימת הספריות הממתינות לביקורת. עכשיו צריך שמישהו מהקהילה יתנדב להיות מנהל הביקורת (review manager).

הוספת הקשר לתרגומי Gettext

ב־יום שני, 24 במאי 2010, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, Unicode; ‏4 תגובות

אחת התכונות החסרות ביותר ב־gettext הייתה עד לא מזמן היא העדר אפשרות להעביר מידע על הקשר המילה. כך למשל, מילה "exchange" יכולה להיות מתורגמת ל"החלף" כשמדובר בחפצים ו"המר" כשמדובר בכסף. אבל אם שתי המילים מופיעות באותה תוכנה הדורשות תרגומים שונים בהקשרים שונים, ב־gettext לא הייתה שום דרך להבחין ביניהם.

החל מגרסה 0.15 התווספה התמיכה במה שנקרא הקשר. אם עד היום התרגום של מחרוזת "exchange" נעשה כ:

gettext("exchange");

אז הפונקציה pgettext מאפשרת להוסיף הקשר לתרגום:

pgettext("currency","exchange");

שיכולה להיות מתורגמת בצורה נכונה בכל הקשר. בקטלוג מחרוזות po הדוגמה הזו תופיע כ־

msgctxt "currency"
msgid "exchange"
msgstr "המר"

חשוב לזכור:

  • צריך להשתמש ב־gettext עדכני
  • צריך להשתמש בכלי תרגום עדכניים שיודעים לעבוד עם msgctxt.

    כך KBabel כלל לא תומך ב־msgctxt, ‏poedit לא מציג מידע על הקשר. עד כמה שידוע לי, גרסאות עדכניות של lokalize ו־gtranslator תומכות בהקשרים במילוני gettext.

כמובן שגם Boost.Locale תומך בהקשרים של Gettext.

העמוד הבא

העמוד הבא

דפים

נושאים