|
|
@@ -0,0 +1,1217 @@
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+//
|
|
|
+// Legalese:
|
|
|
+// This file is part of the OpenNETCF time.h port for Windows CE.
|
|
|
+// You are free to use, modify or distribute this code or any
|
|
|
+// derivative work that you create. This code is provided WITHOUT
|
|
|
+// WARRANTY and OpenNETCF does NOT claim in any way that this code
|
|
|
+// is fit for any specific or general use and holds NO RESPONSIBILITY
|
|
|
+// for consequences of using any of it. It is simply provided as-is.
|
|
|
+//
|
|
|
+// About:
|
|
|
+// This is part of a free and open project to provide a simply way to
|
|
|
+// port that uses time.h functions to Windows CE. For the latest
|
|
|
+// code, or to submit fixes, feature additions, etc. visit:
|
|
|
+//
|
|
|
+// http://www.opennetcf.com
|
|
|
+//
|
|
|
+// Version 0.01 - March 22, 2007
|
|
|
+// Initial Release
|
|
|
+//
|
|
|
+// Version 0.02 - July 5, 2007
|
|
|
+// Bug fixes. UTC offset not properly accounted for unless SetTz had been previously called.
|
|
|
+// UTC offset used for functions like localtime using old, rather than current data
|
|
|
+//
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+// Many but not all of the functions were created from the following source:
|
|
|
+//
|
|
|
+// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
|
|
|
+//
|
|
|
+// Redistribution and use in source and binary forms, with or without
|
|
|
+// modification, are permitted provided that the following conditions
|
|
|
+// are met:
|
|
|
+//
|
|
|
+// 1. Redistributions of source code must retain the above copyright
|
|
|
+// notice, this list of conditions and the following disclaimer.
|
|
|
+// 2. Redistributions in binary form must reproduce the above copyright
|
|
|
+// notice, this list of conditions and the following disclaimer in the
|
|
|
+// documentation and/or other materials provided with the distribution.
|
|
|
+// 3. Neither the name of the project nor the names of its contributors
|
|
|
+// may be used to endorse or promote products derived from this software
|
|
|
+// without specific prior written permission.
|
|
|
+//
|
|
|
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
|
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
+// SUCH DAMAGE.
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#include <windows.h>
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include "celibc.h"
|
|
|
+
|
|
|
+#ifndef __GNUC__
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+// Macros
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+#define TIME_FAILURE 0xFFFFFFFF
|
|
|
+#define ASC_BUFF_SIZE 26 // Ascii buffer size is 26 bytes, (24 chars and CR+LF)
|
|
|
+#define SEC_IN_HOUR 3600L
|
|
|
+#define SECS_IN_MIN 60L
|
|
|
+#define DAYSPERWEEK 7
|
|
|
+#define YEAR0 1900
|
|
|
+#define EPOCH_YR 1970
|
|
|
+#define SECS_DAY (24L * 60L * 60L)
|
|
|
+#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
|
|
|
+#define TIME_MAX 2147483647L
|
|
|
+
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+// Local Variables
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+// Number of seconds between local time and UTC time, includes DST bias
|
|
|
+//
|
|
|
+LONG _localtime;
|
|
|
+
|
|
|
+// Is the local time in daylight savings time
|
|
|
+//
|
|
|
+DWORD _isdst;
|
|
|
+
|
|
|
+// Bias for daylight savings time
|
|
|
+//
|
|
|
+int _dstBias;
|
|
|
+
|
|
|
+// Contains the time zone string
|
|
|
+//
|
|
|
+char tz_name[2][32];
|
|
|
+
|
|
|
+// Contains the 1/1/1970 reference date/time
|
|
|
+//
|
|
|
+const SYSTEMTIME st1970 = {1970, 1, 4, 1, 0, 0, 0, 0};
|
|
|
+
|
|
|
+// Contains the number of days per month for
|
|
|
+// non leap and leap years
|
|
|
+//
|
|
|
+const int _ytab[2][12] =
|
|
|
+{
|
|
|
+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
|
|
+ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
|
|
+};
|
|
|
+
|
|
|
+// Contains the days of the week abreviation
|
|
|
+//
|
|
|
+static char *aday[] = {
|
|
|
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
|
|
+};
|
|
|
+
|
|
|
+// Contains the days of the week full name
|
|
|
+//
|
|
|
+static char *day[] = {
|
|
|
+ "Sunday", "Monday", "Tuesday", "Wednesday",
|
|
|
+ "Thursday", "Friday", "Saturday"
|
|
|
+};
|
|
|
+
|
|
|
+// Contains the months of the year abreviation
|
|
|
+//
|
|
|
+static char *amonth[] = {
|
|
|
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
|
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
|
+};
|
|
|
+
|
|
|
+// Contains the months of the year full name
|
|
|
+//
|
|
|
+static char *month[] = {
|
|
|
+ "January", "February", "March", "April", "May", "June",
|
|
|
+ "July", "August", "September", "October", "November", "December"
|
|
|
+};
|
|
|
+
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+// Forward declaration of internal functions
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+// Convert system time into seconds since 1970
|
|
|
+//
|
|
|
+LONGLONG SystemTimeToSecondsSince1970(SYSTEMTIME * st);
|
|
|
+
|
|
|
+// Convert seconds since 1970 into a system time
|
|
|
+//
|
|
|
+void SecondsSince1970ToSystemTime(const time_t * timer, SYSTEMTIME * st,
|
|
|
+ BOOLEAN local);
|
|
|
+
|
|
|
+// Initialize the time zone information needed for the time methods
|
|
|
+//
|
|
|
+void SetTz(SYSTEMTIME *_st);
|
|
|
+
|
|
|
+// Copy system time structure to tm structure
|
|
|
+//
|
|
|
+void SystemTimeToTm(SYSTEMTIME *st, struct tm * tmbuffer);
|
|
|
+void TmToSystemTime(struct tm * tmbuffer, SYSTEMTIME *st);
|
|
|
+
|
|
|
+// Get Julian Days from the begining of the year
|
|
|
+//
|
|
|
+DWORD JulianDays(SYSTEMTIME * st);
|
|
|
+
|
|
|
+// Method parses and formats strings
|
|
|
+//
|
|
|
+static void strfmt(char *str, const char *fmt, ...);
|
|
|
+
|
|
|
+// Reentrant version of gmttime
|
|
|
+//
|
|
|
+struct tm *gmtime_r_ce(const time_t *timer, struct tm *tmbuf, BOOLEAN local);
|
|
|
+
|
|
|
+// Reentrant version of localtime
|
|
|
+//
|
|
|
+struct tm *localtime_r_ce(const time_t *timer, struct tm *tmbuf);
|
|
|
+
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+// Methods - The meat
|
|
|
+///////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+// Convert tm to a string in the format "Www Mmm dd hh:mm:ss yyyy",
|
|
|
+// where Www is the weekday, Mmm the month in letters, dd the day
|
|
|
+// of the month, hh:mm:ss the time, and yyyy the year. The string
|
|
|
+// is followed by a newline and a terminating null character,
|
|
|
+// conforming a total of 26 characters.
|
|
|
+//
|
|
|
+char *asctime(const struct tm* tmptr)
|
|
|
+{
|
|
|
+ static char ascbuf[ASC_BUFF_SIZE];
|
|
|
+ strftime(ascbuf, ASC_BUFF_SIZE, "%c\n", tmptr);
|
|
|
+ return ascbuf;
|
|
|
+}
|
|
|
+#endif //__GNUC__
|
|
|
+
|
|
|
+// Return number of clock ticks since process start.
|
|
|
+// NOTE: This differs from standard clock since GetTickCount is the
|
|
|
+// number of milliseconds since system startup not process start.
|
|
|
+// This will also rollover after 49.7 days of continuous system
|
|
|
+// runtime.
|
|
|
+//
|
|
|
+clock_t clock(void)
|
|
|
+{
|
|
|
+ return GetTickCount();
|
|
|
+}
|
|
|
+
|
|
|
+#ifndef __GNUC__
|
|
|
+// Convert time_t value to string in the same format as asctime.
|
|
|
+//
|
|
|
+char* ctime(const time_t* timer)
|
|
|
+{
|
|
|
+ return asctime(localtime(timer));
|
|
|
+}
|
|
|
+
|
|
|
+// Reentrant version of gmttime_ce
|
|
|
+//
|
|
|
+struct tm *gmtime_r_ce(const time_t *timer, struct tm *tmbuf, BOOLEAN local)
|
|
|
+{
|
|
|
+ SYSTEMTIME st;
|
|
|
+
|
|
|
+ SecondsSince1970ToSystemTime(timer, &st, local);
|
|
|
+ SetTz(&st);
|
|
|
+ if(_isdst) {
|
|
|
+ SecondsSince1970ToSystemTime(timer, &st, local);
|
|
|
+ }
|
|
|
+
|
|
|
+ // copy SYSTEMTIME data to tm structure
|
|
|
+ //
|
|
|
+ SystemTimeToTm(&st, tmbuf);
|
|
|
+
|
|
|
+ return tmbuf;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// Reentrant version of localtime
|
|
|
+//
|
|
|
+struct tm *localtime_r_ce(const time_t *timer, struct tm *tmbuf)
|
|
|
+{
|
|
|
+ return gmtime_r_ce(timer, tmbuf, TRUE);
|
|
|
+}
|
|
|
+
|
|
|
+// Convert a time_t value to a tm structure as UTC time.
|
|
|
+//
|
|
|
+struct tm *gmtime(const time_t *timer)
|
|
|
+{
|
|
|
+ return gmtime_r_ce(timer, &tmbuf, FALSE);
|
|
|
+}
|
|
|
+
|
|
|
+// Convert a time_t value to a tm structure as local time.
|
|
|
+//
|
|
|
+struct tm *localtime(const time_t *timer)
|
|
|
+{
|
|
|
+ return localtime_r_ce(timer, &tmbuf);
|
|
|
+}
|
|
|
+
|
|
|
+// time_t represents seconds since midnight January 1, 1970 UTC
|
|
|
+// (coordinated universal time) in 32-bits Win32 FILETIME structure is 64-bit,
|
|
|
+// which represents the number of 100-nanosecond (hns) intervals since
|
|
|
+// January 1, 1601 UTC (coordinate universal time) the time difference
|
|
|
+// between midnight January 1, 1970 and midnight January 1, 1601 is 11644473600 seconds
|
|
|
+//
|
|
|
+time_t mktime(struct tm *tptr)
|
|
|
+{
|
|
|
+ SYSTEMTIME st;
|
|
|
+
|
|
|
+ int day = 0;
|
|
|
+ int year = 0;
|
|
|
+ int seconds = 0;
|
|
|
+ int overflow;
|
|
|
+ int tm_year;
|
|
|
+ int yday, month;
|
|
|
+
|
|
|
+ TmToSystemTime(tptr, &st);
|
|
|
+ SetTz(&st);
|
|
|
+
|
|
|
+ // see if seconds are < 0
|
|
|
+ while(tptr->tm_sec < 0)
|
|
|
+ {
|
|
|
+ // steal 60 seconds from the minutes
|
|
|
+ tptr->tm_sec += 60;
|
|
|
+ tptr->tm_min--;
|
|
|
+ }
|
|
|
+ // roll any seconds > 60 into the minutes
|
|
|
+ tptr->tm_min += tptr->tm_sec / 60;
|
|
|
+ // then crop them off
|
|
|
+ tptr->tm_sec %= 60;
|
|
|
+
|
|
|
+ // see if minutes are < 0
|
|
|
+ while(tptr->tm_min < 0)
|
|
|
+ {
|
|
|
+ // steal 60 minutes from the hours
|
|
|
+ tptr->tm_min += 60;
|
|
|
+ tptr->tm_hour--;
|
|
|
+ }
|
|
|
+ // roll any minutes > 60 into the hours
|
|
|
+ tptr->tm_hour += tptr->tm_min / 60;
|
|
|
+ // then crop them off
|
|
|
+ tptr->tm_min %= 60;
|
|
|
+
|
|
|
+ // see if hours are < 0
|
|
|
+ while(tptr->tm_hour < 0)
|
|
|
+ {
|
|
|
+ // steal 24 hours from the days
|
|
|
+ tptr->tm_hour += 24;
|
|
|
+ day--;
|
|
|
+ }
|
|
|
+ // keep any "excess" days (tm doesn't have a convenient place for this)
|
|
|
+ day += tptr->tm_hour / 24;
|
|
|
+ // crop
|
|
|
+ tptr->tm_hour %= 24;
|
|
|
+
|
|
|
+ // roll any months > 12 into the years
|
|
|
+ tptr->tm_year += tptr->tm_mon / 12;
|
|
|
+ // then crop the off
|
|
|
+ tptr->tm_mon %= 12;
|
|
|
+
|
|
|
+ // see if months are < 0
|
|
|
+ if (tptr->tm_mon < 0)
|
|
|
+ {
|
|
|
+ // steal 12 months from the years
|
|
|
+ tptr->tm_mon += 12;
|
|
|
+ tptr->tm_year--;
|
|
|
+ }
|
|
|
+
|
|
|
+ // add number of days into the month to total day
|
|
|
+ day += (tptr->tm_mday - 1);
|
|
|
+
|
|
|
+ // if days are < 0 then calculate the number of days
|
|
|
+ // checking to see if the month is a leap year month
|
|
|
+ while (day < 0)
|
|
|
+ {
|
|
|
+ // If months are < 0 then steal 12 months from number of years
|
|
|
+ // for the day calculation
|
|
|
+ if(--tptr->tm_mon < 0)
|
|
|
+ {
|
|
|
+ tptr->tm_year--;
|
|
|
+ tptr->tm_mon = 11;
|
|
|
+ }
|
|
|
+ day += _ytab[LEAPYEAR(YEAR0 + tptr->tm_year)][tptr->tm_mon];
|
|
|
+ }
|
|
|
+ // if day is greater then the number of days in the month
|
|
|
+ // subtract the number of days in the month and adjust the
|
|
|
+ // month
|
|
|
+ while (day >= _ytab[LEAPYEAR(YEAR0 + tptr->tm_year)][tptr->tm_mon])
|
|
|
+ {
|
|
|
+ day -= _ytab[LEAPYEAR(YEAR0 + tptr->tm_year)][tptr->tm_mon];
|
|
|
+ if (++(tptr->tm_mon) == 12)
|
|
|
+ {
|
|
|
+ tptr->tm_mon = 0;
|
|
|
+ tptr->tm_year++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tptr->tm_mday = day + 1;
|
|
|
+ year = EPOCH_YR;
|
|
|
+
|
|
|
+ // if year is less then 1970 then return error
|
|
|
+ if (tptr->tm_year < year - YEAR0) return (time_t) -1;
|
|
|
+
|
|
|
+ seconds = 0;
|
|
|
+ day = 0; // Means days since day 0 now
|
|
|
+ overflow = 0;
|
|
|
+
|
|
|
+ // Assume that when day becomes negative, there will certainly
|
|
|
+ // be overflow on seconds.
|
|
|
+ // The check for overflow needs not to be done for leapyears
|
|
|
+ // divisible by 400.
|
|
|
+ // The code only works when year (1970) is not a leapyear.
|
|
|
+ tm_year = tptr->tm_year + YEAR0;
|
|
|
+
|
|
|
+ // make sure we are not past the max year for 32-bit number
|
|
|
+ if (TIME_MAX / 365 < tm_year - year) overflow++;
|
|
|
+
|
|
|
+ // calculate number of days since EPOCH
|
|
|
+ day = (tm_year - year) * 365;
|
|
|
+
|
|
|
+ if (TIME_MAX - day < (tm_year - year) / 4 + 1) overflow++;
|
|
|
+
|
|
|
+ day += (tm_year - year) / 4 + ((tm_year % 4) && tm_year % 4 < year % 4);
|
|
|
+ day -= (tm_year - year) / 100 + ((tm_year % 100) && tm_year % 100 < year % 100);
|
|
|
+ day += (tm_year - year) / 400 + ((tm_year % 400) && tm_year % 400 < year % 400);
|
|
|
+
|
|
|
+ // setup for calculation of the yday or Julian day since Jan 1
|
|
|
+ yday = month = 0;
|
|
|
+
|
|
|
+ // add up the number of days for the preceding months
|
|
|
+ while (month < tptr->tm_mon)
|
|
|
+ {
|
|
|
+ yday += _ytab[LEAPYEAR(tm_year)][month];
|
|
|
+ month++;
|
|
|
+ }
|
|
|
+ // add the number of days in the current month
|
|
|
+ yday += (tptr->tm_mday - 1);
|
|
|
+
|
|
|
+ // make sure the didn't overflow
|
|
|
+ if (day + yday < 0) overflow++;
|
|
|
+
|
|
|
+ day += yday;
|
|
|
+
|
|
|
+ // set the year day in the structure
|
|
|
+ tptr->tm_yday = yday;
|
|
|
+
|
|
|
+ // calculate the weekday
|
|
|
+ tptr->tm_wday = (day + 4) % 7; // Day 0 was thursday (4)
|
|
|
+
|
|
|
+ // start the seconds calculation by totaling the hours, min, seconds
|
|
|
+ seconds = ((tptr->tm_hour * 60L) + tptr->tm_min) * 60L + tptr->tm_sec;
|
|
|
+
|
|
|
+ // make sure we are not going to overflow
|
|
|
+ if ((TIME_MAX - seconds) / SECS_DAY < day) overflow++;
|
|
|
+
|
|
|
+ // calculate the number of seconds for the number of days
|
|
|
+ seconds += day * SECS_DAY;
|
|
|
+
|
|
|
+ // Now adjust according to timezone and daylight saving time
|
|
|
+ if (((_localtime > 0) && (TIME_MAX - _localtime < seconds))
|
|
|
+ || ((_localtime < 0) && (seconds < -_localtime)))
|
|
|
+ overflow++;
|
|
|
+
|
|
|
+ // Adjust for local time zone
|
|
|
+ seconds += _localtime;
|
|
|
+
|
|
|
+ // return error if we are going to blow the max values
|
|
|
+ if (overflow) return (time_t) -1;
|
|
|
+
|
|
|
+ if ((time_t) seconds != seconds) return (time_t) -1;
|
|
|
+
|
|
|
+ // return the number of seconds since EPOCH
|
|
|
+ return (time_t) seconds;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Get the current system time and convert to seconds since
|
|
|
+// 1/1/1970. Store the seconds value in tloc if not a NULL pointer then
|
|
|
+// return the seconds value.
|
|
|
+//
|
|
|
+time_t time(time_t *tloc)
|
|
|
+{
|
|
|
+ SYSTEMTIME st;
|
|
|
+ LONGLONG secs = 0;
|
|
|
+
|
|
|
+ // Get current system time
|
|
|
+ GetSystemTime(&st);
|
|
|
+
|
|
|
+ // Set time zone information
|
|
|
+ //
|
|
|
+ SetTz(&st);
|
|
|
+
|
|
|
+ // convert system time to number of seconds since 1970
|
|
|
+ //
|
|
|
+ secs = SystemTimeToSecondsSince1970(&st);
|
|
|
+
|
|
|
+ // check for failure
|
|
|
+ //
|
|
|
+ if(secs == TIME_FAILURE)
|
|
|
+ {
|
|
|
+ return TIME_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // If tloc is not NULL, the return value is also stored in the location to which tloc points
|
|
|
+ //
|
|
|
+ if(tloc != NULL)
|
|
|
+ {
|
|
|
+ if(IsBadWritePtr(tloc, sizeof(time_t)))
|
|
|
+ {
|
|
|
+ return TIME_FAILURE;
|
|
|
+ }
|
|
|
+ memcpy(tloc, &secs, sizeof(time_t));
|
|
|
+ }
|
|
|
+
|
|
|
+ return secs;
|
|
|
+}
|
|
|
+
|
|
|
+// The strftime function is a modified version created by the following:
|
|
|
+// written 6 september 1989 by jim nutt
|
|
|
+// released into the public domain by jim nutt
|
|
|
+//
|
|
|
+// modified 21-Oct-89 by Rob Duff
|
|
|
+//
|
|
|
+//
|
|
|
+// size_t strftime(char *str,
|
|
|
+// size_t maxs,
|
|
|
+// const char *fmt,
|
|
|
+// const struct tm *t)
|
|
|
+//
|
|
|
+// this functions acts much like a sprintf for time/date output.
|
|
|
+// given a pointer to an output buffer, a format string and a
|
|
|
+// time, it copies the time to the output buffer formatted in
|
|
|
+// accordance with the format string. the parameters are used
|
|
|
+// as follows:
|
|
|
+//
|
|
|
+// str is a pointer to the output buffer, there should
|
|
|
+// be at least maxs characters available at the address
|
|
|
+// pointed to by str.
|
|
|
+//
|
|
|
+// maxs is the maximum number of characters to be copied
|
|
|
+// into the output buffer, included the '\0' terminator
|
|
|
+//
|
|
|
+// fmt is the format string. a percent sign (%) is used
|
|
|
+// to indicate that the following character is a special
|
|
|
+// format character. the following are valid format
|
|
|
+// characters:
|
|
|
+//
|
|
|
+// %A full weekday name (Monday)
|
|
|
+// %a abbreviated weekday name (Mon)
|
|
|
+// %B full month name (January)
|
|
|
+// %b abbreviated month name (Jan)
|
|
|
+// %c standard date and time representation
|
|
|
+// %d day-of-month (01-31)
|
|
|
+// %H hour (24 hour clock) (00-23)
|
|
|
+// %I hour (12 hour clock) (01-12)
|
|
|
+// %j day-of-year (001-366)
|
|
|
+// %M minute (00-59)
|
|
|
+// %m month (01-12)
|
|
|
+// %p local equivalent of AM or PM
|
|
|
+// %S second (00-59)
|
|
|
+// %U week-of-year, first day sunday (00-53)
|
|
|
+// %W week-of-year, first day monday (00-53)
|
|
|
+// %w weekday (0-6, sunday is 0)
|
|
|
+// %X standard time representation
|
|
|
+// %x standard date representation
|
|
|
+// %Y year with century
|
|
|
+// %y year without century (00-99)
|
|
|
+// %Z timezone name
|
|
|
+// %% percent sign
|
|
|
+//
|
|
|
+// the standard date string is equivalent to:
|
|
|
+//
|
|
|
+// %a %b %d %Y
|
|
|
+//
|
|
|
+// the standard time string is equivalent to:
|
|
|
+//
|
|
|
+// %H:%M:%S
|
|
|
+//
|
|
|
+// the standard date and time string is equivalent to:
|
|
|
+//
|
|
|
+// %a %b %d %H:%M:%S %Y
|
|
|
+//
|
|
|
+// strftime returns the number of characters placed in the
|
|
|
+// buffer, not including the terminating \0, or zero if more
|
|
|
+// than maxs characters were produced.
|
|
|
+//
|
|
|
+size_t strftime(char *s, size_t maxs, const char *f, const struct tm *t)
|
|
|
+{
|
|
|
+ int w;
|
|
|
+ char *p, *q, *r;
|
|
|
+ static char buf[26];
|
|
|
+
|
|
|
+ p = s;
|
|
|
+ q = s + maxs - 1;
|
|
|
+ while ((*f != '\0'))
|
|
|
+ {
|
|
|
+ if (*f++ == '%')
|
|
|
+ {
|
|
|
+ r = buf;
|
|
|
+ switch (*f++)
|
|
|
+ {
|
|
|
+ case '%' :
|
|
|
+ r = "%";
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'a' :
|
|
|
+ r = aday[t->tm_wday];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'A' :
|
|
|
+ r = day[t->tm_wday];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'b' :
|
|
|
+ r = amonth[t->tm_mon];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'B' :
|
|
|
+ r = month[t->tm_mon];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'c' :
|
|
|
+ strfmt(r, "%0 %0 %2 %2:%2:%2 %4",
|
|
|
+ aday[t->tm_wday], amonth[t->tm_mon],
|
|
|
+ t->tm_mday,t->tm_hour, t->tm_min,
|
|
|
+ t->tm_sec, t->tm_year+1900);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'd' :
|
|
|
+ strfmt(r,"%2",t->tm_mday);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'H' :
|
|
|
+ strfmt(r,"%2",t->tm_hour);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'I' :
|
|
|
+ strfmt(r,"%2",(t->tm_hour%12)?t->tm_hour%12:12);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'j' :
|
|
|
+ strfmt(r,"%3",t->tm_yday+1);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'm' :
|
|
|
+ strfmt(r,"%2",t->tm_mon+1);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'M' :
|
|
|
+ strfmt(r,"%2",t->tm_min);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'p' :
|
|
|
+ r = (t->tm_hour>11)?"PM":"AM";
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'S' :
|
|
|
+ strfmt(r,"%2",t->tm_sec);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'U' :
|
|
|
+ w = t->tm_yday/7;
|
|
|
+ if (t->tm_yday%7 > t->tm_wday)
|
|
|
+ w++;
|
|
|
+ strfmt(r, "%2", w);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'W' :
|
|
|
+ w = (t->tm_yday + DAYSPERWEEK -
|
|
|
+ (t->tm_wday ?
|
|
|
+ (t->tm_wday - 1) :
|
|
|
+ (DAYSPERWEEK - 1))) / DAYSPERWEEK;
|
|
|
+ strfmt(r, "%2", w);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'w' :
|
|
|
+ strfmt(r,"%1",t->tm_wday);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'x' :
|
|
|
+ strfmt(r, "%2/%2/%2", t->tm_mon + 1,
|
|
|
+ t->tm_mday, t->tm_year+1900);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'X' :
|
|
|
+ strfmt(r, "%2:%2:%2", t->tm_hour,
|
|
|
+ t->tm_min, t->tm_sec);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'y' :
|
|
|
+ strfmt(r,"%2",t->tm_year%100);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'Y' :
|
|
|
+ strfmt(r,"%4",t->tm_year+1900);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'Z' :
|
|
|
+ r = (t->tm_isdst && tz_name[1][0])?tz_name[1]:tz_name[0];
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ buf[0] = '%'; // reconstruct the format
|
|
|
+ buf[1] = f[-1];
|
|
|
+ buf[2] = '\0';
|
|
|
+ if (buf[1] == 0)
|
|
|
+ f--; // back up if at end of string
|
|
|
+ }
|
|
|
+ while (*r)
|
|
|
+ {
|
|
|
+ if (p == q)
|
|
|
+ {
|
|
|
+ *q = '\0';
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ *p++ = *r++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (p == q)
|
|
|
+ {
|
|
|
+ *q = '\0';
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ *p++ = f[-1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *p = '\0';
|
|
|
+ return p - s;
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// static void strfmt(char *str, char *fmt);
|
|
|
+//
|
|
|
+// simple sprintf for strftime
|
|
|
+//
|
|
|
+// each format descriptor is of the form %n
|
|
|
+// where n goes from zero to four
|
|
|
+//
|
|
|
+// 0 -- string %s
|
|
|
+// 1..4 -- int %?.?d
|
|
|
+//
|
|
|
+static void strfmt(char *str, const char *fmt, ...)
|
|
|
+{
|
|
|
+ int ival, ilen;
|
|
|
+ char *sval;
|
|
|
+ static int pow[5] = { 1, 10, 100, 1000, 10000 };
|
|
|
+ va_list vp;
|
|
|
+
|
|
|
+ va_start(vp, fmt);
|
|
|
+ while (*fmt)
|
|
|
+ {
|
|
|
+ if (*fmt++ == '%')
|
|
|
+ {
|
|
|
+ ilen = *fmt++ - '0';
|
|
|
+ if (ilen == 0) // zero means string arg
|
|
|
+ {
|
|
|
+ sval = va_arg(vp, char*);
|
|
|
+ while (*sval)
|
|
|
+ *str++ = *sval++;
|
|
|
+ }
|
|
|
+ else // always leading zeros
|
|
|
+ {
|
|
|
+ ival = va_arg(vp, int);
|
|
|
+ while (ilen)
|
|
|
+ {
|
|
|
+ ival %= pow[ilen--];
|
|
|
+ *str++ = (char)('0' + ival / pow[ilen]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else *str++ = fmt[-1];
|
|
|
+ }
|
|
|
+ *str = '\0';
|
|
|
+ va_end(vp);
|
|
|
+}
|
|
|
+
|
|
|
+// internal functions
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// Convert 100ns units since 1601 to seconds since 1970
|
|
|
+//
|
|
|
+LONGLONG SystemTimeToSecondsSince1970(SYSTEMTIME *st)
|
|
|
+{
|
|
|
+ ULARGE_INTEGER uli;
|
|
|
+ FILETIME ft;
|
|
|
+ ULARGE_INTEGER uli1970;
|
|
|
+ FILETIME ft1970;
|
|
|
+
|
|
|
+ // convert to a FILETIME
|
|
|
+ // Gives number of 100-nanosecond intervals since January 1, 1601 (UTC)
|
|
|
+ //
|
|
|
+ if(!SystemTimeToFileTime(st, &ft))
|
|
|
+ {
|
|
|
+ return TIME_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // convert to a FILETIME
|
|
|
+ // Gives number of 100-nanosecond intervals since January 1, 1970 (UTC)
|
|
|
+ //
|
|
|
+ if(!SystemTimeToFileTime(&st1970, &ft1970))
|
|
|
+ {
|
|
|
+ return TIME_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Copy file time structures into ularge integer so we can do
|
|
|
+ // the math more easily
|
|
|
+ //
|
|
|
+ memcpy(&uli, &ft, sizeof(uli));
|
|
|
+ memcpy(&uli1970, &ft1970, sizeof(uli1970));
|
|
|
+
|
|
|
+ // Subtract the 1970 number of 100 ns value from the 1601 100 ns value
|
|
|
+ // so we can get the number of 100 ns value between 1970 and now
|
|
|
+ // then devide be 10,000,000 to get the number of seconds since 1970
|
|
|
+ //
|
|
|
+ uli.QuadPart = ((uli.QuadPart - uli1970.QuadPart) / 10000000);
|
|
|
+
|
|
|
+ return (LONGLONG)uli.QuadPart;
|
|
|
+}
|
|
|
+
|
|
|
+// Convert seconds since 1970 to a file time in 100ns units since 1601
|
|
|
+// then to a system time.
|
|
|
+//
|
|
|
+void SecondsSince1970ToSystemTime(const time_t * timer, SYSTEMTIME * st,
|
|
|
+ BOOLEAN local)
|
|
|
+{
|
|
|
+ ULARGE_INTEGER uli;
|
|
|
+ FILETIME ft;
|
|
|
+ ULARGE_INTEGER uli1970;
|
|
|
+ FILETIME ft1970;
|
|
|
+
|
|
|
+ // Convert system time to file time
|
|
|
+ //
|
|
|
+ if(!SystemTimeToFileTime(&st1970, &ft1970))
|
|
|
+ {
|
|
|
+ st = NULL;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // convert hundreds of nanosecs to secs: 1 sec = 1e7 100ns
|
|
|
+ // Gives number of seconds since 1/1/1601 (UTC)
|
|
|
+ //
|
|
|
+ memcpy(&uli, timer, sizeof(uli));
|
|
|
+ memcpy(&uli1970, &ft1970, sizeof(uli1970));
|
|
|
+
|
|
|
+ // If we want local time then subtract the number of seconds between
|
|
|
+ // UTC and current local time
|
|
|
+ //
|
|
|
+ if (local)
|
|
|
+ {
|
|
|
+ // Calculate 100ns since 1/1/1601 local time
|
|
|
+ //
|
|
|
+ uli.QuadPart = (((uli.QuadPart - _localtime)*10000000) + uli1970.QuadPart);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Calculate 100ns since 1/1/1601 UTC
|
|
|
+ //
|
|
|
+ uli.QuadPart = ((uli.QuadPart)*10000000 + uli1970.QuadPart);
|
|
|
+ }
|
|
|
+
|
|
|
+ // copy data back into the ft
|
|
|
+ //
|
|
|
+ memcpy(&ft, &uli, sizeof(uli));
|
|
|
+
|
|
|
+ // convert to a SYSTEMTIME
|
|
|
+ //
|
|
|
+ if(!FileTimeToSystemTime(&ft, st))
|
|
|
+ {
|
|
|
+ st = NULL;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+// Set the time zone information needed for the rest of the methods
|
|
|
+//
|
|
|
+void SetTz(SYSTEMTIME *_st)
|
|
|
+{
|
|
|
+ TIME_ZONE_INFORMATION tz;
|
|
|
+ SYSTEMTIME st = *_st;
|
|
|
+ FILETIME ftDT; // Daylight savings file time
|
|
|
+ FILETIME ftST; // Standard time file time
|
|
|
+ FILETIME ft; // file time to compare
|
|
|
+ int i;
|
|
|
+
|
|
|
+ GetTimeZoneInformation(&tz);
|
|
|
+
|
|
|
+ // Convert current system time, daylight savings changover time
|
|
|
+ // and standard time to file time to see if current time is between
|
|
|
+ // the two dates. If so then we are in daylight savings otherwise we
|
|
|
+ // are not.
|
|
|
+ //
|
|
|
+ SystemTimeToFileTime(&st, &ft);
|
|
|
+ tz.DaylightDate.wYear = st.wYear;
|
|
|
+ tz.StandardDate.wYear = st.wYear;
|
|
|
+ SystemTimeToFileTime(&tz.DaylightDate, &ftDT);
|
|
|
+ SystemTimeToFileTime(&tz.StandardDate, &ftST);
|
|
|
+
|
|
|
+ // -1 First file time is earlier than second file time.
|
|
|
+ // 0 First file time is equal to second file time.
|
|
|
+ // 1 First file time is later than second file time.
|
|
|
+ //
|
|
|
+ if ((CompareFileTime(&ft,&ftDT) >= 0) && (CompareFileTime(&ft,&ftST) <= 0) )
|
|
|
+ {
|
|
|
+ _isdst = TRUE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _isdst = FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set localtime difference in seconds from UTC
|
|
|
+ //
|
|
|
+ if (_isdst)
|
|
|
+ {
|
|
|
+ // Adjust for Daylight Savings Time and convert to seconds
|
|
|
+ //
|
|
|
+ _localtime = (tz.Bias + tz.DaylightBias) * SECS_IN_MIN;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Convert to seconds
|
|
|
+ //
|
|
|
+ _localtime = tz.Bias * SECS_IN_MIN;
|
|
|
+ }
|
|
|
+
|
|
|
+ _dstBias = tz.DaylightBias;
|
|
|
+
|
|
|
+ // Set the standard and daylight strings
|
|
|
+ //
|
|
|
+ for (i=0;i<32;i++)
|
|
|
+ {
|
|
|
+ tz_name[0][i] = (char)tz.StandardName[i];
|
|
|
+ tz_name[1][i] = (char)tz.DaylightName[i];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Copy system time structure to tm structure
|
|
|
+//
|
|
|
+void SystemTimeToTm(SYSTEMTIME *st, struct tm * tmbuffer)
|
|
|
+{
|
|
|
+ tmbuffer->tm_hour = st->wHour;
|
|
|
+ tmbuffer->tm_mday = st->wDay;
|
|
|
+ tmbuffer->tm_min = st->wMinute;
|
|
|
+ tmbuffer->tm_mon = st->wMonth - 1;
|
|
|
+ tmbuffer->tm_sec = st->wSecond;
|
|
|
+ tmbuffer->tm_wday = st->wDayOfWeek;
|
|
|
+ tmbuffer->tm_yday = JulianDays(st); // Julian days, numer of days since Jan 1
|
|
|
+ tmbuffer->tm_year = st->wYear - 1900;
|
|
|
+ tmbuffer->tm_isdst = _isdst; // Is Daylight Savings Time
|
|
|
+}
|
|
|
+
|
|
|
+void TmToSystemTime(struct tm * tmbuffer, SYSTEMTIME *st)
|
|
|
+{
|
|
|
+ st->wHour = tmbuffer->tm_hour;
|
|
|
+ st->wDay = tmbuffer->tm_mday;
|
|
|
+ st->wMinute = tmbuffer->tm_min;
|
|
|
+ st->wMonth = tmbuffer->tm_mon + 1;
|
|
|
+ st->wSecond = tmbuffer->tm_sec;
|
|
|
+ st->wDayOfWeek = tmbuffer->tm_wday;
|
|
|
+ st->wYear = tmbuffer->tm_year + 1900;
|
|
|
+ st->wMilliseconds = 0;
|
|
|
+}
|
|
|
+
|
|
|
+// Get the JulianDay from a Gregorian Date for number of days into the current
|
|
|
+// year
|
|
|
+// Algorithm from: http://www.vsg.cape.com/~pbaum/date/jdalg2.htm
|
|
|
+//
|
|
|
+DWORD JulianDays(SYSTEMTIME * st)
|
|
|
+{
|
|
|
+ int m = 0;
|
|
|
+ int y = 0;
|
|
|
+ double jdd = 0;
|
|
|
+ double jddYearStart = 0;
|
|
|
+
|
|
|
+ // Calculate the Julian day for the beginning of the year
|
|
|
+ //
|
|
|
+ m = 13;
|
|
|
+ y = st->wYear - 1;
|
|
|
+ jddYearStart = 1 + (153 * m - 457) / 5 + 365 * y + (y / 4) - (y / 100) + (y / 400) + 1721118.5;
|
|
|
+
|
|
|
+ // Calculate Julian Day for Current Date
|
|
|
+ //
|
|
|
+ if (st->wMonth >= 3)
|
|
|
+ {
|
|
|
+ m = st->wMonth;
|
|
|
+ y = st->wYear;
|
|
|
+ }
|
|
|
+ jdd = st->wDay + (153 * m - 457) / 5 + 365 * y + (y / 4) - (y / 100) + (y / 400) + 1721118.5;
|
|
|
+
|
|
|
+ // Subract the year start Julian date from the Current Julian date to get
|
|
|
+ // the number of Julian days from the year start
|
|
|
+ //
|
|
|
+ return (DWORD)(jdd - jddYearStart);
|
|
|
+}
|
|
|
+#endif //__GNUC__
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * LuaCE
|
|
|
+ *
|
|
|
+ * Pedro Miller Rabinovitch, <[email protected]>
|
|
|
+ * http://www.inf.puc-rio.br/~miller/luace
|
|
|
+ *
|
|
|
+ * A quick port of Lua for Windows CE.
|
|
|
+ **/
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//int errno = 0;
|
|
|
+
|
|
|
+const char *getenv( const char *name ) {
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+char *strdup( const char *str ) {
|
|
|
+ char *ptr = (char *)malloc( sizeof(char) * strlen( str ) + 1 );
|
|
|
+ strcpy( ptr, str );
|
|
|
+ return ptr;
|
|
|
+}
|
|
|
+
|
|
|
+FILE *tmpfile() {
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+char *tmpnam( char *str ) {
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+#define _tcslen wcslen
|
|
|
+#define _tcsncpy wcsncpy
|
|
|
+#define _T(a) L##a
|
|
|
+
|
|
|
+int system( const char *cmd ) {
|
|
|
+ TCHAR tpath[MAX_PATH], args[1024], cmds[1024];
|
|
|
+ BOOL ret, cont = TRUE;
|
|
|
+ int i, len, exit_code = -100;
|
|
|
+ PROCESS_INFORMATION pi;
|
|
|
+
|
|
|
+ ZeroMemory( &pi, sizeof(pi) );
|
|
|
+
|
|
|
+ memset(tpath,0,MAX_PATH*sizeof(TCHAR));
|
|
|
+ memset(cmds,0,1024*sizeof(TCHAR));
|
|
|
+ memset(args,0,1024*sizeof(TCHAR));
|
|
|
+
|
|
|
+ mbstowcs(cmds, cmd, 1024);
|
|
|
+ len = _tcslen(cmds);
|
|
|
+
|
|
|
+ if (cmds[0] == _T('"')) {
|
|
|
+ for (i = 1; i < len; i++) {
|
|
|
+ if (cmds[i] == _T('"'))
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (i >= len)
|
|
|
+ return -1;
|
|
|
+ i++;
|
|
|
+ _tcsncpy(tpath, cmds + 1, i - 2);
|
|
|
+ _tcsncpy(args, cmds + i, len - i);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ for (i = 0; i < len; i++) {
|
|
|
+ if (cmds[i] == _T(' '))
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ _tcsncpy(tpath, cmds, i);
|
|
|
+ _tcsncpy(args, cmds + i, len - i);
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef DEBUGGING_PROCESS
|
|
|
+ ret = CreateProcess(tpath, args, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, NULL, &pi);
|
|
|
+#else
|
|
|
+ ret = CreateProcess(tpath, args, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (!ret) {
|
|
|
+ return GetLastError();
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef DEBUGGING_PROCESS
|
|
|
+ // Enter debug loop
|
|
|
+ while (cont) {
|
|
|
+
|
|
|
+ DEBUG_EVENT dbgEvt;
|
|
|
+
|
|
|
+ if ( WaitForDebugEvent( &dbgEvt, INFINITE ) ) {
|
|
|
+
|
|
|
+ switch (dbgEvt.dwDebugEventCode) {
|
|
|
+
|
|
|
+ case EXCEPTION_DEBUG_EVENT:
|
|
|
+ exit_code = (int) (dbgEvt.u.Exception.ExceptionRecord.ExceptionCode - 0xC0000000);
|
|
|
+ TerminateProcess( pi.hProcess, exit_code + (1 << 16) );
|
|
|
+ break;
|
|
|
+
|
|
|
+ case EXIT_PROCESS_DEBUG_EVENT:
|
|
|
+ cont = FALSE;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ContinueDebugEvent( dbgEvt.dwProcessId, dbgEvt.dwThreadId, DBG_CONTINUE );
|
|
|
+ }
|
|
|
+ }
|
|
|
+#else
|
|
|
+ // Wait until child process exits.
|
|
|
+ WaitForSingleObject( pi.hProcess, INFINITE );
|
|
|
+#endif
|
|
|
+
|
|
|
+ GetExitCodeProcess( pi.hProcess, &exit_code );
|
|
|
+
|
|
|
+ // Close process and thread handles.
|
|
|
+ CloseHandle( pi.hProcess );
|
|
|
+
|
|
|
+ return exit_code;
|
|
|
+}
|
|
|
+
|
|
|
+/* alloc's and returns a converted wide-char string from a normal one */
|
|
|
+wchar_t *atowcs( const char *str ) {
|
|
|
+ int len;
|
|
|
+ wchar_t *wstr;
|
|
|
+ if( str == NULL )
|
|
|
+ return NULL;
|
|
|
+ len = strlen( str );
|
|
|
+ wstr = (wchar_t *)malloc( sizeof( wchar_t )*2*(len + 1) );
|
|
|
+ wsprintf( wstr, L"%hs", str );
|
|
|
+ return wstr;
|
|
|
+}
|
|
|
+
|
|
|
+int rename( const char *src, const char *dst ) {
|
|
|
+ wchar_t *wsrc = atowcs( src ),
|
|
|
+ *wdst = atowcs( dst );
|
|
|
+ int res = 0;
|
|
|
+
|
|
|
+ if( !MoveFile( wsrc, wdst ))
|
|
|
+ res = GetLastError();
|
|
|
+
|
|
|
+ free( wsrc );
|
|
|
+ free( wdst );
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+int remove( const char *fname ) {
|
|
|
+ wchar_t *wfname = atowcs( fname );
|
|
|
+ int res = 0;
|
|
|
+
|
|
|
+ if( !DeleteFile( wfname ))
|
|
|
+ res = GetLastError();
|
|
|
+
|
|
|
+ free( wfname );
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+char *setlocale( int category, const char *locale ) {
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+struct lconv *localeconv( void )
|
|
|
+{
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int file_exists(const char* filename) {
|
|
|
+ FILE* f = fopen(filename, "r");
|
|
|
+ if(f != NULL)
|
|
|
+ {
|
|
|
+ fclose(f);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static char* conv_filename(char *filename) {
|
|
|
+ size_t i;
|
|
|
+ for (i = 0; i < strlen(filename); i++) {
|
|
|
+ if (filename[i] == '/')
|
|
|
+ filename[i] = '\\';
|
|
|
+ }
|
|
|
+ return filename;
|
|
|
+}
|
|
|
+
|
|
|
+static char* find_file(const char* filename) {
|
|
|
+ char* fullpath = malloc(sizeof(char) * (MAX_PATH + 1));
|
|
|
+ if(!fullpath)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ if (filename != NULL && strlen(filename) > 0)
|
|
|
+ {
|
|
|
+ if (filename[0] == '\\' || filename[0] == '/')//absolute path
|
|
|
+ {
|
|
|
+ strcpy(fullpath, filename);
|
|
|
+ return conv_filename(fullpath);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ TCHAR tpath[MAX_PATH + 1];
|
|
|
+ char* lastDash;
|
|
|
+ memset(tpath, 0, (MAX_PATH+1) * sizeof(TCHAR));
|
|
|
+ GetModuleFileName(NULL, tpath, MAX_PATH);
|
|
|
+ wcstombs(fullpath, tpath, MAX_PATH);
|
|
|
+ lastDash = strrchr(fullpath,'\\');
|
|
|
+ fullpath[lastDash - fullpath+1] = 0;
|
|
|
+ strncat(fullpath, filename, MAX_PATH - strlen(filename));
|
|
|
+ return conv_filename(fullpath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ free(fullpath);
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+FILE* _fopen(const char *filename, const char *flags) {
|
|
|
+ FILE *fp = NULL;
|
|
|
+ char *full_path = find_file(filename);
|
|
|
+ if (full_path) {
|
|
|
+ fp = fopen(full_path, flags);
|
|
|
+ free(full_path);
|
|
|
+ }
|
|
|
+ return fp;
|
|
|
+}
|
|
|
+
|
|
|
+#if 0
|
|
|
+int chdir(const char *path) {
|
|
|
+ wchar_t *wpath = atowcs( path );
|
|
|
+ int res = 0;
|
|
|
+
|
|
|
+ if( !_wchdir( wpath ))
|
|
|
+ res = GetLastError();
|
|
|
+
|
|
|
+ free( wpath );
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+int mkdir(const char *path) {
|
|
|
+ wchar_t *wpath = atowcs( path );
|
|
|
+ int res = 0;
|
|
|
+
|
|
|
+ if( !CreateDirectory(wpath, NULL))
|
|
|
+ res = GetLastError();
|
|
|
+
|
|
|
+ free( wpath );
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+HINSTANCE LoadLibraryA(LPCSTR path)
|
|
|
+{
|
|
|
+ wchar_t *wpath = atowcs( path );
|
|
|
+ HINSTANCE res = LoadLibrary( wpath );
|
|
|
+ free( wpath );
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+HMODULE GetModuleHandleA(LPCSTR module)
|
|
|
+{
|
|
|
+ wchar_t *wmodule = atowcs( module );
|
|
|
+ HMODULE res = GetModuleHandle( module );
|
|
|
+ free( module );
|
|
|
+ return res;
|
|
|
+}
|