mrr@softie.UUCP (09/26/87)
# This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file" # Created Fri Sep 25 07:26:29 1987 # # This archive contains: # DateRequest.c # MRDates.c # MRDates.h # DiskMisc.c # FileMisc.c echo "Creating DateRequest.c" cat > DateRequest.c <<"***EOF DateRequest.c***" /* Date Requester Package * Author: Mark R. Rinfret * Description: * This source file contains a canned date requester routine which * supports time and date entry in MM/DD/YY HH:MM:SS notation (time is * optional) to a DateStamp structure. This package is dependent upon * the package "MRDates.c" (same author) for DateStamp/string conversions. * * History: (most recent change first) * * 08/18/87 -MRR- Added up/down arrows to gadgetry * 07/20/87 -MRR- Created this file. */ #include <intuition/intuition.h> #include <intuition/intuitionbase.h> #include <libraries/dosextens.h> #include <graphics/gfxbase.h> #include <graphics/gfx.h> #include <graphics/display.h> #include <graphics/text.h> #include <functions.h> #include <ctype.h> #include <MRDates.h> #define DATEREQWIDTH 260 #define DATEREQHEIGHT 80 /********************************************************************** * Gadget Structure Definitions * * Some of the following structures were defined using EGAD! * (by the Programmer's Network) and further modified by the author. * **********************************************************************/ /* Gadget ID Definitions */ #define DATEGAD 0 #define UPMONTHGAD 1 #define UPDAYGAD 2 #define UPYEARGAD 3 #define UPHOURGAD 4 #define UPMINGAD 5 #define UPSECGAD 6 #define DOWNMONTHGAD 7 #define DOWNDAYGAD 8 #define DOWNYEARGAD 9 #define DOWNHOURGAD 10 #define DOWNMINGAD 11 #define DOWNSECGAD 12 #define NOWGAD 13 #define OKGAD 14 /********************************************************************** * Text attribute structures used in rendering IntuiTexts **********************************************************************/ static char def_font[] ="topaz.font"; static struct TextAttr TxtAt_Plain = { (UBYTE *)def_font, 8, FS_NORMAL, FPF_ROMFONT }; /********************************************************************** * String information for the dategad string gadget. **********************************************************************/ static UBYTE dategad_sbuf_1[19] = "00/00/00 00:00:00"; static UBYTE dategad_ubuf_1[19]; static struct StringInfo dategad_txstr_1 = { dategad_sbuf_1, dategad_ubuf_1, /* Buffer, UndoBuffer */ 0, 18, 0, /* BufferPos, MaxChars, DispPos */ 0, 18, /* UndoPos, NumChars */ 0, 0, 0, /* DispCount, CLeft, CTop */ 0x0, 0, /* LayerPtr, LongInt */ 0x0 /* AltKeyMap */ }; /********************************************************************** * Gadget Structure definition for the dategad gadget. **********************************************************************/ static struct Gadget dategad = { NULL, /* NextGadget pointer */ 64, 50, /* LeftEdge, TopEdge */ 8 * 17, /* Width (8 pixels * 17 characters) */ 8, /* Height */ GADGHCOMP, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | STRGADGET, /* GadgetType */ NULL, /* GadgetRender - no border */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ (APTR)&dategad_txstr_1, /* SpecialInfo */ DATEGAD, /* GadgetID */ NULL /* UserData Pointer */ }; static struct IntuiText nowtext = { 1, 0, /* FrontPen / BackPen */ JAM2, /* DrawMode */ 0, /* LeftEdge */ 0, /* TopEdge */ &TxtAt_Plain, /* ITextFont */ (UBYTE *) "NOW", /* IText */ NULL /* NextText */ }; static struct Gadget nowgad = { &dategad, /* NextGadget pointer */ 220, 50, /* LeftEdge, TopEdge */ 24, 8, /* Width, Height */ GADGHCOMP, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ NULL, /* GadgetRender */ NULL, /* SelectRender */ &nowtext, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ NOWGAD, /* GadgetID */ NULL /* UserData Pointer */ }; static struct IntuiText oktext = { 1, 0, /* FrontPen / BackPen */ JAM2, /* DrawMode */ 0, /* LeftEdge */ 0, /* TopEdge */ &TxtAt_Plain, /* ITextFont */ (UBYTE *) "OK", /* IText */ NULL /* NextText */ }; static struct Gadget okgad = { &nowgad, /* NextGadget pointer */ 30, 50, /* LeftEdge, TopEdge */ 16, 8, /* Width, Height */ GADGHNONE, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ NULL, /* GadgetRender */ NULL, /* SelectRender */ &oktext, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ OKGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /* These coordinate pairs define the border of the up-arrow gadgets. */ static SHORT upborder_pairs[] = { 7, 0, 14, 7, 0, 7, 7, 0 }; /* The up-arrow border definition. */ static struct Border upborder = { -1, -1, /* LeftEdge, TopEdge */ 1, 2, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 4, /* number of pairs */ (SHORT *) &upborder_pairs, NULL /* NextBorder */ }; /* These coordinate pairs define the border of the down-arrow gadgets. */ static SHORT downborder_pairs[] = { 0, 0, 14, 0, 7, 7, 0, 0 }; /* The down-arrow border definition. */ static struct Border downborder = { -1, -1, /* LeftEdge, TopEdge */ 1, 2, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 4, /* number of pairs */ (SHORT *) &downborder_pairs, NULL /* NextBorder */ }; /********************************************************************** * Gadget Structure definition for the upsec gadget. **********************************************************************/ /* Each component of the date and time can be incremented/decremented * by clicking on the appropriate up or down arrow gadgets. */ static struct Gadget downsecgad = { &okgad, /* NextGadget pointer */ 184, 60, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &downborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ DOWNSECGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upmin gadget. **********************************************************************/ static struct Gadget downmingad = { &downsecgad, /* NextGadget pointer */ 160, 60, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &downborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ DOWNMINGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the uphour gadget. **********************************************************************/ static struct Gadget downhourgad = { &downmingad, /* NextGadget pointer */ 136, 60, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &downborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ DOWNHOURGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upyear gadget. **********************************************************************/ static struct Gadget downyeargad = { &downhourgad, /* NextGadget pointer */ 112, 60, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &downborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ DOWNYEARGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upday gadget. **********************************************************************/ static struct Gadget downdaygad = { &downyeargad, /* NextGadget pointer */ 88, 60, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &downborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ DOWNDAYGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upmonth gadget. **********************************************************************/ static struct Gadget downmonthgad = { &downdaygad, /* NextGadget pointer */ 64, 60, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ /* Gadget Flags */ NULL, RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &downborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ DOWNMONTHGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upsec gadget. **********************************************************************/ static struct Gadget upsecgad = { &downmonthgad, /* NextGadget pointer */ 184, 40, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &upborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ UPSECGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upmin gadget. **********************************************************************/ static struct Gadget upmingad = { &upsecgad, /* NextGadget pointer */ 160, 40, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &upborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ UPMINGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the uphour gadget. **********************************************************************/ static struct Gadget uphourgad = { &upmingad, /* NextGadget pointer */ 136, 40, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &upborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ UPHOURGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upyear gadget. **********************************************************************/ static struct Gadget upyeargad = { &uphourgad, /* NextGadget pointer */ 112, 40, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &upborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ UPYEARGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upday gadget. **********************************************************************/ static struct Gadget updaygad = { &upyeargad, /* NextGadget pointer */ 88, 40, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ NULL, /* Gadget Flags */ RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &upborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ UPDAYGAD, /* GadgetID */ NULL /* UserData Pointer */ }; /********************************************************************** * Gadget Structure definition for the upmonth gadget. **********************************************************************/ static struct Gadget upmonthgad = { &updaygad, /* NextGadget pointer */ 64, 40, /* LeftEdge, TopEdge */ 15, 8, /* Width, Height */ /* Gadget Flags */ NULL, RELVERIFY , /* Activation Flags */ REQGADGET | BOOLGADGET, /* GadgetType */ (APTR) &upborder, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ NULL, /* SpecialInfo */ UPMONTHGAD, /* GadgetID */ NULL /* UserData Pointer */ }; static struct Requester daterequest; /* requester for the date */ /* Date requester border 2 coordinate pairs. */ static SHORT datereq_pairs2[] = { 8, 4, DATEREQWIDTH - 8, 4, DATEREQWIDTH - 8, DATEREQHEIGHT - 4, 8, DATEREQHEIGHT - 4, 8, 4 }; /* Date requester border 2 definition */ static struct Border datereq_bord2 = { -1, -1, /* LeftEdge, TopEdge */ 0, 2, JAM2, /* FrontPen, BackPen, DrawMode*/ 5, /* Count of XY pairs */ (SHORT *)&datereq_pairs2, /* XY pairs */ NULL /* Next Border */ }; /* Date requester border 1 coordinate pairs. */ static SHORT datereq_pairs1[] = { 4, 2, DATEREQWIDTH - 4, 2, DATEREQWIDTH - 4, DATEREQHEIGHT - 2, 4, DATEREQHEIGHT - 2, 4, 2 }; /* Date requester border 1 definition. */ static struct Border datereq_bord1 = { -1, -1, /* LeftEdge, TopEdge */ 0, 2, JAM2, /* FrontPen, BackPen, DrawMode*/ 5, /* Count of XY pairs */ (SHORT *)&datereq_pairs1, /* XY pairs */ &datereq_bord2 /* Next Border */ }; /* This is the definition for the prompt string (user-supplied) which * appears in the requester. */ static struct IntuiText datereqtext = { 1, 0, /* FrontPen / BackPen */ JAM2, /* DrawMode */ 20, /* LeftEdge */ 15, /* TopEdge */ &TxtAt_Plain, /* ITextFont */ NULL, /* IText */ NULL /* NextText */ }; static initialized = 0; /* set to 1 after initialization */ static InitDateRequest() { InitRequester(&daterequest); daterequest.LeftEdge = 60; daterequest.TopEdge = 10; daterequest.Width = DATEREQWIDTH; daterequest.Height = DATEREQHEIGHT; daterequest.ReqGadget = &upmonthgad; daterequest.ReqText = &datereqtext; daterequest.ReqBorder = &datereq_bord1; daterequest.BackFill = 2; ++initialized; } /* Request a date from the user. * Called with: * window: pointer to window structure * prompt: string to be used as the prompt text * default_date: pointer to default date or NULL * date: pointer to date result (returned) * Returns: * status code: 0 => success, 1 => failure * (actually, always returns 0 - can't leave without good date) */ DateRequest(window,prompt,default_date,date) struct Window *window; char *prompt; struct DateStamp *default_date,*date; { ULONG class; /* message class */ USHORT code; /* message code */ struct Gadget *gadget; /* pointer to gadget affected */ USHORT gadgid; /* gadget ID */ struct IntuiMessage *msg; /* Intuition message pointer */ UnpackedDS upd; /* unpacked version of date */ SHORT x,y; /* mouse x and y position */ if (!initialized) InitDateRequest(); datereqtext.IText = (UBYTE *) prompt; if (default_date) /* write default date in requester? */ DS2Str(dategad_sbuf_1,"%02m/%02d/%02y %02h:%02n:%02s", default_date); else *dategad_sbuf_1 = '\0'; Request(&daterequest, window); for (;;) { Wait(1L << window->UserPort->mp_SigBit); while (msg = (struct IntuiMessage *) GetMsg(window->UserPort)) { class = msg->Class; code = msg->Code; gadget = (struct Gadget *) msg->IAddress; x = msg->MouseX; y = msg->MouseY; ReplyMsg(msg); /* acknowledge the message */ switch (class) { case REQSET: ActivateGadget(&dategad,window,&daterequest); break; case GADGETUP: gadgid = gadget->GadgetID; if (gadgid == NOWGAD) DateStamp(date); else if (gadgid == OKGAD) gadgid = DATEGAD; UnpackDS(date, &upd); switch (gadgid) { case DATEGAD: if ( ! Str2DS(dategad_sbuf_1, date) ) { EndRequest(&daterequest, window); return 0; } else DisplayBeep(window->WScreen); /* bad conversion */ break; case UPYEARGAD: ++upd.year; break; case DOWNYEARGAD: if (upd.year > 1978) --upd.year; break; case UPMONTHGAD: if (++upd.month > 12) upd.month = 1; break; case DOWNMONTHGAD: if (--upd.month < 1) upd.month = 12; break; case UPDAYGAD: if (upd.day < 31) ++upd.day; break; case DOWNDAYGAD: if (upd.day > 1) --upd.day; break; case UPHOURGAD: if (++upd.hour > 23) upd.hour = 0; break; case DOWNHOURGAD: if (--upd.hour < 0) upd.hour = 23; break; case UPMINGAD: if (++upd.minute > 59) upd.minute = 0; break; case DOWNMINGAD: if (--upd.minute < 0) upd.minute = 59; break; case UPSECGAD: if (++upd.second > 59) upd.second = 0; break; case DOWNSECGAD: if (--upd.second < 0) upd.second = 59; break; default: break; } /* end switch(gadgid) */ /* Reformat the new date value. */ PackDS(date, &upd); if (upd.year) DS2Str(dategad_sbuf_1,"%02m/%02d/%02y %02h:%02n:%02s", date); else strcpy(dategad_sbuf_1,"00/00/00 00:00:00"); RefreshGadgets(&dategad, window, &daterequest); break; default: break; /* ignore the rest */ } /* end switch(class) */ } } } /*#define DEBUG */ #ifdef DEBUG /* --- Only compiled in the debug version --- */ #include <exec/memory.h> /* New window structure */ struct NewWindow newwindow = { 0,0,640,200,0,1, /* IDCMP Flags */ MOUSEMOVE | MENUPICK | MOUSEBUTTONS | CLOSEWINDOW | GADGETDOWN | GADGETUP | REQSET, /* Flags */ WINDOWCLOSE | WINDOWDEPTH | ACTIVATE | RMBTRAP | REPORTMOUSE, NULL, /* First gadget */ NULL, /* Checkmark */ (UBYTE *)"Date Requester Test Program", /* Window title */ NULL, /* No custom streen */ NULL, /* Not a super bitmap window */ 0,0,640,200, /* Not used, but set up anyway */ WBENCHSCREEN }; struct IntuitionBase *IntuitionBase; struct Window *mywindow; struct DateStamp *ds; static struct IntuiText MoreText = { AUTOFRONTPEN, /* FrontPen */ AUTOBACKPEN, /* BackPen */ JAM2, /* DrawMode */ AUTOLEFTEDGE, /* LeftEdge */ AUTOTOPEDGE, /* TopEdge */ AUTOITEXTFONT, /* ITextFont */ (UBYTE *) "Want to play some more?", /* IText */ NULL /* NextText */ }; static struct IntuiText YesText = { AUTOFRONTPEN, /* FrontPen */ AUTOBACKPEN, /* BackPen */ AUTODRAWMODE, /* DrawMode */ AUTOLEFTEDGE, /* LeftEdge */ AUTOTOPEDGE, /* TopEdge */ AUTOITEXTFONT, /* ITextFont */ (UBYTE *) "Sure!", /* IText */ NULL /* NextText */ }; static struct IntuiText NoText = { AUTOFRONTPEN, /* FrontPen */ AUTOBACKPEN, /* BackPen */ JAM2, /* DrawMode */ AUTOLEFTEDGE, /* LeftEdge */ AUTOTOPEDGE, /* TopEdge */ AUTOITEXTFONT, /* ITextFont */ (UBYTE *) "Nope!", /* IText */ NULL /* NextText */ }; main() { short keep_going; if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",33L))) { puts("Failed to open Intuition library!"); exit(1); } ds = (struct DateStamp *) AllocMem((long) sizeof(struct DateStamp), MEMF_PUBLIC); DateStamp(ds); /* get current date/time */ mywindow = OpenWindow(&newwindow); do { DateRequest(mywindow, "Enter date and time", ds, ds); keep_going = AutoRequest(mywindow, &MoreText, &YesText, &NoText, NULL, NULL, 220L, 50L); } while (keep_going); if (mywindow) CloseWindow(mywindow); if (IntuitionBase) CloseLibrary(IntuitionBase); } #endif ***EOF DateRequest.c*** echo "Creating MRDates.c" cat > MRDates.c <<"***EOF MRDates.c***" /* General routines to provide date support for the DateStamp * date format. * * Author: Mark R. Rinfret (mark@unisec.usi.com) * Date: 07/18/87 * * This source is released to the public domain by the author, without * restrictions. However, it is requested that you give credit where * credit is due and share any bug fixes or enhancements with him. * * History: (most recent change first) * * 08/20/87 -MRR- Gack! I wrote this? In the interests of orthogonality, * I have replaced SetDateStamp with PackDS, the inverse * of UnpackDS. I have also renamed the package MRDates * to provide a unique name, hopefully relieving conflicts * with other packages providing date/time functions. The * UnpackedDS type is now defined in MRDates.h and can * be included by modules which require PackDS and UnpackDS. */ /* The following #define MUST be set to inhibit certain declarations in * the include file MRDates.h: */ #define MRDATES #include <libraries/dos.h> #include <exec/memory.h> #include <ctype.h> #include <functions.h> #include "MRDates.h" /* #define DEBUG */ char *daynames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; USHORT monthdays[12] = {0,31,59,90,120,151,181,212,243,273,304,334}; char *monthnames[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; /* Compare two DateStamp values. * Called with: * d1,d2: pointers to DateStamp structs * * Returns: * < 0 => d1 < d2 * 0 => d1 == d2 * > 0 => d1 > d2 * * Note: * This routine makes an assumption about the DateStamp structure, * specifically that it can be viewed as an array of 3 long integers * in days, minutes and ticks order. */ int CompareDS(d1, d2) long *d1, *d2; { USHORT i; long compare; for (i = 0; i < 3; ++i) { if (compare = (d1[i] - d2[i])) { if (compare < 0) return -1; return 1; } } return 0; /* dates match */ } /* Convert a DateStamp to a formatted string. * Called with: * fmt: format string * The format of the format string is very similar to that * for printf, with the exception that the following letters * have special significance: * y => year minus 1900 * Y => full year value * m => month value as integer * M => month name * d => day of month (1..31) * D => day name ("Monday".."Sunday") * h => hour in twenty-four hour notation * H => hour in twelve hour notation * i => 12 hour indicator for H notation (AM or PM) * I => same as i * n => minutes (sorry...conflict with m = months) * N => same as n * s => seconds * S => same as s * * All other characters are passed through as part of the normal * formatting process. The following are some examples with * Saturday, July 18, 1987, 13:53 as an input date: * * "%y/%m/%d" => 87/7/18 * "%02m/%02d/%2y" => 07/18/87 * "%D, %M %d, %Y" => Saturday, July 18, 1987 * "%02H:%02m i" => 01:53 PM * "Time now: %h%m" => Time now: 13:53 * * str: string to write date on * d: pointer to DateStamp structure * */ void DS2Str(str,fmt,d) char *str, *fmt; struct DateStamp *d; { UnpackedDS date; char fc,*fs,*out; USHORT ivalue; char new_fmt[256]; /* make it big to be "safe" */ USHORT new_fmt_lng; char *svalue; UnpackDS(d, &date); /* convert DateStamp to unpacked format */ *str = '\0'; /* insure output is empty */ out = str; fs = fmt; /* make copy of format string pointer */ while (fc = *fs++) { /* get format characters */ if (fc == '%') { /* formatting meta-character? */ new_fmt_lng = 0; new_fmt[new_fmt_lng++] = fc; /* copy width information */ while (isdigit(fc = *fs++) || fc == '-') new_fmt[new_fmt_lng++] = fc; switch (fc) { /* what are we trying to do? */ case 'y': /* year - 1980 */ ivalue = date.year - 1900; write_int: new_fmt[new_fmt_lng++] = 'd'; new_fmt[new_fmt_lng] = '\0'; sprintf(out,new_fmt,ivalue); out = str + strlen(str); break; case 'Y': /* full year value */ ivalue = date.year; goto write_int; case 'm': /* month */ ivalue = date.month; goto write_int; case 'M': /* month name */ svalue = monthnames[date.month - 1]; write_str: new_fmt[new_fmt_lng++] = 's'; new_fmt[new_fmt_lng] = '\0'; sprintf(out,new_fmt,svalue); out = str + strlen(str); break; case 'd': /* day */ ivalue = date.day; goto write_int; case 'D': /* day name */ svalue = daynames[d->ds_Days % 7]; goto write_str; case 'h': /* hour */ ivalue = date.hour; goto write_int; case 'H': /* hour in 12 hour notation */ ivalue = date.hour; if (ivalue >= 12) ivalue -= 12; goto write_int; case 'i': /* AM/PM indicator */ case 'I': if (date.hour >= 12) svalue = "PM"; else svalue = "AM"; goto write_str; case 'n': /* minutes */ case 'N': ivalue = date.minute; goto write_int; case 's': /* seconds */ case 'S': ivalue = date.second; goto write_int; default: /* We are in deep caca - don't know what to do with this * format character. Copy the raw format string to the * output as debugging information. */ new_fmt[new_fmt_lng++] = fc; new_fmt[new_fmt_lng] = '\0'; strcat(out, new_fmt); out = out + strlen(out); /* advance string pointer */ break; } } else *out++ = fc; /* copy literal character */ } *out = '\0'; /* terminating null */ } /* Convert a string to a DateStamp. * Called with: * str: string containing date in MM/DD/YY format * d: pointer to DateStamp structure * Returns: * status code (0 => success, 1 => failure) */ int Str2DS(str, d) char *str; struct DateStamp *d; { register char c; int count; int i, item; UnpackedDS upd; /* unpacked DateStamp */ char *s; int values[3]; int value; s = str; for (item = 0; item < 2; ++item) { /* item = date, then time */ for (i = 0; i < 3; ++i) values[i] = 0; count = 0; while (c = *s++) { /* get date value */ if (c <= ' ') break; if (isdigit(c)) { value = 0; do { value = value*10 + c - '0'; c = *s++; } while (isdigit(c)); if (count == 3) { bad_value: #ifdef DEBUG puts("Error in date-time format.\n"); printf("at %s: values(%d) = %d, %d, %d\n", s, count, values[0], values[1], values[2]); #endif return 1; } values[count++] = value; if (c <= ' ') break; } } /* end while */ if (item) { /* getting time? */ upd.hour = values[0]; upd.minute = values[1]; upd.second = values[2]; } else { /* getting date? */ /* It's OK to have a null date string, but it's not OK to specify only * 1 or 2 of the date components. */ if (count && count != 3) goto bad_value; upd.month = values[0]; upd.day = values[1]; upd.year = values[2]; } } /* end for */ PackDS(d,&upd); return 0; } /* Set a DateStamp structure, given the date/time components. * Called with: * d: pointer to DateStamp * upd: pointer to UnpackedDS */ PackDS(d,upd) struct DateStamp *d; UnpackedDS *upd; { USHORT leapyear; short year,month,day,hour,minute,second; year = upd->year; /* copy date components to locals */ month = upd->month; day = upd->day; hour = upd->hour; minute = upd->minute; second = upd->second; if (year > 1900) year = year - 1900; leapyear = (year % 4 ? 0 : 1); year = year - 78; if (month < 1 || month > 12) /* somebody goofed? */ month = 1; day = day - 1 + monthdays[month-1]; if (leapyear && (month > 2)) ++day; d->ds_Days = year * 365 + (year + 1) / 4 + day; d->ds_Minute = hour * 60 + minute; d->ds_Tick = second * TICKS_PER_SECOND; } /* Unpack a DateStamp structure into an UnpackedDS structure. * Called with: * ds: pointer to DateStamp structure * du: pointer to UnpackedDS structure */ UnpackDS(ds, du) struct DateStamp *ds; UnpackedDS *du; { USHORT i, leap_years, leap, temp, test_value; du->year = ds->ds_Days / 365 + 1978; /* is current year a leapyear? */ leap = ( (du->year % 4) == 0); /* how many leap years since "beginning of time"? */ leap_years = (du->year - 1976 - 1) / 4; /* get days remaining in year */ temp = ds->ds_Days % 365 - leap_years; /* find month */ du->month = 0; du->day = 0; for (i = 11; i >= 0; --i) { test_value = monthdays[i]; if (i > 2) test_value += leap; if (temp >= test_value) { du->month = i + 1; du->day = temp - test_value + 1; break; } } du->hour = ds->ds_Minute / 60; du->minute = ds->ds_Minute % 60; du->second = ds->ds_Tick / TICKS_PER_SECOND; } #ifdef DEBUG main() { int compflag; char datestr[81], instr[81]; struct DateStamp *ds, *now; UnpackedDS du; now = (struct DateStamp *) AllocMem((long) sizeof(struct DateStamp), MEMF_PUBLIC); ds = (struct DateStamp *) AllocMem((long) sizeof(struct DateStamp), MEMF_PUBLIC); puts("Enter a date string and I will convert it. To quit, hit RETURN"); while (1) { DateStamp(now); UnpackDS(now, &du); printf("\nCurrent date and time: %02d/%02d/%02d %02d:%02d:%02d\n", du.month,du.day,du.year,du.hour,du.minute,du.second); puts("\nEnter the date [and time]:"); gets(instr); if (*instr == '\0') break; if (Str2DS(instr,ds)) puts("Error encountered in input string"); else { DS2Str(datestr, "%02m/%02d/%02y %02h:%02n:%02s", ds); puts(datestr); DS2Str(datestr, "%D, %M %d, %Y", ds); puts(datestr); DS2Str(datestr, "The time entered is %02H:%02N %i", ds); puts(datestr); compflag = CompareDS(ds,now); printf("The date input is "); if (compflag < 0) printf("earlier than"); else if (compflag == 0) printf("the same as"); else printf("later than"); puts(" the current date."); } } FreeMem(ds, (long) sizeof(struct DateStamp)); FreeMem(now, (long) sizeof(struct DateStamp)); } #endif ***EOF MRDates.c*** echo "Creating MRDates.h" cat > MRDates.h <<"***EOF MRDates.h***" /* Filename: MRDates.h * Various definitions used to support the MRDates package. * * Important note: * If the preprocessor symbol MRDATES is undefined, certain * useful structures will be declared for use by the module * including this file. */ #include <exec/types.h> typedef struct { short year,month,day,hour,minute,second; } UnpackedDS; #ifndef MRDATES /* This is not MRDates.c? */ extern char *daynames[7]; /* day name strings, [0] = "Sunday" */ extern USHORT monthdays[12];/* Number of days preceding each month, * requires diddling for leap years. */ extern char *monthnames[12];/* [0] = January */ #endif ***EOF MRDates.h*** echo "Creating DiskMisc.c" cat > DiskMisc.c <<"***EOF DiskMisc.c***" /* DiskMisc.c - miscellaneous disk support routines. * Mark Rinfret (et al), 1987 */ /*#define DEBUG*/ #include <exec/types.h> #include <exec/memory.h> #include <exec/ports.h> #include <exec/io.h> #include <libraries/dosextens.h> #include <functions.h> extern LONG sendpkt(); /* This routine returns the number of disk blocks remaining on the * drive specified by 'name'. Though 'name' would typically be the * drive name or volume name, it can also be the name of any file * on the disk drive. * Called with: * name: disk device or volume name * Returns: * > 0 => number of blocks available * < 0 => error status */ long DiskBlocks(name) char *name; { struct FileLock *lock = NULL; struct InfoData *info = NULL; long int blocks = -1L; long IoErr(); if (lock = (struct FileLock *) Lock(name,ACCESS_READ)) { if (info = AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC)) { if (Info(lock,info)) { blocks = info->id_NumBlocks - info->id_NumBlocksUsed; } else { blocks = -IoErr(); #ifdef DEBUG printf("DiskBlocks: can't get Info on %s; error %ld\n", name, blocks); #endif } } else { blocks = -ERROR_NO_FREE_STORE; #ifdef DEBUG puts("DiskBlocks: no memory!"); #endif } } else { blocks = -IoErr(); #ifdef DEBUG printf("DiskBlocks: can't lock %s; error %ld\n",name,blocks); #endif } if (lock) UnLock(lock); if (info) FreeMem(info,(long)sizeof(struct InfoData)); return blocks; /* bad status indicator */ } /* Disk ACTION_INHIBIT support routine. * Author: Mark R. Rinfret * Date: 06/29/87 * * This routine provides support for user-written disk formatting, copy * operations which benefit from suppressing/restoring disk validation. */ int Inhibit(drivename, code) char *drivename; int code; { struct MsgPort *task; LONG arg[2]; LONG rc; if (!(task=(struct MsgPort *) DeviceProc(drivename))) return 1; /* fail, darn it! */ arg[0] = code; /* Now, cross all your fingers and toes... */ return ( !sendpkt(task,ACTION_INHIBIT,arg,1)); } #ifdef DEBUG main() { long blocks; blocks = DiskBlocks("df0:"); if (blocks == -1L) puts("Bad status from DiskBlocks()"); else printf("Disk blocks left on df0: %ld\n",blocks); } #endif ***EOF DiskMisc.c*** echo "Creating FileMisc.c" cat > FileMisc.c <<"***EOF FileMisc.c***" /* File date routines. * Filename: FileDates.c * History: (most recent change first) * * 09/24/87 -MRR- SetFileDate was allocating a BSTR of 68 bytes, rather * than using the length of the file name string. I don't * have the foggiest notion why (that was DUMB!). */ #include "exec/types.h" #include "exec/ports.h" #include "exec/io.h" #include "exec/memory.h" #include "libraries/dosextens.h" #include <stdio.h> #define AZTEC 1 #ifdef AZTEC #include "functions.h" /* aztec C include */ #endif #define ACTION_SETDATE_MODE 34L /* Set creation date on file */ #define DOSTRUE -1L /* AmigaDos TRUE */ #define MAXARGS 7L /* limit in packet structure (dosextens.h) */ #define NARGS 4L /* Number of args for setdate */ long sendpkt(); /*---------------------------------------------------------------------*/ /* GetFileDate: get the datestamp the given file. */ /*---------------------------------------------------------------------*/ BOOL GetFileDate(name, date) char *name; register struct DateStamp *date; { struct FileInfoBlock *Fib; ULONG FLock; int result; register struct DateStamp *d; if ((FLock = (ULONG)Lock(name,(long)(ACCESS_READ)))== NULL) return FALSE; Fib = (struct FileInfoBlock *) AllocMem((long)sizeof(struct FileInfoBlock), (long)(MEMF_CHIP|MEMF_PUBLIC)); if (Fib == NULL ) result = FALSE; else{ if (!Examine(FLock,Fib )) result = FALSE; else if (Fib->fib_DirEntryType > 0 ) result = FALSE; /* It's a directory */ else{ d = &Fib->fib_Date; date->ds_Days = d->ds_Days; date->ds_Minute = d->ds_Minute; date->ds_Tick = d->ds_Tick; result = TRUE; } FreeMem((void *)Fib,(long)sizeof(struct FileInfoBlock)); } UnLock(FLock); return result; } /* Examine a pathname to determine if it is a device or directory name. * Called with: * name: pathname specification * Returns: * 0 => no * 1 => yes * <0 => -<system error number> */ int IsDir(name) char *name; { struct FileInfoBlock *FIB = NULL; struct Lock *lock = NULL; int status; if (!(FIB = AllocMem((long)sizeof(struct FileInfoBlock), MEMF_CHIP|MEMF_CLEAR))) { return -ERROR_NO_FREE_STORE; } if (!(lock=Lock(name,SHARED_LOCK))) { status = -IoErr(); goto done; } if ((Examine(lock,FIB))==0){ status = -IoErr(); goto done; } status = (FIB->fib_DirEntryType > 0); done: if (FIB) FreeMem(FIB, (long) sizeof(struct FileInfoBlock)); UnLock(lock); return status; } /*---------------------------------------------------------------------*/ /* SetFileDate: datestamp the given file with the given date. */ /*---------------------------------------------------------------------*/ BOOL SetFileDate(name,date ) char *name; struct DateStamp *date; { struct MsgPort *task; /* for process id handler */ ULONG arg[4]; /* array of arguments */ int nameleng; char *bstr, *strcpy(); /* of file to be set */ long rc; char *strchr(); int strlen(); rc = 0; nameleng = strlen(name); if (!(bstr = (char *)AllocMem((long) (nameleng + 2),MEMF_PUBLIC))) goto exit2; if (!(task = (struct MsgPort *)DeviceProc(name ))) goto exit1; /* Dos Packet needs the filename in Bstring format */ (void) strcpy(bstr+1, name ); *bstr = nameleng; arg[0]= (ULONG)NULL; arg[1]= (ULONG)IoErr(); /* lock on parent director set by DeviceProc() */ arg[2]= (ULONG)bstr >> 2; arg[3]= (ULONG)date; rc = sendpkt(task,ACTION_SETDATE_MODE,arg,4L ); exit1: if (bstr ) FreeMem((void *)bstr, (long) (nameleng + 2)); exit2: if (rc == DOSTRUE ) return TRUE; else return FALSE; } ***EOF FileMisc.c*** -- < Mark R. Rinfret, mrr@softie, ..rayssd!unisec!softie!mrr > < SofTech, Inc. Home: 401-846-7639 > < 1 Silva Lane, Work: 401-849-4174 > < Middletown, RI 02840 "The name has changed but I'm still guilty." >