Newsgroups: comp.sys.apple2.programmer Path: news.uiowa.edu!hobbes.physics.uiowa.edu!newsrelay.iastate.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!agate!ames!waikato!comp.vuw.ac.nz!actrix.gen.nz!dempson From: dempson@atlantis.actrix.gen.nz (David Empson) Subject: Re: using C with pascal Message-ID: Sender: news@actrix.gen.nz (News Administrator) Organization: Actrix - Internet Services Date: Sun, 6 Aug 1995 13:19:47 GMT References: <4020i5$4no@bbs.ausom.net.au> X-Nntp-Posting-Host: atlantis.actrix.gen.nz Lines: 276 > Can someone help me I am tring to uses the functions build into ORCA/C > to calculate the day of the week and day in year for a pascal program. OK. > What am I doing wrong? The following is your program, with my comments and suggested corrections. I have NOT used the normal "quoting" notation here. ************************************************************ pascal program program test2 (input,output); type ptr_tm = ^tm; tm = record second : integer; minute : integer; hour : integer; day : integer; month : integer; year : integer; Wday : integer; dayofYear : integer; isdaysave : integer; end; var my_time : longint; MY_Int : integer; timerec : tm; ptr_time : ptr_tm; function GetTime : longint; extern; (* You had: function GetTime ( myin : integer ) : longint; extern; I see no reason for the dummy integer parameter. *) function FixDayWeek ( mytime : ptr_tm ) : ptr_tm; extern; (* You had: function FixDayWeek ( myin : univ longint ) : longint; extern; You may as well use the correct types. *) procedure PrintTime ( My_Time : ptr_tm); begin writeln ( 'Pointer :',ord4(my_time)); (* You spelled "Pointer" wrong above. In the following output, you are going to get strange values for the month, which is stored as 0-11 in the original struct tm: add one for the normal notation. Similarly, the year is 0-based at 1900, so add 1900 to get the year in normal notation. *) with my_time^ do begin writeln ( 'date : ',day:2,'/',month:2,'/',year:4); writeln ('Time : ',hour:2,':',minute:2,':',second:2); writeln ( 'day of week : ',wday:2,' Day of Year : ',dayofyear:2); end; end; begin My_time := 0; MY_int := 0 ; (* This isn't needed *) writeln ('This is my Time now ',My_time); MY_Time := GetTime (* (MY_Int) *); writeln ('This is my Time after calling time ',My_time); with timerec do begin day := 2; month := 4; (* This will be May. Use 3 for April. *) year := 95; (* Your version had 1995 *) second := 2; minute :=33; hour :=12; Wday :=0; dayofyear :=0; (* You should also add the following line: *) isdaysave := 0; end; writeln (' Time before Call'); PrintTime ( @timerec ); ptr_time := @timerec; ptr_time := FixDayWeek ( ptr_time ); (* no typecast now *) PrintTime ( ptr_time); end. ********************************************************************* the C functions /********************/ #pragma keep "timec" #pragma noroot #pragma lint -1 #include "time.h" #include "intmath.h" #include "stdio.h" pascal LongWord GetTime (void) /* was (Word MY_in) */ { LongWord gstime; gstime = time(NULL); return gstime; /* This could be simplified to one line: return time(NULL); */ } pascal struct tm * FixDayWeek ( struct tm *my_ptr ) { struct tm time_rec; struct tm *ptr_tm; time_t mytime; /* unsigned long ptr; */ /* Not used */ int p; /* was char - getchar() returns int */ /* ptr_tm = my_ptr; */ /* Not necessary */ printf("%lx",my_ptr); /* was "%x" */ /* printf("%x",*my_ptr); */ /* This line is bad - see below */ p = getchar(); mytime = mktime(my_ptr /* was ptr_tm */); printf("%lx",mytime); /* was "%x" */ p = getchar(); ptr_tm = localtime(&mytime); printf("%lx",ptr_tm); /* was "%x" */ p = getchar() ; return ptr_tm; } ******************** Regarding the printf() I commented out: you were passing the contents of the structure and trying to print the first word as a hex value. The rest of it would have been left on the stack, which might have caused a crash, depending on whether you were optimizing the code. Similarly, your other printf() calls were passing larger values than they were printing. In general, I can't see anything fundamentally wrong with what you are doing. The localtime() call is not strictly necessary, as mktime() will recalculate tm_wday and tm_yday in your input structure. Here is a much more versatile way of calculating the day of week, all done in Pascal, though it does use the IIgs toolbox. System 5.0.3 or later is required. The main point of this program is to demonstrate the use of the ConvSeconds toolbox call, which does everything you need. program ConvSecondsExample(output); uses Common, MscToolSet; const (* Conversion verb (first parameter) for ConvSeconds *) ConvSecsToTimeRec = 0; (* Convert to time record *) ConvTimeRecToSecs = 1; (* Convert from time record *) ConvSecsToAscii = 2; (* Convert to ASCII-formatted time *) ConvSecsToProDOS = 4; (* Convert to ProDOS packed time *) ConvProDOSToSecs = 5; (* Convert from ProDOS packed time *) ConvGetTime = 6; (* Get current time in seconds *) ConvSetTime = 7; (* Set current time in seconds *) ConvProDOSToTimeRec = 8; (* Convert ProDOS to TimeRec in place *) ConvTimeRecToProDOS = 9; (* Convert TimeRec to ProDOS in place *) ConvSecsToHyperCard = 10; (* Convert to HyperCard time record *) ConvHyperCardToSecs = 11; (* Convert from HyperCard time record *) type TimeRec = record second : byte; (* 0 to 59 *) minute: byte; (* 0 to 59 *) hour : byte; (* 0 to 23 *) year : byte; (* year minus 1900 *) day : byte; (* 0 to 30: add 1 for normal day *) month : byte; (* 0 to 11: add 1 for normal month *) extra : byte; (* unused - only required for positioning *) weekDay : byte; (* 1 to 7, with 1 = Sunday *) end; var myTimeRec : TimeRec; mySeconds, dummy : longint; Begin with myTimeRec do begin day := 1; (* day is zero-based: add 1 for normal notation *) month := 4; (* month is zero-based: add 1 for normal notation *) year := 95; second := 2; minute := 33; hour := 12; end; (* ConvSeconds expects three parameters: First parameter is the conversion verb (see constants above). Second parameter is the "seconds" value, when converting from seconds to another format, or 0 if not used. Third parameter is a pointer to the input or output data structure for most operations. The return value is the "seconds" value when converting to seconds from another format, or undefined otherwise. The "seconds" type is a long integer which contains the number of seconds since 1st January 1904. *) (* We have a record in standard TimeRec format, so convert it to seconds. *) myseconds := ConvSeconds(ConvTimeRecToSecs, 0, @myTimeRec); (* Now convert the seconds back to a TimeRec, which will give us the day of week. The return value must be ignored. *) dummy := ConvSeconds(ConvSecsToTimeRec, myseconds, @myTimeRec); (* Add code in here to do the necessary extra steps, e.g. *) writeln('The day of the week was ', myTimeRec.weekDay); end. If you want to get the current time (in seconds), use: seconds := ConvSeconds(ConvGetTime, 0, NIL); The "HyperCard" format mentioned in the constants is the same data structure as TimeRec, except that "day" and "month" start at one instead of zero. You are unlikely to need ProDOS format. ASCII format is rather messy. It produces a packed array of 20 characters containing the time in the order specified by the Control Panel. There is no end terminator, and the characters are in high ASCII, so they should be converted to low ASCII before use. The buffer needs to be at least 40 bytes long, even though only 20 bytes are used. Here is an example of how it can be used: type Str20 = packed array[0..20] of char; Procedure TimeString(seconds: longint; var timeStr: Str20); const ConvSecsToAscii = 2; (* Convert to ASCII-formatted time *) var timebuf : packed array[1..40] of byte; i : integer; dummy : longint; begin dummy := ConvSeconds(ConvSecsToASCII, seconds, @timebuf); for i := 1 to 20 do timeStr[i] := chr(timebuf[i] - 128); timeStr[0] := 20; (* Set the string length *) end; (*TimeString*) -- David Empson dempson@actrix.gen.nz Snail mail: P.O. Box 27-103, Wellington, New Zealand