fix several signed/unsigned problems

This commit is contained in:
2018-08-06 10:28:22 +02:00
parent 9891a75bcd
commit 03d6d9672e
6 changed files with 54 additions and 37 deletions

View File

@ -23,26 +23,23 @@ written or read value.
<dd>
Not allowed.
</dd>
<dt>LONG format (e.g. <code>%i</code>):</dt>
<dt>LONG or ENUM format (e.g. <code>%i</code>):</dt>
<dd>
<dl>
<dt>If <code>MASK==0</code> (because <code>NOBT</code> is not set):</dt>
<dd>
<u>Output:</u> <code><i>x</i>=VAL</code><br>
<u>Input:</u> <code>VAL=<i>x</i></code><br>
<u>Output:</u> <code><i>x</i>=RVAL</code><br>
<u>Input:</u> <code>RAL=<i>x</i></code>, <code>VAL=RVAL&gt;&gt;SHFT</code><br>
</dd>
<dt>If <code>MASK!=0</code>:</dt>
<dd>
<u>Output:</u> <code><i>x</i>=RVAL&amp;MASK</code><br>
<u>Input:</u> <code>RBV=RVAL=<i>x</i>&amp;MASK</code><br>
<u>Input:</u> <code>RBV=RVAL=<i>x</i>&amp;MASK</code>, <code>VAL=RVAL&gt;&gt;SHFT</code><br>
</dd>
</dl>
<code>MASK</code> is initialized to <code>NOBT</code> 1-bits shifted
left by <code>SHFT</code>.
</dd>
<dt>ENUM format (e.g. <code>%{</code>):</dt>
<dd>
Not allowed.
left by <code>SHFT</code> (<code>((2^NOBT)-1)&lt;&lt;SHFT</code>).
The record calculates <code>RVAL=VAL&lt;&lt;SHFT</code>.
</dd>
<dt>STRING format (e.g. <code>%s</code>):</dt>
<dd>

View File

@ -34,7 +34,7 @@ int RawConverter::
parse(const StreamFormat& fmt, StreamBuffer&,
const char*&, bool)
{
return (fmt.flags & (sign_flag|zero_flag)) ? signed_format : unsigned_format;
return (fmt.flags & zero_flag) ? unsigned_format : signed_format;
}
bool RawConverter::
@ -112,7 +112,7 @@ scanLong(const StreamFormat& fmt, const char* input, long& value)
unsigned int shift = 0;
while (--width && shift < sizeof(long)*8)
{
val |= ((unsigned char)input[consumed++]) << shift;
val |= (unsigned long)((unsigned char)input[consumed++]) << shift;
shift += 8;
}
if (width == 0)
@ -120,12 +120,12 @@ scanLong(const StreamFormat& fmt, const char* input, long& value)
if (fmt.flags & zero_flag)
{
// fill with zero
val |= ((unsigned char)input[consumed++]) << shift;
val |= (unsigned long)((unsigned char)input[consumed++]) << shift;
}
else
{
// fill with sign
val |= ((signed char)input[consumed++]) << shift;
val |= ((long)(signed char)input[consumed++]) << shift;
}
}
consumed += width; // ignore upper bytes not fitting in long

View File

@ -92,25 +92,26 @@ static long readData(dbCommon *record, format_t *format)
static long writeData(dbCommon *record, format_t *format)
{
boRecord *bo = (boRecord *)record;
long val;
switch (format->type)
{
case DBF_ULONG:
val = bo->rval;
break;
case DBF_LONG:
{
return streamPrintf(record, format, bo->rval);
}
val = bo->mask ? (epicsInt32)bo->rval : (epicsInt16)bo->val;
break;
case DBF_ENUM:
{
return streamPrintf(record, format, (long)bo->val);
}
val = bo->val;
break;
case DBF_STRING:
{
return streamPrintf(record, format,
bo->val ? bo->onam : bo->znam);
}
default:
return ERROR;
}
return ERROR;
return streamPrintf(record, format, val);
}
static long initRecord(dbCommon *record)

View File

@ -71,7 +71,7 @@ static long writeData(dbCommon *record, format_t *format)
{
case DBF_ULONG:
case DBF_ENUM:
return streamPrintf(record, format, (unsigned long)lo->val);
return streamPrintf(record, format, lo->val);
case DBF_LONG:
return streamPrintf(record, format, (long)lo->val);
}

View File

@ -36,12 +36,11 @@ static long readData(dbCommon *record, format_t *format)
if (format->type != DBF_ULONG && format->type != DBF_LONG)
return ERROR;
if (streamScanf(record, format, &val) == ERROR) return ERROR;
if (mbboD->mask)
val &= mbboD->mask;
if (mbboD->mask) val &= mbboD->mask;
mbboD->rbv = val;
mbboD->rval = val;
if (mbboD->shft > 0) val >>= mbboD->shft;
val >>= mbboD->shft;
mbboD->val = val; /* no cast because we cannot be sure about type of VAL */
if (record->pact) return DO_NOT_CONVERT;
@ -87,19 +86,26 @@ static long writeData(dbCommon *record, format_t *format)
mbboDirectRecord *mbboD = (mbboDirectRecord *)record;
long val;
if (format->type == DBF_ULONG || format->type == DBF_LONG)
switch (format->type)
{
if (mbboD->mask) val = mbboD->rval & mbboD->mask;
else val = mbboD->val;
return streamPrintf(record, format, val);
case DBF_ULONG:
case DBF_ENUM:
val = mbboD->rval;
if (mbboD->mask) val &= mbboD->mask;
break;
case DBF_LONG:
val = (epicsInt32)mbboD->rval;
if (mbboD->mask) val &= (epicsInt32)mbboD->mask;
break;
default:
return ERROR;
}
return ERROR;
return streamPrintf(record, format, val);
}
static long initRecord(dbCommon *record)
{
mbboDirectRecord *mbboD = (mbboDirectRecord *)record;
mbboD->mask <<= mbboD->shft;
/* Workaround for bug in mbboDirect record:

View File

@ -107,14 +107,12 @@ static long readData(dbCommon *record, format_t *format)
static long writeData(dbCommon *record, format_t *format)
{
mbboRecord *mbbo = (mbboRecord *)record;
unsigned long val;
long val;
int i;
switch (format->type)
{
case DBF_ULONG:
case DBF_LONG:
{
/* print VAL or RVAL ? */
val = mbbo->val;
if (mbbo->sdef) for (i=0; i<16; i++)
@ -128,10 +126,25 @@ static long writeData(dbCommon *record, format_t *format)
}
}
return streamPrintf(record, format, val);
case DBF_LONG:
{
/* print VAL or RVAL ? */
val = (epicsInt16)mbbo->val;
if (mbbo->sdef) for (i=0; i<16; i++)
{
if ((&mbbo->zrvl)[i])
{
/* any values defined ? */
val = (epicsInt32)mbbo->rval;
if (mbbo->mask) val &= mbbo->mask;
break;
}
}
return streamPrintf(record, format, val);
}
case DBF_ENUM:
{
return streamPrintf(record, format, (long)mbbo->val);
return streamPrintf(record, format, mbbo->val);
}
case DBF_STRING:
{