Compare commits
12 Commits
stream_2_6
...
stream_2_6
Author | SHA1 | Date | |
---|---|---|---|
b721d26fb8 | |||
7530c7c67d | |||
824cd4d283 | |||
2e30e7aee6 | |||
3a5a3e22b9 | |||
51bd766ba6 | |||
0ab0d6db07 | |||
a12de614d6 | |||
240abd2788 | |||
e131fcb32f | |||
f88f594e87 | |||
56ef0651f2 |
BIN
doc/PSI.gif
BIN
doc/PSI.gif
Binary file not shown.
Before Width: | Height: | Size: 1.6 KiB |
BIN
doc/PSI.png
Normal file
BIN
doc/PSI.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: aai Records</h1>
|
||||
<h1>aai Records</h1>
|
||||
<p>
|
||||
<b>Note:</b> aai record support is disabled per default.
|
||||
Enable it in <code>src/CONFIG_STREAM</code>.
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: aao Records</h1>
|
||||
<h1>aao Records</h1>
|
||||
<p>
|
||||
<b>Note:</b> aao record support is disabled per default.
|
||||
Enable it in <code>src/CONFIG_STREAM</code>.
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: ai Records</h1>
|
||||
<h1>ai Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: ao Records</h1>
|
||||
<h1>ao Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: bi Records</h1>
|
||||
<h1>bi Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: bo Records</h1>
|
||||
<h1>bo Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: calcout Records</h1>
|
||||
<h1>calcout Records</h1>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Device support for calcout records is only available for
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Using EPICS 3.13</h1>
|
||||
<h1>Using EPICS 3.13</h1>
|
||||
|
||||
<a name="pre"></a>
|
||||
<h2>1. Prerequisites</h2>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Format Converter API</h1>
|
||||
<h1>Format Converter API</h1>
|
||||
|
||||
<a name="class"></a>
|
||||
<h2>Converter Class</h2>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Format Converters</h1>
|
||||
<h1>Format Converters</h1>
|
||||
|
||||
<a name="syntax"></a>
|
||||
<h2>1. Format Syntax</h2>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: longin Records</h1>
|
||||
<h1>longin Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: longout Records</h1>
|
||||
<h1>longout Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
35
doc/makepdf
Executable file
35
doc/makepdf
Executable file
@ -0,0 +1,35 @@
|
||||
PAGES="
|
||||
index.html
|
||||
setup.html
|
||||
epics3_13.html
|
||||
protocol.html
|
||||
formats.html
|
||||
processing.html
|
||||
recordtypes.html
|
||||
aai.html
|
||||
aao.html
|
||||
ai.html
|
||||
ao.html
|
||||
bi.html
|
||||
bo.html
|
||||
mbbi.html
|
||||
mbbo.html
|
||||
mbbiDirect.html
|
||||
mbboDirect.html
|
||||
stringin.html
|
||||
stringout.html
|
||||
longin.html
|
||||
longout.html
|
||||
waveform.html
|
||||
calcout.html
|
||||
scalcout.html
|
||||
tipsandtricks.html
|
||||
recordinterface.html
|
||||
businterface.html
|
||||
formatconverter.html
|
||||
osinterface.html
|
||||
"
|
||||
|
||||
rm -f stream.pdf
|
||||
wkhtmltopdf --print-media-type --dpi 1200 --zoom 0.85 --page-size Letter \
|
||||
$PAGES stream.pdf
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: mbbi Records</h1>
|
||||
<h1>mbbi Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: mbbiDirect Records</h1>
|
||||
<h1>mbbiDirect Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: mbbo Records</h1>
|
||||
<h1>mbbo Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: mbboDirect Records</h1>
|
||||
<h1>mbboDirect Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Operating System API</h1>
|
||||
<h1>Operating System API</h1>
|
||||
|
||||
<h2>Sorry, this documentation is still missing.</h2>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Record Processing</h1>
|
||||
<h1>Record Processing</h1>
|
||||
|
||||
<a name="proc"></a>
|
||||
<h2>1. Normal Processing</h2>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Protocol Files</h1>
|
||||
<h1>Protocol Files</h1>
|
||||
<a name="gen"></a>
|
||||
<h2>1. General Information</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Record API</h1>
|
||||
<h1>Record API</h1>
|
||||
|
||||
<h2>Sorry, this documentation is still missing.</h2>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Record Types</h1>
|
||||
<h1>Record Types</h1>
|
||||
|
||||
<h2>Supported Record Types</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: scalcout Records</h1>
|
||||
<h1>scalcout Records</h1>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> The scalcout record is part of the <i>calc</i> module of
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Setup</h1>
|
||||
<h1>Setup</h1>
|
||||
|
||||
<a name="pre"></a>
|
||||
<h2>1. Prerequisites</h2>
|
||||
|
@ -5,8 +5,9 @@ a:hover {color: #FF0000;}
|
||||
body {
|
||||
margin-right:1em;
|
||||
margin-left:15em;
|
||||
margin-top:11ex;
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
margin-top:70px;
|
||||
padding-top:1px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size:14px;
|
||||
background-color:#ffffff;
|
||||
}
|
||||
@ -30,26 +31,26 @@ dt {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size:225%;
|
||||
font-size:250%;
|
||||
margin-top:0;
|
||||
font-style:italic;
|
||||
font-family:serif;
|
||||
font-weight:bold;
|
||||
font-family:"Times New Roman", serif;
|
||||
text-align:center;
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
min-height:60px;
|
||||
height: 4ex;
|
||||
line-height:190%;
|
||||
background-color:white;
|
||||
border-top:6px solid #1b4486;
|
||||
border-bottom:4px solid #1b4486;
|
||||
border-width:0;
|
||||
border-bottom:3px solid #1b4486;
|
||||
white-space:nowrap;
|
||||
background-image:url(PSI.gif);
|
||||
background-image:url(PSI.png);
|
||||
background-repeat:no-repeat;
|
||||
background-position:10px 2px;
|
||||
text-shadow: .1em .1em .1em lightgray;
|
||||
background-position:10px 5px;
|
||||
text-shadow:.1em .1em .1em darkgray;
|
||||
box-shadow:0 .3em .1em -.2em darkgray;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@ -91,7 +92,7 @@ code {
|
||||
position:fixed;
|
||||
left:0;
|
||||
top:0;
|
||||
padding-top:9ex;
|
||||
padding-top:70px;
|
||||
width:14em;
|
||||
height:100%;
|
||||
border-style:solid;
|
||||
@ -115,13 +116,9 @@ a[target=ex]:hover:after {
|
||||
}
|
||||
|
||||
@media print {
|
||||
a:link {color: black; text-decoration:none;}
|
||||
a:visited {color: black; text-decoration:none;}
|
||||
a:hover {color: black; text-decoration:none;}
|
||||
a[target=ex] {text-decoration:underline;}
|
||||
a:link {text-decoration:none;}
|
||||
a[target=ex]:after {content:" [" attr(href) "]";}
|
||||
code {color: black; }
|
||||
body {margin-left:10px;}
|
||||
h1 {position:absolute;}
|
||||
body {margin:0 4em;}
|
||||
h1 {position:relative; background-position:0 0;}
|
||||
#navleft {display:none;}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: stringin Records</h1>
|
||||
<h1>stringin Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: stringout Records</h1>
|
||||
<h1>stringout Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: Tips and Tricks</h1>
|
||||
<h1>Tips and Tricks</h1>
|
||||
|
||||
<a name="argvar"></a>
|
||||
<h2>I have many almost identical protocols</h2>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="nav.html" id="navleft"></iframe>
|
||||
<h1>StreamDevice: waveform Records</h1>
|
||||
<h1>waveform Records</h1>
|
||||
|
||||
<h2>Normal Operation</h2>
|
||||
<p>
|
||||
|
@ -680,7 +680,7 @@ writeHandler()
|
||||
clientName());
|
||||
status = pasynOctet->read(pvtOctet, pasynUser,
|
||||
buffer, sizeof(buffer), &received, &eomReason);
|
||||
if (received == 0) break;
|
||||
if (status == asynError || received == 0) break;
|
||||
#ifndef NO_TEMPORARY
|
||||
if (received) debug("AsynDriverInterface::writeHandler(%s): flushing %ld bytes: \"%s\"\n",
|
||||
clientName(), (long)received, StreamBuffer(buffer, received).expand()());
|
||||
|
@ -763,8 +763,8 @@ printValue(const StreamFormat& fmt, long value)
|
||||
name(), value);
|
||||
return false;
|
||||
}
|
||||
debug("StreamCore::printValue(%s, long): \"%s\"\n",
|
||||
name(), outputLine.expand()());
|
||||
debug("StreamCore::printValue %s %%%c long %ld (%lx): \"%s\"\n",
|
||||
name(), fmt.conv, value, value, outputLine.expand()());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -785,8 +785,8 @@ printValue(const StreamFormat& fmt, double value)
|
||||
name(), value);
|
||||
return false;
|
||||
}
|
||||
debug("StreamCore::printValue(%s, double): \"%s\"\n",
|
||||
name(), outputLine.expand()());
|
||||
debug("StreamCore::printValue %s %%%c double %#g: \"%s\"\n",
|
||||
name(), fmt.conv, value, outputLine.expand()());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -808,8 +808,8 @@ printValue(const StreamFormat& fmt, char* value)
|
||||
name(), buffer.expand()());
|
||||
return false;
|
||||
}
|
||||
debug("StreamCore::printValue(%s, char*): \"%s\"\n",
|
||||
name(), outputLine.expand()());
|
||||
debug("StreamCore::printValue %s %%%c char* \"%s\"): \"%s\"\n",
|
||||
name(), fmt.conv, value, outputLine.expand()());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ epicsExportRegistrar(streamRegistrar);
|
||||
struct stream_drvsup {
|
||||
long number;
|
||||
long (*report)(int);
|
||||
DRVSUPFUN init;
|
||||
long (*init)();
|
||||
} stream = {
|
||||
2,
|
||||
Stream::report,
|
||||
@ -416,6 +416,7 @@ long streamInit(int after)
|
||||
long streamInitRecord(dbCommon* record, const struct link *ioLink,
|
||||
streamIoFunction readData, streamIoFunction writeData)
|
||||
{
|
||||
long status;
|
||||
char filename[80];
|
||||
char protocol[80];
|
||||
char busname[80];
|
||||
@ -441,13 +442,14 @@ long streamInitRecord(dbCommon* record, const struct link *ioLink,
|
||||
// scan the i/o link
|
||||
debug("streamInitRecord(%s): parse link \"%s\"\n",
|
||||
record->name, ioLink->value.instio.string);
|
||||
pstream->parseLink(ioLink, filename, protocol,
|
||||
status = pstream->parseLink(ioLink, filename, protocol,
|
||||
busname, &addr, busparam);
|
||||
// (re)initialize bus and protocol
|
||||
debug("streamInitRecord(%s): calling initRecord\n",
|
||||
record->name);
|
||||
long status = pstream->initRecord(filename, protocol,
|
||||
busname, addr, busparam);
|
||||
if (status == 0)
|
||||
status = pstream->initRecord(filename, protocol,
|
||||
busname, addr, busparam);
|
||||
if (status != OK && status != DO_NOT_CONVERT)
|
||||
{
|
||||
error("%s: Record initialization failed\n", record->name);
|
||||
@ -963,13 +965,13 @@ getFieldAddress(const char* fieldname, StreamBuffer& address)
|
||||
else
|
||||
{
|
||||
// FIELD in this record or VAL in other record
|
||||
char fullname[PVNAME_SZ + 1];
|
||||
sprintf(fullname, "%s.%s", name(), fieldname);
|
||||
if (dbNameToAddr(fullname, &dbaddr) != OK)
|
||||
StreamBuffer fullname;
|
||||
fullname.print("%s.%s", name(), fieldname);
|
||||
if (dbNameToAddr(fullname(), &dbaddr) != OK)
|
||||
{
|
||||
// VAL in other record
|
||||
sprintf(fullname, "%s.VAL", fieldname);
|
||||
if (dbNameToAddr(fullname, &dbaddr) != OK) return false;
|
||||
fullname.clear().print("%s.VAL", fieldname);
|
||||
if (dbNameToAddr(fullname(), &dbaddr) != OK) return false;
|
||||
}
|
||||
}
|
||||
address.append(&dbaddr, sizeof(dbaddr));
|
||||
@ -996,11 +998,8 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
// Format like "%([record.]field)..." has requested to get value
|
||||
// from field of this or other record.
|
||||
DBADDR* pdbaddr = (DBADDR*)fieldaddress;
|
||||
long i;
|
||||
long nelem = pdbaddr->no_elements;
|
||||
size_t size = nelem * typeSize[format.type];
|
||||
char* buffer = fieldBuffer.clear().reserve(size);
|
||||
|
||||
/* Handle time stamps special. %T converter takes double. */
|
||||
if (strcmp(((dbFldDes*)pdbaddr->pfldDes)->name, "TIME") == 0)
|
||||
{
|
||||
double time;
|
||||
@ -1016,6 +1015,8 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
/* if getting time from own record, update timestamp first */
|
||||
recGblGetTimeStamp(record);
|
||||
}
|
||||
/* convert EPICS epoch (1990) to unix epoch (1970) */
|
||||
/* we are losing about 3 digits precision here */
|
||||
time = pdbaddr->precord->time.secPastEpoch +
|
||||
631152000u + pdbaddr->precord->time.nsec * 1e-9;
|
||||
debug("Stream::formatValue(%s): read %f from TIME field\n",
|
||||
@ -1023,7 +1024,29 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
return printValue(format, time);
|
||||
}
|
||||
|
||||
if (dbGet(pdbaddr, dbfMapping[format.type], buffer,
|
||||
/* convert type to LONG, ENUM, DOUBLE, or STRING */
|
||||
int type = dbfMapping[format.type];
|
||||
long nelem = pdbaddr->no_elements;
|
||||
size_t size = nelem * typeSize[format.type];
|
||||
|
||||
/* print (U)CHAR arrays as string */
|
||||
if (format.type == string_format &&
|
||||
(pdbaddr->field_type == DBF_CHAR || pdbaddr->field_type == DBF_UCHAR))
|
||||
{
|
||||
debug("Stream::formatValue(%s): format %s.%s array[%ld] size %d of %s as string\n",
|
||||
name(),
|
||||
pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
nelem,
|
||||
pdbaddr->field_size,
|
||||
pamapdbfType[pdbaddr->field_type].strvalue);
|
||||
type = DBF_CHAR;
|
||||
size = nelem;
|
||||
}
|
||||
|
||||
char* buffer = fieldBuffer.clear().reserve(size);
|
||||
|
||||
if (dbGet(pdbaddr, type, buffer,
|
||||
NULL, &nelem, NULL) != 0)
|
||||
{
|
||||
error("%s: dbGet(%s.%s, %s) failed\n",
|
||||
@ -1033,6 +1056,18 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
pamapdbfType[dbfMapping[format.type]].strvalue);
|
||||
return false;
|
||||
}
|
||||
debug("Stream::formatValue(%s): got %ld elements\n",
|
||||
name(),nelem);
|
||||
|
||||
/* terminate CHAR array as string */
|
||||
if (type == DBF_CHAR)
|
||||
{
|
||||
if (nelem >= pdbaddr->no_elements) nelem = pdbaddr->no_elements-1;
|
||||
buffer[nelem] = 0;
|
||||
nelem = 1; /* array is only 1 string */
|
||||
}
|
||||
|
||||
long i;
|
||||
for (i = 0; i < nelem; i++)
|
||||
{
|
||||
switch (format.type)
|
||||
@ -1060,6 +1095,7 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
error("%s: %%(FIELD) syntax not allowed "
|
||||
"with pseudo formats\n",
|
||||
name());
|
||||
return false;
|
||||
default:
|
||||
error("INTERNAL ERROR %s: Illegal format.type=%d\n",
|
||||
name(), format.type);
|
||||
|
@ -26,6 +26,24 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* timezone in UNIX contains the seconds between UTC and local time,
|
||||
but not in Free-BSD! Here timezone() is a function delivering
|
||||
the time zone abbreviation (e.g. CET). Alternatively, the timezone
|
||||
value can also be gained from tm_gmtoff of the tm-structure.
|
||||
HJK, 4.4.14 */
|
||||
/* The same seems to be true for other BSDs. DZ. */
|
||||
|
||||
#if defined(__FreeBSD__) || \
|
||||
defined(__NetBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__bsdi__ ) || \
|
||||
defined(__DragonFly__)
|
||||
static int timezone_bsd=0;
|
||||
#define timezone timezone_bsd
|
||||
#define tzset() { struct tm tm; time_t timet; tzset(); time(&timet); \
|
||||
localtime_r(&timet, &tm); timezone=tm.tm_gmtoff; }
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define tzset() _tzset()
|
||||
#define timezone _timezone
|
||||
@ -46,6 +64,13 @@ int timezone = 0;
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
/* MinGW has no re-entrant localtime. How about other environments? */
|
||||
/* Just let's hope for the best */
|
||||
#undef localtime_r
|
||||
#define localtime_r(timet,tm) (*(tm)=*localtime(timet))
|
||||
#endif
|
||||
|
||||
class TimestampConverter : public StreamFormatConverter
|
||||
{
|
||||
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||
@ -366,7 +391,7 @@ startover:
|
||||
debug ("TimestampConverter::scantime: %s hour = %d\n", pm?"PM":"AM", tm->tm_hour);
|
||||
break;
|
||||
case 'M': /* minute */
|
||||
i = nummatch(input, 1, 59);
|
||||
i = nummatch(input, 0, 59);
|
||||
if (i < 0)
|
||||
{
|
||||
error ("error parsing minute: '%.20s'\n", input);
|
||||
@ -376,7 +401,7 @@ startover:
|
||||
debug ("TimestampConverter::scantime: min = %d\n", tm->tm_min);
|
||||
break;
|
||||
case 'S': /* second */
|
||||
i = nummatch(input, 1, 60);
|
||||
i = nummatch(input, 0, 60);
|
||||
if (i < 0)
|
||||
{
|
||||
error ("error parsing week second: '%.20s'\n", input);
|
||||
|
Reference in New Issue
Block a user