שוחררה גרסת 0.0.5 של CppCMS (ענף יציב)

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

שוחררה גרסה חדשה של ענף יציב של CppCMS, שינויים:

תיקוני בעיות אבטחה:

  • נכתב מעקף לבעיה של ספריית CgiCC שהיה יכול לגרום ל־DoS.
  • תוקנה בעיה שהייתה עלולה לגרום להווצרות SID בעלי אנטרופיה נמוכה.

תיקוני באגים:

  • תוקן זמן חיים של ערכים "חשופים" בניהול מצב (sessions)
  • תוקן באג שמנע אפשרות עבודה ב־FastCGI/SCGI מעל TCP/IP
  • תוקנו בעיות בניה עם גרסאות Boost לא סטנדרטיות.
  • תוקנו בעיות ביצירת HTTP Status Headers לא נכונים במקרה של שגיאות.
  • תוקנו בעיות בניה עם גרסאות gcc שונות ועם קומפיילר של אינטל.

שיפורים:

  • שופרו זמני בעיות views בצורה משמעות.

ל־CppCMS יש קהילה פעילה

ב־יום ראשון, 22 בנובמבר 2009, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, CppCMS; ‏6 תגובות

בחודש חודשיים אחרונים אני רואה פעילות ערה מסביב ל־CppCMS. רשימת התפוצה הפכה להיות פעילה, דיווחי באגים מגיעים ואפילו...

לפני ימים אחדים קיבלתי מספר דיווחי באגים ותרגום של הבלוג הזה לסינית, כך שאם מישהו רוצה בלוג שמיליארד סינים יוכלו לקרוא אותו בלי ליצור עומסים, זאת לא בעיה ;-).

האמת היא, אני שמח ש־CppCMS לאט־לאט צובר תאוצה והקהילה נבנית מסביבו.

למה להמציא גלגל מחדש זה לא תמיד עובד טוב

ב־יום חמישי, 12 בנובמבר 2009, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, C++‎‏, ‏CMake‏; ‏8 תגובות

לאחרונה אני מנסה להגר ל־CMake מ־autotools בפרויקט CppCMS בעיקר כדי להבטיח תמיכה טובה יותר בסביבת Windows ובפרט ב־MSVC מתישהו בעתיד.

עשיתי כבר הרבה עובדה והענף הניסיוני עבר ל־CMake. אפילו לא מעט אנשים ברשימת התפוצה התלהבו מהעובדה שהמערכת תעבוד על CMake... רבים חוץ ממני. אחרי שהתחלתי לעבוד אתה בצורה יותר עניינית הבנתי: היא באמת יותר מוצלחת בפיתוח ל־Windows מאשר autotools בעיקר בגלל שהיא קצת יותר גמישה בנושא ה־exports וכמובן התמיכה ב־MSVC.

אבל פה בערך נגמר היתרון. עכשיו אני אתלונן על דברים שמעצבנים אותי:

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

  1. ב־autotools הייתה הפרדה ברורה בין automake שמגדיר את מבנה הפרויקט לבין autoconf שמגדיר את קונפיגורציית הפלטפורמה. מצד אחד זה היה קצת מפריע אבל מצד שני זה היה מאוד נוח: הוספת קובץ חדש לא פרויקט לא דרשה הרצת configure מחדש מצד אחד, מצד שני כל שינוי בצורת הקונפיגורציה ביצע הרצת configure שלמה.

    לעומת זאת, CMake אף פעם לא מנקה את ה־Cache שלו (אלא אם אתה עושה את זה במפורש). מה שגורם לכך ששינויים בקונפיגורציה לא תמיד יבואו לידי ביטוי כי ב־cache שלו הוא זוכר משהו אחר (אולי בדיקה אחרת לא תקינה).

    מצד שני, אם אני מוחק CMakeCache ומעדכן את CMakeLists.txt הוא לא זוכר את הפרטרים המקורים שהרצתי אתו את cmake כמו "איפה נמצאות הספריות או איזו אופציה שאני העברתי"

  2. מנגנון מעקב אחרי התלויות של CMake לא בודק את הקובץ config.h משמע... אם עשיתי שינויים בקונפיגורציה הקוד לא ייבנה מחדש. צריך להריץ make clean ו־make שוב! העיקר שיש להם cache חזק.

הרבה מגנונים הקיימים לוקים בחסר או לא מתוכננים היבט. לדוגמה:

  1. משהו מאוד פופולרי כמו AC_SEARCH_LIBS שמאפשר לך לבדוק אם פוקנציה מסוימת קיימת, אם כו אז אל תעשה דבר, חפש אותה בספריות. דוגמה קלאסית. pthreads, iconv, dlopen, socket שלפעמים מהווים חלק מהספרייה הסטנדרטית ולפעמים דורשים ספריות חיצוניות. אין פונקציונליות כזו בכלל.
  2. בדיקת sizeof היא בכלל פנינת CMake. יש לה מספר בעיות:

    • היא נעשית ע"י הרצת קוד מה שאומר היא לא תעבוד בקרוס־קומפילציה. כאשר ב־autotools עושים טריק מאוד יפה המאפשר לבצע בדיקה כזו ללא הרצת קוד אלא קומפילציה בלבד.
    • היא לא מאפשרת להוסיף header כך שלא ניתן לבדוק sizeof של טיפוסים הנמצאים ב־includes לא סטנדרטיים.
  3. אין פונקציונליות דומה ל־AC_ARG_ENABLE המאפשרת להציג רשימת הפרמטרים לקונפיגורציה והערות לגביהם -- קרי אין כלי כמו ‎./configure --help שמאוד עוזר בהרבה מקרים.

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

אני מקווה שיום אחד autotools ידעו לתמוך גם ב־MSVC בסה"כ זה לא אמור להיות מי יודע מה מסובך... ICU משתמשים ב־autotools יחד עם MSVC בצורה מוצלחת למידי (למעשה הבעיה היא אפילו לא automake ו־autoconf הם דווקא איכשהו עובדים עם הקומפיילר, (הוא מסתבר כן תומך בהרבה דגלונים הרגילים כמו "‎-o -I" ועוד) הבעיה היא בעיקר libtool.

במילים אחרות... אם אתם לא מתכוונים לתמוך ב־MSVC תתרחקו מ־CMake, אבל ממש תתרחקו ממנו.

תכירו Boost.Locale

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

אחרי תהיות עמוקות על תמיכה בלוקליזציה ב־C++‎, הבנתי שלא ניתן יהיה ללכת איתה רחוק. לקחתי ICU והתחלתי לעטוף אותו בסביבה ידידותית לתכנות C++‎ מודרני.

אחרי הרבה עבודה הבנתי... כל מה שאני עושה יהיה שימושי הרבה מעבר ל־CppCMS ולכן החלטתי להכין ספריה נפרדת שמטפלת בלוקליזציה במטרה לשלב אותה ב־Boost. כך נולד Boost.Locale שנותנת כלים פשוטים וחזקים לעבודה עם לוקליזציה.

דוגמה פשוטה שתבהיר את החשיבותה ועוצמתה. הנה קטע קוד שמציג למשל את תאריך המאמר באתר:

out << format(translate("{1}, posted  at {2,date} on {2,time} by {3}")) 
          % title % date % author;

ועכשיו המתרגם יכול לתרגם את המשפט לצורה הבאה:

"{1}, פורסם ב{2,locale=he_IL@calendar=hebrew,date} ‏(לועזי {2,date}) ב־{2,time} ע"י {3}"

מה קרה כאן? התצוגה באנגלית תהיה

‎Some article was published at 11/8/2009 on 10:30 PM by somebody

כאשר התצוגה בעברית תהיה

מאמר מסוים פורסם בכ"א בחשון התש"ע (לועזי 08/11/2009) ב־22:30 ע"י מישהו

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

למעשה, עבזרת Boost.Locale ניתן לעשות המון דברים בצורה פשוטה. למשל:

cout << as::spellout << 123 <<endl;

יידפיס בלוקל עברי

מאה עשרים ושלוש

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

תכירו Boost.Locale:

תהנו, אשמח גם לתגובות.

על תמיכה בלוקליזציה ב־C++‎ ועל תקן שבור

ב־יום רביעי, 7 באוקטובר 2009, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, C++‎‏, Unicode; ‏0 תגובות

ככל שעובד הזמן אנחנו מתקרבים יותר ויותר לתקן C++‎ החדש שבהחלט מעשיר את השפה בהרבה כלים חיוניים -- הן מבחינת ליבת השפה והן לבחינת הספריה הסטנדרטית.

אבל נשאר מקום אחד שבו C++0x כמעט ולא נגע, אפילו שהתקן שבור לחלוטין -- לוקליזציה...

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

#include <iostream>
#include <fstream>
#include <locale>


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

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

        // write a number to file and close it
        number<<13456<<std::endl;
}

תכנה פשוטה אפילו טריוויאלית. עכשיו בואו נעשה אותו דבר ב־C.

#include <stdio.h>
#include <locale.h>

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

גם פשוט ביותר.

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

 ‎13<?>456

כאשר אם נריץ תכנה ב־C נקבל דווקא משהו נכון: ‎13 456

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

מה בעצם קראה כאן?

לפי הגדרות הלוקל הרוסי. התו שמפריד בין אלפים ומאות הוא תו U2002 -- ‏ EN SPACE -- סוג של רווח שונה מרווח ASCII רגיל U0020. כלומר בגלל שמדובר בתו Unicode שהוא לא בתחום ASCII הוא צריך להיות מקודד כמחרוזת ארוכה מבית 1.

אז למה ספריית C מתמודדת יפה מאוד עם בעיה זו וספריית C++‎ לא?

עכשיו בואו נסתכל בהגדרות הסביבה להצגת מספרים: המחלקה ‏std::numpunct מייצגת את סימון ההפרדה thousands_sep‏ כבית בודד! לכן אין שום סיכוי לייצג תו Unicode U2002, לעומת זאת, ספריית C, מייצגת את סימון ההפרדה כמחרוזת ולא כתו בודד. מכאן, אין שום בעיה לייצר מספרים.

זאת הייתה דוגמה של בעיוה הטריוויאלית לשחזור. קיימים עוד בעיות עקרוניות רבות כאלה בתקן לוקליזציה הקיים ב־C++‎ היום. חבל שהוועדה שמטפלת ב־C++0x כלל לא התייחסת לנושא זה --- אולי הגיע זמן להעלות את הנושא?

העמוד הקודם

העמוד הבא

דפים

נושאים