Changes in / [eb083ad:3e67ab1] in mainline
- Files:
-
- 12 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
reb083ad r3e67ab1 185 185 $(USPACE_PATH)/app/vuhid/vuh \ 186 186 $(USPACE_PATH)/app/mkbd/mkbd \ 187 $(USPACE_PATH)/app/websrv/websrv \ 188 $(USPACE_PATH)/app/date/date 187 $(USPACE_PATH)/app/websrv/websrv 189 188 190 189 ifeq ($(CONFIG_PCC),y) -
boot/arch/amd64/Makefile.inc
reb083ad r3e67ab1 42 42 char/ps2mouse \ 43 43 char/xtkbd \ 44 time/cmos-rtc \45 44 bus/usb/ehci\ 46 45 bus/usb/ohci \ -
uspace/Makefile
reb083ad r3e67ab1 71 71 app/sysinfo \ 72 72 app/mkbd \ 73 app/date \74 73 app/websrv \ 75 74 srv/clipboard \ … … 124 123 drv/nic/ne2k \ 125 124 drv/nic/e1k \ 126 drv/nic/rtl8139 \125 drv/nic/rtl8139 127 126 128 127 ifeq ($(CONFIG_PCC),y) … … 148 147 drv/bus/isa \ 149 148 drv/char/ns8250 \ 150 drv/time/cmos-rtc \151 149 srv/hw/irc/apic \ 152 150 srv/hw/irc/i8259 … … 159 157 drv/bus/isa \ 160 158 drv/char/ns8250 \ 161 drv/time/cmos-rtc \162 159 srv/hw/irc/apic \ 163 160 srv/hw/irc/i8259 -
uspace/drv/bus/isa/isa.dev
reb083ad r3e67ab1 27 27 dma 1 28 28 dma 5 29 30 cmos-rtc:31 match 100 isa/cmos-rtc32 io_range 70 2 -
uspace/lib/c/Makefile
reb083ad r3e67ab1 69 69 generic/device/hw_res_parsed.c \ 70 70 generic/device/char_dev.c \ 71 generic/device/clock_dev.c \72 71 generic/device/nic.c \ 73 72 generic/device/pci.c \ -
uspace/lib/c/generic/time.c
reb083ad r3e67ab1 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2011 Petr Koupy4 * Copyright (c) 2011 Jiri Zarevucky5 3 * All rights reserved. 6 4 * … … 45 43 #include <ddi.h> 46 44 #include <libc.h> 47 #include <stdint.h>48 #include <stdio.h>49 #include <ctype.h>50 51 #define ASCTIME_BUF_LEN 2652 45 53 46 /** Pointer to kernel shared variables with time */ … … 57 50 volatile sysarg_t seconds2; 58 51 } *ktime = NULL; 59 60 /* Helper functions ***********************************************************/61 62 #define HOURS_PER_DAY (24)63 #define MINS_PER_HOUR (60)64 #define SECS_PER_MIN (60)65 #define MINS_PER_DAY (MINS_PER_HOUR * HOURS_PER_DAY)66 #define SECS_PER_HOUR (SECS_PER_MIN * MINS_PER_HOUR)67 #define SECS_PER_DAY (SECS_PER_HOUR * HOURS_PER_DAY)68 69 /**70 * Checks whether the year is a leap year.71 *72 * @param year Year since 1900 (e.g. for 1970, the value is 70).73 * @return true if year is a leap year, false otherwise74 */75 static bool _is_leap_year(time_t year)76 {77 year += 1900;78 79 if (year % 400 == 0)80 return true;81 if (year % 100 == 0)82 return false;83 if (year % 4 == 0)84 return true;85 return false;86 }87 88 /**89 * Returns how many days there are in the given month of the given year.90 * Note that year is only taken into account if month is February.91 *92 * @param year Year since 1900 (can be negative).93 * @param mon Month of the year. 0 for January, 11 for December.94 * @return Number of days in the specified month.95 */96 static int _days_in_month(time_t year, time_t mon)97 {98 assert(mon >= 0 && mon <= 11);99 100 static int month_days[] =101 { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };102 103 if (mon == 1) {104 year += 1900;105 /* february */106 return _is_leap_year(year) ? 29 : 28;107 } else {108 return month_days[mon];109 }110 }111 112 /**113 * For specified year, month and day of month, returns which day of that year114 * it is.115 *116 * For example, given date 2011-01-03, the corresponding expression is:117 * _day_of_year(111, 0, 3) == 2118 *119 * @param year Year (year 1900 = 0, can be negative).120 * @param mon Month (January = 0).121 * @param mday Day of month (First day is 1).122 * @return Day of year (First day is 0).123 */124 static int _day_of_year(time_t year, time_t mon, time_t mday)125 {126 static int mdays[] =127 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };128 static int leap_mdays[] =129 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };130 131 return (_is_leap_year(year) ? leap_mdays[mon] : mdays[mon]) + mday - 1;132 }133 134 /**135 * Integer division that rounds to negative infinity.136 * Used by some functions in this file.137 *138 * @param op1 Dividend.139 * @param op2 Divisor.140 * @return Rounded quotient.141 */142 static time_t _floor_div(time_t op1, time_t op2)143 {144 if (op1 >= 0 || op1 % op2 == 0) {145 return op1 / op2;146 } else {147 return op1 / op2 - 1;148 }149 }150 151 /**152 * Modulo that rounds to negative infinity.153 * Used by some functions in this file.154 *155 * @param op1 Dividend.156 * @param op2 Divisor.157 * @return Remainder.158 */159 static time_t _floor_mod(time_t op1, time_t op2)160 {161 int div = _floor_div(op1, op2);162 163 /* (a / b) * b + a % b == a */164 /* thus, a % b == a - (a / b) * b */165 166 int result = op1 - div * op2;167 168 /* Some paranoid checking to ensure I didn't make a mistake here. */169 assert(result >= 0);170 assert(result < op2);171 assert(div * op2 + result == op1);172 173 return result;174 }175 176 /**177 * Number of days since the Epoch.178 * Epoch is 1970-01-01, which is also equal to day 0.179 *180 * @param year Year (year 1900 = 0, may be negative).181 * @param mon Month (January = 0).182 * @param mday Day of month (first day = 1).183 * @return Number of days since the Epoch.184 */185 static time_t _days_since_epoch(time_t year, time_t mon, time_t mday)186 {187 return (year - 70) * 365 + _floor_div(year - 69, 4) -188 _floor_div(year - 1, 100) + _floor_div(year + 299, 400) +189 _day_of_year(year, mon, mday);190 }191 192 /**193 * Seconds since the Epoch. see also _days_since_epoch().194 *195 * @param tm Normalized broken-down time.196 * @return Number of seconds since the epoch, not counting leap seconds.197 */198 static time_t _secs_since_epoch(const struct tm *tm)199 {200 return _days_since_epoch(tm->tm_year, tm->tm_mon, tm->tm_mday) *201 SECS_PER_DAY + tm->tm_hour * SECS_PER_HOUR +202 tm->tm_min * SECS_PER_MIN + tm->tm_sec;203 }204 205 /**206 * Which day of week the specified date is.207 *208 * @param year Year (year 1900 = 0).209 * @param mon Month (January = 0).210 * @param mday Day of month (first = 1).211 * @return Day of week (Sunday = 0).212 */213 static int _day_of_week(time_t year, time_t mon, time_t mday)214 {215 /* 1970-01-01 is Thursday */216 return _floor_mod((_days_since_epoch(year, mon, mday) + 4), 7);217 }218 219 /**220 * Normalizes the broken-down time and optionally adds specified amount of221 * seconds.222 *223 * @param tm Broken-down time to normalize.224 * @param sec_add Seconds to add.225 * @return 0 on success, -1 on overflow226 */227 static int _normalize_time(struct tm *tm, time_t sec_add)228 {229 // TODO: DST correction230 231 /* Set initial values. */232 time_t sec = tm->tm_sec + sec_add;233 time_t min = tm->tm_min;234 time_t hour = tm->tm_hour;235 time_t day = tm->tm_mday - 1;236 time_t mon = tm->tm_mon;237 time_t year = tm->tm_year;238 239 /* Adjust time. */240 min += _floor_div(sec, SECS_PER_MIN);241 sec = _floor_mod(sec, SECS_PER_MIN);242 hour += _floor_div(min, MINS_PER_HOUR);243 min = _floor_mod(min, MINS_PER_HOUR);244 day += _floor_div(hour, HOURS_PER_DAY);245 hour = _floor_mod(hour, HOURS_PER_DAY);246 247 /* Adjust month. */248 year += _floor_div(mon, 12);249 mon = _floor_mod(mon, 12);250 251 /* Now the difficult part - days of month. */252 253 /* First, deal with whole cycles of 400 years = 146097 days. */254 year += _floor_div(day, 146097) * 400;255 day = _floor_mod(day, 146097);256 257 /* Then, go in one year steps. */258 if (mon <= 1) {259 /* January and February. */260 while (day > 365) {261 day -= _is_leap_year(year) ? 366 : 365;262 year++;263 }264 } else {265 /* Rest of the year. */266 while (day > 365) {267 day -= _is_leap_year(year + 1) ? 366 : 365;268 year++;269 }270 }271 272 /* Finally, finish it off month per month. */273 while (day >= _days_in_month(year, mon)) {274 day -= _days_in_month(year, mon);275 mon++;276 if (mon >= 12) {277 mon -= 12;278 year++;279 }280 }281 282 /* Calculate the remaining two fields. */283 tm->tm_yday = _day_of_year(year, mon, day + 1);284 tm->tm_wday = _day_of_week(year, mon, day + 1);285 286 /* And put the values back to the struct. */287 tm->tm_sec = (int) sec;288 tm->tm_min = (int) min;289 tm->tm_hour = (int) hour;290 tm->tm_mday = (int) day + 1;291 tm->tm_mon = (int) mon;292 293 /* Casts to work around libc brain-damage. */294 if (year > ((int)INT_MAX) || year < ((int)INT_MIN)) {295 tm->tm_year = (year < 0) ? ((int)INT_MIN) : ((int)INT_MAX);296 return -1;297 }298 299 tm->tm_year = (int) year;300 return 0;301 }302 303 /**304 * Which day the week-based year starts on, relative to the first calendar day.305 * E.g. if the year starts on December 31st, the return value is -1.306 *307 * @param Year since 1900.308 * @return Offset of week-based year relative to calendar year.309 */310 static int _wbyear_offset(int year)311 {312 int start_wday = _day_of_week(year, 0, 1);313 return _floor_mod(4 - start_wday, 7) - 3;314 }315 316 /**317 * Returns week-based year of the specified time.318 *319 * @param tm Normalized broken-down time.320 * @return Week-based year.321 */322 static int _wbyear(const struct tm *tm)323 {324 int day = tm->tm_yday - _wbyear_offset(tm->tm_year);325 if (day < 0) {326 /* Last week of previous year. */327 return tm->tm_year - 1;328 }329 if (day > 364 + _is_leap_year(tm->tm_year)) {330 /* First week of next year. */331 return tm->tm_year + 1;332 }333 /* All the other days are in the calendar year. */334 return tm->tm_year;335 }336 337 /**338 * Week number of the year, assuming weeks start on sunday.339 * The first Sunday of January is the first day of week 1;340 * days in the new year before this are in week 0.341 *342 * @param tm Normalized broken-down time.343 * @return The week number (0 - 53).344 */345 static int _sun_week_number(const struct tm *tm)346 {347 int first_day = (7 - _day_of_week(tm->tm_year, 0, 1)) % 7;348 return (tm->tm_yday - first_day + 7) / 7;349 }350 351 /**352 * Week number of the year, assuming weeks start on monday.353 * If the week containing January 1st has four or more days in the new year,354 * then it is considered week 1. Otherwise, it is the last week of the previous355 * year, and the next week is week 1. Both January 4th and the first Thursday356 * of January are always in week 1.357 *358 * @param tm Normalized broken-down time.359 * @return The week number (1 - 53).360 */361 static int _iso_week_number(const struct tm *tm)362 {363 int day = tm->tm_yday - _wbyear_offset(tm->tm_year);364 if (day < 0) {365 /* Last week of previous year. */366 return 53;367 }368 if (day > 364 + _is_leap_year(tm->tm_year)) {369 /* First week of next year. */370 return 1;371 }372 /* All the other days give correct answer. */373 return (day / 7 + 1);374 }375 376 /**377 * Week number of the year, assuming weeks start on monday.378 * The first Monday of January is the first day of week 1;379 * days in the new year before this are in week 0.380 *381 * @param tm Normalized broken-down time.382 * @return The week number (0 - 53).383 */384 static int _mon_week_number(const struct tm *tm)385 {386 int first_day = (1 - _day_of_week(tm->tm_year, 0, 1)) % 7;387 return (tm->tm_yday - first_day + 7) / 7;388 }389 390 /******************************************************************************/391 392 52 393 53 /** Add microseconds to given timeval. … … 568 228 } 569 229 570 /**571 * This function first normalizes the provided broken-down time572 * (moves all values to their proper bounds) and then tries to573 * calculate the appropriate time_t representation.574 *575 * @param tm Broken-down time.576 * @return time_t representation of the time, undefined value on overflow.577 */578 time_t mktime(struct tm *tm)579 {580 // TODO: take DST flag into account581 // TODO: detect overflow582 583 _normalize_time(tm, 0);584 return _secs_since_epoch(tm);585 }586 587 /**588 * Convert time and date to a string, based on a specified format and589 * current locale.590 *591 * @param s Buffer to write string to.592 * @param maxsize Size of the buffer.593 * @param format Format of the output.594 * @param tm Broken-down time to format.595 * @return Number of bytes written.596 */597 size_t strftime(char *restrict s, size_t maxsize,598 const char *restrict format, const struct tm *restrict tm)599 {600 assert(s != NULL);601 assert(format != NULL);602 assert(tm != NULL);603 604 // TODO: use locale605 static const char *wday_abbr[] = {606 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"607 };608 static const char *wday[] = {609 "Sunday", "Monday", "Tuesday", "Wednesday",610 "Thursday", "Friday", "Saturday"611 };612 static const char *mon_abbr[] = {613 "Jan", "Feb", "Mar", "Apr", "May", "Jun",614 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"615 };616 static const char *mon[] = {617 "January", "February", "March", "April", "May", "June", "July",618 "August", "September", "October", "November", "December"619 };620 621 if (maxsize < 1) {622 return 0;623 }624 625 char *ptr = s;626 size_t consumed;627 size_t remaining = maxsize;628 629 #define append(...) { \630 /* FIXME: this requires POSIX-correct snprintf */ \631 /* otherwise it won't work with non-ascii chars */ \632 consumed = snprintf(ptr, remaining, __VA_ARGS__); \633 if (consumed >= remaining) { \634 return 0; \635 } \636 ptr += consumed; \637 remaining -= consumed; \638 }639 640 #define recurse(fmt) { \641 consumed = strftime(ptr, remaining, fmt, tm); \642 if (consumed == 0) { \643 return 0; \644 } \645 ptr += consumed; \646 remaining -= consumed; \647 }648 649 #define TO_12H(hour) (((hour) > 12) ? ((hour) - 12) : \650 (((hour) == 0) ? 12 : (hour)))651 652 while (*format != '\0') {653 if (*format != '%') {654 append("%c", *format);655 format++;656 continue;657 }658 659 format++;660 if (*format == '0' || *format == '+') {661 // TODO: padding662 format++;663 }664 while (isdigit(*format)) {665 // TODO: padding666 format++;667 }668 if (*format == 'O' || *format == 'E') {669 // TODO: locale's alternative format670 format++;671 }672 673 switch (*format) {674 case 'a':675 append("%s", wday_abbr[tm->tm_wday]); break;676 case 'A':677 append("%s", wday[tm->tm_wday]); break;678 case 'b':679 append("%s", mon_abbr[tm->tm_mon]); break;680 case 'B':681 append("%s", mon[tm->tm_mon]); break;682 case 'c':683 // TODO: locale-specific datetime format684 recurse("%Y-%m-%d %H:%M:%S"); break;685 case 'C':686 append("%02d", (1900 + tm->tm_year) / 100); break;687 case 'd':688 append("%02d", tm->tm_mday); break;689 case 'D':690 recurse("%m/%d/%y"); break;691 case 'e':692 append("%2d", tm->tm_mday); break;693 case 'F':694 recurse("%+4Y-%m-%d"); break;695 case 'g':696 append("%02d", _wbyear(tm) % 100); break;697 case 'G':698 append("%d", _wbyear(tm)); break;699 case 'h':700 recurse("%b"); break;701 case 'H':702 append("%02d", tm->tm_hour); break;703 case 'I':704 append("%02d", TO_12H(tm->tm_hour)); break;705 case 'j':706 append("%03d", tm->tm_yday); break;707 case 'k':708 append("%2d", tm->tm_hour); break;709 case 'l':710 append("%2d", TO_12H(tm->tm_hour)); break;711 case 'm':712 append("%02d", tm->tm_mon); break;713 case 'M':714 append("%02d", tm->tm_min); break;715 case 'n':716 append("\n"); break;717 case 'p':718 append("%s", tm->tm_hour < 12 ? "AM" : "PM"); break;719 case 'P':720 append("%s", tm->tm_hour < 12 ? "am" : "PM"); break;721 case 'r':722 recurse("%I:%M:%S %p"); break;723 case 'R':724 recurse("%H:%M"); break;725 case 's':726 append("%ld", _secs_since_epoch(tm)); break;727 case 'S':728 append("%02d", tm->tm_sec); break;729 case 't':730 append("\t"); break;731 case 'T':732 recurse("%H:%M:%S"); break;733 case 'u':734 append("%d", (tm->tm_wday == 0) ? 7 : tm->tm_wday);735 break;736 case 'U':737 append("%02d", _sun_week_number(tm)); break;738 case 'V':739 append("%02d", _iso_week_number(tm)); break;740 case 'w':741 append("%d", tm->tm_wday); break;742 case 'W':743 append("%02d", _mon_week_number(tm)); break;744 case 'x':745 // TODO: locale-specific date format746 recurse("%Y-%m-%d"); break;747 case 'X':748 // TODO: locale-specific time format749 recurse("%H:%M:%S"); break;750 case 'y':751 append("%02d", tm->tm_year % 100); break;752 case 'Y':753 append("%d", 1900 + tm->tm_year); break;754 case 'z':755 // TODO: timezone756 break;757 case 'Z':758 // TODO: timezone759 break;760 case '%':761 append("%%");762 break;763 default:764 /* Invalid specifier, print verbatim. */765 while (*format != '%') {766 format--;767 }768 append("%%");769 break;770 }771 format++;772 }773 774 #undef append775 #undef recurse776 777 return maxsize - remaining;778 }779 780 struct tm *gmtime(const time_t *timer)781 {782 assert(timer != NULL);783 784 static struct tm result;785 786 /* Set result to epoch. */787 result.tm_sec = 0;788 result.tm_min = 0;789 result.tm_hour = 0;790 result.tm_mday = 1;791 result.tm_mon = 0;792 result.tm_year = 70; /* 1970 */793 794 if (_normalize_time(&result, *timer) == -1) {795 errno = EOVERFLOW;796 return NULL;797 }798 799 return &result;800 }801 802 /**803 * Converts broken-down time to a string in format804 * "Sun Jan 1 00:00:00 1970\n". (Obsolete)805 *806 * @param timeptr Broken-down time structure.807 * @return Pointer to a statically allocated string.808 */809 char *asctime(const struct tm *timeptr)810 {811 static char buf[ASCTIME_BUF_LEN];812 813 assert(timeptr != NULL);814 815 static const char *wday[] = {816 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"817 };818 static const char *mon[] = {819 "Jan", "Feb", "Mar", "Apr", "May", "Jun",820 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"821 };822 823 snprintf(buf, ASCTIME_BUF_LEN, "%s %s %2d %02d:%02d:%02d %d\n",824 wday[timeptr->tm_wday],825 mon[timeptr->tm_mon],826 timeptr->tm_mday, timeptr->tm_hour,827 timeptr->tm_min, timeptr->tm_sec,828 1900 + timeptr->tm_year);829 830 return buf;831 832 }833 834 /**835 * Converts a time value to a broken-down local time.836 *837 * @param timer Time to convert.838 * @return Normalized broken-down time in local timezone, NULL on overflow.839 */840 struct tm *localtime(const time_t *timer)841 {842 // TODO: deal with timezone843 // currently assumes system and all times are in GMT844 845 static struct tm result;846 847 /* Set result to epoch. */848 result.tm_sec = 0;849 result.tm_min = 0;850 result.tm_hour = 0;851 result.tm_mday = 1;852 result.tm_mon = 0;853 result.tm_year = 70; /* 1970 */854 855 if (_normalize_time(&result, *timer) == -1) {856 errno = EOVERFLOW;857 return NULL;858 }859 860 return &result;861 }862 863 /**864 * Equivalent to asctime(localtime(clock)).865 *866 * @param timer Time to convert.867 * @return Pointer to a statically allocated string holding the date.868 */869 char *ctime(const time_t *timer)870 {871 struct tm *loctime = localtime(timer);872 if (loctime == NULL) {873 return NULL;874 }875 return asctime(loctime);876 }877 878 /**879 * Calculate the difference between two times, in seconds.880 *881 * @param time1 First time.882 * @param time0 Second time.883 * @return Time in seconds.884 */885 double difftime(time_t time1, time_t time0)886 {887 return (double) (time1 - time0);888 }889 890 230 /** @} 891 231 */ -
uspace/lib/c/include/ipc/dev_iface.h
reb083ad r3e67ab1 52 52 USBHID_DEV_IFACE, 53 53 54 /** Interface provided by Real Time Clock devices */55 CLOCK_DEV_IFACE,56 57 54 DEV_IFACE_MAX 58 55 } dev_inferface_idx_t; -
uspace/lib/c/include/sys/time.h
reb083ad r3e67ab1 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2011 Petr Koupy4 * Copyright (c) 2011 Jiri Zarevucky5 3 * All rights reserved. 6 4 * … … 41 39 42 40 #define DST_NONE 0 43 #define ASCTIME_BUF_LEN 2644 41 45 42 typedef long time_t; … … 48 45 typedef uint32_t useconds_t; 49 46 typedef uint32_t mseconds_t; 50 51 struct tm {52 int tm_sec; /* Seconds [0,60]. */53 int tm_min; /* Minutes [0,59]. */54 int tm_hour; /* Hour [0,23]. */55 int tm_mday; /* Day of month [1,31]. */56 int tm_mon; /* Month of year [0,11]. */57 int tm_year; /* Years since 1900. */58 int tm_wday; /* Day of week [0,6] (Sunday = 0). */59 int tm_yday; /* Day of year [0,365]. */60 int tm_isdst; /* Daylight Savings flag. */61 };62 47 63 48 struct timeval { … … 79 64 extern void udelay(useconds_t); 80 65 81 extern time_t mktime(struct tm *tm);82 extern struct tm *gmtime(const time_t *timer);83 extern char *asctime(const struct tm *timeptr);84 extern struct tm *localtime(const time_t *timer);85 extern char *ctime(const time_t *timer);86 extern double difftime(time_t time1, time_t time0);87 extern size_t strftime(char *restrict s, size_t maxsize,88 const char *restrict format, const struct tm *restrict tm);89 90 66 #endif 91 67 -
uspace/lib/drv/Makefile
reb083ad r3e67ab1 44 44 generic/remote_pci.c \ 45 45 generic/remote_usbhc.c \ 46 generic/remote_usbhid.c \ 47 generic/remote_clock_dev.c 46 generic/remote_usbhid.c 48 47 49 48 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/drv/generic/dev_iface.c
reb083ad r3e67ab1 41 41 #include "remote_hw_res.h" 42 42 #include "remote_char_dev.h" 43 #include "remote_clock_dev.h"44 43 #include "remote_nic.h" 45 44 #include "remote_usb.h" … … 56 55 &remote_usb_iface, 57 56 &remote_usbhc_iface, 58 &remote_usbhid_iface, 59 &remote_clock_dev_iface, 57 &remote_usbhid_iface 60 58 } 61 59 }; -
uspace/lib/posix/time.c
reb083ad r3e67ab1 140 140 * Used by some functions in this file. 141 141 * 142 * @param op1 Dividen d.142 * @param op1 Divident. 143 143 * @param op2 Divisor. 144 144 * @return Rounded quotient. … … 157 157 * Used by some functions in this file. 158 158 * 159 * @param op1 Dividen d.159 * @param op1 Divident. 160 160 * @param op2 Divisor. 161 161 * @return Remainder. … … 195 195 196 196 /** 197 * Seconds since the Epoch. see also _days_since_epoch(). 198 * 199 * @param tm Normalized broken-down time. 200 * @return Number of seconds since the epoch, not counting leap seconds. 201 */ 202 static time_t _secs_since_epoch(const struct posix_tm *tm) 203 { 204 return _days_since_epoch(tm->tm_year, tm->tm_mon, tm->tm_mday) * 205 SECS_PER_DAY + tm->tm_hour * SECS_PER_HOUR + 206 tm->tm_min * SECS_PER_MIN + tm->tm_sec; 207 } 208 209 /** 197 210 * Which day of week the specified date is. 198 211 * … … 216 229 * @return 0 on success, -1 on overflow 217 230 */ 218 static int _normalize_time(struct tm *tm, time_t sec_add)231 static int _normalize_time(struct posix_tm *tm, time_t sec_add) 219 232 { 220 233 // TODO: DST correction … … 292 305 } 293 306 307 /** 308 * Which day the week-based year starts on, relative to the first calendar day. 309 * E.g. if the year starts on December 31st, the return value is -1. 310 * 311 * @param Year since 1900. 312 * @return Offset of week-based year relative to calendar year. 313 */ 314 static int _wbyear_offset(int year) 315 { 316 int start_wday = _day_of_week(year, 0, 1); 317 return _floor_mod(4 - start_wday, 7) - 3; 318 } 319 320 /** 321 * Returns week-based year of the specified time. 322 * 323 * @param tm Normalized broken-down time. 324 * @return Week-based year. 325 */ 326 static int _wbyear(const struct posix_tm *tm) 327 { 328 int day = tm->tm_yday - _wbyear_offset(tm->tm_year); 329 if (day < 0) { 330 /* Last week of previous year. */ 331 return tm->tm_year - 1; 332 } 333 if (day > 364 + _is_leap_year(tm->tm_year)) { 334 /* First week of next year. */ 335 return tm->tm_year + 1; 336 } 337 /* All the other days are in the calendar year. */ 338 return tm->tm_year; 339 } 340 341 /** 342 * Week number of the year, assuming weeks start on sunday. 343 * The first Sunday of January is the first day of week 1; 344 * days in the new year before this are in week 0. 345 * 346 * @param tm Normalized broken-down time. 347 * @return The week number (0 - 53). 348 */ 349 static int _sun_week_number(const struct posix_tm *tm) 350 { 351 int first_day = (7 - _day_of_week(tm->tm_year, 0, 1)) % 7; 352 return (tm->tm_yday - first_day + 7) / 7; 353 } 354 355 /** 356 * Week number of the year, assuming weeks start on monday. 357 * If the week containing January 1st has four or more days in the new year, 358 * then it is considered week 1. Otherwise, it is the last week of the previous 359 * year, and the next week is week 1. Both January 4th and the first Thursday 360 * of January are always in week 1. 361 * 362 * @param tm Normalized broken-down time. 363 * @return The week number (1 - 53). 364 */ 365 static int _iso_week_number(const struct posix_tm *tm) 366 { 367 int day = tm->tm_yday - _wbyear_offset(tm->tm_year); 368 if (day < 0) { 369 /* Last week of previous year. */ 370 return 53; 371 } 372 if (day > 364 + _is_leap_year(tm->tm_year)) { 373 /* First week of next year. */ 374 return 1; 375 } 376 /* All the other days give correct answer. */ 377 return (day / 7 + 1); 378 } 379 380 /** 381 * Week number of the year, assuming weeks start on monday. 382 * The first Monday of January is the first day of week 1; 383 * days in the new year before this are in week 0. 384 * 385 * @param tm Normalized broken-down time. 386 * @return The week number (0 - 53). 387 */ 388 static int _mon_week_number(const struct posix_tm *tm) 389 { 390 int first_day = (1 - _day_of_week(tm->tm_year, 0, 1)) % 7; 391 return (tm->tm_yday - first_day + 7) / 7; 392 } 393 294 394 /******************************************************************************/ 295 395 … … 311 411 312 412 /** 413 * Calculate the difference between two times, in seconds. 414 * 415 * @param time1 First time. 416 * @param time0 Second time. 417 * @return Time in seconds. 418 */ 419 double posix_difftime(time_t time1, time_t time0) 420 { 421 return (double) (time1 - time0); 422 } 423 424 /** 425 * This function first normalizes the provided broken-down time 426 * (moves all values to their proper bounds) and then tries to 427 * calculate the appropriate time_t representation. 428 * 429 * @param tm Broken-down time. 430 * @return time_t representation of the time, undefined value on overflow. 431 */ 432 time_t posix_mktime(struct posix_tm *tm) 433 { 434 // TODO: take DST flag into account 435 // TODO: detect overflow 436 437 _normalize_time(tm, 0); 438 return _secs_since_epoch(tm); 439 } 440 441 /** 442 * Converts a time value to a broken-down UTC time. 443 * 444 * @param timer Time to convert. 445 * @return Normalized broken-down time in UTC, NULL on overflow. 446 */ 447 struct posix_tm *posix_gmtime(const time_t *timer) 448 { 449 assert(timer != NULL); 450 451 static struct posix_tm result; 452 return posix_gmtime_r(timer, &result); 453 } 454 455 /** 313 456 * Converts a time value to a broken-down UTC time. 314 457 * … … 317 460 * @return Value of result on success, NULL on overflow. 318 461 */ 319 struct tm *posix_gmtime_r(const time_t *restrict timer,320 struct tm *restrict result)462 struct posix_tm *posix_gmtime_r(const time_t *restrict timer, 463 struct posix_tm *restrict result) 321 464 { 322 465 assert(timer != NULL); … … 341 484 /** 342 485 * Converts a time value to a broken-down local time. 486 * 487 * @param timer Time to convert. 488 * @return Normalized broken-down time in local timezone, NULL on overflow. 489 */ 490 struct posix_tm *posix_localtime(const time_t *timer) 491 { 492 static struct posix_tm result; 493 return posix_localtime_r(timer, &result); 494 } 495 496 /** 497 * Converts a time value to a broken-down local time. 343 498 * 344 499 * @param timer Time to convert. … … 346 501 * @return Value of result on success, NULL on overflow. 347 502 */ 348 struct tm *posix_localtime_r(const time_t *restrict timer,349 struct tm *restrict result)503 struct posix_tm *posix_localtime_r(const time_t *restrict timer, 504 struct posix_tm *restrict result) 350 505 { 351 506 // TODO: deal with timezone 352 507 // currently assumes system and all times are in GMT 353 508 return posix_gmtime_r(timer, result); 509 } 510 511 /** 512 * Converts broken-down time to a string in format 513 * "Sun Jan 1 00:00:00 1970\n". (Obsolete) 514 * 515 * @param timeptr Broken-down time structure. 516 * @return Pointer to a statically allocated string. 517 */ 518 char *posix_asctime(const struct posix_tm *timeptr) 519 { 520 static char buf[ASCTIME_BUF_LEN]; 521 return posix_asctime_r(timeptr, buf); 354 522 } 355 523 … … 363 531 * @return Value of buf. 364 532 */ 365 char *posix_asctime_r(const struct tm *restrict timeptr,533 char *posix_asctime_r(const struct posix_tm *restrict timeptr, 366 534 char *restrict buf) 367 535 { … … 388 556 389 557 /** 558 * Equivalent to asctime(localtime(clock)). 559 * 560 * @param timer Time to convert. 561 * @return Pointer to a statically allocated string holding the date. 562 */ 563 char *posix_ctime(const time_t *timer) 564 { 565 struct posix_tm *loctime = posix_localtime(timer); 566 if (loctime == NULL) { 567 return NULL; 568 } 569 return posix_asctime(loctime); 570 } 571 572 /** 390 573 * Reentrant variant of ctime(). 391 574 * … … 397 580 char *posix_ctime_r(const time_t *timer, char *buf) 398 581 { 399 struct tm loctime;582 struct posix_tm loctime; 400 583 if (posix_localtime_r(timer, &loctime) == NULL) { 401 584 return NULL; 402 585 } 403 586 return posix_asctime_r(&loctime, buf); 587 } 588 589 /** 590 * Convert time and date to a string, based on a specified format and 591 * current locale. 592 * 593 * @param s Buffer to write string to. 594 * @param maxsize Size of the buffer. 595 * @param format Format of the output. 596 * @param tm Broken-down time to format. 597 * @return Number of bytes written. 598 */ 599 size_t posix_strftime(char *restrict s, size_t maxsize, 600 const char *restrict format, const struct posix_tm *restrict tm) 601 { 602 assert(s != NULL); 603 assert(format != NULL); 604 assert(tm != NULL); 605 606 // TODO: use locale 607 static const char *wday_abbr[] = { 608 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 609 }; 610 static const char *wday[] = { 611 "Sunday", "Monday", "Tuesday", "Wednesday", 612 "Thursday", "Friday", "Saturday" 613 }; 614 static const char *mon_abbr[] = { 615 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 616 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 617 }; 618 static const char *mon[] = { 619 "January", "February", "March", "April", "May", "June", "July", 620 "August", "September", "October", "November", "December" 621 }; 622 623 if (maxsize < 1) { 624 return 0; 625 } 626 627 char *ptr = s; 628 size_t consumed; 629 size_t remaining = maxsize; 630 631 #define append(...) { \ 632 /* FIXME: this requires POSIX-correct snprintf */ \ 633 /* otherwise it won't work with non-ascii chars */ \ 634 consumed = snprintf(ptr, remaining, __VA_ARGS__); \ 635 if (consumed >= remaining) { \ 636 return 0; \ 637 } \ 638 ptr += consumed; \ 639 remaining -= consumed; \ 640 } 641 642 #define recurse(fmt) { \ 643 consumed = posix_strftime(ptr, remaining, fmt, tm); \ 644 if (consumed == 0) { \ 645 return 0; \ 646 } \ 647 ptr += consumed; \ 648 remaining -= consumed; \ 649 } 650 651 #define TO_12H(hour) (((hour) > 12) ? ((hour) - 12) : \ 652 (((hour) == 0) ? 12 : (hour))) 653 654 while (*format != '\0') { 655 if (*format != '%') { 656 append("%c", *format); 657 format++; 658 continue; 659 } 660 661 format++; 662 if (*format == '0' || *format == '+') { 663 // TODO: padding 664 format++; 665 } 666 while (isdigit(*format)) { 667 // TODO: padding 668 format++; 669 } 670 if (*format == 'O' || *format == 'E') { 671 // TODO: locale's alternative format 672 format++; 673 } 674 675 switch (*format) { 676 case 'a': 677 append("%s", wday_abbr[tm->tm_wday]); break; 678 case 'A': 679 append("%s", wday[tm->tm_wday]); break; 680 case 'b': 681 append("%s", mon_abbr[tm->tm_mon]); break; 682 case 'B': 683 append("%s", mon[tm->tm_mon]); break; 684 case 'c': 685 // TODO: locale-specific datetime format 686 recurse("%Y-%m-%d %H:%M:%S"); break; 687 case 'C': 688 append("%02d", (1900 + tm->tm_year) / 100); break; 689 case 'd': 690 append("%02d", tm->tm_mday); break; 691 case 'D': 692 recurse("%m/%d/%y"); break; 693 case 'e': 694 append("%2d", tm->tm_mday); break; 695 case 'F': 696 recurse("%+4Y-%m-%d"); break; 697 case 'g': 698 append("%02d", _wbyear(tm) % 100); break; 699 case 'G': 700 append("%d", _wbyear(tm)); break; 701 case 'h': 702 recurse("%b"); break; 703 case 'H': 704 append("%02d", tm->tm_hour); break; 705 case 'I': 706 append("%02d", TO_12H(tm->tm_hour)); break; 707 case 'j': 708 append("%03d", tm->tm_yday); break; 709 case 'k': 710 append("%2d", tm->tm_hour); break; 711 case 'l': 712 append("%2d", TO_12H(tm->tm_hour)); break; 713 case 'm': 714 append("%02d", tm->tm_mon); break; 715 case 'M': 716 append("%02d", tm->tm_min); break; 717 case 'n': 718 append("\n"); break; 719 case 'p': 720 append("%s", tm->tm_hour < 12 ? "AM" : "PM"); break; 721 case 'P': 722 append("%s", tm->tm_hour < 12 ? "am" : "PM"); break; 723 case 'r': 724 recurse("%I:%M:%S %p"); break; 725 case 'R': 726 recurse("%H:%M"); break; 727 case 's': 728 append("%ld", _secs_since_epoch(tm)); break; 729 case 'S': 730 append("%02d", tm->tm_sec); break; 731 case 't': 732 append("\t"); break; 733 case 'T': 734 recurse("%H:%M:%S"); break; 735 case 'u': 736 append("%d", (tm->tm_wday == 0) ? 7 : tm->tm_wday); break; 737 case 'U': 738 append("%02d", _sun_week_number(tm)); break; 739 case 'V': 740 append("%02d", _iso_week_number(tm)); break; 741 case 'w': 742 append("%d", tm->tm_wday); break; 743 case 'W': 744 append("%02d", _mon_week_number(tm)); break; 745 case 'x': 746 // TODO: locale-specific date format 747 recurse("%Y-%m-%d"); break; 748 case 'X': 749 // TODO: locale-specific time format 750 recurse("%H:%M:%S"); break; 751 case 'y': 752 append("%02d", tm->tm_year % 100); break; 753 case 'Y': 754 append("%d", 1900 + tm->tm_year); break; 755 case 'z': 756 // TODO: timezone 757 break; 758 case 'Z': 759 // TODO: timezone 760 break; 761 case '%': 762 append("%%"); 763 break; 764 default: 765 /* Invalid specifier, print verbatim. */ 766 while (*format != '%') { 767 format--; 768 } 769 append("%%"); 770 break; 771 } 772 format++; 773 } 774 775 #undef append 776 #undef recurse 777 778 return maxsize - remaining; 404 779 } 405 780 … … 518 893 stats_task_t *task_stats = stats_get_task(task_get_id()); 519 894 if (task_stats) { 520 total_cycles = (posix_clock_t) (task_stats->kcycles + 521 task_stats->ucycles); 895 total_cycles = (posix_clock_t) (task_stats->kcycles + task_stats->ucycles); 522 896 free(task_stats); 523 897 task_stats = 0; -
uspace/lib/posix/time.h
reb083ad r3e67ab1 63 63 #endif 64 64 65 #undef ASCTIME_BUF_LEN 66 #define ASCTIME_BUF_LEN 26 67 65 68 #undef CLOCK_REALTIME 66 69 #define CLOCK_REALTIME ((posix_clockid_t) 0) 70 71 struct posix_tm { 72 int tm_sec; /* Seconds [0,60]. */ 73 int tm_min; /* Minutes [0,59]. */ 74 int tm_hour; /* Hour [0,23]. */ 75 int tm_mday; /* Day of month [1,31]. */ 76 int tm_mon; /* Month of year [0,11]. */ 77 int tm_year; /* Years since 1900. */ 78 int tm_wday; /* Day of week [0,6] (Sunday = 0). */ 79 int tm_yday; /* Day of year [0,365]. */ 80 int tm_isdst; /* Daylight Savings flag. */ 81 }; 67 82 68 83 struct posix_timespec { … … 84 99 extern void posix_tzset(void); 85 100 101 /* Elapsed Time */ 102 extern double posix_difftime(time_t time1, time_t time0); 103 86 104 /* Broken-down Time */ 87 extern struct tm *posix_gmtime_r(const time_t *restrict timer, 88 struct tm *restrict result); 89 extern struct tm *posix_localtime_r(const time_t *restrict timer, 90 struct tm *restrict result); 105 extern time_t posix_mktime(struct posix_tm *tm); 106 extern struct posix_tm *posix_gmtime(const time_t *timer); 107 extern struct posix_tm *posix_gmtime_r(const time_t *restrict timer, 108 struct posix_tm *restrict result); 109 extern struct posix_tm *posix_localtime(const time_t *timer); 110 extern struct posix_tm *posix_localtime_r(const time_t *restrict timer, 111 struct posix_tm *restrict result); 91 112 92 113 /* Formatting Calendar Time */ 93 extern char *posix_asctime_r(const struct tm *restrict timeptr, 114 extern char *posix_asctime(const struct posix_tm *timeptr); 115 extern char *posix_asctime_r(const struct posix_tm *restrict timeptr, 94 116 char *restrict buf); 117 extern char *posix_ctime(const time_t *timer); 95 118 extern char *posix_ctime_r(const time_t *timer, char *buf); 119 extern size_t posix_strftime(char *restrict s, size_t maxsize, 120 const char *restrict format, const struct posix_tm *restrict tm); 96 121 97 122 /* Clocks */ … … 109 134 110 135 #ifndef LIBPOSIX_INTERNAL 136 #define tm posix_tm 111 137 #define timespec posix_timespec 112 138 #define itimerspec posix_itimerspec … … 118 144 #define tzset posix_tzset 119 145 146 #define difftime posix_difftime 147 148 #define mktime posix_mktime 149 #define gmtime posix_gmtime 120 150 #define gmtime_r posix_gmtime_r 151 #define localtime posix_localtime 121 152 #define localtime_r posix_localtime_r 122 153 154 #define asctime posix_asctime 123 155 #define asctime_r posix_asctime_r 156 #define ctime posix_ctime 124 157 #define ctime_r posix_ctime_r 158 #define strftime posix_strftime 125 159 126 160 #define clock_getres posix_clock_getres -
uspace/srv/locsrv/locsrv.c
reb083ad r3e67ab1 1308 1308 categ_dir_add_cat(&cdir, cat); 1309 1309 1310 cat = category_new("clock");1311 categ_dir_add_cat(&cdir, cat);1312 1313 1310 cat = category_new("test3"); 1314 1311 categ_dir_add_cat(&cdir, cat);
Note:
See TracChangeset
for help on using the changeset viewer.