#include <stdio.h>
#include <ctype.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>


int strcoll_compare(unsigned char * a, unsigned char * b)
{
    char buf1[2], buf2[2];
    buf1[0] = *a; buf2[0] = *b; buf1[1] = buf2[1] = 0;
    return strcoll(buf1, buf2);
}

int strxfrm_compare(unsigned char * a, unsigned char * b)
{
    char s1[2], s2[2];
    char d1[16], d2[16];
    int i1, i2;
    s1[0] = *a; s2[0] = *b; s1[1] = s2[1] = 0;
    i1 = strxfrm(d1, s1, 16); i2 = strxfrm(d2, s2, 16);
    if (i1 > 16 || i2 > 16)
	printf ("i1=%d i2=%d\n", i1, i2);
    return strcmp(d1, d2);
}

int main (int argc, char * argv[])
{
    int i, n;
    char buf[1024];
    char format[1024];
    struct tm *tm1, tm2;
    int len = 1023, err = 0;
    time_t now;


    setlocale(LC_ALL, argc < 2 ? "" : argv[1]);
    
    printf("\nisprint:");
    for (n=i=0; i < 256; ++i)
	if (isprint(i)) {
	    if (n % 64 == 0) printf("\n\t");
	    putchar(i);
	    ++n;
	}
    printf("\nisascii && isprint:");
    for (n=i=0; i < 256; ++i)
	if (isascii(i) && isprint(i)) {
	    if (n % 64 == 0) printf("\n\t");
	    putchar(i);
	    ++n;
	}
    printf("\nisalpha:");
    for (n=i=0; i < 256; ++i)
	if (isalpha(i)) {
	    if (n % 64 == 0) printf("\n\t");
	    putchar(i);
	    ++n;
	}
    printf("\nislower:");
    for (n=i=0; i < 256; ++i)
	if (islower(i)) {
	    if (n % 64 == 0) printf("\n\t");
	    putchar(i);
	    ++n;
	}
    printf("\nisupper:");
    for (n=i=0; i < 256; ++i)
	if (isupper(i)) {
	    if (n % 64 == 0) printf("\n\t");
	    putchar(i);
	    ++n;
	}
    printf("\ntolower:");
    for (n=i=0; i < 256; ++i)
	if (isupper(i)) {
	    if (n % 64 == 0) printf("\n\t");
	    putchar(tolower(i));
	    ++n;
	}
    printf("\ntoupper:");
    for (n=i=0; i < 256; ++i)
	if (islower(i)) {
	    if (n % 64 == 0) printf("\n\t");
	    putchar(toupper(i));
	    ++n;
	}
    printf("\nstrcoll:");
    for (i=0; i < 256; ++i) buf[i] = i+1;
    qsort(buf, 255, 1, strcoll_compare);
    for (n=i=0; i < 256; ++i)
    if (isprint(buf[i])) {
	if (n % 64 == 0) printf("\n\t");
	putchar(buf[i]);
	++n;
    }
    printf("\nstrxfrm:");
    for (i=0; i < 256; ++i) buf[i] = i+1;
    qsort(buf, 255, 1, strxfrm_compare);
    for (n=i=0; i < 256; ++i)
    if (isprint(buf[i])) {
	if (n % 64 == 0) printf("\n\t");
	putchar(buf[i]);
	++n;
    }    
    putchar('\n');
    
    strcpy (format, "%H:%M:%S %p %m/%d/%y %a %b %y %j");
    time (&now);
    tm1 = localtime (&now);
    strftime (buf, len, format, tm1);
    printf ("strftime:\n\t %s\n", buf);
    bzero (&tm2, sizeof (struct tm));
    strptime (buf, format, &tm2);
    if (tm1->tm_sec != tm2.tm_sec)
	err++, printf ("\ttm_sec is different (%d - %d)\n", tm1->tm_sec, tm2.tm_sec);
    if (tm1->tm_min != tm2.tm_min)
	err++, printf ("\ttm_min is different (%d - %d)\n", tm1->tm_min, tm2.tm_min);
    if (tm1->tm_hour != tm2.tm_hour)
	err++, printf ("\ttm_hour is different (%d - %d)\n", tm1->tm_hour, tm2.tm_hour);
    if (tm1->tm_mday != tm2.tm_mday)
	err++, printf ("\ttm_mday is different (%d - %d)\n", tm1->tm_mday, tm2.tm_mday);
    if (tm1->tm_mon != tm2.tm_mon)
	err++, printf ("\ttm_mon is different (%d - %d)\n", tm1->tm_mon, tm2.tm_mon);
    if (tm1->tm_year != tm2.tm_year)
	err++, printf ("\ttm_year is different (%d - %d)\n", tm1->tm_year, tm2.tm_year);
    if (tm1->tm_wday != tm2.tm_wday)
	err++, printf ("\ttm_wday is different (%d - %d)\n", tm1->tm_wday, tm2.tm_wday);
    if (tm1->tm_yday != tm2.tm_yday)
	err++, printf ("\ttm_yday is different (%d - %d)\n", tm1->tm_yday, tm2.tm_yday);
    if (!err)
	printf ("strptime:\n\tOK: tm struct has been filled correctly\n");
    else
	printf ("strptime:\n\rERROR: %d out of %d fields filled incorrectly\n", 7 - err, 7);
}
