File: pr_date.c

package info (click to toggle)
dosemu-freedos 1%3A0.0.b9r5a%2Betch.1-0etch1
  • links: PTS
  • area: contrib
  • in suites: etch
  • size: 19,744 kB
  • ctags: 23,279
  • sloc: ansic: 143,864; asm: 20,397; makefile: 3,868; perl: 1,106; yacc: 690; sh: 553; pascal: 297; xml: 150; cpp: 67
file content (171 lines) | stat: -rw-r--r-- 4,418 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*	$id$
	$Locker:  $	$Name:  $	$State: Exp $

	Parses a date given in ASCIIZ into a dosdate_t structure.

	1 number -> day only (month & year filled with current values)
	2 numbers -> day & month (year filled with current value)
	3 numbers -> day, month,& year

	if datep == NULL, the result is not returned in *datep
		-> thus checking for valid values only

	Return:
		E_None: *datep filled
		E_Empty: empty line
		else: some error

	This file bases on DATE.C of FreeCOM v0.81 beta 1.

	$Log: pr_date.c,v $
	Revision 1.2  2001/04/29 12:56:57  skaus
	bugfix: DATE: does not accept empty line
	
	Revision 1.1  2001/04/12 00:33:53  skaus
	chg: new structure
	chg: If DEBUG enabled, no available commands are displayed on startup
	fix: PTCHSIZE also patches min extra size to force to have this amount
	   of memory available on start
	bugfix: CALL doesn't reset options
	add: PTCHSIZE to patch heap size
	add: VSPAWN, /SWAP switch, .SWP resource handling
	bugfix: COMMAND.COM A:\
	bugfix: CALL: if swapOnExec == ERROR, no change of swapOnExec allowed
	add: command MEMORY
	bugfix: runExtension(): destroys command[-2]
	add: clean.bat
	add: localized CRITER strings
	chg: use LNG files for hard-coded strings (hangForEver(), init.c)
		via STRINGS.LIB
	add: DEL.C, COPY.C, CBREAK.C: STRINGS-based prompts
	add: fixstrs.c: prompts & symbolic keys
	add: fixstrs.c: backslash escape sequences
	add: version IDs to DEFAULT.LNG and validation to FIXSTRS.C
	chg: splitted code apart into LIB\*.c and CMD\*.c
	bugfix: IF is now using error system & STRINGS to report errors
	add: CALL: /N
	
 */

#include "../config.h"

#include <assert.h>
#include <dos.h>
#include <string.h>

#include "../include/command.h"
#include "../include/misc.h"
#include "../include/nls.h"


static unsigned char months[2][13] =
{
  {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

int parsedate(const char * s, struct dosdate_t *datep)
{
  struct dosdate_t d;
  unsigned char leap;
  int nums[3],
    items;

  assert(s);

  /* Parse at maximum three numbers */
  s = parsenum(s, 3, &items, nums);

  if (!s || *s)                 /* general error or too many characters */
    return E_Empty;

  _dos_getdate(&d);             /* fetch current info */
#ifdef FEATURE_NLS
	refreshNLS();
	assert(nlsBuf);
	assert(0 <= nlsBuf->datefmt && nlsBuf->datefmt <= 2);
	assert(nlsBuf->dateSep);
	switch(nlsBuf->datefmt) {
	case 0:		/* mm/dd/yy */
#endif
		switch (items) {
		case 0:                    /* empty line --> always OK */
		  return E_Empty;

		case 1:                    /* single number --> day only */
		  d.day = nums[0];
		  break;

		case 3:                    /* three numbers --> year, month & day */
		  d.year = nums[2];
		  /* fall through */

		case 2:                    /* two numbers --> month & day */
		  d.day = nums[1], d.month = nums[0];
		  break;
		}

#ifdef FEATURE_NLS
		break;
	case 1:		/* dd/mm/yy */
		switch (items) {
		case 0:                    /* empty line --> always OK */
		  return E_Empty;

		case 3:                    /* three numbers --> year, month & day */
		  d.year = nums[2];
		  /* fall through */

		case 2:                    /* two numbers --> month & day */
		  d.month = nums[1];
		  /* fall through */

		case 1:
		  d.day = nums[0]; 
		  break;
		}
		break;

	case 2:		/* yy/mm/dd */
		switch (items) {
		case 0:                    /* empty line --> always OK */
		  return E_Empty;

		case 3:                    /* three numbers --> year, month & day */
		  d.year = nums[0];
		  d.month = nums[1];
		  d.day = nums[2]; 
		  break;

		case 2:                    /* two numbers --> month & day */
		  d.month = nums[0];
		  d.day = nums[1]; 
		  break;

		case 1:
		  d.day = nums[0]; 
		  break;
		}
		break;
	}
#endif

  /* if only entered two digits for year, assume 1900's */
  if (d.year < 80)
    d.year += 2000;
  else if (d.year < 200)
    d.year += 1900;

  leap = (!(d.year % 4) && (d.year % 100)) || !(d.year % 400);

  if ((d.month >= 1 && d.month <= 12) &&
      (d.day >= 1 && d.day <= months[leap][d.month]) &&
      (d.year >= 1980 && d.year <= 2099))
  {
    if(datep)
    	memcpy(datep, &d, sizeof(d));
    return E_None;
  }

  return E_Range;
}