There is a problem restoring long strings of length 0 in EPICS base 7. It was restoring the string "0" rather than a 0 length string.
@MarkRivers said:
The message in SR_get_array is printed here:
status = dbGet(paddr, request_field_type, pArray, NULL, pnum_elements, NULL);
if (save_restoreDebug >= 10) {
errlogPrintf("dbrestore:SR_get_array: '%s' currently has %ld elements\n", PVname, *pnum_elements);
}
So it seems clear what the problem is. In 3.15.5 dbGet() is returning
120 (the maximum string size) while 7.0.1 is returning the actual
string size including the terminating 0 byte.
This seems like a major difference.
@anjohnson replied:
First, note that all the PV names being printed by your debug messages end with $ so they are being requested as an array of chars, not as a DBF_STRING (which is correct, the latter would truncate the value at 40 characters). The IOC code that handles long strings has been improved several times since that functionality was originally added.
When you ask dbGet() for an array, it tells you how many elements it wrote to your buffer in *pnum_elements (on input this holds the maximum number the buffer can accept). In Base-3.15.5 and earlier for long-strings that are accessed as arrays we just returned the length of the whole buffer, but I added this optimization towards the end of dbGet() in April so it will be in Base-3.15.6 and new 7.0 releases:
if(!status && dbrType==DBF_CHAR && nRequest &&
paddr->pfldDes && paddr->pfldDes->field_type==DBF_STRING)
{
/* long string ensure nil and truncate to actual length */
long nReq = *nRequest;
pbuf[nReq-1] = '\0';
*nRequest = strlen(pbuf)+1;
}
The write_it() code you quoted earlier is seeing the single element reported for an empty string as being a scalar integer with value 0, instead of first checking the long string flag and handling that
appropriately:
errno = 0;
if (pchannel->curr_elements <= 1) {
/* treat as scalar */
if (pchannel->enum_val >= 0) {
n = fprintf(out_fd, "%d\n",pchannel->enum_val);
} else {
n = fprintf(out_fd, "%-s\n", pchannel->value);
}
} else if (is_long_string) {
/* write first BUF-SIZE-1 characters of long string, so dbrestore doesn't choke. */
I think it just needs to do the if (is_long_string) check first, so this might be a relatively simple fix.
There is a problem restoring long strings of length 0 in EPICS base 7. It was restoring the string "0" rather than a 0 length string.
@MarkRivers said:
@anjohnson replied: