lemon-project-template-glpk

annotate deps/glpk/src/glpmpl05.c @ 11:4fc6ad2fb8a6

Test GLPK in src/main.cc
author Alpar Juttner <alpar@cs.elte.hu>
date Sun, 06 Nov 2011 21:43:29 +0100
parents
children
rev   line source
alpar@9 1 /* glpmpl05.c */
alpar@9 2
alpar@9 3 /***********************************************************************
alpar@9 4 * This code is part of GLPK (GNU Linear Programming Kit).
alpar@9 5 *
alpar@9 6 * Authors: Andrew Makhorin <mao@gnu.org>
alpar@9 7 * Heinrich Schuchardt <xypron.glpk@gmx.de>
alpar@9 8 *
alpar@9 9 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
alpar@9 10 * 2009, 2010, 2011 Andrew Makhorin, Department for Applied Informatics,
alpar@9 11 * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
alpar@9 12 * E-mail: <mao@gnu.org>.
alpar@9 13 *
alpar@9 14 * GLPK is free software: you can redistribute it and/or modify it
alpar@9 15 * under the terms of the GNU General Public License as published by
alpar@9 16 * the Free Software Foundation, either version 3 of the License, or
alpar@9 17 * (at your option) any later version.
alpar@9 18 *
alpar@9 19 * GLPK is distributed in the hope that it will be useful, but WITHOUT
alpar@9 20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
alpar@9 21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
alpar@9 22 * License for more details.
alpar@9 23 *
alpar@9 24 * You should have received a copy of the GNU General Public License
alpar@9 25 * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
alpar@9 26 ***********************************************************************/
alpar@9 27
alpar@9 28 #define _GLPSTD_STDIO
alpar@9 29 #define _GLPSTD_TIME
alpar@9 30 #include "glpmpl.h"
alpar@9 31
alpar@9 32 double fn_gmtime(MPL *mpl)
alpar@9 33 { /* obtain the current calendar time (UTC) */
alpar@9 34 time_t timer;
alpar@9 35 struct tm *tm;
alpar@9 36 int j;
alpar@9 37 time(&timer);
alpar@9 38 if (timer == (time_t)(-1))
alpar@9 39 err: error(mpl, "gmtime(); unable to obtain current calendar time");
alpar@9 40 tm = gmtime(&timer);
alpar@9 41 if (tm == NULL) goto err;
alpar@9 42 j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year);
alpar@9 43 if (j < 0) goto err;
alpar@9 44 return (((double)(j - jday(1, 1, 1970)) * 24.0 +
alpar@9 45 (double)tm->tm_hour) * 60.0 + (double)tm->tm_min) * 60.0 +
alpar@9 46 (double)tm->tm_sec;
alpar@9 47 }
alpar@9 48
alpar@9 49 static char *week[] = { "Monday", "Tuesday", "Wednesday", "Thursday",
alpar@9 50 "Friday", "Saturday", "Sunday" };
alpar@9 51
alpar@9 52 static char *moon[] = { "January", "February", "March", "April", "May",
alpar@9 53 "June", "July", "August", "September", "October", "November",
alpar@9 54 "December" };
alpar@9 55
alpar@9 56 static void error1(MPL *mpl, const char *str, const char *s,
alpar@9 57 const char *fmt, const char *f, const char *msg)
alpar@9 58 { xprintf("Input string passed to str2time:\n");
alpar@9 59 xprintf("%s\n", str);
alpar@9 60 xprintf("%*s\n", (s - str) + 1, "^");
alpar@9 61 xprintf("Format string passed to str2time:\n");
alpar@9 62 xprintf("%s\n", fmt);
alpar@9 63 xprintf("%*s\n", (f - fmt) + 1, "^");
alpar@9 64 error(mpl, "%s", msg);
alpar@9 65 /* no return */
alpar@9 66 }
alpar@9 67
alpar@9 68 double fn_str2time(MPL *mpl, const char *str, const char *fmt)
alpar@9 69 { /* convert character string to the calendar time */
alpar@9 70 int j, year, month, day, hh, mm, ss, zone;
alpar@9 71 const char *s, *f;
alpar@9 72 year = month = day = hh = mm = ss = -1, zone = INT_MAX;
alpar@9 73 s = str;
alpar@9 74 for (f = fmt; *f != '\0'; f++)
alpar@9 75 { if (*f == '%')
alpar@9 76 { f++;
alpar@9 77 if (*f == 'b' || *f == 'h')
alpar@9 78 { /* the abbreviated month name */
alpar@9 79 int k;
alpar@9 80 char *name;
alpar@9 81 if (month >= 0)
alpar@9 82 error1(mpl, str, s, fmt, f, "month multiply specified"
alpar@9 83 );
alpar@9 84 while (*s == ' ') s++;
alpar@9 85 for (month = 1; month <= 12; month++)
alpar@9 86 { name = moon[month-1];
alpar@9 87 for (k = 0; k <= 2; k++)
alpar@9 88 { if (toupper((unsigned char)s[k]) !=
alpar@9 89 toupper((unsigned char)name[k])) goto next;
alpar@9 90 }
alpar@9 91 s += 3;
alpar@9 92 for (k = 3; name[k] != '\0'; k++)
alpar@9 93 { if (toupper((unsigned char)*s) !=
alpar@9 94 toupper((unsigned char)name[k])) break;
alpar@9 95 s++;
alpar@9 96 }
alpar@9 97 break;
alpar@9 98 next: ;
alpar@9 99 }
alpar@9 100 if (month > 12)
alpar@9 101 error1(mpl, str, s, fmt, f, "abbreviated month name m"
alpar@9 102 "issing or invalid");
alpar@9 103 }
alpar@9 104 else if (*f == 'd')
alpar@9 105 { /* the day of the month as a decimal number (01..31) */
alpar@9 106 if (day >= 0)
alpar@9 107 error1(mpl, str, s, fmt, f, "day multiply specified");
alpar@9 108 while (*s == ' ') s++;
alpar@9 109 if (!('0' <= *s && *s <= '9'))
alpar@9 110 error1(mpl, str, s, fmt, f, "day missing or invalid");
alpar@9 111 day = (*s++) - '0';
alpar@9 112 if ('0' <= *s && *s <= '9')
alpar@9 113 day = 10 * day + ((*s++) - '0');
alpar@9 114 if (!(1 <= day && day <= 31))
alpar@9 115 error1(mpl, str, s, fmt, f, "day out of range");
alpar@9 116 }
alpar@9 117 else if (*f == 'H')
alpar@9 118 { /* the hour as a decimal number, using a 24-hour clock
alpar@9 119 (00..23) */
alpar@9 120 if (hh >= 0)
alpar@9 121 error1(mpl, str, s, fmt, f, "hour multiply specified")
alpar@9 122 ;
alpar@9 123 while (*s == ' ') s++;
alpar@9 124 if (!('0' <= *s && *s <= '9'))
alpar@9 125 error1(mpl, str, s, fmt, f, "hour missing or invalid")
alpar@9 126 ;
alpar@9 127 hh = (*s++) - '0';
alpar@9 128 if ('0' <= *s && *s <= '9')
alpar@9 129 hh = 10 * hh + ((*s++) - '0');
alpar@9 130 if (!(0 <= hh && hh <= 23))
alpar@9 131 error1(mpl, str, s, fmt, f, "hour out of range");
alpar@9 132 }
alpar@9 133 else if (*f == 'm')
alpar@9 134 { /* the month as a decimal number (01..12) */
alpar@9 135 if (month >= 0)
alpar@9 136 error1(mpl, str, s, fmt, f, "month multiply specified"
alpar@9 137 );
alpar@9 138 while (*s == ' ') s++;
alpar@9 139 if (!('0' <= *s && *s <= '9'))
alpar@9 140 error1(mpl, str, s, fmt, f, "month missing or invalid"
alpar@9 141 );
alpar@9 142 month = (*s++) - '0';
alpar@9 143 if ('0' <= *s && *s <= '9')
alpar@9 144 month = 10 * month + ((*s++) - '0');
alpar@9 145 if (!(1 <= month && month <= 12))
alpar@9 146 error1(mpl, str, s, fmt, f, "month out of range");
alpar@9 147 }
alpar@9 148 else if (*f == 'M')
alpar@9 149 { /* the minute as a decimal number (00..59) */
alpar@9 150 if (mm >= 0)
alpar@9 151 error1(mpl, str, s, fmt, f, "minute multiply specifie"
alpar@9 152 "d");
alpar@9 153 while (*s == ' ') s++;
alpar@9 154 if (!('0' <= *s && *s <= '9'))
alpar@9 155 error1(mpl, str, s, fmt, f, "minute missing or invali"
alpar@9 156 "d");
alpar@9 157 mm = (*s++) - '0';
alpar@9 158 if ('0' <= *s && *s <= '9')
alpar@9 159 mm = 10 * mm + ((*s++) - '0');
alpar@9 160 if (!(0 <= mm && mm <= 59))
alpar@9 161 error1(mpl, str, s, fmt, f, "minute out of range");
alpar@9 162 }
alpar@9 163 else if (*f == 'S')
alpar@9 164 { /* the second as a decimal number (00..60) */
alpar@9 165 if (ss >= 0)
alpar@9 166 error1(mpl, str, s, fmt, f, "second multiply specifie"
alpar@9 167 "d");
alpar@9 168 while (*s == ' ') s++;
alpar@9 169 if (!('0' <= *s && *s <= '9'))
alpar@9 170 error1(mpl, str, s, fmt, f, "second missing or invali"
alpar@9 171 "d");
alpar@9 172 ss = (*s++) - '0';
alpar@9 173 if ('0' <= *s && *s <= '9')
alpar@9 174 ss = 10 * ss + ((*s++) - '0');
alpar@9 175 if (!(0 <= ss && ss <= 60))
alpar@9 176 error1(mpl, str, s, fmt, f, "second out of range");
alpar@9 177 }
alpar@9 178 else if (*f == 'y')
alpar@9 179 { /* the year without a century as a decimal number
alpar@9 180 (00..99); the values 00 to 68 mean the years 2000 to
alpar@9 181 2068 while the values 69 to 99 mean the years 1969 to
alpar@9 182 1999 */
alpar@9 183 if (year >= 0)
alpar@9 184 error1(mpl, str, s, fmt, f, "year multiply specified")
alpar@9 185 ;
alpar@9 186 while (*s == ' ') s++;
alpar@9 187 if (!('0' <= *s && *s <= '9'))
alpar@9 188 error1(mpl, str, s, fmt, f, "year missing or invalid")
alpar@9 189 ;
alpar@9 190 year = (*s++) - '0';
alpar@9 191 if ('0' <= *s && *s <= '9')
alpar@9 192 year = 10 * year + ((*s++) - '0');
alpar@9 193 year += (year >= 69 ? 1900 : 2000);
alpar@9 194 }
alpar@9 195 else if (*f == 'Y')
alpar@9 196 { /* the year as a decimal number, using the Gregorian
alpar@9 197 calendar */
alpar@9 198 if (year >= 0)
alpar@9 199 error1(mpl, str, s, fmt, f, "year multiply specified")
alpar@9 200 ;
alpar@9 201 while (*s == ' ') s++;
alpar@9 202 if (!('0' <= *s && *s <= '9'))
alpar@9 203 error1(mpl, str, s, fmt, f, "year missing or invalid")
alpar@9 204 ;
alpar@9 205 year = 0;
alpar@9 206 for (j = 1; j <= 4; j++)
alpar@9 207 { if (!('0' <= *s && *s <= '9')) break;
alpar@9 208 year = 10 * year + ((*s++) - '0');
alpar@9 209 }
alpar@9 210 if (!(1 <= year && year <= 4000))
alpar@9 211 error1(mpl, str, s, fmt, f, "year out of range");
alpar@9 212 }
alpar@9 213 else if (*f == 'z')
alpar@9 214 { /* time zone offset in the form zhhmm */
alpar@9 215 int z, hh, mm;
alpar@9 216 if (zone != INT_MAX)
alpar@9 217 error1(mpl, str, s, fmt, f, "time zone offset multipl"
alpar@9 218 "y specified");
alpar@9 219 while (*s == ' ') s++;
alpar@9 220 if (*s == 'Z')
alpar@9 221 { z = hh = mm = 0, s++;
alpar@9 222 goto skip;
alpar@9 223 }
alpar@9 224 if (*s == '+')
alpar@9 225 z = +1, s++;
alpar@9 226 else if (*s == '-')
alpar@9 227 z = -1, s++;
alpar@9 228 else
alpar@9 229 error1(mpl, str, s, fmt, f, "time zone offset sign mi"
alpar@9 230 "ssing");
alpar@9 231 hh = 0;
alpar@9 232 for (j = 1; j <= 2; j++)
alpar@9 233 { if (!('0' <= *s && *s <= '9'))
alpar@9 234 err1: error1(mpl, str, s, fmt, f, "time zone offset valu"
alpar@9 235 "e incomplete or invalid");
alpar@9 236 hh = 10 * hh + ((*s++) - '0');
alpar@9 237 }
alpar@9 238 if (hh > 23)
alpar@9 239 err2: error1(mpl, str, s, fmt, f, "time zone offset value o"
alpar@9 240 "ut of range");
alpar@9 241 if (*s == ':')
alpar@9 242 { s++;
alpar@9 243 if (!('0' <= *s && *s <= '9')) goto err1;
alpar@9 244 }
alpar@9 245 mm = 0;
alpar@9 246 if (!('0' <= *s && *s <= '9')) goto skip;
alpar@9 247 for (j = 1; j <= 2; j++)
alpar@9 248 { if (!('0' <= *s && *s <= '9')) goto err1;
alpar@9 249 mm = 10 * mm + ((*s++) - '0');
alpar@9 250 }
alpar@9 251 if (mm > 59) goto err2;
alpar@9 252 skip: zone = z * (60 * hh + mm);
alpar@9 253 }
alpar@9 254 else if (*f == '%')
alpar@9 255 { /* literal % character */
alpar@9 256 goto test;
alpar@9 257 }
alpar@9 258 else
alpar@9 259 error1(mpl, str, s, fmt, f, "invalid conversion specifie"
alpar@9 260 "r");
alpar@9 261 }
alpar@9 262 else if (*f == ' ')
alpar@9 263 ;
alpar@9 264 else
alpar@9 265 test: { /* check a matching character in the input string */
alpar@9 266 if (*s != *f)
alpar@9 267 error1(mpl, str, s, fmt, f, "character mismatch");
alpar@9 268 s++;
alpar@9 269 }
alpar@9 270 }
alpar@9 271 if (year < 0) year = 1970;
alpar@9 272 if (month < 0) month = 1;
alpar@9 273 if (day < 0) day = 1;
alpar@9 274 if (hh < 0) hh = 0;
alpar@9 275 if (mm < 0) mm = 0;
alpar@9 276 if (ss < 0) ss = 0;
alpar@9 277 if (zone == INT_MAX) zone = 0;
alpar@9 278 j = jday(day, month, year);
alpar@9 279 xassert(j >= 0);
alpar@9 280 return (((double)(j - jday(1, 1, 1970)) * 24.0 + (double)hh) *
alpar@9 281 60.0 + (double)mm) * 60.0 + (double)ss - 60.0 * (double)zone;
alpar@9 282 }
alpar@9 283
alpar@9 284 static void error2(MPL *mpl, const char *fmt, const char *f,
alpar@9 285 const char *msg)
alpar@9 286 { xprintf("Format string passed to time2str:\n");
alpar@9 287 xprintf("%s\n", fmt);
alpar@9 288 xprintf("%*s\n", (f - fmt) + 1, "^");
alpar@9 289 error(mpl, "%s", msg);
alpar@9 290 /* no return */
alpar@9 291 }
alpar@9 292
alpar@9 293 static int weekday(int j)
alpar@9 294 { /* determine weekday number (1 = Mon, ..., 7 = Sun) */
alpar@9 295 return (j + jday(1, 1, 1970)) % 7 + 1;
alpar@9 296 }
alpar@9 297
alpar@9 298 static int firstday(int year)
alpar@9 299 { /* determine the first day of the first week for a specified year
alpar@9 300 according to ISO 8601 */
alpar@9 301 int j;
alpar@9 302 /* if 1 January is Monday, Tuesday, Wednesday or Thursday, it is
alpar@9 303 in week 01; if 1 January is Friday, Saturday or Sunday, it is
alpar@9 304 in week 52 or 53 of the previous year */
alpar@9 305 j = jday(1, 1, year) - jday(1, 1, 1970);
alpar@9 306 switch (weekday(j))
alpar@9 307 { case 1: /* 1 Jan is Mon */ j += 0; break;
alpar@9 308 case 2: /* 1 Jan is Tue */ j -= 1; break;
alpar@9 309 case 3: /* 1 Jan is Wed */ j -= 2; break;
alpar@9 310 case 4: /* 1 Jan is Thu */ j -= 3; break;
alpar@9 311 case 5: /* 1 Jan is Fri */ j += 3; break;
alpar@9 312 case 6: /* 1 Jan is Sat */ j += 2; break;
alpar@9 313 case 7: /* 1 Jan is Sun */ j += 1; break;
alpar@9 314 default: xassert(j != j);
alpar@9 315 }
alpar@9 316 /* the first day of the week must be Monday */
alpar@9 317 xassert(weekday(j) == 1);
alpar@9 318 return j;
alpar@9 319 }
alpar@9 320
alpar@9 321 void fn_time2str(MPL *mpl, char *str, double t, const char *fmt)
alpar@9 322 { /* convert the calendar time to character string */
alpar@9 323 int j, year, month, day, hh, mm, ss, len;
alpar@9 324 double temp;
alpar@9 325 const char *f;
alpar@9 326 char buf[MAX_LENGTH+1];
alpar@9 327 if (!(-62135596800.0 <= t && t <= 64092211199.0))
alpar@9 328 error(mpl, "time2str(%.*g,...); argument out of range",
alpar@9 329 DBL_DIG, t);
alpar@9 330 t = floor(t + 0.5);
alpar@9 331 temp = fabs(t) / 86400.0;
alpar@9 332 j = (int)floor(temp);
alpar@9 333 if (t < 0.0)
alpar@9 334 { if (temp == floor(temp))
alpar@9 335 j = - j;
alpar@9 336 else
alpar@9 337 j = - (j + 1);
alpar@9 338 }
alpar@9 339 xassert(jdate(j + jday(1, 1, 1970), &day, &month, &year) == 0);
alpar@9 340 ss = (int)(t - 86400.0 * (double)j);
alpar@9 341 xassert(0 <= ss && ss < 86400);
alpar@9 342 mm = ss / 60, ss %= 60;
alpar@9 343 hh = mm / 60, mm %= 60;
alpar@9 344 len = 0;
alpar@9 345 for (f = fmt; *f != '\0'; f++)
alpar@9 346 { if (*f == '%')
alpar@9 347 { f++;
alpar@9 348 if (*f == 'a')
alpar@9 349 { /* the abbreviated weekday name */
alpar@9 350 memcpy(buf, week[weekday(j)-1], 3), buf[3] = '\0';
alpar@9 351 }
alpar@9 352 else if (*f == 'A')
alpar@9 353 { /* the full weekday name */
alpar@9 354 strcpy(buf, week[weekday(j)-1]);
alpar@9 355 }
alpar@9 356 else if (*f == 'b' || *f == 'h')
alpar@9 357 { /* the abbreviated month name */
alpar@9 358 memcpy(buf, moon[month-1], 3), buf[3] = '\0';
alpar@9 359 }
alpar@9 360 else if (*f == 'B')
alpar@9 361 { /* the full month name */
alpar@9 362 strcpy(buf, moon[month-1]);
alpar@9 363 }
alpar@9 364 else if (*f == 'C')
alpar@9 365 { /* the century of the year */
alpar@9 366 sprintf(buf, "%02d", year / 100);
alpar@9 367 }
alpar@9 368 else if (*f == 'd')
alpar@9 369 { /* the day of the month as a decimal number (01..31) */
alpar@9 370 sprintf(buf, "%02d", day);
alpar@9 371 }
alpar@9 372 else if (*f == 'D')
alpar@9 373 { /* the date using the format %m/%d/%y */
alpar@9 374 sprintf(buf, "%02d/%02d/%02d", month, day, year % 100);
alpar@9 375 }
alpar@9 376 else if (*f == 'e')
alpar@9 377 { /* the day of the month like with %d, but padded with
alpar@9 378 blank (1..31) */
alpar@9 379 sprintf(buf, "%2d", day);
alpar@9 380 }
alpar@9 381 else if (*f == 'F')
alpar@9 382 { /* the date using the format %Y-%m-%d */
alpar@9 383 sprintf(buf, "%04d-%02d-%02d", year, month, day);
alpar@9 384 }
alpar@9 385 else if (*f == 'g')
alpar@9 386 { /* the year corresponding to the ISO week number, but
alpar@9 387 without the century (range 00 through 99); this has
alpar@9 388 the same format and value as %y, except that if the
alpar@9 389 ISO week number (see %V) belongs to the previous or
alpar@9 390 next year, that year is used instead */
alpar@9 391 int iso;
alpar@9 392 if (j < firstday(year))
alpar@9 393 iso = year - 1;
alpar@9 394 else if (j < firstday(year + 1))
alpar@9 395 iso = year;
alpar@9 396 else
alpar@9 397 iso = year + 1;
alpar@9 398 sprintf(buf, "%02d", iso % 100);
alpar@9 399 }
alpar@9 400 else if (*f == 'G')
alpar@9 401 { /* the year corresponding to the ISO week number; this
alpar@9 402 has the same format and value as %Y, excepth that if
alpar@9 403 the ISO week number (see %V) belongs to the previous
alpar@9 404 or next year, that year is used instead */
alpar@9 405 int iso;
alpar@9 406 if (j < firstday(year))
alpar@9 407 iso = year - 1;
alpar@9 408 else if (j < firstday(year + 1))
alpar@9 409 iso = year;
alpar@9 410 else
alpar@9 411 iso = year + 1;
alpar@9 412 sprintf(buf, "%04d", iso);
alpar@9 413 }
alpar@9 414 else if (*f == 'H')
alpar@9 415 { /* the hour as a decimal number, using a 24-hour clock
alpar@9 416 (00..23) */
alpar@9 417 sprintf(buf, "%02d", hh);
alpar@9 418 }
alpar@9 419 else if (*f == 'I')
alpar@9 420 { /* the hour as a decimal number, using a 12-hour clock
alpar@9 421 (01..12) */
alpar@9 422 sprintf(buf, "%02d",
alpar@9 423 hh == 0 ? 12 : hh <= 12 ? hh : hh - 12);
alpar@9 424 }
alpar@9 425 else if (*f == 'j')
alpar@9 426 { /* the day of the year as a decimal number (001..366) */
alpar@9 427 sprintf(buf, "%03d",
alpar@9 428 jday(day, month, year) - jday(1, 1, year) + 1);
alpar@9 429 }
alpar@9 430 else if (*f == 'k')
alpar@9 431 { /* the hour as a decimal number, using a 24-hour clock
alpar@9 432 like %H, but padded with blank (0..23) */
alpar@9 433 sprintf(buf, "%2d", hh);
alpar@9 434 }
alpar@9 435 else if (*f == 'l')
alpar@9 436 { /* the hour as a decimal number, using a 12-hour clock
alpar@9 437 like %I, but padded with blank (1..12) */
alpar@9 438 sprintf(buf, "%2d",
alpar@9 439 hh == 0 ? 12 : hh <= 12 ? hh : hh - 12);
alpar@9 440 }
alpar@9 441 else if (*f == 'm')
alpar@9 442 { /* the month as a decimal number (01..12) */
alpar@9 443 sprintf(buf, "%02d", month);
alpar@9 444 }
alpar@9 445 else if (*f == 'M')
alpar@9 446 { /* the minute as a decimal number (00..59) */
alpar@9 447 sprintf(buf, "%02d", mm);
alpar@9 448 }
alpar@9 449 else if (*f == 'p')
alpar@9 450 { /* either AM or PM, according to the given time value;
alpar@9 451 noon is treated as PM and midnight as AM */
alpar@9 452 strcpy(buf, hh <= 11 ? "AM" : "PM");
alpar@9 453 }
alpar@9 454 else if (*f == 'P')
alpar@9 455 { /* either am or pm, according to the given time value;
alpar@9 456 noon is treated as pm and midnight as am */
alpar@9 457 strcpy(buf, hh <= 11 ? "am" : "pm");
alpar@9 458 }
alpar@9 459 else if (*f == 'r')
alpar@9 460 { /* the calendar time using the format %I:%M:%S %p */
alpar@9 461 sprintf(buf, "%02d:%02d:%02d %s",
alpar@9 462 hh == 0 ? 12 : hh <= 12 ? hh : hh - 12,
alpar@9 463 mm, ss, hh <= 11 ? "AM" : "PM");
alpar@9 464 }
alpar@9 465 else if (*f == 'R')
alpar@9 466 { /* the hour and minute using the format %H:%M */
alpar@9 467 sprintf(buf, "%02d:%02d", hh, mm);
alpar@9 468 }
alpar@9 469 else if (*f == 'S')
alpar@9 470 { /* the second as a decimal number (00..59) */
alpar@9 471 sprintf(buf, "%02d", ss);
alpar@9 472 }
alpar@9 473 else if (*f == 'T')
alpar@9 474 { /* the time of day using the format %H:%M:%S */
alpar@9 475 sprintf(buf, "%02d:%02d:%02d", hh, mm, ss);
alpar@9 476 }
alpar@9 477 else if (*f == 'u')
alpar@9 478 { /* the day of the week as a decimal number (1..7),
alpar@9 479 Monday being 1 */
alpar@9 480 sprintf(buf, "%d", weekday(j));
alpar@9 481 }
alpar@9 482 else if (*f == 'U')
alpar@9 483 { /* the week number of the current year as a decimal
alpar@9 484 number (range 00 through 53), starting with the first
alpar@9 485 Sunday as the first day of the first week; days
alpar@9 486 preceding the first Sunday in the year are considered
alpar@9 487 to be in week 00 */
alpar@9 488 #if 1 /* 09/I-2009 */
alpar@9 489 #undef sun
alpar@9 490 /* causes compilation error in SunOS */
alpar@9 491 #endif
alpar@9 492 int sun;
alpar@9 493 /* sun = the first Sunday of the year */
alpar@9 494 sun = jday(1, 1, year) - jday(1, 1, 1970);
alpar@9 495 sun += (7 - weekday(sun));
alpar@9 496 sprintf(buf, "%02d", (j + 7 - sun) / 7);
alpar@9 497 }
alpar@9 498 else if (*f == 'V')
alpar@9 499 { /* the ISO week number as a decimal number (range 01
alpar@9 500 through 53); ISO weeks start with Monday and end with
alpar@9 501 Sunday; week 01 of a year is the first week which has
alpar@9 502 the majority of its days in that year; week 01 of
alpar@9 503 a year can contain days from the previous year; the
alpar@9 504 week before week 01 of a year is the last week (52 or
alpar@9 505 53) of the previous year even if it contains days
alpar@9 506 from the new year */
alpar@9 507 int iso;
alpar@9 508 if (j < firstday(year))
alpar@9 509 iso = j - firstday(year - 1);
alpar@9 510 else if (j < firstday(year + 1))
alpar@9 511 iso = j - firstday(year);
alpar@9 512 else
alpar@9 513 iso = j - firstday(year + 1);
alpar@9 514 sprintf(buf, "%02d", iso / 7 + 1);
alpar@9 515 }
alpar@9 516 else if (*f == 'w')
alpar@9 517 { /* the day of the week as a decimal number (0..6),
alpar@9 518 Sunday being 0 */
alpar@9 519 sprintf(buf, "%d", weekday(j) % 7);
alpar@9 520 }
alpar@9 521 else if (*f == 'W')
alpar@9 522 { /* the week number of the current year as a decimal
alpar@9 523 number (range 00 through 53), starting with the first
alpar@9 524 Monday as the first day of the first week; days
alpar@9 525 preceding the first Monday in the year are considered
alpar@9 526 to be in week 00 */
alpar@9 527 int mon;
alpar@9 528 /* mon = the first Monday of the year */
alpar@9 529 mon = jday(1, 1, year) - jday(1, 1, 1970);
alpar@9 530 mon += (8 - weekday(mon)) % 7;
alpar@9 531 sprintf(buf, "%02d", (j + 7 - mon) / 7);
alpar@9 532 }
alpar@9 533 else if (*f == 'y')
alpar@9 534 { /* the year without a century as a decimal number
alpar@9 535 (00..99) */
alpar@9 536 sprintf(buf, "%02d", year % 100);
alpar@9 537 }
alpar@9 538 else if (*f == 'Y')
alpar@9 539 { /* the year as a decimal number, using the Gregorian
alpar@9 540 calendar */
alpar@9 541 sprintf(buf, "%04d", year);
alpar@9 542 }
alpar@9 543 else if (*f == '%')
alpar@9 544 { /* a literal % character */
alpar@9 545 buf[0] = '%', buf[1] = '\0';
alpar@9 546 }
alpar@9 547 else
alpar@9 548 error2(mpl, fmt, f, "invalid conversion specifier");
alpar@9 549 }
alpar@9 550 else
alpar@9 551 buf[0] = *f, buf[1] = '\0';
alpar@9 552 if (len + strlen(buf) > MAX_LENGTH)
alpar@9 553 error(mpl, "time2str; output string length exceeds %d chara"
alpar@9 554 "cters", MAX_LENGTH);
alpar@9 555 memcpy(str+len, buf, strlen(buf));
alpar@9 556 len += strlen(buf);
alpar@9 557 }
alpar@9 558 str[len] = '\0';
alpar@9 559 return;
alpar@9 560 }
alpar@9 561
alpar@9 562 /* eof */