langdate.c

Go to the documentation of this file.
00001 
00002 /*  $Id: langdate.c 1254 2006-04-12 20:27:14Z sethdill $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "memory.h"
00032 #include "frontierconfig.h"
00033 #include "error.h"
00034 #include "ops.h"
00035 #include "strings.h"
00036 #include "frontierwindows.h"
00037 #include "shell.h"
00038 #include "shellhooks.h"
00039 #include "oplist.h"
00040 #include "lang.h"
00041 #include "langinternal.h"
00042 #include "langexternal.h"
00043 #include "langsystem7.h"
00044 #include "langipc.h"
00045 #include "langwinipc.h"
00046 #include "tablestructure.h"
00047 #include "tableverbs.h"
00048 #include "process.h"
00049 #include "processinternal.h"
00050 #include "kernelverbs.h"
00051 #include "kernelverbdefs.h"
00052 #include "timedate.h"
00053 
00054 static char * dayofweeknames[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
00055 static char * monthnames[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
00056 
00057 #define STR_P_MONTHLIST         BIGSTRING ("\x7A""{\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"}")
00058 #define STR_P_DAYOFWEEKLIST     BIGSTRING ("\x4E""{\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"}")
00059 #define STR_P_USERPREFSDATES    BIGSTRING ("\x10""user.prefs.dates")
00060 #define STR_P_MONTHNAMES        BIGSTRING ("\x0A""monthNames")
00061 #define STR_P_DAYNAMES          BIGSTRING ("\x08""dayNames")
00062 #define STR_P_PREFS             BIGSTRING ("\x05""prefs")
00063 #define STR_P_DATES             BIGSTRING ("\x05""dates")
00064 #define STR_P_USER              BIGSTRING ("\x04""user")
00065 #define STR_P_GMT               BIGSTRING ("\x04"" GMT")
00066 #define STR_P_COMMA             BIGSTRING ("\x02"", ")
00067 
00068 /*These should go elsewhere...?*/
00069 #define STR_P_MONTHNUMERROR     BIGSTRING ("\x40""Can't convert ^0 to a string because it is not between 1 and 12.")
00070 #define STR_P_DAYNUMERROR       BIGSTRING ("\x3F""Can't convert ^0 to a string because it is not between 1 and 7.")
00071 
00072 
00073 /* Return a string that looks like: Sat, 29 Nov 1997 00:51:47 GMT */
00074  
00075 boolean datenetstandardstring (long localdate, tyvaluerecord *vreturn) {
00076 
00077     handlestream s;
00078     short day, month, year, hour, minute, second;
00079     short dayofweek;
00080     bigstring bs;
00081     long ctz = getcurrenttimezonebias();
00082     long gmtdate = localdate - ctz;
00083     
00084     openhandlestream (nil, &s);
00085 
00086     if ((localdate >= 0) && (gmtdate < 0)) /* check for wrap-around */
00087         gmtdate = 0L;
00088 
00089     secondstodayofweek (gmtdate, &dayofweek);
00090     
00091     if (!writehandlestream (&s, dayofweeknames[dayofweek - 1], 3))
00092         goto exit;
00093 
00094     if (!writehandlestreamstring (&s, STR_P_COMMA))
00095         goto exit;
00096 
00097     secondstodatetime (gmtdate, &day, &month, &year, &hour, &minute, &second);
00098 
00099     numbertostring ((long) day, bs);
00100 
00101     if (stringlength (bs) == 1)
00102         insertchar ('0', bs);
00103 
00104     if (!writehandlestreamstring (&s, bs))
00105         goto exit;
00106 
00107     if (!writehandlestreamchar (&s, ' '))
00108         goto exit;
00109     
00110     if (!writehandlestream (&s, monthnames[month - 1], 3))
00111         goto exit;
00112 
00113     if (!writehandlestreamchar (&s, ' '))
00114         goto exit;
00115 
00116     numbertostring ((long) year, bs);
00117 
00118     if (!writehandlestreamstring (&s, bs))
00119         goto exit;
00120 
00121     if (!writehandlestreamchar (&s, ' '))
00122         goto exit;
00123 
00124     numbertostring ((long) hour, bs);
00125 
00126     while (stringlength (bs) < 2)
00127         insertchar ('0', bs);
00128 
00129     if (!writehandlestreamstring (&s, bs))
00130         goto exit;
00131 
00132     if (!writehandlestreamchar (&s, ':'))
00133         goto exit;
00134 
00135     numbertostring ((long) minute, bs);
00136 
00137     while (stringlength (bs) < 2)
00138         insertchar ('0', bs);
00139 
00140     if (!writehandlestreamstring (&s, bs))
00141         goto exit;
00142 
00143     if (!writehandlestreamchar (&s, ':'))
00144         goto exit;
00145 
00146     numbertostring ((long) second, bs);
00147 
00148     while (stringlength (bs) < 2)
00149         insertchar ('0', bs);
00150 
00151     if (!writehandlestreamstring (&s, bs))
00152         goto exit;
00153 
00154     if (!writehandlestreamstring (&s, STR_P_GMT))
00155         goto exit;
00156 
00157     setheapvalue (closehandlestream (&s), stringvaluetype, vreturn);
00158     
00159     return (true);
00160 
00161 exit:
00162     
00163     disposehandlestream (&s);
00164     
00165     return (false);
00166     }/*datenetstandardstring*/
00167 
00168 
00169 /* Get a string representation for the month name, based on user.prefs.dates.monthNames */
00170 
00171 boolean datemonthtostring (long ix, tyvaluerecord *vreturn) {
00172 
00173     hdlhashtable hdatestable;
00174     boolean fl;
00175     tyvaluerecord vlist;
00176     hdlhashnode hnode;
00177     
00178     if ((ix < 1) || (ix > 12)) {
00179 
00180         bigstring bs, bsmonthnum;
00181         
00182         copystring (STR_P_MONTHNUMERROR, bs);
00183         
00184         numbertostring (ix, bsmonthnum);
00185         
00186         parsedialogstring (bs, bsmonthnum, nil, nil, nil, bs);
00187     
00188         langerrormessage (bs);
00189         
00190         return (false);
00191         }
00192     
00193     disablelangerror ();
00194     
00195     fl = langfastaddresstotable (roottable, STR_P_USERPREFSDATES, &hdatestable);
00196     
00197     enablelangerror ();
00198     
00199     if (!fl || !hashtablelookup (hdatestable, STR_P_MONTHNAMES, &vlist, &hnode)) { /*create it*/
00200         
00201         hdlhashtable husertable, hprefstable;
00202         Handle h;
00203         
00204         if (!langsuretablevalue (roottable, STR_P_USER, &husertable))
00205             return (false);
00206 
00207         if (!langsuretablevalue (husertable, STR_P_PREFS, &hprefstable))
00208             return (false);
00209 
00210         if (!langsuretablevalue (hprefstable, STR_P_DATES, &hdatestable))
00211             return (false);
00212         
00213         if (!newtexthandle (STR_P_MONTHLIST, &h))
00214             return (false);
00215         
00216         setheapvalue (h, stringvaluetype, &vlist);
00217 
00218         if (!coercevalue (&vlist, listvaluetype))
00219             return (false);
00220         
00221         exemptfromtmpstack (&vlist);
00222         
00223         if (!hashtableassign (hdatestable, STR_P_MONTHNAMES, vlist)) {
00224             opdisposelist (vlist.data.listvalue);
00225             return (false);
00226             }
00227         }
00228     
00229     if (!coercevalue (&vlist, listvaluetype))
00230         return (false);
00231         
00232     if (!langgetlistitem (&vlist, ix, nil, vreturn))
00233         return (false);
00234     
00235     if (!coercevalue (vreturn, stringvaluetype))
00236         return (false);
00237     
00238     return (true);
00239     }/*datemonthtostring*/
00240 
00241 
00242 /* Get a string representation for the day of week, based on user.prefs.dates.dayNames */
00243 
00244 boolean datedayofweektostring (long ix, tyvaluerecord *vreturn) {
00245 
00246     hdlhashtable hdatestable;
00247     boolean fl;
00248     tyvaluerecord vlist;
00249     hdlhashnode hnode;
00250     
00251     if ((ix < 1) || (ix > 7)) {
00252 
00253         bigstring bs, bsdaynum;
00254         
00255         copystring (STR_P_DAYNUMERROR, bs);
00256         
00257         numbertostring (ix, bsdaynum);
00258         
00259         parsedialogstring (bs, bsdaynum, nil, nil, nil, bs);
00260     
00261         langerrormessage (bs);
00262         
00263         return (false);
00264         }
00265     
00266     disablelangerror ();
00267     
00268     fl = langfastaddresstotable (roottable, STR_P_USERPREFSDATES, &hdatestable);
00269     
00270     enablelangerror ();
00271     
00272     if (!fl || !hashtablelookup (hdatestable, STR_P_DAYNAMES, &vlist, &hnode)) { /*create it*/
00273         
00274         hdlhashtable husertable, hprefstable;
00275         Handle h;
00276         
00277         if (!langsuretablevalue (roottable, STR_P_USER, &husertable))
00278             return (false);
00279 
00280         if (!langsuretablevalue (husertable, STR_P_PREFS, &hprefstable))
00281             return (false);
00282 
00283         if (!langsuretablevalue (hprefstable, STR_P_DATES, &hdatestable))
00284             return (false);
00285         
00286         if (!newtexthandle (STR_P_DAYOFWEEKLIST, &h))
00287             return (false);
00288         
00289         setheapvalue (h, stringvaluetype, &vlist);
00290 
00291         if (!coercevalue (&vlist, listvaluetype))
00292             return (false);
00293         
00294         exemptfromtmpstack (&vlist);
00295         
00296         if (!hashtableassign (hdatestable, STR_P_DAYNAMES, vlist)) {
00297             opdisposelist (vlist.data.listvalue);
00298             return (false);
00299             }
00300         }
00301     
00302     if (!coercevalue (&vlist, listvaluetype))
00303         return (false);
00304         
00305     if (!langgetlistitem (&vlist, ix, nil, vreturn))
00306         return (false);
00307     
00308     if (!coercevalue (vreturn, stringvaluetype))
00309         return (false);
00310     
00311     return (true);
00312     }/*datedayofweektostring*/
00313 
00314 
00315 /*
00316 on versionLessThan (vs1, vs2) {
00317     «1/6/98 by DW
00318         «fixed this case:
00319             «date.versionLessThan ("2.0b9", "2.0")
00320                 «true
00321     on explodeVersion (s, adrtable) {
00322         new (tableType, adrtable);
00323         adrtable^.mainVersionNum = 0;
00324         adrtable^.stageNum = 0;
00325         adrtable^.subVersionNum = 0;
00326         
00327         local (mainVersionString = "");
00328         local (stageChars = {'d', 'a', 'b', 'f'});
00329         while sizeof (s) > 0 {
00330             if stageChars contains s [1] {
00331                 break};
00332             mainVersionString = mainVersionString + s [1];
00333             s = string.delete (s, 1, 1)};
00334         
00335         case string.countFields (mainVersionString, '.') {
00336             0 { //no string
00337                 mainVersionString = "0.0.0"};
00338             1 { //no dots
00339                 mainVersionString = mainVersionString + ".0.0"};
00340             2 { //one dot
00341                 mainVersionString = mainVersionString + ".0"}};
00342         while mainVersionString contains "." {
00343             mainVersionString = mainVersionString - "."};
00344         adrtable^.mainVersionNum = number (mainVersionString);
00345         
00346         if s == "" {
00347             return};
00348         
00349         local (stage = 0, charstodelete = 0);
00350         case string.lower (s [1]) {
00351             'd' {
00352                 stage = 1;
00353                 charstodelete = 1};
00354             'a' {
00355                 stage = 2;
00356                 charstodelete = 1};
00357             'b' {
00358                 stage = 3;
00359                 charstodelete = 1};
00360             'f' {
00361                 stage = 4;
00362                 if string.lower (s [2]) == 'c' {
00363                     charstodelete = 2}
00364                 else {
00365                     charstodelete = 1}}};
00366         s = string.delete (s, 1, charstodelete);
00367         adrtable^.stageNum = stage;
00368         
00369         adrtable^.subVersionNum = number (s)};
00370 */
00371 
00372 static void explodeversion (bigstring bsv, unsigned long *mainversion, unsigned long *subversion) {
00373     
00374     long i, x, ix, len;
00375     bigstring bs;
00376     
00377     for (i = 1; i <= stringlength (bsv); i++)
00378         if ((bsv[i] == 'a') || (bsv[i] == 'b') || (bsv[i] == 'd') || (bsv[i] == 'f'))
00379             break;
00380 
00381     if (textnthword (stringbaseaddress (bsv), i-1, 1, '.', false, &ix, &len)) {     
00382         x = 0;
00383         
00384         midstring (bsv, ix+1, len, bs); /* off by one ??? */
00385         
00386         stringtonumber (bs, &x);
00387     
00388         *mainversion += x * 256 * 256 *256;
00389         }
00390 
00391     if (textnthword (stringbaseaddress (bsv), i-1, 2, '.', false, &ix, &len)) {
00392         x = 0;
00393     
00394         midstring (bsv, ix+1, len, bs);
00395         
00396         stringtonumber (bs, &x);
00397     
00398         *mainversion += x * 256 * 256;
00399         }
00400 
00401     if (textnthword (stringbaseaddress (bsv), i-1, 3, '.', false, &ix, &len)) {
00402         x = 0;
00403     
00404         midstring (bsv, ix+1, len, bs);
00405         
00406         stringtonumber (bs, &x);
00407     
00408         *mainversion += x;
00409         }
00410     
00411     if (i >= stringlength (bsv)) /*there's no subversion*/
00412         return;
00413 
00414     switch (bsv[i]) {
00415             
00416         case 'd':
00417             *subversion = 0 * 255 * 256 * 256;
00418             break;
00419     
00420         case 'a':
00421             *subversion = 1 * 255 * 256 * 256;
00422             break;
00423             
00424         case 'b':
00425             *subversion = 2 * 255 * 256 * 256;
00426             break;
00427             
00428         case 'f':
00429             if (bsv[i+1] == 'c')
00430                 *subversion = 4 * 255 * 256 * 256;
00431             else
00432                 return;
00433             break;
00434             
00435         default:
00436             return;
00437         }
00438     
00439     // 7.1b44 dmb, DON'T munge input string: deletestring (bsv, 1, i);
00440     midstring (bsv, i + 1, stringlength (bsv) - i, bs);
00441 
00442     x = 0;
00443     
00444     stringtonumber (bs, &x);
00445     
00446     *subversion += x;
00447     
00448     return; 
00449     } /*explodeversion*/
00450     
00451 
00452 boolean dateversionlessthan (bigstring bsv1, bigstring bsv2, tyvaluerecord *v) {
00453 
00454     unsigned long m1 = 0;
00455     unsigned long m2 = 0;
00456     unsigned long s1 = 0xffffffff;
00457     unsigned long s2 = 0xffffffff;
00458     
00459     explodeversion (bsv1, &m1, &s1);
00460     
00461     explodeversion (bsv2, &m2, &s2);
00462     
00463     if (m1 != m2)
00464         return (setbooleanvalue ((m1 < m2), v));
00465 
00466     if (s1 != s2)
00467         return (setbooleanvalue ((s1 < s2), v));
00468     
00469     return (setbooleanvalue (false, v)); /*they're equal*/
00470     } /*versionlessthan*/

Generated on Wed May 31 18:19:51 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6