Calendar - for "REAL" programmers: Difference between revisions

Added a C versoin
(Added a C versoin)
Line 651:
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
31 30</pre>
 
=={{header|C}}==
Upper-case C version of the C Calendar task. Relies on the ability of most C compilers to specify #defines on the command line and declares the putchar function to avoid needing any #includes. E.g. for tcc:
<pre>
tcc -DSTRUCT=struct -DCONST=const -DINT=int -DCHAR=char -DVOID=void -DMAIN=main -DIF=if -DELSE=else -DWHILE=while -DFOR=for -DDO=do -DBREAK=break -DRETURN=return -DPUTCHAR=putchar UCCALENDAR.c
</pre>
<lang c>/* UPPER CASE ONLY VERSION OF THE ORIGINAL CALENDAR.C, CHANGES MOSTLY TO AVOID NEEDING #INCLUDES */
/* ERROR MESSAGES GO TO STDOUT TO SLIGHTLY SIMPLIFY THE I/O HANDLING */
/* WHEN COMPILING THIS, THE COMMAND LINE SHOULD SPECIFY -D OPTIONS FOR THE FOLLOWING WORDS: */
/* STRUCT, VOID, INT, CHAR, CONST, MAIN, IF, ELSE, WHILE, FOR, DO, BREAK, RETURN, PUTCHAR */
/* THE VALUE OF EACH MACRO SHOULD BE THE WORD IN LOWER-CASE */
 
INT PUTCHAR(INT);
 
INT WIDTH = 80, YEAR = 1969;
INT COLS, LEAD, GAP;
CONST CHAR *WDAYS[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
STRUCT MONTHS {
CONST CHAR *NAME;
INT DAYS, START_WDAY, AT;
} MONTHS[12] = {
{ "JANUARY", 31, 0, 0 },
{ "FEBRUARY", 28, 0, 0 },
{ "MARCH", 31, 0, 0 },
{ "APRIL", 30, 0, 0 },
{ "MAY", 31, 0, 0 },
{ "JUNE", 30, 0, 0 },
{ "JULY", 31, 0, 0 },
{ "AUGUST", 31, 0, 0 },
{ "SEPTEMBER", 30, 0, 0 },
{ "OCTOBER", 31, 0, 0 },
{ "NOVEMBER", 30, 0, 0 },
{ "DECEMBER", 31, 0, 0 }
};
VOID SPACE(INT N) { WHILE (N-- > 0) PUTCHAR(' '); }
VOID PRINT(CONST CHAR * S){ WHILE (*S != '\0') { PUTCHAR(*S++); } }
INT STRLEN(CONST CHAR * S)
{
INT L = 0;
WHILE (*S++ != '\0') { L ++; };
RETURN L;
}
INT ATOI(CONST CHAR * S)
{
INT I = 0;
INT SIGN = 1;
CHAR C;
WHILE ((C = *S++) != '\0') {
IF (C == '-')
SIGN *= -1;
ELSE {
I *= 10;
I += (C - '0');
}
}
RETURN I * SIGN;
}
 
VOID INIT_MONTHS(VOID)
{
INT I;
IF ((!(YEAR % 4) && (YEAR % 100)) || !(YEAR % 400))
MONTHS[1].DAYS = 29;
YEAR--;
MONTHS[0].START_WDAY
= (YEAR * 365 + YEAR/4 - YEAR/100 + YEAR/400 + 1) % 7;
FOR (I = 1; I < 12; I++)
MONTHS[I].START_WDAY =
(MONTHS[I-1].START_WDAY + MONTHS[I-1].DAYS) % 7;
COLS = (WIDTH + 2) / 22;
WHILE (12 % COLS) COLS--;
GAP = COLS - 1 ? (WIDTH - 20 * COLS) / (COLS - 1) : 0;
IF (GAP > 4) GAP = 4;
LEAD = (WIDTH - (20 + GAP) * COLS + GAP + 1) / 2;
YEAR++;
}
VOID PRINT_ROW(INT ROW)
{
INT C, I, FROM = ROW * COLS, TO = FROM + COLS;
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
I = STRLEN(MONTHS[C].NAME);
SPACE((20 - I)/2);
PRINT(MONTHS[C].NAME);
SPACE(20 - I - (20 - I)/2 + ((C == TO - 1) ? 0 : GAP));
}
PUTCHAR('\012');
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
FOR (I = 0; I < 7; I++) {
PRINT(WDAYS[I]);
PRINT(I == 6 ? "" : " ");
}
IF (C < TO - 1) SPACE(GAP);
ELSE PUTCHAR('\012');
}
WHILE (1) {
FOR (C = FROM; C < TO; C++)
IF (MONTHS[C].AT < MONTHS[C].DAYS) BREAK;
IF (C == TO) BREAK;
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
FOR (I = 0; I < MONTHS[C].START_WDAY; I++) SPACE(3);
WHILE(I++ < 7 && MONTHS[C].AT < MONTHS[C].DAYS) {
INT MM = ++MONTHS[C].AT;
PUTCHAR((MM < 10) ? ' ' : '0' + (MM /10));
PUTCHAR('0' + (MM %10));
IF (I < 7 || C < TO - 1) PUTCHAR(' ');
}
WHILE (I++ <= 7 && C < TO - 1) SPACE(3);
IF (C < TO - 1) SPACE(GAP - 1);
MONTHS[C].START_WDAY = 0;
}
PUTCHAR('\012');
}
PUTCHAR('\012');
}
VOID PRINT_YEAR(VOID)
{
INT Y = YEAR;
INT ROW;
CHAR BUF[32];
CHAR * B = &(BUF[31]);
*B-- = '\0';
DO {
*B-- = '0' + (Y % 10);
Y /= 10;
} WHILE (Y > 0);
B++;
SPACE((WIDTH - STRLEN(B)) / 2);
PRINT(B);PUTCHAR('\012');PUTCHAR('\012');
FOR (ROW = 0; ROW * COLS < 12; ROW++)
PRINT_ROW(ROW);
}
INT MAIN(INT C, CHAR **V)
{
INT I, YEAR_SET = 0, RESULT = 0;
FOR (I = 1; I < C && RESULT == 0; I++) {
IF (V[I][0] == '-' && V[I][1] == 'W' && V[I][2] == '\0') {
IF (++I == C || (WIDTH = ATOI(V[I])) < 20)
RESULT = 1;
} ELSE IF (!YEAR_SET) {
YEAR = ATOI(V[I]);
IF (YEAR <= 0)
YEAR = 1969;
YEAR_SET = 1;
} ELSE
RESULT = 1;
}
IF (RESULT == 0) {
INIT_MONTHS();
PRINT_YEAR();
} ELSE {
PRINT("BAD ARGS\012USAGE: ");
PRINT(V[0]);
PRINT(" YEAR [-W WIDTH (>= 20)]\012");
}
RETURN RESULT;
}</lang>
 
=={{header|COBOL}}==
3,028

edits