From d3b6d018079e07b18a83576ef8d65bbc211a9913 Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Wed, 17 Jul 2013 15:55:49 -0500 Subject: [PATCH 01/38] Added WIN32 system library for epicsSockResolveTest --- src/libCom/test/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile index ef89f3875..0d6ab1487 100644 --- a/src/libCom/test/Makefile +++ b/src/libCom/test/Makefile @@ -50,6 +50,7 @@ TESTS += epicsStdioTest TESTPROD_HOST += epicsSockResolveTest epicsSockResolveTest_SRCS += epicsSockResolveTest.c testHarness_SRCS += epicsSockResolveTest.c +epicsSockResolveTest_SYS_LIBS_WIN32 = ws2_32 TESTS += epicsSockResolveTest TESTPROD_HOST += epicsStringTest From 515f882c7ba674c6094ce4f01bec0229f8e67be6 Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Thu, 25 Jul 2013 10:49:26 -0500 Subject: [PATCH 02/38] Added OPT_CXXFLAGS_YES += -g --- configure/os/CONFIG_SITE.Common.linux-x86 | 1 + configure/os/CONFIG_SITE.Common.linux-x86_64 | 1 + 2 files changed, 2 insertions(+) diff --git a/configure/os/CONFIG_SITE.Common.linux-x86 b/configure/os/CONFIG_SITE.Common.linux-x86 index 1be38cb78..9e7262cce 100644 --- a/configure/os/CONFIG_SITE.Common.linux-x86 +++ b/configure/os/CONFIG_SITE.Common.linux-x86 @@ -38,3 +38,4 @@ COMMANDLINE_LIBRARY = READLINE # This does cost disk space, but not memory as debug symbols are not # loaded into RAM when the binary is loaded. OPT_CFLAGS_YES += -g +OPT_CXXFLAGS_YES += -g diff --git a/configure/os/CONFIG_SITE.Common.linux-x86_64 b/configure/os/CONFIG_SITE.Common.linux-x86_64 index e48241ab0..ddc90d570 100644 --- a/configure/os/CONFIG_SITE.Common.linux-x86_64 +++ b/configure/os/CONFIG_SITE.Common.linux-x86_64 @@ -38,3 +38,4 @@ COMMANDLINE_LIBRARY = READLINE # This does cost disk space, but not memory as debug symbols are not # loaded into RAM when the binary is loaded. OPT_CFLAGS_YES += -g +OPT_CXXFLAGS_YES += -g From ffa96d36e15f770ee2686cf3230daca64c60bc78 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 1 Aug 2013 18:10:18 -0500 Subject: [PATCH 03/38] db: dbpf can now put strings to UCHAR arrays Also improved the dbpf error message on value conversion failures. Source code reformatting inside dbTest.c as well. --- src/db/dbTest.c | 604 ++++++++++++++++++++++++++++-------------------- 1 file changed, 357 insertions(+), 247 deletions(-) diff --git a/src/db/dbTest.c b/src/db/dbTest.c index 84cc23e48..2c9350d6f 100644 --- a/src/db/dbTest.c +++ b/src/db/dbTest.c @@ -8,7 +8,7 @@ \*************************************************************************/ /* $Revision-Id$ */ -/* database access test subroutines */ +/* database access test subroutines */ #include #include @@ -44,7 +44,7 @@ #include "dbTest.h" #define MAXLINE 80 -struct msgBuff { /* line output structure */ +struct msgBuff { /* line output structure */ char out_buff[MAXLINE + 1]; char *pNext; char *pLast; @@ -63,25 +63,26 @@ typedef struct msgBuff TAB_BUFFER; /* Local Routines */ static long nameToAddr(const char *pname, DBADDR *paddr); static void printDbAddr(DBADDR *paddr); -static void printBuffer( - long status,short dbr_type,void *pbuffer,long reqOptions, - long retOptions,long no_elements,TAB_BUFFER *pMsgBuff,int tab_size); -static int dbpr_report( - const char *pname,DBADDR *paddr,int interest_level, - TAB_BUFFER *pMsgBuff,int tab_size); +static void printBuffer(long status, short dbr_type, void *pbuffer, + long reqOptions, long retOptions, long no_elements, + TAB_BUFFER *pMsgBuff, int tab_size); +static int dbpr_report(const char *pname, DBADDR *paddr, int interest_level, + TAB_BUFFER *pMsgBuff, int tab_size); static void dbpr_msgOut(TAB_BUFFER *pMsgBuff,int tab_size); static void dbpr_init_msg(TAB_BUFFER *pMsgBuff,int tab_size); static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,int len,int tab_size); static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size); -static char *dbf[DBF_NTYPES]={ - "STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG", - "FLOAT","DOUBLE","ENUM","MENU","DEVICE", - "INLINK","OUTLINK","FWDLINK","NOACCESS"}; +static char *dbf[DBF_NTYPES] = { + "STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG", + "FLOAT","DOUBLE","ENUM","MENU","DEVICE", + "INLINK","OUTLINK","FWDLINK","NOACCESS" +}; -static char *dbr[DBR_ENUM+2]={ - "STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG", - "FLOAT","DOUBLE","ENUM","NOACCESS"}; +static char *dbr[DBR_ENUM+2] = { + "STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG", + "FLOAT","DOUBLE","ENUM","NOACCESS" +}; long epicsShareAPI dba(const char*pname) { @@ -91,7 +92,10 @@ long epicsShareAPI dba(const char*pname) printf("Usage: dba \"pv name\"\n"); return 1; } - if (nameToAddr(pname, &addr)) return -1; + + if (nameToAddr(pname, &addr)) + return -1; + printDbAddr(&addr); return 0; } @@ -110,6 +114,7 @@ long epicsShareAPI dbl(const char *precordTypename, const char *fields) printf("No database loaded\n"); return 0; } + if (precordTypename && ((*precordTypename == '\0') || !strcmp(precordTypename,"*"))) precordTypename = NULL; @@ -144,6 +149,7 @@ long epicsShareAPI dbl(const char *precordTypename, const char *fields) if (status) { printf("No record type\n"); } + while (!status) { status = dbFirstRecord(pdbentry); while (!status) { @@ -154,11 +160,13 @@ long epicsShareAPI dbl(const char *precordTypename, const char *fields) if (status) { if (!strcmp(papfields[ifield], "recordType")) { pvalue = dbGetRecordTypeName(pdbentry); - } else { - printf(", "); + } + else { + printf(", "); continue; } - } else { + } + else { pvalue = dbGetString(pdbentry); } printf(", \"%s\"", pvalue ? pvalue : ""); @@ -166,7 +174,9 @@ long epicsShareAPI dbl(const char *precordTypename, const char *fields) printf("\n"); status = dbNextRecord(pdbentry); } - if (precordTypename) break; + if (precordTypename) + break; + status = dbNextRecordType(pdbentry); } if (nfields > 0) { @@ -191,12 +201,14 @@ long epicsShareAPI dbnr(int verbose) printf("No database loaded\n"); return 0; } + dbInitEntry(pdbbase, pdbentry); status = dbFirstRecordType(pdbentry); if (status) { printf("No record types loaded\n"); return 0; } + printf("Records Aliases Record Type\n"); while (!status) { naliases = dbGetNAliases(pdbentry); @@ -208,6 +220,7 @@ long epicsShareAPI dbnr(int verbose) nrecords, naliases, dbGetRecordTypeName(pdbentry)); status = dbNextRecordType(pdbentry); } + dbFinishEntry(pdbentry); printf("Total %d records, %d aliases\n", trecords, taliases); return 0; @@ -223,6 +236,7 @@ long epicsShareAPI dbla(const char *pmask) printf("No database loaded\n"); return 0; } + dbInitEntry(pdbbase, pdbentry); status = dbFirstRecordType(pdbentry); while (!status) { @@ -230,14 +244,18 @@ long epicsShareAPI dbla(const char *pmask) status = dbNextRecord(pdbentry)) { char *palias; - if (!dbIsAlias(pdbentry)) continue; + if (!dbIsAlias(pdbentry)) + continue; + palias = dbGetRecordName(pdbentry); - if (pmask && *pmask && !epicsStrGlobMatch(palias, pmask)) continue; + if (pmask && *pmask && !epicsStrGlobMatch(palias, pmask)) + continue; dbFindField(pdbentry, "NAME"); printf("%s -> %s\n", palias, dbGetString(pdbentry)); } status = dbNextRecordType(pdbentry); } + dbFinishEntry(pdbentry); return 0; } @@ -252,21 +270,25 @@ long epicsShareAPI dbgrep(const char *pmask) printf("Usage: dbgrep \"pattern\"\n"); return 1; } + if (!pdbbase) { printf("No database loaded\n"); return 0; } + dbInitEntry(pdbbase, pdbentry); status = dbFirstRecordType(pdbentry); while (!status) { status = dbFirstRecord(pdbentry); while (!status) { char *pname = dbGetRecordName(pdbentry); - if (epicsStrGlobMatch(pname, pmask)) puts(pname); + if (epicsStrGlobMatch(pname, pmask)) + puts(pname); status = dbNextRecord(pdbentry); } status = dbNextRecordType(pdbentry); } + dbFinishEntry(pdbentry); return 0; } @@ -277,64 +299,84 @@ long epicsShareAPI dbgf(const char *pname) long buffer[100]; long *pbuffer=&buffer[0]; DBADDR addr; - long status; long options = 0; long no_elements; static TAB_BUFFER msg_Buff; - int tab_size = 10; if (!pname || !*pname) { printf("Usage: dbgf \"pv name\"\n"); return 1; } - if (nameToAddr(pname, &addr)) return -1; + + if (nameToAddr(pname, &addr)) + return -1; + no_elements = MIN(addr.no_elements, sizeof(buffer)/addr.field_size); if (addr.dbr_field_type == DBR_ENUM) { - status = dbGetField(&addr, DBR_STRING, pbuffer, + long status = dbGetField(&addr, DBR_STRING, pbuffer, &options, &no_elements, NULL); + printBuffer(status, DBR_STRING, pbuffer, 0L, 0L, - no_elements, &msg_Buff, tab_size); - } else { - status = dbGetField(&addr, addr.dbr_field_type, pbuffer, - &options, &no_elements, NULL); - printBuffer(status, addr.dbr_field_type, pbuffer, 0L, 0L, - no_elements, &msg_Buff, tab_size); + no_elements, &msg_Buff, 10); } + else { + long status = dbGetField(&addr, addr.dbr_field_type, pbuffer, + &options, &no_elements, NULL); + + printBuffer(status, addr.dbr_field_type, pbuffer, 0L, 0L, + no_elements, &msg_Buff, 10); + } + msg_Buff.message[0] = '\0'; - dbpr_msgOut(&msg_Buff, tab_size); + dbpr_msgOut(&msg_Buff, 10); return 0; } long epicsShareAPI dbpf(const char *pname,const char *pvalue) { DBADDR addr; - long status = 0; + long status; + epicsUInt16 value; + short dbrType; + long n = 1; if (!pname || !*pname || !pvalue) { printf("Usage: dbpf \"pv name\", \"value\"\n"); return 1; } - if (nameToAddr(pname, &addr)) return -1; - /* For enumerated types must allow for ENUM rather than string*/ - /* If entire field is digits then use DBR_ENUM else DBR_STRING*/ + + if (nameToAddr(pname, &addr)) + return -1; + + /* For enumerated types must allow for ENUM rather than string */ + /* If entire field is digits then use DBR_ENUM else DBR_STRING */ if (addr.dbr_field_type == DBR_ENUM && *pvalue && strspn(pvalue,"0123456789") == strlen(pvalue)) { - unsigned short value; sscanf(pvalue, "%hu", &value); - status = dbPutField(&addr, DBR_ENUM, &value, 1L); - } else if (addr.dbr_field_type == DBR_CHAR && - addr.no_elements > 1) { - status = dbPutField(&addr, DBR_CHAR, pvalue, strlen(pvalue) + 1); - } else { - status = dbPutField(&addr, DBR_STRING, pvalue, 1L); + pvalue = (char *) &value; + dbrType = DBR_ENUM; } + else if (addr.no_elements > 1 && + (addr.dbr_field_type == DBR_CHAR || addr.dbr_field_type == DBR_UCHAR)) { + dbrType = addr.dbr_field_type; + n = strlen(pvalue) + 1; + } + else { + dbrType = DBR_STRING; + } + + status = dbPutField(&addr, dbrType, pvalue, n); if (status) { - errMessage(status,"- dbPutField error\n"); - return status; + if (status == -1) + printf("dbpf: Value conversion from %s to %s failed\n", + dbr[dbrType], dbf[addr.field_type]); + else + errMessage(status,"- dbPutField error\n"); + return status; } - status = dbgf(pname); - return status; + + return dbgf(pname); } long epicsShareAPI dbpr(const char *pname,int interest_level) @@ -349,11 +391,15 @@ long epicsShareAPI dbpr(const char *pname,int interest_level) printf("Usage: dbpr \"pv name\", level\n"); return 1; } - if (nameToAddr(pname, &addr)) return -1; + + if (nameToAddr(pname, &addr)) + return -1; + pmsg = pMsgBuff->message; if (dbpr_report(pname, &addr, interest_level, pMsgBuff, tab_size)) return 1; + pmsg[0] = '\0'; dbpr_msgOut(pMsgBuff, tab_size); return 0; @@ -369,17 +415,23 @@ long epicsShareAPI dbtr(const char *pname) printf("Usage: dbtr \"pv name\"\n"); return 1; } - if (nameToAddr(pname, &addr)) return -1; + + if (nameToAddr(pname, &addr)) + return -1; + precord = (struct dbCommon*)addr.precord; if (precord->pact) { printf("record active\n"); return 1; } + dbScanLock(precord); status = dbProcess(precord); dbScanUnlock(precord); + if (status) recGblRecordError(status, precord, "dbtr(dbProcess)"); + dbpr(pname, 3); return 0; } @@ -402,7 +454,9 @@ long epicsShareAPI dbtgf(const char *pname) printf("Usage: dbtgf \"pv name\"\n"); return 1; } - if (nameToAddr(pname, &addr)) return -1; + + if (nameToAddr(pname, &addr)) + return -1; /* try all options first */ req_options = 0xffffffff; @@ -486,12 +540,6 @@ long epicsShareAPI dbtpf(const char *pname, const char *pvalue) int validULong; int valid = 1; int put_type; - epicsInt8 val_i8; - epicsUInt8 val_u8; - epicsInt16 val_i16; - epicsUInt16 val_u16; - epicsInt32 val_i32; - epicsUInt32 val_u32; epicsFloat32 fvalue; epicsFloat64 dvalue; static TAB_BUFFER msg_Buff; @@ -503,7 +551,9 @@ long epicsShareAPI dbtpf(const char *pname, const char *pvalue) printf("Usage: dbtpf \"pv name\", \"value\"\n"); return 1; } - if (nameToAddr(pname, &addr)) return -1; + + if (nameToAddr(pname, &addr)) + return -1; val_long = strtol(pvalue, &pend, 10); validLong = (*pend == 0); @@ -518,37 +568,37 @@ long epicsShareAPI dbtpf(const char *pname, const char *pvalue) break; case DBR_CHAR: if ((valid = validLong)) { - val_i8 = (epicsInt8)val_long; + epicsInt8 val_i8 = (epicsInt8)val_long; status = dbPutField(&addr, put_type, &val_i8, 1L); } break; case DBR_UCHAR: if ((valid = validULong)) { - val_u8 = (epicsUInt8)val_ulong; + epicsUInt8 val_u8 = (epicsUInt8)val_ulong; status = dbPutField(&addr, put_type, &val_u8, 1L); } break; case DBR_SHORT: if ((valid = validLong)) { - val_i16 = val_long; + epicsInt16 val_i16 = val_long; status = dbPutField(&addr, put_type, &val_i16,1L); } break; case DBR_USHORT: if ((valid = validULong)) { - val_u16 = val_ulong; + epicsUInt16 val_u16 = val_ulong; status = dbPutField(&addr, put_type, &val_u16, 1L); } break; case DBR_LONG: if ((valid = validLong)) { - val_i32 = val_long; + epicsInt32 val_i32 = val_long; status = dbPutField(&addr, put_type,&val_i32,1L); } break; case DBR_ULONG: if ((valid = validULong)) { - val_u32 = val_ulong; + epicsUInt32 val_u32 = val_ulong; status = dbPutField(&addr, put_type, &val_u32, 1L); } break; @@ -562,8 +612,8 @@ long epicsShareAPI dbtpf(const char *pname, const char *pvalue) break; case DBR_ENUM: if ((valid = validULong)) { - val_u16 = val_ulong; - status = dbPutField(&addr, put_type, &val_u16, 1L); + epicsEnum16 val_e16 = val_ulong; + status = dbPutField(&addr, put_type, &val_e16, 1L); } break; } @@ -590,51 +640,65 @@ long epicsShareAPI dbtpf(const char *pname, const char *pvalue) long epicsShareAPI dbior(const char *pdrvName,int interest_level) { - char *pname; - drvSup *pdrvSup; + drvSup *pdrvSup; struct drvet *pdrvet; dbRecordType *pdbRecordType; - devSup *pdevSup; - struct dset *pdset; if (!pdbbase) { printf("No database loaded\n"); return 0; } + if (pdrvName && ((*pdrvName == '\0') || !strcmp(pdrvName,"*"))) pdrvName = NULL; + for (pdrvSup = (drvSup *)ellFirst(&pdbbase->drvList); pdrvSup; pdrvSup = (drvSup *)ellNext(&pdrvSup->node)) { - pname = pdrvSup->name; - if(pdrvName!=NULL && *pdrvName!='\0' && (strcmp(pdrvName,pname)!=0)) continue; - pdrvet = pdrvSup->pdrvet ; - if(pdrvet==NULL) { - printf("No driver entry table is present for %s\n",pname); - continue; - } - if(pdrvet->report==NULL) - printf("Driver: %s No report available\n",pname); - else { - printf("Driver: %s\n",pname); - (*pdrvet->report)(interest_level); - } + const char *pname = pdrvSup->name; + + if (pdrvName!=NULL && *pdrvName!='\0' && + (strcmp(pdrvName,pname)!=0)) + continue; + + pdrvet = pdrvSup->pdrvet ; + if (pdrvet == NULL) { + printf("No driver entry table is present for %s\n", pname); + continue; + } + + if (pdrvet->report == NULL) + printf("Driver: %s No report available\n", pname); + else { + printf("Driver: %s\n", pname); + pdrvet->report(interest_level); + } } + /* now check devSup reports */ for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); pdbRecordType; pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { + devSup *pdevSup; + for (pdevSup = (devSup *)ellFirst(&pdbRecordType->devList); pdevSup; pdevSup = (devSup *)ellNext(&pdevSup->node)) { - if(!(pdset = pdevSup->pdset)) continue; - if(!(pname = pdevSup->name)) continue; - if(pdrvName!=NULL && *pdrvName!='\0' && (strcmp(pdrvName,pname)!=0)) continue; - if(pdset->report!=NULL) { - printf("Device Support: %s\n",pname); - (*pdset->report)(interest_level); - } - } + struct dset *pdset = pdevSup->pdset; + const char *pname = pdevSup->name; + + if (!pdset || !pname) + continue; + + if (pdrvName != NULL && *pdrvName != '\0' && + (strcmp(pdrvName, pname) != 0)) + continue; + + if (pdset->report != NULL) { + printf("Device Support: %s\n", pname); + pdset->report(interest_level); + } + } } return 0; } @@ -645,6 +709,7 @@ int epicsShareAPI dbhcr(void) printf("No database loaded\n"); return 0; } + dbReportDeviceConfig(pdbbase, stdout); return 0; } @@ -652,39 +717,35 @@ int epicsShareAPI dbhcr(void) static long nameToAddr(const char *pname, DBADDR *paddr) { long status = dbNameToAddr(pname, paddr); + if (status) { - printf("Record '%s' not found\n", pname); + printf("PV '%s' not found\n", pname); } return status; } static void printDbAddr(DBADDR *paddr) { - short field_type; - short dbr_field_type; - dbFldDes *pdbFldDes = paddr->pfldDes; + dbFldDes *pdbFldDes = paddr->pfldDes; + short field_type = paddr->field_type; + short dbr_field_type = paddr->dbr_field_type; - printf("Record Address: %p",(void *)paddr->precord); - printf(" Field Address: %p",paddr->pfield); - printf(" Field Description: %p\n",(void *)pdbFldDes); - printf(" No Elements: %ld\n",paddr->no_elements); - printf(" Record Type: %s\n",pdbFldDes->pdbRecordType->name); - printf(" FieldType: DBF_"); - field_type = paddr->field_type; - if(field_type<0 || field_type>DBR_NOACCESS) - printf(" Illegal = %d\n",field_type); - else - printf("%s\n",dbf[field_type]); - printf(" Field Type: %d\n",paddr->field_type); - printf(" Field Size: %d\n",paddr->field_size); - printf(" Special: %d\n",paddr->special); - printf("DBR Field Type: DBR_"); - dbr_field_type = paddr->dbr_field_type; - if(dbr_field_type==DBR_NOACCESS)dbr_field_type=DBR_ENUM + 1; - if(dbr_field_type<0 || dbr_field_type>(DBR_ENUM+1)) - printf(" Illegal = %d\n",dbr_field_type); - else - printf("%s\n",dbr[dbr_field_type]); + printf("Record Address: %p", paddr->precord); + printf(" Field Address: %p", paddr->pfield); + printf(" Field Description: %p\n", pdbFldDes); + printf(" No Elements: %ld\n", paddr->no_elements); + printf(" Record Type: %s\n", pdbFldDes->pdbRecordType->name); + printf(" Field Type: %d = DBF_%s\n", field_type, + (field_type < 0 || field_type > DBR_NOACCESS) ? "????" : + dbf[field_type]); + printf(" Field Size: %d\n", paddr->field_size); + printf(" Special: %d\n", paddr->special); + + if (dbr_field_type == DBR_NOACCESS) + dbr_field_type = DBR_ENUM + 1; + printf("DBR Field Type: %d = DBR_%s\n", paddr->dbr_field_type, + (dbr_field_type < 0 || dbr_field_type > (DBR_ENUM+1)) ? "????" : + dbr[dbr_field_type]); } @@ -704,32 +765,39 @@ static void printBuffer( printf("status = %u, severity = %u\n", pdbr_status->status, pdbr_status->severity); - } else + } + else { printf("status and severity not returned\n"); + } pbuffer = (char *)pbuffer + dbr_status_size; } + if (reqOptions & DBR_UNITS) { if (retOptions & DBR_UNITS) { struct dbr_units *pdbr_units = (void *)pbuffer; printf("units = \"%s\"\n", pdbr_units->units); - }else{ + } + else { printf("units not returned\n"); } pbuffer = (char *)pbuffer + dbr_units_size; } + if (reqOptions & DBR_PRECISION) { if (retOptions & DBR_PRECISION){ struct dbr_precision *pdbr_precision = (void *)pbuffer; printf("precision = %ld\n", pdbr_precision->precision.dp); - }else{ + } + else { printf("precision not returned\n"); } pbuffer = (char *)pbuffer + dbr_precision_size; } + if (reqOptions & DBR_TIME) { if (retOptions & DBR_TIME) { struct dbr_time *pdbr_time = (void *)pbuffer; @@ -737,11 +805,13 @@ static void printBuffer( epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f", &pdbr_time->time); printf("time = %s\n", time_buf); - }else{ + } + else { printf("time not returned\n"); } pbuffer = (char *)pbuffer + dbr_time_size; } + if (reqOptions & DBR_ENUM_STRS) { if (retOptions & DBR_ENUM_STRS) { struct dbr_enumStrs *pdbr_enumStrs = (void *)pbuffer; @@ -750,10 +820,13 @@ static void printBuffer( pdbr_enumStrs->no_str); for (i = 0; i < pdbr_enumStrs->no_str; i++) printf("\t\"%s\"\n", pdbr_enumStrs->strs[i]); - } else + } + else { printf("enum strings not returned\n"); + } pbuffer = (char *)pbuffer + dbr_enumStrs_size; } + if (reqOptions & DBR_GR_LONG) { if (retOptions & DBR_GR_LONG) { struct dbr_grLong *pdbr_grLong = (void *)pbuffer; @@ -761,11 +834,13 @@ static void printBuffer( printf("grLong: %d .. %d\n", pdbr_grLong->lower_disp_limit, pdbr_grLong->upper_disp_limit); - }else{ + } + else { printf("DBRgrLong not returned\n"); } pbuffer = (char *)pbuffer + dbr_grLong_size; } + if (reqOptions & DBR_GR_DOUBLE) { if (retOptions & DBR_GR_DOUBLE) { struct dbr_grDouble *pdbr_grDouble = (void *)pbuffer; @@ -773,11 +848,13 @@ static void printBuffer( printf("grDouble: %g .. %g\n", pdbr_grDouble->lower_disp_limit, pdbr_grDouble->upper_disp_limit); - }else{ + } + else { printf("DBRgrDouble not returned\n"); } pbuffer = (char *)pbuffer + dbr_grDouble_size; } + if (reqOptions & DBR_CTRL_LONG) { if (retOptions & DBR_CTRL_LONG){ struct dbr_ctrlLong *pdbr_ctrlLong = (void *)pbuffer; @@ -785,11 +862,13 @@ static void printBuffer( printf("ctrlLong: %d .. %d\n", pdbr_ctrlLong->lower_ctrl_limit, pdbr_ctrlLong->upper_ctrl_limit); - }else{ + } + else { printf("DBRctrlLong not returned\n"); } pbuffer = (char *)pbuffer + dbr_ctrlLong_size; } + if (reqOptions & DBR_CTRL_DOUBLE) { if (retOptions & DBR_CTRL_DOUBLE) { struct dbr_ctrlDouble *pdbr_ctrlDouble = (void *)pbuffer; @@ -797,11 +876,13 @@ static void printBuffer( printf("ctrlDouble: %g .. %g\n", pdbr_ctrlDouble->lower_ctrl_limit, pdbr_ctrlDouble->upper_ctrl_limit); - }else{ + } + else { printf("DBRctrlDouble not returned\n"); } pbuffer = (char *)pbuffer + dbr_ctrlDouble_size; } + if (reqOptions & DBR_AL_LONG) { if (retOptions & DBR_AL_LONG) { struct dbr_alLong *pdbr_alLong = (void *)pbuffer; @@ -811,11 +892,13 @@ static void printBuffer( pdbr_alLong->lower_warning_limit, pdbr_alLong->upper_warning_limit, pdbr_alLong->upper_alarm_limit); - }else{ + } + else { printf("DBRalLong not returned\n"); } pbuffer = (char *)pbuffer + dbr_alLong_size; } + if (reqOptions & DBR_AL_DOUBLE) { if (retOptions & DBR_AL_DOUBLE) { struct dbr_alDouble *pdbr_alDouble = (void *)pbuffer; @@ -825,13 +908,17 @@ static void printBuffer( pdbr_alDouble->lower_warning_limit, pdbr_alDouble->upper_warning_limit, pdbr_alDouble->upper_alarm_limit); - }else{ + } + else { printf("DBRalDouble not returned\n"); } pbuffer = (char *)pbuffer + dbr_alDouble_size; } + /* Now print values */ - if (no_elements == 0) return; + if (no_elements == 0) + return; + switch (dbr_type) { case (DBR_STRING): if (no_elements == 1) @@ -844,6 +931,7 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for(i=0; i 0) { @@ -853,6 +941,7 @@ static void printBuffer( pbuffer = (char *)pbuffer + MAX_STRING_SIZE; } break; + case (DBR_CHAR): if (no_elements == 1) sprintf(pmsg, "DBR_CHAR: "); @@ -864,11 +953,13 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + if (no_elements == 1) { val_i32 = *(epicsInt8 *) pbuffer; sprintf(pmsg, "%-9d 0x%-9x", val_i32, val_i32); dbpr_msgOut(pMsgBuff, tab_size); - } else { + } + else { for (i = 0; i < no_elements; i+= MAXLINE - 5) { sprintf(pmsg, " \"%.*s\"", MAXLINE - 5, (char *)pbuffer + i); if (i + MAXLINE - 5 < no_elements) strcat(pmsg, " +"); @@ -876,6 +967,7 @@ static void printBuffer( } } break; + case (DBR_UCHAR): if (no_elements == 1) sprintf(pmsg, "DBR_UCHAR: "); @@ -887,6 +979,7 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { val_u32 = *(epicsUInt8 *) pbuffer; sprintf(pmsg, "%-9u 0x%-9x", val_u32, val_u32); @@ -894,6 +987,7 @@ static void printBuffer( pbuffer = (char *)pbuffer + sizeof(epicsUInt8); } break; + case (DBR_SHORT): if (no_elements == 1) sprintf(pmsg, "DBR_SHORT: "); @@ -905,6 +999,7 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { val_i32 = *(epicsInt16 *) pbuffer; sprintf(pmsg, "%-9d 0x%-9x", val_i32, val_i32); @@ -912,6 +1007,7 @@ static void printBuffer( pbuffer = (char *)pbuffer + sizeof(epicsInt16); } break; + case (DBR_USHORT): if (no_elements == 1) sprintf(pmsg, "DBR_USHORT: "); @@ -923,6 +1019,7 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { val_u32 = *(epicsUInt16 *) pbuffer; sprintf(pmsg, "%-9u 0x%-9x", val_u32, val_u32); @@ -930,6 +1027,7 @@ static void printBuffer( pbuffer = (char *)pbuffer + sizeof(epicsUInt16); } break; + case (DBR_LONG): if (no_elements == 1) sprintf(pmsg, "DBR_LONG: "); @@ -941,6 +1039,7 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { val_i32 = *(epicsInt32 *) pbuffer; sprintf(pmsg, "%-9d 0x%-9x", val_i32, val_i32); @@ -948,6 +1047,7 @@ static void printBuffer( pbuffer = (char *)pbuffer + sizeof(epicsInt32); } break; + case (DBR_ULONG): if (no_elements == 1) sprintf(pmsg, "DBR_ULONG: "); @@ -959,6 +1059,7 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { val_u32 = *(epicsUInt32 *) pbuffer; sprintf(pmsg, "%-9u 0x%-9x", val_u32, val_u32); @@ -966,6 +1067,7 @@ static void printBuffer( pbuffer = (char *)pbuffer + sizeof(epicsUInt32); } break; + case (DBR_FLOAT): if (no_elements == 1) sprintf(pmsg, "DBR_FLOAT: "); @@ -977,12 +1079,14 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { sprintf(pmsg, "%-13.6g", *((epicsFloat32 *) pbuffer)); dbpr_msgOut(pMsgBuff, tab_size); pbuffer = (char *)pbuffer + sizeof(epicsFloat32); } break; + case (DBR_DOUBLE): if (no_elements == 1) sprintf(pmsg, "DBR_DOUBLE: "); @@ -994,12 +1098,14 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { sprintf(pmsg, "%-13.6g", *((epicsFloat64 *) pbuffer)); dbpr_msgOut(pMsgBuff, tab_size); pbuffer = (char *)pbuffer + sizeof(epicsFloat64); } break; + case (DBR_ENUM): if (no_elements == 1) sprintf(pmsg, "DBR_ENUM: "); @@ -1011,122 +1117,133 @@ static void printBuffer( dbpr_msgOut(pMsgBuff, tab_size); break; } + for (i = 0; i < no_elements; i++) { sprintf(pmsg, "%-9u", *((epicsEnum16 *) pbuffer)); dbpr_msgOut(pMsgBuff, tab_size); pbuffer = (char *)pbuffer + sizeof(epicsEnum16); } break; + default: printf(" illegal request type."); break; } + dbpr_msg_flush(pMsgBuff, tab_size); return; } static int dbpr_report( - const char *pname,DBADDR *paddr,int interest_level, - TAB_BUFFER *pMsgBuff,int tab_size) + const char *pname, DBADDR *paddr, int interest_level, + TAB_BUFFER *pMsgBuff, int tab_size) { - - char *pmsg; - dbFldDes *pdbFldDes = paddr->pfldDes; - dbRecordType *pdbRecordType = pdbFldDes->pdbRecordType; - short n2; - void *pfield; - char *pfield_name; - char *pfield_value; - DBENTRY dbentry; - DBENTRY *pdbentry = &dbentry; - long status; + char *pmsg; + dbFldDes *pdbFldDes = paddr->pfldDes; + dbRecordType *pdbRecordType = pdbFldDes->pdbRecordType; + short n2; + void *pfield; + char *pfield_name; + char *pfield_value; + DBENTRY dbentry; + DBENTRY *pdbentry = &dbentry; + long status; dbInitEntry(pdbbase,pdbentry); status = dbFindRecord(pdbentry,pname); - if(status) { - errMessage(status,pname); - return(-1); + if (status) { + errMessage(status,pname); + return -1; } + pmsg = pMsgBuff->message; for (n2 = 0; n2 <= pdbRecordType->no_fields - 1; n2++) { - pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->sortFldInd[n2]]; - pfield_name = pdbFldDes->name; - pfield = ((char *)paddr->precord) + pdbFldDes->offset; - if (pdbFldDes->interest > interest_level ) - continue; - switch (pdbFldDes->field_type) { - case DBF_STRING: - case DBF_USHORT: - case DBF_ENUM: - case DBF_FLOAT: - case DBF_CHAR: - case DBF_UCHAR: - case DBF_SHORT: - case DBF_LONG: - case DBF_ULONG: - case DBF_DOUBLE: - case DBF_MENU: - case DBF_DEVICE: - status = dbFindField(pdbentry,pfield_name); - pfield_value = dbGetString(pdbentry); - sprintf(pmsg, "%s: %s", pfield_name, - (pfield_value ? pfield_value : "")); - dbpr_msgOut(pMsgBuff, tab_size); - break; - case DBF_INLINK: - case DBF_OUTLINK: - case DBF_FWDLINK: { - DBLINK *plink = (DBLINK *)pfield; - int ind; + pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->sortFldInd[n2]]; + pfield_name = pdbFldDes->name; + pfield = ((char *)paddr->precord) + pdbFldDes->offset; + if (pdbFldDes->interest > interest_level ) + continue; - status = dbFindField(pdbentry,pfield_name); - for(ind=0; indtype) break; - } - if(ind>=LINK_NTYPES) { - sprintf(pmsg,"%s: Illegal Link Type", pfield_name); - } else { - sprintf(pmsg,"%s:%s %s", pfield_name, - pamaplinkType[ind].strvalue,dbGetString(pdbentry)); - } - dbpr_msgOut(pMsgBuff, tab_size); - } - break; - case DBF_NOACCESS: - if (pfield == (void *)&paddr->precord->time) { - /* Special for the TIME field, make it human-readable */ - char time_buf[40]; - epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f", - &paddr->precord->time); - sprintf(pmsg, "%s: %s", pfield_name, time_buf); - dbpr_msgOut(pMsgBuff, tab_size); - } else if (pdbFldDes->size == sizeof(void *) && + switch (pdbFldDes->field_type) { + case DBF_STRING: + case DBF_USHORT: + case DBF_ENUM: + case DBF_FLOAT: + case DBF_CHAR: + case DBF_UCHAR: + case DBF_SHORT: + case DBF_LONG: + case DBF_ULONG: + case DBF_DOUBLE: + case DBF_MENU: + case DBF_DEVICE: + status = dbFindField(pdbentry,pfield_name); + pfield_value = dbGetString(pdbentry); + sprintf(pmsg, "%s: %s", pfield_name, + (pfield_value ? pfield_value : "")); + dbpr_msgOut(pMsgBuff, tab_size); + break; + + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: { + DBLINK *plink = (DBLINK *)pfield; + int ind; + + status = dbFindField(pdbentry,pfield_name); + for (ind=0; indtype) + break; + } + if (ind>=LINK_NTYPES) { + sprintf(pmsg,"%s: Illegal Link Type", pfield_name); + } + else { + sprintf(pmsg,"%s:%s %s", pfield_name, + pamaplinkType[ind].strvalue,dbGetString(pdbentry)); + } + dbpr_msgOut(pMsgBuff, tab_size); + } + break; + + case DBF_NOACCESS: + if (pfield == (void *)&paddr->precord->time) { + /* Special for the TIME field, make it human-readable */ + char time_buf[40]; + epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f", + &paddr->precord->time); + sprintf(pmsg, "%s: %s", pfield_name, time_buf); + dbpr_msgOut(pMsgBuff, tab_size); + } + else if (pdbFldDes->size == sizeof(void *) && strchr(pdbFldDes->extra, '*')) { /* Special for pointers, needed on little-endian CPUs */ sprintf(pmsg, "%s: %p", pfield_name, *(void **)pfield); dbpr_msgOut(pMsgBuff, tab_size); - } else { /* just print field as hex bytes */ - unsigned char *pchar = (unsigned char *)pfield; - char temp_buf[61]; - char *ptemp_buf = &temp_buf[0]; - short n = pdbFldDes->size; - short i; + } + else { /* just print field as hex bytes */ + unsigned char *pchar = (unsigned char *)pfield; + char temp_buf[61]; + char *ptemp_buf = &temp_buf[0]; + short n = pdbFldDes->size; + short i; unsigned int value; - if (n > sizeof(temp_buf)/3) n = sizeof(temp_buf)/3; - for (i=0; i sizeof(temp_buf)/3) n = sizeof(temp_buf)/3; + for (i=0; imessage; - static int last_tabsize; + int len; + int err = 0; + char *pmsg = pMsgBuff->message; + static int last_tabsize; if (!((tab_size == 10) || (tab_size == 20))) { - printf("tab_size not 10 or 20 - dbpr_msgOut()\n"); - return; + printf("tab_size not 10 or 20 - dbpr_msgOut()\n"); + return; } /* init if first time */ if (!(pMsgBuff->pNext)) - dbpr_init_msg(pMsgBuff, tab_size); + dbpr_init_msg(pMsgBuff, tab_size); if (tab_size != last_tabsize) - pMsgBuff->pNexTab = pMsgBuff->out_buff + tab_size; + pMsgBuff->pNexTab = pMsgBuff->out_buff + tab_size; last_tabsize = tab_size; /* flush output if NULL string command */ if (*pmsg == 0) { - dbpr_msg_flush(pMsgBuff, tab_size); - return; + dbpr_msg_flush(pMsgBuff, tab_size); + return; } /* truncate if too long */ len = strlen(pmsg); @@ -1168,15 +1285,11 @@ static void dbpr_msgOut(TAB_BUFFER *pMsgBuff,int tab_size) /* warn if msg gt 80 */ if (err == 1) { - len = strlen(pmsg); - sprintf(pmsg, - "dbpr_msgOut: ERROR - msg length=%d limit=%d ", - len, - MAXLINE); - dbpr_insert_msg(pMsgBuff, len, tab_size); - return; + len = strlen(pmsg); + sprintf(pmsg, "dbpr_msgOut: ERROR - msg length=%d limit=%d ", + len, MAXLINE); + dbpr_insert_msg(pMsgBuff, len, tab_size); } - return; } static void dbpr_init_msg(TAB_BUFFER *pMsgBuff,int tab_size) @@ -1184,7 +1297,6 @@ static void dbpr_init_msg(TAB_BUFFER *pMsgBuff,int tab_size) pMsgBuff->pNext = pMsgBuff->out_buff; pMsgBuff->pLast = pMsgBuff->out_buff + MAXLINE; pMsgBuff->pNexTab = pMsgBuff->out_buff + tab_size; - return; } static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,int len,int tab_size) @@ -1198,35 +1310,33 @@ static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,int len,int tab_size) /* flush buffer if overflow would occor */ if (tot_line > MAXLINE) - dbpr_msg_flush(pMsgBuff, tab_size); + dbpr_msg_flush(pMsgBuff, tab_size); /* append message to buffer */ n = 0; while ((*pmsg) && (n < len)) { - *pMsgBuff->pNext++ = *pmsg++; + *pMsgBuff->pNext++ = *pmsg++; - /* position to next tab stop */ - if (*(pMsgBuff->pNexTab - 1) != '\0') - pMsgBuff->pNexTab = pMsgBuff->pNexTab + tab_size; - n++; + /* position to next tab stop */ + if (*(pMsgBuff->pNexTab - 1) != '\0') + pMsgBuff->pNexTab = pMsgBuff->pNexTab + tab_size; + n++; } /* fill spaces to next tab stop */ while (*(pMsgBuff->pNexTab - 1) != ' ' - && pMsgBuff->pNext < pMsgBuff->pLast) { - *pMsgBuff->pNext++ = ' '; + && pMsgBuff->pNext < pMsgBuff->pLast) { + *pMsgBuff->pNext++ = ' '; } - return; - } static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size) { /* skip print if buffer empty */ if (pMsgBuff->pNext != pMsgBuff->out_buff) - printf("%s\n", pMsgBuff->out_buff); + printf("%s\n", pMsgBuff->out_buff); + memset(pMsgBuff->out_buff,'\0', (int) MAXLINE + 1); pMsgBuff->pNext = pMsgBuff->out_buff; pMsgBuff->pNexTab = pMsgBuff->out_buff + tab_size; - return; } From fb983fe3825caf76858e7f4df4b466b7eb447cf3 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Fri, 16 Aug 2013 17:00:13 +0200 Subject: [PATCH 04/38] CAref: typos, replace ..._event() calls with ..._subscription() (by J. Lewis Muir) --- src/ca/CAref.html | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ca/CAref.html b/src/ca/CAref.html index bd63bc018..dbde9489f 100644 --- a/src/ca/CAref.html +++ b/src/ca/CAref.html @@ -2320,7 +2320,7 @@ int main ( int argc, char ** argv )

Certain CA client initiated requests asynchronously execute an application supplied call back in the client process when a response arrives. The functions -ca_put_callback, ca_get_callback, and ca_add_event all request notification of +ca_put_callback, ca_get_callback, and ca_create_subscription all request notification of asynchronous completion via this mechanism. The event_handler_args structure is passed by value to the application supplied callback. In this structure the dbr field is a void pointer to any @@ -2679,7 +2679,7 @@ on a channel.

The circuit may be initially connected or disconnected depending on the state of the network and the location of the channel. A channel will only enter -a connected state after server's address is determined, and only if channel +a connected state after the server's address is determined, and only if channel access successfully establishes a virtual circuit through the network to the server. Channel access routines that send a request to a server will return ECA_DISCONNCHID if the channel is currently disconnected.

@@ -2728,7 +2728,7 @@ time.

set this field to nil or 0 if they do not need to have a call back function run in response to each connection state change event.

The following structure is passed by value to the user's - connection connection callback function. The op field will + connection callback function. The op field will be set by the CA client library to CA_OP_CONN_UP when the channel connects, and to CA_OP_CONN_DOWN when the channel disconnects. See ca_puser if the @@ -3056,10 +3056,10 @@ int ca_create_subscription ( chtype TYPE, unsigned long COUNT, invoked whenever the process variable undergoes significant state changes. A significant change can be a change in the process variable's value, alarm status, or alarm severity. In the process control function block database the -deadband field determines the magnitude of a significant change for for the +deadband field determines the magnitude of a significant change for the process variable's value. Each call to this function consumes resources in the client library and potentially a CA server until one of ca_clear_channel or -ca_clear_event is called.

+ca_clear_subscription is called.

Subscriptions may be installed or canceled against both connected and disconnected channels. The specified USERFUNC is called once immediately after @@ -3067,7 +3067,7 @@ the subscription is installed with the process variable's current state if the process variable is connected. Otherwise, the specified USERFUNC is called immediately after establishing a connection (or reconnection) with the process variable. The specified USERFUNC is called immediately with the process -variable's current state from within ca_add_event() if the client and the +variable's current state from within ca_create_subscription() if the client and the process variable share the same address space.

If a subscription is installed on a channel in a disconnected state then the @@ -3125,7 +3125,7 @@ indicating the current state of the channel.

PEVID
This is a pointer to user supplied event id which is overwritten if successful. This event id can later be used to clear a specific - event. This option may may be omitted by passing a nil pointer.
+ event. This option may be omitted by passing a nil pointer.
MASK
@@ -3173,7 +3173,7 @@ int ca_clear_subscription ( evid EVID );

Cancel a subscription.

-

All ca_clear_event() requests such as the above are accumulated (buffered) +

All cancel-subscription requests such as the above are accumulated (buffered) and not forwarded to the server until one of ca_flush_io, ca_pend_io, ca_pend_event, or ca_sg_pend are called. This allows several requests to be efficiently sent together in one message.

@@ -3181,7 +3181,7 @@ efficiently sent together in one message.

Arguments

EVID
-
event id returned by ca_add_event()
+
event id returned by ca_create_subscription()

Returns

@@ -3297,7 +3297,7 @@ activity is processed for TIMEOUT seconds.

background activity is processed.

The ca_pend_event function will not return before the specified -time-out expires and all unfinished channel access labor has been processed, +timeout expires and all unfinished channel access labor has been processed, and unlike ca_pend_io returning from the function does not indicate anything about the status of pending IO requests.

@@ -3934,12 +3934,12 @@ prints diagnostics to standard out.

Examples

void ca_test_event (); 
-status = ca_add_event ( type, chid, ca_test_event, NULL, NULL ); 
+status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL ); 
 SEVCHK ( status, .... );

See Also

-

ca_add_event()

+

ca_create_subscription()

ca_sg_create()

#include <cadef.h>

From 3219ea0608970a366218ab538e16757b0d42ccec Mon Sep 17 00:00:00 2001
From: Andrew Johnson 
Date: Mon, 19 Aug 2013 13:30:19 -0500
Subject: [PATCH 05/38] Fixed file permissions.

---
 configure/RULES_TARGET    | 0
 configure/Sample.Makefile | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 configure/RULES_TARGET
 mode change 100755 => 100644 configure/Sample.Makefile

diff --git a/configure/RULES_TARGET b/configure/RULES_TARGET
old mode 100755
new mode 100644
diff --git a/configure/Sample.Makefile b/configure/Sample.Makefile
old mode 100755
new mode 100644

From 01f0fdbf1ece0aacbc5b1cde2dad3ea1ebc82e44 Mon Sep 17 00:00:00 2001
From: Andrew Johnson 
Date: Mon, 19 Aug 2013 15:46:51 -0500
Subject: [PATCH 06/38] More file permission fixes.

---
 src/as/asHost.rc                           | 0
 src/as/asIoc.rc                            | 0
 src/ca/SearchDest.h                        | 0
 src/ca/ca.rc                               | 0
 src/cas/build/cas.rc                       | 0
 src/db/dbIoc.rc                            | 0
 src/dbStatic/dbStaticHost.rc               | 0
 src/dbStatic/dbStaticIoc.rc                | 0
 src/dbtools/dbtoolsIoc.rc                  | 0
 src/dev/softDev/softDevIoc.rc              | 0
 src/dev/testDev/testDevIoc.rc              | 0
 src/gdd/gdd.rc                             | 0
 src/libCom/Com.rc                          | 0
 src/makeBaseApp/makeBaseApp.pl             | 0
 src/makeBaseExt/makeBaseExt.pl             | 0
 src/misc/misc.rc                           | 0
 src/misc/miscIoc.rc                        | 0
 src/rec/recIoc.rc                          | 0
 src/registry/registerRecordDeviceDriver.pl | 0
 src/registry/registryIoc.rc                | 0
 src/rsrv/rsrvIoc.rc                        | 0
 21 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 src/as/asHost.rc
 mode change 100755 => 100644 src/as/asIoc.rc
 mode change 100755 => 100644 src/ca/SearchDest.h
 mode change 100755 => 100644 src/ca/ca.rc
 mode change 100755 => 100644 src/cas/build/cas.rc
 mode change 100755 => 100644 src/db/dbIoc.rc
 mode change 100755 => 100644 src/dbStatic/dbStaticHost.rc
 mode change 100755 => 100644 src/dbStatic/dbStaticIoc.rc
 mode change 100755 => 100644 src/dbtools/dbtoolsIoc.rc
 mode change 100755 => 100644 src/dev/softDev/softDevIoc.rc
 mode change 100755 => 100644 src/dev/testDev/testDevIoc.rc
 mode change 100755 => 100644 src/gdd/gdd.rc
 mode change 100755 => 100644 src/libCom/Com.rc
 mode change 100755 => 100644 src/makeBaseApp/makeBaseApp.pl
 mode change 100755 => 100644 src/makeBaseExt/makeBaseExt.pl
 mode change 100755 => 100644 src/misc/misc.rc
 mode change 100755 => 100644 src/misc/miscIoc.rc
 mode change 100755 => 100644 src/rec/recIoc.rc
 mode change 100755 => 100644 src/registry/registerRecordDeviceDriver.pl
 mode change 100755 => 100644 src/registry/registryIoc.rc
 mode change 100755 => 100644 src/rsrv/rsrvIoc.rc

diff --git a/src/as/asHost.rc b/src/as/asHost.rc
old mode 100755
new mode 100644
diff --git a/src/as/asIoc.rc b/src/as/asIoc.rc
old mode 100755
new mode 100644
diff --git a/src/ca/SearchDest.h b/src/ca/SearchDest.h
old mode 100755
new mode 100644
diff --git a/src/ca/ca.rc b/src/ca/ca.rc
old mode 100755
new mode 100644
diff --git a/src/cas/build/cas.rc b/src/cas/build/cas.rc
old mode 100755
new mode 100644
diff --git a/src/db/dbIoc.rc b/src/db/dbIoc.rc
old mode 100755
new mode 100644
diff --git a/src/dbStatic/dbStaticHost.rc b/src/dbStatic/dbStaticHost.rc
old mode 100755
new mode 100644
diff --git a/src/dbStatic/dbStaticIoc.rc b/src/dbStatic/dbStaticIoc.rc
old mode 100755
new mode 100644
diff --git a/src/dbtools/dbtoolsIoc.rc b/src/dbtools/dbtoolsIoc.rc
old mode 100755
new mode 100644
diff --git a/src/dev/softDev/softDevIoc.rc b/src/dev/softDev/softDevIoc.rc
old mode 100755
new mode 100644
diff --git a/src/dev/testDev/testDevIoc.rc b/src/dev/testDev/testDevIoc.rc
old mode 100755
new mode 100644
diff --git a/src/gdd/gdd.rc b/src/gdd/gdd.rc
old mode 100755
new mode 100644
diff --git a/src/libCom/Com.rc b/src/libCom/Com.rc
old mode 100755
new mode 100644
diff --git a/src/makeBaseApp/makeBaseApp.pl b/src/makeBaseApp/makeBaseApp.pl
old mode 100755
new mode 100644
diff --git a/src/makeBaseExt/makeBaseExt.pl b/src/makeBaseExt/makeBaseExt.pl
old mode 100755
new mode 100644
diff --git a/src/misc/misc.rc b/src/misc/misc.rc
old mode 100755
new mode 100644
diff --git a/src/misc/miscIoc.rc b/src/misc/miscIoc.rc
old mode 100755
new mode 100644
diff --git a/src/rec/recIoc.rc b/src/rec/recIoc.rc
old mode 100755
new mode 100644
diff --git a/src/registry/registerRecordDeviceDriver.pl b/src/registry/registerRecordDeviceDriver.pl
old mode 100755
new mode 100644
diff --git a/src/registry/registryIoc.rc b/src/registry/registryIoc.rc
old mode 100755
new mode 100644
diff --git a/src/rsrv/rsrvIoc.rc b/src/rsrv/rsrvIoc.rc
old mode 100755
new mode 100644

From d25eff3af7c323ba0ef95d74662b226b97b0af12 Mon Sep 17 00:00:00 2001
From: Andrew Johnson 
Date: Fri, 30 Aug 2013 11:51:51 -0500
Subject: [PATCH 07/38] configure: Darwin build settings

Modify comments and defaults for darwin builds.
Changing to use gcc wasn't working.
---
 configure/os/CONFIG.darwinCommon.darwinCommon |  6 ++++--
 configure/os/CONFIG_SITE.Common.darwin-x86    | 12 ++++++------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/configure/os/CONFIG.darwinCommon.darwinCommon b/configure/os/CONFIG.darwinCommon.darwinCommon
index 517c41361..82b9b4344 100644
--- a/configure/os/CONFIG.darwinCommon.darwinCommon
+++ b/configure/os/CONFIG.darwinCommon.darwinCommon
@@ -59,8 +59,10 @@ COMMANDLINE_LIBRARY=READLINE
 
 GNU_DIR = /usr
 
-CC = $(GNU_BIN)/cc
-CCC = $(GNU_BIN)/c++
+# Apple soft-links these compilers to clang/clang++
+CC = cc
+CCC = c++
+GNU = NO
 
 #
 # Darwin shared libraries
diff --git a/configure/os/CONFIG_SITE.Common.darwin-x86 b/configure/os/CONFIG_SITE.Common.darwin-x86
index 5ddf09ace..9d9686071 100644
--- a/configure/os/CONFIG_SITE.Common.darwin-x86
+++ b/configure/os/CONFIG_SITE.Common.darwin-x86
@@ -14,19 +14,19 @@ ARCH_CLASS = x86_64
 #ARCH_CLASS = i386 x86_64
 
 #
-# Comment out the following 3 lines to build with Apple's GCC instead of CLANG.
+# Uncomment the following 3 lines to build with Apple's GCC instead of CLANG.
 #
-CC  = clang
-CCC = clang++
-GNU = NO
+#CC  = gcc
+#CCC = g++
+#GNU = YES
 
 
-# To use MacPorts GCC, comment out ALL the settings above this line,
-# then uncomment (and modify if necessary) the following instead:
+# To use MacPorts GCC uncomment (and modify if necessary) the following:
 
 #GNU_DIR = /opt/local
 #CC = $(GNU_BIN)/gcc -m64
 #CCC = $(GNU_BIN)/g++ -m64
+#GNU = YES
 
 # If you see this or similar errors while building in the src/cap5 directory
 #   gcc: error: unrecognized option '-no-cpp-precomp'

From e49210a3ea1c2e49fbb5c25b2d3434c23e7870c5 Mon Sep 17 00:00:00 2001
From: Andrew Johnson 
Date: Fri, 30 Aug 2013 12:50:34 -0500
Subject: [PATCH 08/38] configure: IOS version bump to 6.1

---
 configure/os/CONFIG_SITE.Common.iosCommon | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/configure/os/CONFIG_SITE.Common.iosCommon b/configure/os/CONFIG_SITE.Common.iosCommon
index 0fa3d4523..fa7b599e9 100644
--- a/configure/os/CONFIG_SITE.Common.iosCommon
+++ b/configure/os/CONFIG_SITE.Common.iosCommon
@@ -13,7 +13,8 @@
 #IOS_VERSION = 4.3
 #IOS_VERSION = 5.0
 #IOS_VERSION = 5.1
-IOS_VERSION = 6.0
+#IOS_VERSION = 6.0
+IOS_VERSION = 6.1
 
 
 # Which compiler to use:

From 4ae048572a79db693f3051e8193a83540b2f6dd4 Mon Sep 17 00:00:00 2001
From: Andrew Johnson 
Date: Fri, 13 Sep 2013 11:36:52 -0500
Subject: [PATCH 09/38] Added dbTemplateMaxVars variable

Allows users to configure dbLoadTemplate command to accept more than
100 variables or a larger string buffer for variables.
---
 src/dbtools/dbLoadTemplate.y | 49 +++++++++++++++++++++++++-----------
 src/misc/base.dbd            |  2 ++
 2 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/src/dbtools/dbLoadTemplate.y b/src/dbtools/dbLoadTemplate.y
index 0a919dda6..6d45472b9 100644
--- a/src/dbtools/dbLoadTemplate.y
+++ b/src/dbtools/dbLoadTemplate.y
@@ -17,21 +17,27 @@
 #include "dbAccess.h"
 #include "dbmf.h"
 #include "epicsVersion.h"
-
-#define epicsExportSharedSymbols
+#include "epicsExport.h"
 #include "dbLoadTemplate.h"
 
 static int line_num;
-static int yyerror();
-
-#define VAR_MAX_VAR_STRING 5000
-#define VAR_MAX_VARS 100
+static int yyerror(char *str);
 
 static char *sub_collect = NULL;
-static char** vars = NULL;
-static char* db_file_name = NULL;
+static char **vars = NULL;
+static char *db_file_name = NULL;
 static int var_count,sub_count;
 
+/* We allocate MAX_VAR_FACTOR chars in the sub_collect string for each
+ * "variable=value," segment, and will accept at most dbTemplateMaxVars
+ * template variables.  The user can adjust that variable to increase
+ * the number of variables or the length allocated for the buffer.
+ */
+#define MAX_VAR_FACTOR 50
+
+int dbTemplateMaxVars = 100;
+epicsExportAddress(int, dbTemplateMaxVars);
+
 %}
 
 %start template
@@ -111,10 +117,18 @@ vars: vars var
 
 var: WORD
 	{
-	    vars[var_count] = dbmfMalloc(strlen($1)+1);
-	    strcpy(vars[var_count],$1);
-	    var_count++;
-	    dbmfFree($1);
+            if (var_count >= dbTemplateMaxVars) {
+                fprintf(stderr,
+                    "More than dbTemplateMaxVars = %d macro variables used\n",
+                    dbTemplateMaxVars);
+                yyerror(NULL);
+            }
+            else {
+                vars[var_count] = dbmfMalloc(strlen($1)+1);
+                strcpy(vars[var_count],$1);
+                var_count++;
+                dbmfFree($1);
+            }
 	}
 	;
 
@@ -269,14 +283,21 @@ int epicsShareAPI dbLoadTemplate(char* sub_file)
 		return -1;
 	}
 
+        if (dbTemplateMaxVars < 1)
+        {
+                fprintf(stderr,"Error: dbTemplateMaxVars = %d, must be +ve\n",
+                        dbTemplateMaxVars);
+                return -1;
+        }
+
 	if( !(fp=fopen(sub_file,"r")) )
 	{
 		fprintf(stderr,"dbLoadTemplate: error opening sub file %s\n",sub_file);
 		return -1;
 	}
 
-	vars = (char**)malloc(VAR_MAX_VARS * sizeof(char*));
-	sub_collect = malloc(VAR_MAX_VAR_STRING);
+	vars = malloc(dbTemplateMaxVars * sizeof(char*));
+	sub_collect = malloc(dbTemplateMaxVars * MAX_VAR_FACTOR);
 	if (!vars || !sub_collect)
 	{
 		free(vars);
diff --git a/src/misc/base.dbd b/src/misc/base.dbd
index 7c7e99ed2..ec702801d 100644
--- a/src/misc/base.dbd
+++ b/src/misc/base.dbd
@@ -48,3 +48,5 @@ variable(asCaDebug,int)
 variable(dbRecordsOnceOnly,int)
 variable(dbBptNotMonotonic,int)
 
+# dbLoadTemplate settings
+variable(dbTemplateMaxVars,int)

From 2d3a828acd7b074af7eaeb0b38e042c231614302 Mon Sep 17 00:00:00 2001
From: Andrew Johnson 
Date: Fri, 13 Sep 2013 11:57:18 -0500
Subject: [PATCH 10/38] Fixed read-back of TSEL link

Reading back a .TSEL field that was originally pointed to
another record's .TIME field was exposing internal details
that didn't need to be made visible. This commit hides the
.TIME => .VAL change completely, and allows a .TSEL link
field to be saved and restored properly using autosave.
---
 src/db/recGbl.c            | 2 +-
 src/dbStatic/dbStaticLib.c | 8 +++++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/db/recGbl.c b/src/db/recGbl.c
index 2d58c9dab..e0d2480df 100644
--- a/src/db/recGbl.c
+++ b/src/db/recGbl.c
@@ -303,7 +303,7 @@ void epicsShareAPI recGblTSELwasModified(struct link *plink)
     /*Note that the VAL value will not be used*/
     pfieldname = strstr(ppv_link->pvname, ".TIME");
     if (pfieldname) {
-        strcpy(pfieldname, ".VAL");
+        *pfieldname = 0;
         ppv_link->pvlMask |= pvlOptTSELisTime;
     }
 }
diff --git a/src/dbStatic/dbStaticLib.c b/src/dbStatic/dbStaticLib.c
index 56d54928c..8334ef7f6 100644
--- a/src/dbStatic/dbStaticLib.c
+++ b/src/dbStatic/dbStaticLib.c
@@ -2041,9 +2041,11 @@ char * epicsShareAPI dbGetString(DBENTRY *pdbentry)
 		else if(pvlMask&pvlOptCP) ppind=3;
 		else if(pvlMask&pvlOptCPP) ppind=4;
 		else ppind=0;
-		if(plink->value.pv_link.pvname)
-		    strcpy(message,plink->value.pv_link.pvname);
-		else
+		if (plink->value.pv_link.pvname) {
+		    strcpy(message, plink->value.pv_link.pvname);
+		    if (pvlMask & pvlOptTSELisTime)
+			strcat(message, ".TIME");
+		} else
 		    strcpy(message,"");
 		strcat(message," ");
 		strcat(message,ppstring[ppind]);

From 6814b09fad73808e86c6d3c41e1cf918287ce8e5 Mon Sep 17 00:00:00 2001
From: Andrew Johnson 
Date: Fri, 13 Sep 2013 17:30:38 -0500
Subject: [PATCH 11/38] docs: Release Notes update

... for several recent commits.
---
 documentation/RELEASE_NOTES.html | 41 ++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 80c2a76e5..7db4dd541 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -13,6 +13,47 @@
 
 
 
+

Reading TSEL field

+ +

The TSEL link field has two complementary uses; it is read to fetch a +time-stamp event number for the TSE field, or if pointed to the .TIME field of +another record the record's timestamp is copied directly from the target record. +However with the latter usage if the TSEL link is itself read back instead of +pointing to the .TIME field the link appears to have changed to point to the VAL +field. This is due to an internal detail, and makes it impossible to save the +TSEL field's value using autosave. This has been fixed, and now the TSEL field +should always read back the same PV that it was pointed to.

+ +

dbLoadTemplate variable limits adjustable

+ +

The dbLoadTemplate command used to allocate a fixed amount of memory +for the template macro values that it used to 5000 bytes, and also limited the +number of variables that could defined to 100. These limits can now be changed +at runtime using the variable dbTemplateMaxVars which sets the maximum +number of macro variables that can be used; the amount of memory allocated for +value storage is 50 times this number. This variable is registered as an iocsh +variable in the base.dbd file, and can be adjusted as necessary before each +individual call to dbLoadTemplate.

+ +

The code now checks for and prevents any attempt to define more than the set +number of variables, but it does not check for overruns of the storage buffer. +This means that template files which define many long macro value strings could +still cause a buffer overflow and crash the IOC at startup, but increasing the +variable is all that is needed to allow that template file to be loaded.

+ +

Improvements to dbpf

+ +

It is now possible to use the dbpf command to put a long string +value into a UCHAR array field, previously only CHAR arrays were supported by +this command even though through Channel Access could put a long string to +either type. The error message printed by dbpf when a value conversion +fails has also been significantly improved.

+ +

Support for VxWorks 6.9

+ +

Various changes have been made that were needed to allow Base to build and +run properly on VxWorks 6.9.

+

Improvements to aToIPAddr()

The libCom routine aToIPAddr() and the vxWorks implementation of the From 2bf4b36639dc0328551f6a19d381c5e395f6b8a6 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 24 Sep 2013 15:30:26 -0500 Subject: [PATCH 12/38] configure: Support Apple Xcode 5.0 and iOS 7.0 Not tested on the 64-bit ARMv8 architecture, although it should be compatible (confirmation would be welcome). --- configure/os/CONFIG_SITE.Common.ios-arm | 11 ++++++++--- configure/os/CONFIG_SITE.Common.iosCommon | 5 +++-- documentation/RELEASE_NOTES.html | 5 +++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/configure/os/CONFIG_SITE.Common.ios-arm b/configure/os/CONFIG_SITE.Common.ios-arm index e6ae3fcc1..3e20f58f6 100644 --- a/configure/os/CONFIG_SITE.Common.ios-arm +++ b/configure/os/CONFIG_SITE.Common.ios-arm @@ -16,11 +16,16 @@ # # Xcode 4.5 dropped support for the ARMv6. # -# ARMv7s devices: iPhone 5 +# ARMv8 (arm64) devices: iPhone 5S +# ARMv7s devices: iPhone 5 and 5C, iPad Gen 4 +# ARMv7 devices: iPhone 3GS, 4 and 4S, iPod Touch Gen 3 to 5 +# iPad Gen 1 to 3, iPad Mini, Apple TV Gen 2 and 3 # ARMv6 devices: iPhone 1 and 3G, iPod Touch Gen 1 and 2 -# All other devices are ARMv7 -ARCH_CLASS = armv7 armv7s +#ARCH_CLASS = arm64 +#ARCH_CLASS = armv7s arm64 +ARCH_CLASS = armv7 armv7s arm64 +#ARCH_CLASS = armv7 armv7s #ARCH_CLASS = armv7 #ARCH_CLASS = armv6 armv7 #ARCH_CLASS = armv6 diff --git a/configure/os/CONFIG_SITE.Common.iosCommon b/configure/os/CONFIG_SITE.Common.iosCommon index fa7b599e9..7c4b528aa 100644 --- a/configure/os/CONFIG_SITE.Common.iosCommon +++ b/configure/os/CONFIG_SITE.Common.iosCommon @@ -14,11 +14,12 @@ #IOS_VERSION = 5.0 #IOS_VERSION = 5.1 #IOS_VERSION = 6.0 -IOS_VERSION = 6.1 +#IOS_VERSION = 6.1 +IOS_VERSION = 7.0 # Which compiler to use: -# CLANG is preferred for recent versions of Xcode +# CLANG is required for Xcode 5.0 and later # LLVM_GNU uses the llvm-gcc and llvm-g++ compilers # GNU is needed for older versions of Xcode diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 7db4dd541..58feda604 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -13,6 +13,11 @@ +

Support for Apple Xcode 5.0

+ +

This adds the ability to build for iOS 7.0 and the ARMv8 64-bit CPU on the +newest iPhone 5S device.

+

Reading TSEL field

The TSEL link field has two complementary uses; it is read to fetch a From 2ad468dd3894d69e85ad32516bb378094c580728 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 27 Sep 2013 09:59:34 -0500 Subject: [PATCH 13/38] CAref: Fix returns from ca_attach_context() ECA_NORMAL was missing, ECA_ISATTACHED given twice. --- src/ca/CAref.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ca/CAref.html b/src/ca/CAref.html index dbde9489f..87aa96bc9 100644 --- a/src/ca/CAref.html +++ b/src/ca/CAref.html @@ -4318,12 +4318,11 @@ preemptively from more than one thread.

Returns

-

ECA_ISATTACHED - already attached to a CA context

+

ECA_NORMAL - Normal successful completion

-

ECA_NOTTHREADED - the specified context is non-preemptive and therefore does -not allow other threads to join

+

ECA_NOTTHREADED - Context is not preemptive so cannot be joined

-

ECA_ISATTACHED - the current thread is already attached to a CA context

+

ECA_ISATTACHED - Thread already attached to a CA context

See Also

From 42f4c3a0a5eb5a9f1f9ee37e30bb3ee6c9502bcd Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Thu, 17 Oct 2013 09:23:47 -0600 Subject: [PATCH 14/38] fixed potential memory leak --- src/cas/generic/casStrmClient.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cas/generic/casStrmClient.cc b/src/cas/generic/casStrmClient.cc index 51f4d0d7c..5bcefb682 100644 --- a/src/cas/generic/casStrmClient.cc +++ b/src/cas/generic/casStrmClient.cc @@ -884,7 +884,7 @@ caStatus casStrmClient::monitorResponse ( } else { ecaStatus = ECA_GETFAIL; - } + } return monitorFailureResponse ( guard, msg, ecaStatus ); } else { @@ -926,6 +926,7 @@ caStatus casStrmClient::monitorResponse ( int cacStatus = caNetConvert ( msg.m_dataType, pPayload, pPayload, true, msg.m_count ); if ( cacStatus != ECA_NORMAL ) { + pDBRDD->unreference (); return this->sendErrWithEpicsStatus ( guard, & msg, chan.getCID(), S_cas_internal, cacStatus ); } From 4b44881744bdac8774888f53373a52520adec6b8 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 17 Oct 2013 17:21:26 -0500 Subject: [PATCH 15/38] db: Fixed bogus dbScan overrun warnings Penalizing the 0.1 second scan thread by 0.1 seconds guarantees another overrun in most cases... Warning message improved. Also added a release note for Jeff's CAS commit. --- documentation/RELEASE_NOTES.html | 12 ++++++--- src/db/dbScan.c | 45 ++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 58feda604..dd1256064 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -13,6 +13,11 @@ +

CAS: GDD Reference Count Underflow

+ +

Thanks to Bruce Hill a source of an underflow in a GDD reference count in the +CAS code has been fixed.

+

Support for Apple Xcode 5.0

This adds the ability to build for iOS 7.0 and the ARMv8 64-bit CPU on the @@ -127,9 +132,10 @@ provides nanosecond resolution.

long-term drift associated with OS thread sheduling. The new code keeps scan times much more closely tied to the system clock tick, only allowing the scan period to drift if the record processing time takes longer to execute than the -interval between scans. If this happens a 0.1 second penalty is given to the -scan thread (to allow lower priority threads time to process on preemptive -priority scheduled OSs). After 10 repeated over-runs a warning will be logged, +interval between scans. If this happens the scan thread is made to wait for an +additional half-period but at most 1 second before the records are scanned +again, to allow lower priority threads some time to process on a preemptive +priority scheduled OS. After 10 repeated over-runs a warning will be logged, with an increasing delay between messages up to hourly.

This fixes launchpad bug diff --git a/src/db/dbScan.c b/src/db/dbScan.c index 43303453d..f764a1760 100644 --- a/src/db/dbScan.c +++ b/src/db/dbScan.c @@ -82,9 +82,12 @@ typedef struct scan_element{ /* PERIODIC */ +#define OVERRUN_REPORT_DELAY 10.0 /* Time between initial reports */ +#define OVERRUN_REPORT_MAX 3600.0 /* Maximum time between reports */ typedef struct periodic_scan_list { scan_list scan_list; double period; + const char *name; unsigned long overruns; volatile enum ctl scanCtl; epicsEventId loopEvent; @@ -367,8 +370,8 @@ int scanppl(double period) /* print periodic list */ ppsl = papPeriodic[i]; if (ppsl == NULL) continue; if (period > 0.0 && (fabs(period - ppsl->period) >.05)) continue; - sprintf(message, "Scan Period = %g seconds (%lu over-runs)", - ppsl->period, ppsl->overruns); + sprintf(message, "Records with SCAN = '%s' (%lu over-runs):", + ppsl->name, ppsl->overruns); printList(&ppsl->scan_list, message); } return 0; @@ -545,7 +548,11 @@ static void periodicTask(void *arg) periodic_scan_list *ppsl = (periodic_scan_list *)arg; epicsTimeStamp next, reported; unsigned int overruns = 0; - double report_delay = 10.0; + double report_delay = OVERRUN_REPORT_DELAY; + double overtime = 0.0; + double over_min = 0.0; + double over_max = 0.0; + const double penalty = (ppsl->period >= 2) ? 1 : (ppsl->period / 2); taskwdInsert(0, NULL, NULL); epicsEventSignal(startStopEvent); @@ -564,24 +571,40 @@ static void periodicTask(void *arg) epicsTimeGetCurrent(&now); delay = epicsTimeDiffInSeconds(&next, &now); if (delay <= 0.0) { - delay = 0.1; + if (overtime == 0.0) { + overtime = over_min = over_max = -delay; + } + else { + overtime -= delay; + if (over_min + delay > 0) + over_min = -delay; + if (over_max + delay < 0) + over_max = -delay; + } + delay = penalty; ppsl->overruns++; next = now; + epicsTimeAddSeconds(&next, delay); if (++overruns >= 10 && epicsTimeDiffInSeconds(&now, &reported) > report_delay) { - errlogPrintf("dbScan warning: %g second scan over-ran %u times\n", - ppsl->period, overruns); + errlogPrintf("\ndbScan warning from '%s' scan thread:\n" + "\tScan processing averages %.2f seconds (%.2f .. %.2f).\n" + "\tOver-runs have now happened %u times in a row.\n" + "\tTo fix this, move some records to a slower scan rate.\n", + ppsl->name, ppsl->period + overtime / overruns, + ppsl->period + over_min, ppsl->period + over_max, overruns); reported = now; - if (report_delay < 1800.0) + if (report_delay < (OVERRUN_REPORT_MAX / 2)) report_delay *= 2; else - report_delay = 3600.0; /* At most hourly */ + report_delay = OVERRUN_REPORT_MAX; } } else { overruns = 0; - report_delay = 10.0; + report_delay = OVERRUN_REPORT_DELAY; + overtime = 0.0; } epicsEventWaitWithTimeout(ppsl->loopEvent, delay); @@ -611,8 +634,8 @@ static void initPeriodic(void) ppsl->scan_list.lock = epicsMutexMustCreate(); ellInit(&ppsl->scan_list.list); - epicsScanDouble(pmenu->papChoiceValue[i + SCAN_1ST_PERIODIC], - &ppsl->period); + ppsl->name = pmenu->papChoiceValue[i + SCAN_1ST_PERIODIC]; + epicsScanDouble(ppsl->name, &ppsl->period); ppsl->scanCtl = ctlPause; ppsl->loopEvent = epicsEventMustCreate(epicsEventEmpty); From d6dab34ae935133b94dad44338ed78ba94392175 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 7 Nov 2013 17:57:09 -0600 Subject: [PATCH 16/38] Merged changes from Jeff Hill's ca-ref-man-maint branch. This contains only text changes to the CA reference manual. --- src/ca/CAref.html | 141 ++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 74 deletions(-) diff --git a/src/ca/CAref.html b/src/ca/CAref.html index 87aa96bc9..9753a151d 100644 --- a/src/ca/CAref.html +++ b/src/ca/CAref.html @@ -165,7 +165,8 @@ $Date$

  • block for certain requests to complete
  • test to see if certain requests have completed
  • -
  • process CA client library background activities
  • +
  • process CA client library background + activities
  • flush outstanding requests to the server
  • replace the default exception handler
  • @@ -454,26 +455,20 @@ Environment below.

    Firewalls

    -

    If you want channel access clients on a machine to be able to see -beacons and replies to broadcast PV search requests, you need to permit -inbound UDP packets with source port EPICS_CA_SERVER_PORT (default is 5064) -or destination port EPICS_CA_REPEATER_PORT (default is 5065). On systems -using iptables this can be accomplished by rules like

    - -
    -     -A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
    -     -A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT
    -
    +

    If you want channel access clients on a machine to be able to see beacons +and replies to broadcast PV search requests, you need to permit inbound UDP +packets with source port EPICS_CA_SERVER_PORT (default is 5064) or destination +port EPICS_CA_REPEATER_PORT (default is 5065). On systems using iptables this +can be accomplished by rules like

    +
         -A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
    +     -A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT

    If you want channel access servers (e.g. "soft IOCs") on a machine to be able to be seen by clients, you need to permit inbound TCP or UDP packets with -destination port EPICS_CA_SERVER_PORT (default is 5064). -On systems using iptables this can be accomplished by rules like

    - -
    -     -A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
    -     -A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT
    -
    +destination port EPICS_CA_SERVER_PORT (default is 5064). On systems using +iptables this can be accomplished by rules like

    +
         -A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
    +     -A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT

    In all cases the "-s 192.168.0.0/22" specifies the range of addresses from which you wish to accept packets.

    @@ -498,9 +493,8 @@ broadcast address of that subnet is added to the list. For each point to point interface found, the destination address of that link is added to the list. This automatic server address list initialization can be disabled if the EPICS environment variable EPICS_CA_AUTO_ADDR_LIST exists and its value is either -of "no" or "NO". The typical default is to enable network interface -introspection driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES" -or "yes".

    +"no" or "NO". The typical default is to enable network interface introspection +driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES" or "yes".

    Following network interface introspection, any IP addresses specified in the EPICS environment variable EPICS_CA_ADDR_LIST are added to the list of @@ -511,8 +505,8 @@ CA servers unless a CA proxy (gateway) is installed. The addresses in EPICS_CA_ADDR_LIST may be dotted IP addresses or host names if the local OS has support for host name to IP address translation. When multiple names are added to EPICS_CA_ADDR_LIST they must be separated by white space. There is no -requirement that the addresses specified in the EPICS_CA_ADDR_LIST be -broadcast addresses, but this will often be the most convenient choice.

    +requirement that the addresses specified in the EPICS_CA_ADDR_LIST be broadcast +addresses, but this will often be the most convenient choice.

    For any IP addresses specified in the EPICS environment variable EPICS_CA_NAME_SERVERS, TCP connections are opened and used for CA client name @@ -560,7 +554,7 @@ default to EPICS_CA_SERVER_PORT.

    Frequently vxWorks systems boot by default with routes limiting access only to the local subnet. If a EPICS system is operating in a WAN environment it may be necessary to configure routes into the vxWorks system which enable a vxWorks -based CA server to respond to requests originating outside it's subnet. These +based CA server to respond to requests originating outside its subnet. These routing restrictions can also apply to vxWorks base CA clients communicating with off subnet servers. An EPICS system manager can implement an rudimentary, but robust, form of access control for a particular host by not providing @@ -865,8 +859,8 @@ the contents of EPICS_CA_ADDR_LIST is used to augment the list. Otherwise, the list is not augmented.

    The EPICS_CAS_BEACON_PORT parameter specifies the destination port for -server beacons. The only exception to this occurs when ports are specified -in EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If +server beacons. The only exception to this occurs when ports are specified in +EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If EPICS_CAS_BEACON_PORT is not specified then beacons are sent to the port specified in EPICS_CA_REPEATER_PORT.

    @@ -874,7 +868,7 @@ specified in EPICS_CA_REPEATER_PORT.

    The parameter EPICS_CAS_INTF_ADDR_LIST allows a ca server to bind itself to, and therefore accept messages only over, a limited set of the local host's -network interfaces (each specified by it's IP address). On UNIX systems type +network interfaces (each specified by its IP address). On UNIX systems type "netstat -i" (type "ipconfig" on windows) to see a list of the local host's network interfaces. Specifically, UDP search messages addressed to both the IP addresses in EPICS_CAS_INTF_ADDR_LIST and also to the broadcast addresses of @@ -1885,7 +1879,7 @@ order to connect to this new beacon-out-of-range server. The typical situation where a client would not see the server's beacon might be when the client isnt on the same IP subnet as the server, and the client's EPICS_CA_ADDR_LIST was modified to include a destination address for the server, but the server's -beacon address list was not modified so that it's beacons are received by the +beacon address list was not modified so that its beacons are received by the client.

    A Server's IP Address Was Changed

    @@ -2017,8 +2011,8 @@ OS and even between different versions of the same OS.

    If the subscription update producer in the server produces subscription updates faster than the subscription update consumer in the client consumes them, then events have to be discarded if the buffering in the server -isn't allowed to grow to an infinite size. This is a law of nature -- based on queuing theory of course.

    +isn't allowed to grow to an infinite size. This is a law of nature – +based on queuing theory of course.

    What is done depends on the version of the CA server. All server versions place quotas on the maximum number of subscription updates allowed on the @@ -2040,10 +2034,10 @@ server to resume with subscription updates. This prevents slow clients from getting time warped, but also guarantees that intervening events are discarded until the slow client catches up.

    -

    There is currently no message on the IOC's console when a -particular client is slow on the uptake. A message of this type used to exist -many years ago, but it was a source of confusion (and what we will call -message noise) so it was removed.

    +

    There is currently no message on the IOC's console when a particular client +is slow on the uptake. A message of this type used to exist many years ago, but +it was a source of confusion (and what we will call message noise) so it was +removed.

    There is unfortunately no field in the protocol allowing the server to indicate that an intervening subscription update was discarded. We should @@ -2355,8 +2349,8 @@ void myCallback ( struct event_handler_args args )

    Channel Access Exceptions

    When the server detects a failure, and there is no client call back function -attached to the request, an exception handler is executed in the client. -The default exception handler prints a message on the console and exits if the +attached to the request, an exception handler is executed in the client. The +default exception handler prints a message on the console and exits if the exception condition is severe. Certain internal exceptions within the CA client library, and failures detected by the SEVCHK macro may also cause the exception handler to be invoked. To modify this behavior see all OS (in past releases the library was thread safe only on vxWorks). When the client library is initialized the programmer may specify if preemptive callback is to be enabled. Preemptive callback is disabled by default. If preemptive -callback is enabled, then the user's callback functions might be called by -CA's auxiliary threads when the main initiating channel access thread is not -inside of a function in the channel access client library. Otherwise, the -user's callback functions will be called only when the main initiating channel -access thread is executing inside of the CA client library. When the CA client -library invokes a user's callback function, it will always wait for the current +callback is enabled, then the user's callback functions might be called by CA's +auxiliary threads when the main initiating channel access thread is not inside +of a function in the channel access client library. Otherwise, the user's +callback functions will be called only when the main initiating channel access +thread is executing inside of the CA client library. When the CA client library +invokes a user's callback function, it will always wait for the current callback to complete prior to executing another callback function. Programmers enabling preemptive callback should be familiar with using mutex locks to create a reliable multi-threaded program.

    @@ -2457,10 +2451,10 @@ address space (process) to be independent of each other. For example, the database CA links and the sequencer are designed to not use the same CA client library threads, network circuits, and data structures. Each thread that calls ca_context_create() for the first time either -directly or implicitly when calling any CA library function for the first -time, creates a CA client library context. A CA client library context contains -all of the threads, network circuits, and data structures required to connect -and communicate with the channels that a CA client application has created. The +directly or implicitly when calling any CA library function for the first time, +creates a CA client library context. A CA client library context contains all +of the threads, network circuits, and data structures required to connect and +communicate with the channels that a CA client application has created. The priority of auxiliary threads spawned by the CA client library are at fixed offsets from the priority of the thread that called ca_context_create(). An application specific @@ -2530,9 +2524,9 @@ questionable practice for the following reasons.

    • The vxWorks shell thread runs at the very highest priority in the system and therefore socket calls are made at a priority that is above the - priority of tNetTask - a practice that has caused the WRS IP kernel - to get sick in the past. That symptom was observed some time ago, but we - don't know if WRS has fixed the problem.
    • + priority of tNetTask. This has caused problems with the WRS IP kernel in + the past. That symptom was observed some time ago, but we don't know if + WRS has fixed the problem.
    • The vxWorks shell thread runs at the very highest priority in the system @@ -2689,7 +2683,7 @@ a connected state.

      • The first and simplest method requires that you call ca_pend_io(), and wait for successful completion, prior to using a channel that was created - specifying a nil connection call back function pointer.
      • + specifying a nill connection call back function pointer.
      • The second method requires that you register a connection handler by supplying a valid connection callback function pointer. This connection handler is called whenever the connection state of the channel changes. If @@ -2725,7 +2719,7 @@ time.

        USERFUNC
        Optional address of the user's call back function to be run when the connection state changes. Casual users of channel access may decide to - set this field to nil or 0 if they do not need to have a call back + set this field to nill or 0 if they do not need to have a call back function run in response to each connection state change event.

        The following structure is passed by value to the user's connection callback function. The op field will @@ -2745,7 +2739,7 @@ time.

        The value of this void pointer argument is retained in storage associated with the specified channel. See the MACROS manual page for reading and writing this field. Casual users of channel access may - wish to set this field to nil or 0.
        + wish to set this field to nill or 0.
    PRIORITY
    @@ -2853,7 +2847,7 @@ This allows several requests to be efficiently combined into one message.

    Description (IOC Database Specific)

    A CA put request causes the record to process if the record's SCAN field is -set to passive, and the field being written has it's process passive attribute +set to passive, and the field being written has its process passive attribute set to true. If such a record is already processing when a put request is initiated the specified field is written immediately, and the record is scheduled to process again as soon as it finishes processing. Earlier instances @@ -2861,20 +2855,19 @@ of multiple put requests initiated while the record is being processing may be discarded, but the last put request initiated is always written and processed.

    -

    A CA put callback request causes -the record to process if the record's SCAN field is set to passive, and the -field being written has it's process passive attribute set to true. For such a -record, the user's put callback function is not called until after the record, -and any records that the record links to, finish processing. If such a record -is already processing when a put callback request is initiated the put callback request is postponed until the -record, and any records it links to, finish processing.

    +

    A CA put callback request causes the record to process if the +record's SCAN field is set to passive, and the field being written has its +process passive attribute set to true. For such a record, the user's put +callback function is not called until after the record, and any records that +the record links to, finish processing. If such a record is already processing +when a put callback request is initiated the put callback +request is postponed until the record, and any records it links to, finish +processing.

    If the record's SCAN field is not set to passive, or the field being written -has it's process passive attribute set to false then the CA put or CA put -callback request cause the specified field to be immediately written, but they -do not cause the record to be processed.

    +has its process passive attribute set to false then the CA put or CA put +callback request cause the specified field to be immediately written, +but they do not cause the record to be processed.

    Arguments

    @@ -3124,8 +3117,8 @@ indicating the current state of the channel.

    PEVID
    This is a pointer to user supplied event id which is overwritten if - successful. This event id can later be used to clear a specific - event. This option may be omitted by passing a nil pointer.
    + successful. This event id can later be used to clear a specific event. + This option may be omitted by passing a nill pointer.
    MASK
    @@ -3232,9 +3225,9 @@ activities.

    network delays such as Ethernet collision exponential back off until retransmission delays which can be quite long on overloaded networks.

    -

    Unlike ca_pend_event, this routine will -not process CA's background activities if none of the selected IO requests are -pending.

    +

    Unlike ca_pend_event, this routine +will not process CA's background activities if none of the selected IO requests +are pending.

    Arguments

    @@ -3409,7 +3402,7 @@ field should not be used.

    USERFUNC
    Address of user callback function to be executed when an exceptions - occur. Passing a nil value causes the default exception handler to be + occur. Passing a nill value causes the default exception handler to be reinstalled. The following structure is passed by value to the user's callback function. Currently, the op field can be one of CA_OP_GET, CA_OP_PUT, CA_OP_CREATE_CHANNEL, CA_OP_ADD_EVENT, @@ -3544,7 +3537,7 @@ default handler uses fprintf to send messages to 'stderr'.

    PFUNC
    The address of a user supplied call back handler to be invoked when CA - prints diagnostic messages. Installing a nil pointer will cause the + prints diagnostic messages. Installing a nill pointer will cause the default call back handler to be reinstalled.
    @@ -3591,7 +3584,7 @@ specified channel.

    PFUNC
    -
    Address of user supplied call back function. A nil pointer uninstalls +
    Address of user supplied call back function. A nill pointer uninstalls the current handler. The following arguments are passed by value to the supplied callback handler.
    typedef struct ca_access_rights {
    @@ -4285,7 +4278,7 @@ ca_client_status() prints information about the calling threads CA context.

    Description

    -

    Returns a pointer to the current thread's CA context. If none then nil is +

    Returns a pointer to the current thread's CA context. If none then nill is returned.

    See Also

    From 66209118f68aae635099062ddc6d540d8344b05a Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 13 Nov 2013 12:39:23 -0600 Subject: [PATCH 17/38] libCom/macLib: Don't use unsigned chars in macParseDefns() These pointers are really pointing to standard chars. --- src/libCom/macLib/macUtil.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libCom/macLib/macUtil.c b/src/libCom/macLib/macUtil.c index d47d3a131..a18d36037 100644 --- a/src/libCom/macLib/macUtil.c +++ b/src/libCom/macLib/macUtil.c @@ -3,8 +3,7 @@ * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* $Revision-Id$ @@ -51,11 +50,11 @@ epicsShareAPI macParseDefns( int quote; int escape; size_t nbytes; - const unsigned char **ptr; - const unsigned char **end; + const char **ptr; + const char **end; int *del; char *memCp, **memCpp; - const unsigned char *c; + const char *c; char *s, *d, **p; enum { preName, inName, preValue, inValue } state; @@ -68,8 +67,8 @@ epicsShareAPI macParseDefns( numMax = strlen( defns ); if ( numMax < altNumMax ) numMax = altNumMax; - ptr = (const unsigned char **) calloc( numMax, sizeof( char * ) ); - end = (const unsigned char **) calloc( numMax, sizeof( char * ) ); + ptr = (const char **) calloc( numMax, sizeof( char * ) ); + end = (const char **) calloc( numMax, sizeof( char * ) ); del = (int *) calloc( numMax, sizeof( int ) ); if ( ptr == NULL || end == NULL || del == NULL ) goto error; @@ -80,7 +79,7 @@ epicsShareAPI macParseDefns( del[0] = FALSE; quote = 0; state = preName; - for ( c = (const unsigned char *) defns; *c != '\0'; c++ ) { + for ( c = (const char *) defns; *c != '\0'; c++ ) { /* handle quotes */ if ( quote ) From 2d520674842e4e4b177ac217890d349c091e3c0d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 19 Nov 2013 15:26:22 -0600 Subject: [PATCH 18/38] libCom: Clean up build warnings from Visual Studio. --- src/libCom/calc/postfix.c | 10 +++++----- src/libCom/macLib/macUtil.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libCom/calc/postfix.c b/src/libCom/calc/postfix.c index 168c0f03d..ca25bea42 100644 --- a/src/libCom/calc/postfix.c +++ b/src/libCom/calc/postfix.c @@ -205,7 +205,7 @@ static int * convert an infix expression to a postfix expression */ epicsShareFunc long - postfix(const char *psrc, char * const ppostfix, short *perror) + postfix(const char *psrc, char *pout, short *perror) { ELEMENT stack[80]; ELEMENT *pstacktop = stack; @@ -213,7 +213,7 @@ epicsShareFunc long int operand_needed = TRUE; int runtime_depth = 0; int cond_count = 0; - char *pout = ppostfix; + char * const pdest = pout; char *pnext; double lit_d; int lit_i; @@ -249,7 +249,7 @@ epicsShareFunc long goto bad; } psrc = pnext; - lit_i = lit_d; + lit_i = (int) lit_d; if (lit_d != (double) lit_i) { *pout++ = pel->code; memcpy(pout, (void *)&lit_d, sizeof(double)); @@ -276,7 +276,7 @@ epicsShareFunc long break; case STORE_OPERATOR: - if (pout == ppostfix || pstacktop > stack || + if (pout == pdest || pstacktop > stack || *--pout < FETCH_A || *pout > FETCH_L) { *perror = CALC_ERR_BAD_ASSIGNMENT; goto bad; @@ -477,7 +477,7 @@ epicsShareFunc long return 0; bad: - *ppostfix = END_EXPRESSION; + *pdest = END_EXPRESSION; return -1; } diff --git a/src/libCom/macLib/macUtil.c b/src/libCom/macLib/macUtil.c index a18d36037..ee7b53f7f 100644 --- a/src/libCom/macLib/macUtil.c +++ b/src/libCom/macLib/macUtil.c @@ -225,8 +225,8 @@ epicsShareAPI macParseDefns( } /* free workspace */ - free( ptr ); - free( end ); + free( ( void * ) ptr ); + free( ( void * ) end ); free( ( char * ) del ); /* debug output */ @@ -239,8 +239,8 @@ epicsShareAPI macParseDefns( /* error exit */ error: errlogPrintf( "macParseDefns: failed to allocate memory\n" ); - if ( ptr != NULL ) free( ptr ); - if ( end != NULL ) free( end ); + if ( ptr != NULL ) free( ( void * ) ptr ); + if ( end != NULL ) free( ( void * ) end ); if ( del != NULL ) free( ( char * ) del ); *pairs = NULL; return -1; From 176ee926ad9a5603234c55d4018aa6942c0bf770 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 19 Nov 2013 18:41:03 -0600 Subject: [PATCH 19/38] cygwin: Fixed SocketSystemCallInterruptMechanism Cygwin changed it back again. --- src/libCom/osi/os/cygwin32/systemCallIntMech.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp b/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp index bca269532..ee97f8b3e 100644 --- a/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp +++ b/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp @@ -21,8 +21,8 @@ enum epicsSocketSystemCallInterruptMechanismQueryInfo epicsSocketSystemCallInterruptMechanismQuery () { -#if (CYGWIN_VERSION_DLL_MAJOR >= 1007) - // Behaviour changed in Cygwin 1.7 release. +#if 0 + // Some broken versions of cygwin needed this: return esscimqi_socketCloseRequired; #else return esscimqi_socketBothShutdownRequired; From 93be1400c1a695e7e3fb16401f621f80ac99226f Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 19 Nov 2013 18:42:45 -0600 Subject: [PATCH 20/38] Fixed various 64-bit windows build issues. --- src/gdd/gdd.cc | 12 ++++++------ src/libCom/bucketLib/bucketLib.c | 8 ++++---- src/libCom/osi/os/WIN32/osdMutex.c | 4 +++- src/libCom/osi/os/WIN32/osdThread.c | 4 ++-- src/libCom/osi/os/default/devLibVMEOSD.c | 3 ++- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/gdd/gdd.cc b/src/gdd/gdd.cc index ea8e1ba5b..2ff4675fe 100644 --- a/src/gdd/gdd.cc +++ b/src/gdd/gdd.cc @@ -594,7 +594,7 @@ size_t gdd::describedDataSizeBytes(void) const size_t gdd::getTotalSizeBytes(void) const { size_t sz; - unsigned long tsize; + size_t tsize; const gdd* pdd; // add up size of bounds + size of this DD @@ -924,8 +924,8 @@ int gdd::flattenDDs(gddContainer* dd, void* buf, size_t size) gddStatus gdd::convertOffsetsToAddress(void) { aitUint8* pdd = (aitUint8*)this; - unsigned long bnds = (unsigned long)(bounds); - unsigned long dp = (unsigned long)(dataPointer()); + size_t bnds = (size_t)(bounds); + size_t dp = (size_t)(dataPointer()); gdd* tdd; gddContainer* cdd; gddCursor cur; @@ -943,7 +943,7 @@ gddStatus gdd::convertOffsetsToAddress(void) for(tdd=cur.first();tdd;tdd=cur.next()) { - if(tdd->next()) tdd->setNext((gdd*)(pdd+(unsigned long)tdd->next())); + if(tdd->next()) tdd->setNext((gdd*)(pdd+(size_t)tdd->next())); tdd->convertOffsetsToAddress(); } } @@ -962,7 +962,7 @@ gddStatus gdd::convertOffsetsToAddress(void) if(str[i].string()) { cstr=str[i].string(); - str[i].installBuf((char *)(pdd+(unsigned long)cstr), + str[i].installBuf((char *)(pdd+(size_t)cstr), str[i].length(), str[i].length()+1); } else @@ -982,7 +982,7 @@ gddStatus gdd::convertOffsetsToAddress(void) if(str->string()) { cstr=str->string(); - str->installBuf((char *)(pdd+(unsigned long)cstr), + str->installBuf((char *)(pdd+(size_t)cstr), str->length(), str->length()+1u); } else diff --git a/src/libCom/bucketLib/bucketLib.c b/src/libCom/bucketLib/bucketLib.c index 9fd887b6d..1f68e1d97 100644 --- a/src/libCom/bucketLib/bucketLib.c +++ b/src/libCom/bucketLib/bucketLib.c @@ -167,16 +167,16 @@ static BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId) static BUCKETID bucketPointerHash (BUCKET *pb, const void *pId) { void * const *ppId = (void * const *) pId; - unsigned long src; + size_t src; BUCKETID hashid; /* - * This makes the assumption that - * a pointer will fit inside of a long + * This makes the assumption that size_t + * can be used to hold a pointer value * (this assumption may not port to all * CPU architectures) */ - src = (unsigned long) *ppId; + src = (size_t) *ppId; hashid = src; src = src >> pb->hashIdNBits; while(src){ diff --git a/src/libCom/osi/os/WIN32/osdMutex.c b/src/libCom/osi/os/WIN32/osdMutex.c index 63c039eef..710151848 100644 --- a/src/libCom/osi/os/WIN32/osdMutex.c +++ b/src/libCom/osi/os/WIN32/osdMutex.c @@ -38,7 +38,9 @@ * It appears that the only entry point used here that causes * portability problems with W95\W98\WME is TryEnterCriticalSection. */ -#define _WIN32_WINNT 0x0400 +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +#endif #include #define epicsExportSharedSymbols diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c index a3125e1f5..c15161c6f 100644 --- a/src/libCom/osi/os/WIN32/osdThread.c +++ b/src/libCom/osi/os/WIN32/osdThread.c @@ -22,8 +22,8 @@ #define VC_EXTRALEAN #define STRICT -#if _WIN64 -# define _WIN32_WINNT 0x400 /* defining this drops support for W95 */ +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x400 /* No support for W95 */ #endif #include #include /* for _endthread() etc */ diff --git a/src/libCom/osi/os/default/devLibVMEOSD.c b/src/libCom/osi/os/default/devLibVMEOSD.c index 1b968e9c2..1b4fa7a66 100644 --- a/src/libCom/osi/os/default/devLibVMEOSD.c +++ b/src/libCom/osi/os/default/devLibVMEOSD.c @@ -10,8 +10,9 @@ #include +#define epicsExportSharedSymbols #include "devLibVME.h" /* This file must contain no definitions other than the following: */ -devLibVME *pdevLibVME; +epicsShareDef devLibVME *pdevLibVME; From 570993e32ba61bce5300486a5992b2efbfa19a56 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 19 Nov 2013 18:50:49 -0600 Subject: [PATCH 21/38] configure: New targets cygwin-x86_64 and windows-x64-mingw --- configure/CONFIG_SITE | 2 ++ configure/os/CONFIG.Common.cygwin-x86_64 | 14 ++++++++++++++ configure/os/CONFIG.Common.windows-x64-mingw | 15 +++++++++++++++ configure/os/CONFIG.cygwin-x86_64.Common | 10 ++++++++++ .../os/CONFIG.cygwin-x86_64.cygwin-x86_64 | 11 +++++++++++ .../os/CONFIG.win32-x86-mingw.win32-x86-mingw | 19 ++++++++++--------- configure/os/CONFIG.windows-x64-mingw.Common | 11 +++++++++++ ...CONFIG.windows-x64-mingw.windows-x64-mingw | 11 +++++++++++ configure/os/CONFIG_SITE.Common.cygwin-x86_64 | 14 ++++++++++++++ ...G_SITE.windows-x64-mingw.windows-x64-mingw | 9 +++++++++ documentation/RELEASE_NOTES.html | 4 ++++ 11 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 configure/os/CONFIG.Common.cygwin-x86_64 create mode 100644 configure/os/CONFIG.Common.windows-x64-mingw create mode 100644 configure/os/CONFIG.cygwin-x86_64.Common create mode 100644 configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64 create mode 100644 configure/os/CONFIG.windows-x64-mingw.Common create mode 100644 configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw create mode 100644 configure/os/CONFIG_SITE.Common.cygwin-x86_64 create mode 100644 configure/os/CONFIG_SITE.windows-x64-mingw.windows-x64-mingw diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE index f60c7662a..57779f637 100644 --- a/configure/CONFIG_SITE +++ b/configure/CONFIG_SITE @@ -19,6 +19,7 @@ # aix-ppc (IBM compiler used for host builds) # aix-ppc-gnu (GNU compiler used for host builds) # cygwin-x86 (cygwin compiler used for host builds) +# cygwin-x86_64 (cygwin compiler used for host builds) # darwin-ppc (PowerPC based Apple running OSX) # darwin-ppcx86 (Universal binaries for both CPUs) # darwin-x86 (Intel based Apple running OSX) @@ -41,6 +42,7 @@ # win32-x86-cygwin (WIN32 API with cygwin GNU compiler used for host builds) # win32-x86-mingw (MinGW compiler used for host builds) # windows-x64 (MS Visual C++ compiler used for host builds) +# windows-x64-mingw (MinGW compiler used for host builds) # Debugging builds # linux-x86-debug (GNU compiler with -g option for host builds) diff --git a/configure/os/CONFIG.Common.cygwin-x86_64 b/configure/os/CONFIG.Common.cygwin-x86_64 new file mode 100644 index 000000000..380e686be --- /dev/null +++ b/configure/os/CONFIG.Common.cygwin-x86_64 @@ -0,0 +1,14 @@ +# CONFIG.Common.cygwin-x86_64 +# +# $Revision-Id$ +# This file is maintained by the build community. +# +# Definitions for cygwin-x86_64 target builds +# Sites may override these definitions in CONFIG_SITE.Common.cygwin-x86_64 +#------------------------------------------------------- + +include $(CONFIG)/os/CONFIG.Common.cygwin-x86 + +ARCH_DEP_CFLAGS = -m64 +ARCH_DEP_LDFLAGS = -m64 + diff --git a/configure/os/CONFIG.Common.windows-x64-mingw b/configure/os/CONFIG.Common.windows-x64-mingw new file mode 100644 index 000000000..b2943af16 --- /dev/null +++ b/configure/os/CONFIG.Common.windows-x64-mingw @@ -0,0 +1,15 @@ +# CONFIG.Common.windows-x64-mingw +# +# $Revision-Id$ +# This file is maintained by the build community. +# +# Definitions for windows-x64-mingw target builds +# Sites may override these definitions in CONFIG_SITE.Common.windows-x64-mingw +#------------------------------------------------------- + +include $(CONFIG)/os/CONFIG.Common.win32-x86-mingw + +ARCH_CLASS = x64 + +ARCH_DEP_CFLAGS = -m64 +ARCH_DEP_LDFLAGS = -m64 diff --git a/configure/os/CONFIG.cygwin-x86_64.Common b/configure/os/CONFIG.cygwin-x86_64.Common new file mode 100644 index 000000000..ff6c3e2c8 --- /dev/null +++ b/configure/os/CONFIG.cygwin-x86_64.Common @@ -0,0 +1,10 @@ +# CONFIG.cygwin-x86_64.Common +# +# $Revision-Id$ +# This file is maintained by the build community. +# +# Definitions for cygwin-x86_64 host archs +# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.Common +#------------------------------------------------------- + +include $(CONFIG)/os/CONFIG.cygwin-x86.Common diff --git a/configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64 b/configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64 new file mode 100644 index 000000000..20a52a6d8 --- /dev/null +++ b/configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64 @@ -0,0 +1,11 @@ +# CONFIG.cygwin-x86_64.cygwin-x86_64 +# +# $Revision-Id$ +# +# Definitions for cygwin-x86_64 host - cygwin-x86_64 target builds +# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.cygwin-x86_64 +#------------------------------------------------------- + +# Include common gnu compiler definitions +include $(CONFIG)/os/CONFIG.cygwin-x86.cygwin-x86 + diff --git a/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw b/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw index 8309f8b45..96fa115fc 100644 --- a/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw +++ b/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw @@ -9,14 +9,15 @@ # Include common gnu compiler definitions include $(CONFIG)/CONFIG.gnuCommon -# gcc, g++, ar, ld, and ranlib must be in user's path -CC = gcc -CCC = g++ -AR = ar -rc -LD = ld -r -RANLIB = ranlib -RES=.coff -RCCMD = windres $(INCLUDES) $< $@ +CMPLR_PREFIX = + +CC = $(CMPLR_PREFIX)gcc +CCC = $(CMPLR_PREFIX)g++ +AR = $(CMPLR_PREFIX)ar -rc +LD = $(CMPLR_PREFIX)ld -r +RANLIB = $(CMPLR_PREFIX)ranlib +RES = .coff +RCCMD = $(CMPLR_PREFIX)windres $(INCLUDES) $< $@ # No -fPIC avoids "-fPIC ignored for target (all code is position independent)" SHRLIB_CFLAGS = @@ -26,4 +27,4 @@ LOADABLE_SHRLIB_LDFLAGS = -shared -Wl,--out-implib,$(LIB_PREFIX)$*$(LIB_SUFFIX) # Override linking with gcc library from CONFIG.gnuCommon GNU_LDLIBS_YES = -OP_SYS_LDLIBS = -lws2_32 +OP_SYS_LDLIBS = -lws2_32 diff --git a/configure/os/CONFIG.windows-x64-mingw.Common b/configure/os/CONFIG.windows-x64-mingw.Common new file mode 100644 index 000000000..c467a3a51 --- /dev/null +++ b/configure/os/CONFIG.windows-x64-mingw.Common @@ -0,0 +1,11 @@ +# CONFIG.windows-x64-mingw.Common +# +# $Revision-Id$ +# This file is maintained by the build community. +# +# Definitions for windows-x64-mingw host archs +# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.Common +#------------------------------------------------------- + +include $(CONFIG)/os/CONFIG.win32-x86-mingw.Common + diff --git a/configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw b/configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw new file mode 100644 index 000000000..9e42784aa --- /dev/null +++ b/configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw @@ -0,0 +1,11 @@ +# CONFIG.windows-x64-mingw.windows-x64-mingw +# +# $Revision-Id$ +# This file is maintained by the build community. +# +# Definitions for windows-x64-mingw target archs +# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.windows-x64-mingw +#------------------------------------------------------- + +# Include common gnu compiler definitions +include $(CONFIG)/os/CONFIG.win32-x86-mingw.win32-x86-mingw diff --git a/configure/os/CONFIG_SITE.Common.cygwin-x86_64 b/configure/os/CONFIG_SITE.Common.cygwin-x86_64 new file mode 100644 index 000000000..3950526d1 --- /dev/null +++ b/configure/os/CONFIG_SITE.Common.cygwin-x86_64 @@ -0,0 +1,14 @@ +# CONFIG_SITE.Common.cygwin-x86_64 +# +# $Revision-Id$ +# +# Site Specific definitions for cygwin-x86_64 target +# Only the local epics system manager should modify this file + +# If readline is installed uncomment the following line +# to add command-line editing and history support +#COMMANDLINE_LIBRARY = READLINE + +# Uncomment the following line if readline has problems +#LDLIBS_READLINE = -lreadline -lcurses + diff --git a/configure/os/CONFIG_SITE.windows-x64-mingw.windows-x64-mingw b/configure/os/CONFIG_SITE.windows-x64-mingw.windows-x64-mingw new file mode 100644 index 000000000..bdb8c995e --- /dev/null +++ b/configure/os/CONFIG_SITE.windows-x64-mingw.windows-x64-mingw @@ -0,0 +1,9 @@ +# CONFIG_SITE.windows-x64-mingw.windows-x64-mingw +# +# $Revision-Id$ +# +# Site Specific definitions for windows-x64-mingw target +# Only the local epics system manager should modify this file + +# Prefix for mingw compiler from cygwin +#CMPLR_PREFIX = x86_64-w64-mingw32- diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index dd1256064..9dc7e4fac 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -13,6 +13,10 @@ +

    Added support for 64-bit Cygwin and MinGW targets

    + +

    Both windows-x64-mingw and cygwin-x86_64 build targets are now provided.

    +

    CAS: GDD Reference Count Underflow

    Thanks to Bruce Hill a source of an underflow in a GDD reference count in the From 9ab6f8960445e01a7e39c419ea07a7a7c5ad3407 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 20 Nov 2013 16:21:10 -0600 Subject: [PATCH 22/38] Clean up epicsExport.h includes Mostly in record and device support, this commit puts the include in the right place and moves some other includes around to get the order right. --- src/dbStatic/dbLexRoutines.c | 1 - src/dev/softDev/devGeneralTime.c | 2 +- src/dev/softDev/devSoStdio.c | 2 +- src/dev/softDev/devTimestamp.c | 3 +-- src/dev/testDev/devTestAsyn.c | 1 + src/rec/aSubRecord.c | 2 +- src/rec/aaiRecord.c | 1 + src/rec/aaoRecord.c | 1 + src/rec/aiRecord.c | 1 + src/rec/aoRecord.c | 3 ++- src/rec/biRecord.c | 2 ++ src/rec/boRecord.c | 7 ++++--- src/rec/calcRecord.c | 1 + src/rec/calcoutRecord.c | 4 ++-- src/rec/compressRecord.c | 1 + src/rec/dfanoutRecord.c | 1 + src/rec/eventRecord.c | 1 + src/rec/fanoutRecord.c | 1 + src/rec/histogramRecord.c | 1 + src/rec/longinRecord.c | 1 + src/rec/longoutRecord.c | 7 ++++--- src/rec/mbbiDirectRecord.c | 1 + src/rec/mbbiRecord.c | 2 ++ src/rec/mbboDirectRecord.c | 7 ++++--- src/rec/mbboRecord.c | 7 ++++--- src/rec/permissiveRecord.c | 1 + src/rec/selRecord.c | 1 + src/rec/stateRecord.c | 1 + src/rec/stringinRecord.c | 3 ++- src/rec/stringoutRecord.c | 9 +++++---- src/rec/subArrayRecord.c | 1 + src/rec/subRecord.c | 1 + src/rec/waveformRecord.c | 3 ++- 33 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/dbStatic/dbLexRoutines.c b/src/dbStatic/dbLexRoutines.c index 3620cc7b9..9932dceae 100644 --- a/src/dbStatic/dbLexRoutines.c +++ b/src/dbStatic/dbLexRoutines.c @@ -31,7 +31,6 @@ #include "epicsString.h" #include "epicsExport.h" -#define epicsExportSharedSymbols #include "dbFldTypes.h" #include "link.h" #include "dbStaticLib.h" diff --git a/src/dev/softDev/devGeneralTime.c b/src/dev/softDev/devGeneralTime.c index 4c42a80f4..c656c85db 100644 --- a/src/dev/softDev/devGeneralTime.c +++ b/src/dev/softDev/devGeneralTime.c @@ -24,12 +24,12 @@ #include "devSup.h" #include "epicsString.h" #include "epicsGeneralTime.h" -#include "epicsExport.h" #include "aiRecord.h" #include "boRecord.h" #include "longinRecord.h" #include "stringinRecord.h" +#include "epicsExport.h" /********* ai record **********/ diff --git a/src/dev/softDev/devSoStdio.c b/src/dev/softDev/devSoStdio.c index c720f7e4e..684dab178 100644 --- a/src/dev/softDev/devSoStdio.c +++ b/src/dev/softDev/devSoStdio.c @@ -15,9 +15,9 @@ #include "errlog.h" #include "recGbl.h" #include "recSup.h" -#include "epicsExport.h" #include "stringoutRecord.h" +#include "epicsExport.h" typedef int (*PRINTFFUNC)(const char *fmt, ...); diff --git a/src/dev/softDev/devTimestamp.c b/src/dev/softDev/devTimestamp.c index f8de440c4..b7e2c7e1a 100644 --- a/src/dev/softDev/devTimestamp.c +++ b/src/dev/softDev/devTimestamp.c @@ -17,11 +17,10 @@ #include "alarm.h" #include "devSup.h" #include "recGbl.h" -#include "epicsExport.h" #include "aiRecord.h" #include "stringinRecord.h" - +#include "epicsExport.h" /* Extended device support to allow INP field changes */ diff --git a/src/dev/testDev/devTestAsyn.c b/src/dev/testDev/devTestAsyn.c index 52adcd39e..4b1d8a5e9 100644 --- a/src/dev/testDev/devTestAsyn.c +++ b/src/dev/testDev/devTestAsyn.c @@ -20,6 +20,7 @@ #include "callback.h" #include "devSup.h" #include "dbCommon.h" + #include "epicsExport.h" static long addRec(struct dbCommon *prec) diff --git a/src/rec/aSubRecord.c b/src/rec/aSubRecord.c index fd96ede20..ccf4af9bd 100644 --- a/src/rec/aSubRecord.c +++ b/src/rec/aSubRecord.c @@ -32,12 +32,12 @@ #include "devSup.h" #include "special.h" #include "registryFunction.h" -#include "epicsExport.h" #include "recGbl.h" #define GEN_SIZE_OFFSET #include "aSubRecord.h" #undef GEN_SIZE_OFFSET +#include "epicsExport.h" typedef long (*GENFUNCPTR)(struct aSubRecord *); diff --git a/src/rec/aaiRecord.c b/src/rec/aaiRecord.c index 5c88791c4..04797fd1c 100644 --- a/src/rec/aaiRecord.c +++ b/src/rec/aaiRecord.c @@ -41,6 +41,7 @@ #include "recGbl.h" #include "cantProceed.h" #include "menuYesNo.h" + #define GEN_SIZE_OFFSET #include "aaiRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/aaoRecord.c b/src/rec/aaoRecord.c index 695f8e1b1..318e29d3c 100644 --- a/src/rec/aaoRecord.c +++ b/src/rec/aaoRecord.c @@ -41,6 +41,7 @@ #include "recGbl.h" #include "cantProceed.h" #include "menuYesNo.h" + #define GEN_SIZE_OFFSET #include "aaoRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/aiRecord.c b/src/rec/aiRecord.c index e6977005f..57ea32163 100644 --- a/src/rec/aiRecord.c +++ b/src/rec/aiRecord.c @@ -36,6 +36,7 @@ #include "recGbl.h" #include "special.h" #include "menuConvert.h" + #define GEN_SIZE_OFFSET #include "aiRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/aoRecord.c b/src/rec/aoRecord.c index bce43e3e4..e4fb7e533 100644 --- a/src/rec/aoRecord.c +++ b/src/rec/aoRecord.c @@ -37,10 +37,11 @@ #include "menuConvert.h" #include "menuOmsl.h" #include "menuYesNo.h" +#include "menuIvoa.h" + #define GEN_SIZE_OFFSET #include "aoRecord.h" #undef GEN_SIZE_OFFSET -#include "menuIvoa.h" #include "epicsExport.h" /* Create RSET - Record Support Entry Table*/ diff --git a/src/rec/biRecord.c b/src/rec/biRecord.c index b58bb65d5..1ba7b129b 100644 --- a/src/rec/biRecord.c +++ b/src/rec/biRecord.c @@ -34,10 +34,12 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" + #define GEN_SIZE_OFFSET #include "biRecord.h" #undef GEN_SIZE_OFFSET #include "epicsExport.h" + /* Create RSET - Record Support Entry Table*/ #define report NULL #define initialize NULL diff --git a/src/rec/boRecord.c b/src/rec/boRecord.c index 5248bd661..ee21ce56d 100644 --- a/src/rec/boRecord.c +++ b/src/rec/boRecord.c @@ -33,12 +33,13 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" -#define GEN_SIZE_OFFSET -#include "boRecord.h" -#undef GEN_SIZE_OFFSET #include "menuIvoa.h" #include "menuOmsl.h" #include "menuYesNo.h" + +#define GEN_SIZE_OFFSET +#include "boRecord.h" +#undef GEN_SIZE_OFFSET #include "epicsExport.h" /* Create RSET - Record Support Entry Table*/ diff --git a/src/rec/calcRecord.c b/src/rec/calcRecord.c index 8accf60d9..1bff7b85f 100644 --- a/src/rec/calcRecord.c +++ b/src/rec/calcRecord.c @@ -32,6 +32,7 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" + #define GEN_SIZE_OFFSET #include "calcRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/calcoutRecord.c b/src/rec/calcoutRecord.c index 89265f3cc..37951f32f 100644 --- a/src/rec/calcoutRecord.c +++ b/src/rec/calcoutRecord.c @@ -36,13 +36,13 @@ #include "special.h" #include "callback.h" #include "taskwd.h" +#include "menuIvoa.h" #define GEN_SIZE_OFFSET #include "calcoutRecord.h" #undef GEN_SIZE_OFFSET -#include "menuIvoa.h" #include "epicsExport.h" - + /* Create RSET - Record Support Entry Table*/ #define report NULL #define initialize NULL diff --git a/src/rec/compressRecord.c b/src/rec/compressRecord.c index 2879852d8..d0539b218 100644 --- a/src/rec/compressRecord.c +++ b/src/rec/compressRecord.c @@ -31,6 +31,7 @@ #include "special.h" #include "recSup.h" #include "recGbl.h" + #define GEN_SIZE_OFFSET #include "compressRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/dfanoutRecord.c b/src/rec/dfanoutRecord.c index 723d1a59c..382c5a46f 100644 --- a/src/rec/dfanoutRecord.c +++ b/src/rec/dfanoutRecord.c @@ -38,6 +38,7 @@ #include "recGbl.h" #include "special.h" #include "menuOmsl.h" + #define GEN_SIZE_OFFSET #include "dfanoutRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/eventRecord.c b/src/rec/eventRecord.c index b8cc2b208..9977640f0 100644 --- a/src/rec/eventRecord.c +++ b/src/rec/eventRecord.c @@ -33,6 +33,7 @@ #include "recSup.h" #include "recGbl.h" #include "menuYesNo.h" + #define GEN_SIZE_OFFSET #include "eventRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/fanoutRecord.c b/src/rec/fanoutRecord.c index 1b11056a3..4a76b9ddd 100644 --- a/src/rec/fanoutRecord.c +++ b/src/rec/fanoutRecord.c @@ -29,6 +29,7 @@ #include "recSup.h" #include "recGbl.h" #include "dbCommon.h" + #define GEN_SIZE_OFFSET #include "fanoutRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/histogramRecord.c b/src/rec/histogramRecord.c index e78be26c5..f794f315c 100644 --- a/src/rec/histogramRecord.c +++ b/src/rec/histogramRecord.c @@ -37,6 +37,7 @@ #include "recSup.h" #include "recGbl.h" #include "menuYesNo.h" + #define GEN_SIZE_OFFSET #include "histogramRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/longinRecord.c b/src/rec/longinRecord.c index 011b6c882..176b3b5e0 100644 --- a/src/rec/longinRecord.c +++ b/src/rec/longinRecord.c @@ -32,6 +32,7 @@ #include "recSup.h" #include "recGbl.h" #include "menuYesNo.h" + #define GEN_SIZE_OFFSET #include "longinRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/longoutRecord.c b/src/rec/longoutRecord.c index d7d53d44f..ce0ab80d7 100644 --- a/src/rec/longoutRecord.c +++ b/src/rec/longoutRecord.c @@ -29,13 +29,14 @@ #include "recSup.h" #include "recGbl.h" #include "menuYesNo.h" +#include "menuIvoa.h" +#include "menuOmsl.h" + #define GEN_SIZE_OFFSET #include "longoutRecord.h" #undef GEN_SIZE_OFFSET -#include "menuIvoa.h" -#include "menuOmsl.h" #include "epicsExport.h" - + /* Create RSET - Record Support Entry Table*/ #define report NULL #define initialize NULL diff --git a/src/rec/mbbiDirectRecord.c b/src/rec/mbbiDirectRecord.c index e8942a75f..f6591e274 100644 --- a/src/rec/mbbiDirectRecord.c +++ b/src/rec/mbbiDirectRecord.c @@ -34,6 +34,7 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" + #define GEN_SIZE_OFFSET #include "mbbiDirectRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/mbbiRecord.c b/src/rec/mbbiRecord.c index 6a1ef943d..0a07ba1a1 100644 --- a/src/rec/mbbiRecord.c +++ b/src/rec/mbbiRecord.c @@ -32,10 +32,12 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" + #define GEN_SIZE_OFFSET #include "mbbiRecord.h" #undef GEN_SIZE_OFFSET #include "epicsExport.h" + /* Create RSET - Record Support Entry Table*/ #define report NULL #define initialize NULL diff --git a/src/rec/mbboDirectRecord.c b/src/rec/mbboDirectRecord.c index 3d3a419f0..8ec8a3acd 100644 --- a/src/rec/mbboDirectRecord.c +++ b/src/rec/mbboDirectRecord.c @@ -32,12 +32,13 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" -#define GEN_SIZE_OFFSET -#include "mbboDirectRecord.h" -#undef GEN_SIZE_OFFSET #include "menuOmsl.h" #include "menuIvoa.h" #include "menuYesNo.h" + +#define GEN_SIZE_OFFSET +#include "mbboDirectRecord.h" +#undef GEN_SIZE_OFFSET #include "epicsExport.h" /* Create RSET - Record Support Entry Table*/ diff --git a/src/rec/mbboRecord.c b/src/rec/mbboRecord.c index 5df97ff07..79a3c8227 100644 --- a/src/rec/mbboRecord.c +++ b/src/rec/mbboRecord.c @@ -33,12 +33,13 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" -#define GEN_SIZE_OFFSET -#include "mbboRecord.h" -#undef GEN_SIZE_OFFSET #include "menuOmsl.h" #include "menuIvoa.h" #include "menuYesNo.h" + +#define GEN_SIZE_OFFSET +#include "mbboRecord.h" +#undef GEN_SIZE_OFFSET #include "epicsExport.h" /* Create RSET - Record Support Entry Table*/ diff --git a/src/rec/permissiveRecord.c b/src/rec/permissiveRecord.c index a1d96d151..65077253a 100644 --- a/src/rec/permissiveRecord.c +++ b/src/rec/permissiveRecord.c @@ -29,6 +29,7 @@ #include "errMdef.h" #include "recSup.h" #include "recGbl.h" + #define GEN_SIZE_OFFSET #include "permissiveRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/selRecord.c b/src/rec/selRecord.c index 6174dab3d..52f22b74b 100644 --- a/src/rec/selRecord.c +++ b/src/rec/selRecord.c @@ -31,6 +31,7 @@ #include "errMdef.h" #include "recSup.h" #include "recGbl.h" + #define GEN_SIZE_OFFSET #include "selRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/stateRecord.c b/src/rec/stateRecord.c index 193d7ca51..b295ccbb7 100644 --- a/src/rec/stateRecord.c +++ b/src/rec/stateRecord.c @@ -30,6 +30,7 @@ #include "errMdef.h" #include "recSup.h" #include "recGbl.h" + #define GEN_SIZE_OFFSET #include "stateRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/stringinRecord.c b/src/rec/stringinRecord.c index bff03b4fc..02f454788 100644 --- a/src/rec/stringinRecord.c +++ b/src/rec/stringinRecord.c @@ -33,11 +33,12 @@ #include "recSup.h" #include "recGbl.h" #include "menuYesNo.h" + #define GEN_SIZE_OFFSET #include "stringinRecord.h" #undef GEN_SIZE_OFFSET #include "epicsExport.h" - + /* Create RSET - Record Support Entry Table*/ #define report NULL #define initialize NULL diff --git a/src/rec/stringoutRecord.c b/src/rec/stringoutRecord.c index 1555f5b61..64532a601 100644 --- a/src/rec/stringoutRecord.c +++ b/src/rec/stringoutRecord.c @@ -32,14 +32,15 @@ #include "errMdef.h" #include "recSup.h" #include "recGbl.h" -#define GEN_SIZE_OFFSET -#include "stringoutRecord.h" -#undef GEN_SIZE_OFFSET #include "menuOmsl.h" #include "menuIvoa.h" #include "menuYesNo.h" + +#define GEN_SIZE_OFFSET +#include "stringoutRecord.h" +#undef GEN_SIZE_OFFSET #include "epicsExport.h" - + /* Create RSET - Record Support Entry Table*/ #define report NULL #define initialize NULL diff --git a/src/rec/subArrayRecord.c b/src/rec/subArrayRecord.c index dc18a6ad3..d24eb77dd 100644 --- a/src/rec/subArrayRecord.c +++ b/src/rec/subArrayRecord.c @@ -37,6 +37,7 @@ #include "recSup.h" #include "recGbl.h" #include "cantProceed.h" + #define GEN_SIZE_OFFSET #include "subArrayRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/subRecord.c b/src/rec/subRecord.c index b16a89c3c..dd31e4ab5 100644 --- a/src/rec/subRecord.c +++ b/src/rec/subRecord.c @@ -35,6 +35,7 @@ #include "recSup.h" #include "recGbl.h" #include "special.h" + #define GEN_SIZE_OFFSET #include "subRecord.h" #undef GEN_SIZE_OFFSET diff --git a/src/rec/waveformRecord.c b/src/rec/waveformRecord.c index 6cd7a05b4..918a7b0a9 100644 --- a/src/rec/waveformRecord.c +++ b/src/rec/waveformRecord.c @@ -23,6 +23,7 @@ #include "dbDefs.h" #include "epicsPrint.h" +#include "epicsString.h" #include "alarm.h" #include "dbAccess.h" #include "dbEvent.h" @@ -34,11 +35,11 @@ #include "recGbl.h" #include "cantProceed.h" #include "menuYesNo.h" + #define GEN_SIZE_OFFSET #include "waveformRecord.h" #undef GEN_SIZE_OFFSET #include "epicsExport.h" -#include "epicsString.h" /* Create RSET - Record Support Entry Table*/ #define report NULL From 1a3e7414b35f45188b3ac9d30fc0e7c483c14ca3 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 20 Nov 2013 18:02:28 -0600 Subject: [PATCH 23/38] Creating 3.14.12.4-pre1 --- configure/CONFIG_BASE_VERSION | 6 +++--- documentation/RELEASE_NOTES.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index 06822ea70..3e1c804c9 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -30,11 +30,11 @@ EPICS_MODIFICATION = 12 # EPICS_PATCH_LEVEL must be a number (win32 resource file requirement) # Not included if zero -EPICS_PATCH_LEVEL = 3 +EPICS_PATCH_LEVEL = 4 # This will end in -DEV between official releases -EPICS_DEV_SNAPSHOT=-DEV -#EPICS_DEV_SNAPSHOT=-pre1 +#EPICS_DEV_SNAPSHOT=-DEV +EPICS_DEV_SNAPSHOT=-pre1 #EPICS_DEV_SNAPSHOT=-pre1-DEV #EPICS_DEV_SNAPSHOT=-pre2 #EPICS_DEV_SNAPSHOT=-pre2-DEV diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 9dc7e4fac..cdbca97cf 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -3,11 +3,11 @@ - EPICS Base R3.14.12.3 Release Notes + EPICS Base R3.14.12.4-pre1 Release Notes -

    EPICS Base Release 3.14.12.3

    +

    EPICS Base Release 3.14.12.4-pre1

    Changes between 3.14.12.3 and 3.14.12.4

    From bd825542996077ebbd3ca649a04138d0cdcecd3f Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 20 Nov 2013 18:03:16 -0600 Subject: [PATCH 24/38] Set snapshot to 3.14.12.4-pre1-DEV --- configure/CONFIG_BASE_VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index 3e1c804c9..3e3ab1775 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -34,8 +34,8 @@ EPICS_PATCH_LEVEL = 4 # This will end in -DEV between official releases #EPICS_DEV_SNAPSHOT=-DEV -EPICS_DEV_SNAPSHOT=-pre1 -#EPICS_DEV_SNAPSHOT=-pre1-DEV +#EPICS_DEV_SNAPSHOT=-pre1 +EPICS_DEV_SNAPSHOT=-pre1-DEV #EPICS_DEV_SNAPSHOT=-pre2 #EPICS_DEV_SNAPSHOT=-pre2-DEV #EPICS_DEV_SNAPSHOT=-rc1 From 78a4e462d5538490e8f24cf9d9b083bb043c9cab Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 2 Dec 2013 11:12:19 -0600 Subject: [PATCH 25/38] libCom: Recognize hex literals in epicsStrtod() Allows Windows and VxWorks to accept hex integers as a double. --- documentation/RELEASE_NOTES.html | 8 ++++++++ src/libCom/misc/epicsStdlib.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index cdbca97cf..0b5b01f4e 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -13,6 +13,14 @@ +

    Hex literal support in epicStrtod()

    + +

    Some OS implementations of the standard C library routine strtod() do not +recognize hexadecimal integers, in particular the libraries provided on Windows +and VxWorks. The internal implementation of epicsStrtod() that these targets use +now recognizes the 0x prefix and will convert hex numbers correctly. Thanks to +Dirk Zimoch for suggesting this change.

    +

    Added support for 64-bit Cygwin and MinGW targets

    Both windows-x64-mingw and cygwin-x86_64 build targets are now provided.

    diff --git a/src/libCom/misc/epicsStdlib.c b/src/libCom/misc/epicsStdlib.c index 494fc60be..f1c89aaa3 100644 --- a/src/libCom/misc/epicsStdlib.c +++ b/src/libCom/misc/epicsStdlib.c @@ -60,6 +60,12 @@ epicsShareFunc double epicsStrtod(const char *str, char **endp) cp++; } + if (epicsStrnCaseCmp("0x", cp, 2) == 0) { + if (negative) + return strtol(str, endp, 16); + else + return strtoul(str, endp, 16); + } if (!isalpha((int)*cp)) return strtod(str, endp); From 082df890909d5dcb11ab5fa40024c14594161be3 Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Mon, 2 Dec 2013 13:54:20 -0600 Subject: [PATCH 26/38] Creating 3.14.12.4-rc1 --- configure/CONFIG_BASE_VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index 3e3ab1775..a4d83bff8 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -35,10 +35,10 @@ EPICS_PATCH_LEVEL = 4 # This will end in -DEV between official releases #EPICS_DEV_SNAPSHOT=-DEV #EPICS_DEV_SNAPSHOT=-pre1 -EPICS_DEV_SNAPSHOT=-pre1-DEV +#EPICS_DEV_SNAPSHOT=-pre1-DEV #EPICS_DEV_SNAPSHOT=-pre2 #EPICS_DEV_SNAPSHOT=-pre2-DEV -#EPICS_DEV_SNAPSHOT=-rc1 +EPICS_DEV_SNAPSHOT=-rc1 #EPICS_DEV_SNAPSHOT=-rc1-DEV #EPICS_DEV_SNAPSHOT=-rc2 #EPICS_DEV_SNAPSHOT=-rc2-DEV From 90d1d9568c31411f1979da4488e82cb60aa99963 Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Mon, 2 Dec 2013 13:56:17 -0600 Subject: [PATCH 27/38] Creating 3.14.12.4-rc1 --- documentation/RELEASE_NOTES.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 0b5b01f4e..05132dd45 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -1,13 +1,14 @@ - EPICS Base R3.14.12.4-pre1 Release Notes + EPICS Base R3.14.12.4-rc1 Release Notes -

    EPICS Base Release 3.14.12.4-pre1

    +

    EPICS Base Release 3.14.12.4-rc1

    Changes between 3.14.12.3 and 3.14.12.4

    From 4209abe2cfba492d9dbe7f269d78af49504fc580 Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Mon, 2 Dec 2013 14:12:45 -0600 Subject: [PATCH 28/38] Set snapshot to 3.14.12.4-rc1-DEV --- configure/CONFIG_BASE_VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index a4d83bff8..892c6b2e6 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -38,8 +38,8 @@ EPICS_PATCH_LEVEL = 4 #EPICS_DEV_SNAPSHOT=-pre1-DEV #EPICS_DEV_SNAPSHOT=-pre2 #EPICS_DEV_SNAPSHOT=-pre2-DEV -EPICS_DEV_SNAPSHOT=-rc1 -#EPICS_DEV_SNAPSHOT=-rc1-DEV +#EPICS_DEV_SNAPSHOT=-rc1 +EPICS_DEV_SNAPSHOT=-rc1-DEV #EPICS_DEV_SNAPSHOT=-rc2 #EPICS_DEV_SNAPSHOT=-rc2-DEV #EPICS_DEV_SNAPSHOT= From 4ac35ab85c92456d892bf933a0585116de63f691 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 4 Dec 2013 10:37:44 -0600 Subject: [PATCH 29/38] docs: iPhone Simulator builds broken by Xcode 5 From Mark Engbretson, no known solution yet. --- documentation/RELEASE_NOTES.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 05132dd45..4958fb27f 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -34,7 +34,9 @@ CAS code has been fixed.

    Support for Apple Xcode 5.0

    This adds the ability to build for iOS 7.0 and the ARMv8 64-bit CPU on the -newest iPhone 5S device.

    +newest iPhone 5S device. Unfortunately the Xcode upgrade breaks the build of the +ios-x86 simulator target, although the ios-arm target successfully builds code +which runs fine on the real hardware.

    Reading TSEL field

    From 76e967c960230a355373d442b747f5f5fe01a16a Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 4 Dec 2013 17:37:42 -0600 Subject: [PATCH 30/38] dbStatic: Fixed crash loading record of unknown type Fixed segfault when dbLoadRecords tried to load a record of a type that was not defined in its DBD files. --- documentation/RELEASE_NOTES.html | 5 +++++ src/dbStatic/dbLexRoutines.c | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 4958fb27f..8534b27fe 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -14,6 +14,11 @@ +

    Fixed crash loading record instance of unknown type

    + +

    Fixed segfault when dbLoadRecords tried to load a record of a type that was +not defined in its DBD files.

    +

    Hex literal support in epicStrtod()

    Some OS implementations of the standard C library routine strtod() do not diff --git a/src/dbStatic/dbLexRoutines.c b/src/dbStatic/dbLexRoutines.c index 9932dceae..efa8501df 100644 --- a/src/dbStatic/dbLexRoutines.c +++ b/src/dbStatic/dbLexRoutines.c @@ -112,8 +112,6 @@ static void yyerrorAbort(char *str) { yyerror(str); yyAbort = TRUE; - while (ellCount(&tempList)) - popFirstTemp(); } static void allocTemp(void *pvoid) @@ -256,6 +254,11 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp, my_buffer_ptr = my_buffer; ellAdd(&inputFileList,&pinputFile->node); status = pvt_yy_parse(); + + if (yyAbort) + while (ellCount(&tempList)) + popFirstTemp(); + dbFreePath(pdbbase); if(!status) { /*add RTYP and VERS as an attribute */ DBENTRY dbEntry; @@ -923,7 +926,7 @@ static void dbRecordHead(char *recordType, char *name, int visible) allocTemp(pdbentry); status = dbFindRecordType(pdbentry, recordType); if (status) { - epicsPrintf("Record \"%s\" is of unknown type \"%s\" - ", + epicsPrintf("Record \"%s\" is of unknown type \"%s\"\n", name, recordType); yyerrorAbort(NULL); return; @@ -932,8 +935,8 @@ static void dbRecordHead(char *recordType, char *name, int visible) status = dbCreateRecord(pdbentry,name); if (status==S_dbLib_recExists) { if (strcmp(recordType, dbGetRecordTypeName(pdbentry))!=0) { - epicsPrintf("Record \"%s\" already defined with different type " - "\"%s\"\n", name, dbGetRecordTypeName(pdbentry)); + epicsPrintf("Record \"%s\" of type \"%s\" redefined with new type " + "\"%s\"\n", name, dbGetRecordTypeName(pdbentry), recordType); yyerror(NULL); duplicate = TRUE; return; From b0cf5c256a5e04ea99ac8acbca034ffde6234e77 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 10 Dec 2013 16:28:08 -0600 Subject: [PATCH 31/38] startup: Add cygwin-x86_64 to EpicsHostArch.pl script --- startup/EpicsHostArch.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/startup/EpicsHostArch.pl b/startup/EpicsHostArch.pl index 942d55940..e6babf6d3 100755 --- a/startup/EpicsHostArch.pl +++ b/startup/EpicsHostArch.pl @@ -31,7 +31,10 @@ sub GetEpicsHostArch { # no args } elsif ($arch =~ m/arm-linux/) { return "linux-arm"; } elsif ($arch =~ m/MSWin32-x86/) { return "win32-x86"; } elsif ($arch =~ m/MSWin32-x64/) { return "windows-x64"; - } elsif ($arch =~ m/cygwin/) { return "cygwin-x86"; + } elsif ($arch =~ m/cygwin/) { + my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname(); + if ($cpu =~ m/x86_64/) { return "cygwin-x86_64"; } + return "cygwin-x86"; } elsif ($arch =~ m/darwin/) { my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname(); if ($cpu =~ m/Power Macintosh/) { return "darwin-ppc"; } From 197e992241885faf3ad0f4765fa26a7cc2255041 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 11 Dec 2013 17:50:29 -0600 Subject: [PATCH 32/38] Fixed iocsh stream redirection for several commands Eric provided the fixes to iocsh (empty commands would not reset redirected streams), I fixed various commands. --- documentation/RELEASE_NOTES.html | 12 ++ src/ca/iocinf.cpp | 2 +- src/ca/test_event.cpp | 2 +- src/libCom/gpHash/gpHashLib.c | 20 +-- src/libCom/iocsh/iocsh.cpp | 212 ++++++++++++++++-------------- src/libCom/iocsh/libComRegister.c | 16 +-- src/libCom/osi/epicsGeneralTime.c | 2 +- src/libCom/taskwd/taskwd.c | 2 +- 8 files changed, 148 insertions(+), 120 deletions(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 8534b27fe..0ed88c4a4 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -14,6 +14,18 @@ +

    Fixed iocsh stream redirection for several commands

    + +

    A number of iocsh commands did not respond correctly to redirection of their +output using the iocsh '>file' or '2>error-file' syntax, and redirecting an +empty command could create files with garbage names. There may still be a few +commands that do not properly redirect their output, please notify the core +developers if you discover any. Thanks to Eric Norum for the iocsh changes.

    + +

    For externally developed commands, the simplest way to support redirection in +your C/C++ code is to #include "epicsStdioRedirect.h" instead of +stdio.h.

    +

    Fixed crash loading record instance of unknown type

    Fixed segfault when dbLoadRecords tried to load a record of a type that was diff --git a/src/ca/iocinf.cpp b/src/ca/iocinf.cpp index 487067c00..b3e634928 100644 --- a/src/ca/iocinf.cpp +++ b/src/ca/iocinf.cpp @@ -22,12 +22,12 @@ #include #include -#include #include #include #include "envDefs.h" #include "epicsAssert.h" +#include "epicsStdioRedirect.h" #include "errlog.h" #include "osiWireFormat.h" diff --git a/src/ca/test_event.cpp b/src/ca/test_event.cpp index 17cfe2f47..8b5a8bb54 100644 --- a/src/ca/test_event.cpp +++ b/src/ca/test_event.cpp @@ -14,7 +14,7 @@ * simple stub for testing monitors */ -#include +#include "epicsStdioRedirect.h" #define epicsExportSharedSymbols #include "cadef.h" diff --git a/src/libCom/gpHash/gpHashLib.c b/src/libCom/gpHash/gpHashLib.c index 6a800531f..842f3b4de 100644 --- a/src/libCom/gpHash/gpHashLib.c +++ b/src/libCom/gpHash/gpHashLib.c @@ -9,8 +9,7 @@ /* $Revision-Id$ */ /* Author: Marty Kraimer Date: 04-07-94 */ - -#include + #include #include #include @@ -18,6 +17,7 @@ #define epicsExportSharedSymbols #include "cantProceed.h" #include "epicsMutex.h" +#include "epicsStdioRedirect.h" #include "epicsString.h" #include "dbDefs.h" #include "ellLib.h" @@ -34,13 +34,14 @@ typedef struct gphPvt { #define MIN_SIZE 256 #define DEFAULT_SIZE 512 #define MAX_SIZE 65536 - + + void epicsShareAPI gphInitPvt(gphPvt **ppvt, int size) { gphPvt *pgphPvt; if (size & (size - 1)) { - printf("gphInitPvt: %d is not a power of 2\n", size); + fprintf(stderr, "gphInitPvt: %d is not a power of 2\n", size); size = DEFAULT_SIZE; } @@ -88,7 +89,7 @@ GPHENTRY * epicsShareAPI gphFind(gphPvt *pgphPvt, const char *name, void *pvtid) epicsMutexUnlock(pgphPvt->lock); return pgphNode; } - + GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid) { ELLLIST **paplist; @@ -127,7 +128,7 @@ GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid) epicsMutexUnlock(pgphPvt->lock); return (pgphNode); } - + void epicsShareAPI gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid) { ELLLIST **paplist; @@ -161,7 +162,7 @@ void epicsShareAPI gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid) epicsMutexUnlock(pgphPvt->lock); return; } - + void epicsShareAPI gphFreeMem(gphPvt *pgphPvt) { ELLLIST **paplist; @@ -203,9 +204,10 @@ void epicsShareAPI gphDumpFP(FILE *fp, gphPvt *pgphPvt) ELLLIST **paplist; int h; - if (pgphPvt == NULL) return; + if (pgphPvt == NULL) + return; - printf("Hash table has %d buckets", pgphPvt->size); + fprintf(fp, "Hash table has %d buckets", pgphPvt->size); paplist = pgphPvt->paplist; for (h = 0; h < pgphPvt->size; h++) { diff --git a/src/libCom/iocsh/iocsh.cpp b/src/libCom/iocsh/iocsh.cpp index c140e56a9..c1d50d27e 100644 --- a/src/libCom/iocsh/iocsh.cpp +++ b/src/libCom/iocsh/iocsh.cpp @@ -3,8 +3,7 @@ * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* iocsh.cpp */ @@ -68,6 +67,7 @@ struct iocshRedirect { const char *mode; FILE *fp; FILE *oldFp; + int mustRestore; }; /* @@ -101,7 +101,8 @@ iocshTableUnlock (void) /* * Register a command */ -void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef, iocshCallFunc func) +void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef, + iocshCallFunc func) { struct iocshCommand *l, *p, *n; int i; @@ -118,7 +119,8 @@ void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef, iocshCallFu if (i < 0) break; } - n = (struct iocshCommand *)callocMustSucceed (1, sizeof *n, "iocshRegister"); + n = (struct iocshCommand *) callocMustSucceed (1, sizeof *n, + "iocshRegister"); if (!registryAdd(iocshCmdID, piocshFuncDef->name, (void *)n)) { free (n); iocshTableUnlock (); @@ -162,7 +164,8 @@ void epicsShareAPI iocshRegisterVariable (const iocshVarDef *piocshVarDef) for (l = NULL, p = iocshVariableHead ; p != NULL ; l = p, p = p->next) { i = strcmp (piocshVarDef->name, p->pVarDef->name); if (i == 0) { - errlogPrintf("Warning -- iocshRegisterVariable redefining %s.\n", piocshVarDef->name); + errlogPrintf("Warning: iocshRegisterVariable redefining %s.\n", + piocshVarDef->name); p->pVarDef = piocshVarDef; found = 1; break; @@ -171,11 +174,13 @@ void epicsShareAPI iocshRegisterVariable (const iocshVarDef *piocshVarDef) break; } if (!found) { - n = (struct iocshVariable *)callocMustSucceed(1, sizeof *n, "iocshRegisterVariable"); + n = (struct iocshVariable *) callocMustSucceed(1, sizeof *n, + "iocshRegisterVariable"); if (!registryAdd(iocshVarID, piocshVarDef->name, (void *)n)) { free(n); iocshTableUnlock(); - errlogPrintf("iocshRegisterVariable failed to add %s.\n", piocshVarDef->name); + errlogPrintf("iocshRegisterVariable failed to add %s.\n", + piocshVarDef->name); return; } if (l == NULL) { @@ -225,14 +230,15 @@ showError (const char *filename, int lineno, const char *msg, ...) va_start (ap, msg); if (filename) - fprintf (stderr, "%s -- Line %d -- ", filename, lineno); - vfprintf (stderr, msg, ap); - fputc ('\n', stderr); + fprintf(epicsGetStderr(), "%s line %d: ", filename, lineno); + vfprintf (epicsGetStderr(), msg, ap); + fputc ('\n', epicsGetStderr()); va_end (ap); } static int -cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const iocshArg *piocshArg) +cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, + const iocshArg *piocshArg) { char *endp; @@ -245,12 +251,13 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const errno = 0; argBuf->ival = strtoul (arg, &endp, 0); if (errno == ERANGE) { - showError (filename, lineno, "Integer '%s' out of range", arg); + showError(filename, lineno, "Integer '%s' out of range", + arg); return 0; } } if (*endp) { - showError (filename, lineno, "Illegal integer '%s'", arg); + showError(filename, lineno, "Illegal integer '%s'", arg); return 0; } } @@ -263,7 +270,7 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const if (arg && *arg) { argBuf->dval = epicsStrtod (arg, &endp); if (*endp) { - showError (filename, lineno, "Illegal double '%s'", arg); + showError(filename, lineno, "Illegal double '%s'", arg); return 0; } } @@ -279,7 +286,7 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const case iocshArgPersistentString: argBuf->sval = epicsStrDup(arg); if (argBuf->sval == NULL) { - showError (filename, lineno, "Out of memory"); + showError(filename, lineno, "Out of memory"); return 0; } break; @@ -288,17 +295,18 @@ cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, const /* Argument must be missing or 0 or pdbbase */ if(!arg || !*arg || (*arg == '0') || (strcmp(arg, "pdbbase") == 0)) { if(!iocshPpdbbase || !*iocshPpdbbase) { - showError (filename, lineno, "pdbbase not present"); + showError(filename, lineno, "pdbbase not present"); return 0; } argBuf->vval = *iocshPpdbbase; break; } - showError (filename, lineno, "Expecting 'pdbbase' got '%s'", arg); + showError(filename, lineno, "Expecting 'pdbbase' got '%s'", arg); return 0; default: - showError (filename, lineno, "Illegal argument type %d", piocshArg->type); + showError(filename, lineno, "Illegal argument type %d", + piocshArg->type); return 0; } return 1; @@ -329,6 +337,7 @@ openRedirect(const char *filename, int lineno, struct iocshRedirect *redirect) } return -1; } + redirect->mustRestore = 0; } } return 0; @@ -349,14 +358,17 @@ startRedirect(const char * /*filename*/, int /*lineno*/, case 0: redirect->oldFp = epicsGetThreadStdin(); epicsSetThreadStdin(redirect->fp); + redirect->mustRestore = 1; break; case 1: redirect->oldFp = epicsGetThreadStdout(); epicsSetThreadStdout(redirect->fp); + redirect->mustRestore = 1; break; case 2: redirect->oldFp = epicsGetThreadStderr(); epicsSetThreadStderr(redirect->fp); + redirect->mustRestore = 1; break; } } @@ -377,10 +389,12 @@ stopRedirect(const char *filename, int lineno, struct iocshRedirect *redirect) showError(filename, lineno, "Error closing \"%s\": %s.", redirect->name, strerror(errno)); redirect->fp = NULL; - switch(i) { - case 0: epicsSetThreadStdin(redirect->oldFp); break; - case 1: epicsSetThreadStdout(redirect->oldFp); break; - case 2: epicsSetThreadStderr(redirect->oldFp); break; + if (redirect->mustRestore) { + switch(i) { + case 0: epicsSetThreadStdin(redirect->oldFp); break; + case 1: epicsSetThreadStdout(redirect->oldFp); break; + case 2: epicsSetThreadStderr(redirect->oldFp); break; + } } } redirect->name = NULL; @@ -404,30 +418,31 @@ static void helpCallFunc(const iocshArgBuf *args) if (argc == 1) { int l, col = 0; - printf ("Type 'help command_name' to get more information about a particular command.\n"); + fprintf(epicsGetStdout(), + "Type 'help ' to see the arguments of .\n"); iocshTableLock (); for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) { piocshFuncDef = pcmd->pFuncDef; l = strlen (piocshFuncDef->name); if ((l + col) >= 79) { - fputc ('\n', stdout); + fputc('\n', epicsGetStdout()); col = 0; } - fputs (piocshFuncDef->name, stdout); + fputs(piocshFuncDef->name, epicsGetStdout()); col += l; if (col >= 64) { - fputc ('\n', stdout); + fputc('\n', epicsGetStdout()); col = 0; } else { do { - fputc (' ', stdout); + fputc(' ', epicsGetStdout()); col++; } while ((col % 16) != 0); } } if (col) - fputc ('\n', stdout); + fputc('\n', epicsGetStdout()); iocshTableUnlock (); } else { @@ -435,18 +450,18 @@ static void helpCallFunc(const iocshArgBuf *args) for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) { piocshFuncDef = pcmd->pFuncDef; if (epicsStrGlobMatch(piocshFuncDef->name, argv[iarg]) != 0) { - fputs (piocshFuncDef->name, stdout); + fputs(piocshFuncDef->name, epicsGetStdout()); for (int a = 0 ; a < piocshFuncDef->nargs ; a++) { const char *cp = piocshFuncDef->arg[a]->name; if ((piocshFuncDef->arg[a]->type == iocshArgArgv) || (strchr (cp, ' ') == NULL)) { - fprintf (stdout, " %s", cp); + fprintf(epicsGetStdout(), " %s", cp); } else { - fprintf (stdout, " '%s'", cp); + fprintf(epicsGetStdout(), " '%s'", cp); } } - fprintf (stdout,"\n");; + fprintf(epicsGetStdout(),"\n");; } } } @@ -478,7 +493,6 @@ iocshBody (const char *pathname, const char *commandLine) iocshArgBuf *argBuf = NULL; int argBufCapacity = 0; struct iocshCommand *found; - struct iocshFuncDef const *piocshFuncDef; void *readlineContext = NULL; int wasOkToBlock; @@ -493,7 +507,8 @@ iocshBody (const char *pathname, const char *commandLine) else { fp = fopen (pathname, "r"); if (fp == NULL) { - fprintf (stderr, "Can't open %s: %s\n", pathname, strerror (errno)); + fprintf(epicsGetStderr(), "Can't open %s: %s\n", pathname, + strerror (errno)); return -1; } if ((filename = strrchr (pathname, '/')) == NULL) @@ -507,7 +522,7 @@ iocshBody (const char *pathname, const char *commandLine) * Create a command-line input context */ if ((readlineContext = epicsReadlineBegin(fp)) == NULL) { - fprintf(stderr, "Can't allocate command-line object.\n"); + fprintf(epicsGetStderr(), "Can't allocate command-line object.\n"); if (fp) fclose(fp); return -1; @@ -519,7 +534,7 @@ iocshBody (const char *pathname, const char *commandLine) */ redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects); if (redirects == NULL) { - printf ("Out of memory!\n"); + fprintf(epicsGetStderr(), "Out of memory!\n"); return -1; } @@ -604,7 +619,7 @@ iocshBody (const char *pathname, const char *commandLine) argvCapacity += 50; av = (char **)realloc (argv, argvCapacity * sizeof *argv); if (av == NULL) { - printf ("Out of memory!\n"); + fprintf (epicsGetStderr(), "Out of memory!\n"); argc = -1; break; } @@ -699,17 +714,17 @@ iocshBody (const char *pathname, const char *commandLine) backslash = 0; } if (redirect != NULL) { - showError (filename, lineno, "Illegal redirection."); + showError(filename, lineno, "Illegal redirection."); continue; } if (argc < 0) break; if (quote != EOF) { - showError (filename, lineno, "Unbalanced quote."); + showError(filename, lineno, "Unbalanced quote."); continue; } if (backslash) { - showError (filename, lineno, "Trailing backslash."); + showError(filename, lineno, "Trailing backslash."); continue; } if (inword) @@ -730,73 +745,68 @@ iocshBody (const char *pathname, const char *commandLine) stopRedirect(filename, lineno, redirects); continue; } - if (openRedirect(filename, lineno, redirects) < 0) - continue; /* - * Look up command + * Special command? */ - if (argc) { - /* - * Special command? - */ - if (strncmp (argv[0], "exit", 4) == 0) - break; - if ((strcmp (argv[0], "?") == 0) - || (strncmp (argv[0], "help", 4) == 0)) { - } + if ((argc > 0) && (strcmp(argv[0], "exit") == 0)) + break; + /* + * Set up redirection + */ + if ((openRedirect(filename, lineno, redirects) == 0) && (argc > 0)) { /* * Look up command */ found = (iocshCommand *)registryFind (iocshCmdID, argv[0]); - if (!found) { - showError (filename, lineno, "Command %s not found.", argv[0]); - continue; - } - piocshFuncDef = found->pFuncDef; - - /* - * Process arguments and call function - */ - for (int iarg = 0 ; ; ) { - if (iarg == piocshFuncDef->nargs) { - startRedirect(filename, lineno, redirects); - (*found->func)(argBuf); - stopRedirect(filename, lineno, redirects); - break; - } - if (iarg >= argBufCapacity) { - void *np; - - argBufCapacity += 20; - np = realloc (argBuf, argBufCapacity * sizeof *argBuf); - if (np == NULL) { - fprintf (stderr, "Out of memory!\n"); - argBufCapacity -= 20; + if (found) { + /* + * Process arguments and call function + */ + struct iocshFuncDef const *piocshFuncDef = found->pFuncDef; + for (int iarg = 0 ; ; ) { + if (iarg == piocshFuncDef->nargs) { + startRedirect(filename, lineno, redirects); + (*found->func)(argBuf); break; } - argBuf = (iocshArgBuf *)np; + if (iarg >= argBufCapacity) { + void *np; + + argBufCapacity += 20; + np = realloc (argBuf, argBufCapacity * sizeof *argBuf); + if (np == NULL) { + fprintf (epicsGetStderr(), "Out of memory!\n"); + argBufCapacity -= 20; + break; + } + argBuf = (iocshArgBuf *)np; + } + if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) { + argBuf[iarg].aval.ac = argc-iarg; + argBuf[iarg].aval.av = argv+iarg; + iarg = piocshFuncDef->nargs; + } + else { + if (!cvtArg (filename, lineno, + ((iarg < argc) ? argv[iarg+1] : NULL), + &argBuf[iarg], piocshFuncDef->arg[iarg])) + break; + iarg++; + } } - if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) { - argBuf[iarg].aval.ac = argc-iarg; - argBuf[iarg].aval.av = argv+iarg; - iarg = piocshFuncDef->nargs; - } - else { - if (!cvtArg (filename, lineno, - ((iarg < argc) ? argv[iarg+1] : NULL), - &argBuf[iarg], piocshFuncDef->arg[iarg])) - break; - iarg++; + if ((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) { + const char *newPrompt; + if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL) + prompt = newPrompt; } } - if((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) { - const char *newPrompt; - if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL) - prompt = newPrompt; + else { + showError(filename, lineno, "Command %s not found.", argv[0]); } } + stopRedirect(filename, lineno, redirects); } if (fp && (fp != stdin)) fclose (fp); @@ -840,7 +850,8 @@ static void varHandler(const iocshVarDef *v, const char *setString) { switch(v->type) { default: - printf("Can't handle variable %s of type %d.\n", v->name, v->type); + fprintf(epicsGetStderr(), "Can't handle variable %s of type %d.\n", + v->name, v->type); return; case iocshArgInt: break; case iocshArgDouble: break; @@ -849,10 +860,10 @@ static void varHandler(const iocshVarDef *v, const char *setString) switch(v->type) { default: break; case iocshArgInt: - printf("%s = %d\n", v->name, *(int *)v->pval); + fprintf(epicsGetStdout(), "%s = %d\n", v->name, *(int *)v->pval); break; case iocshArgDouble: - printf("%s = %g\n", v->name, *(double *)v->pval); + fprintf(epicsGetStdout(), "%s = %g\n", v->name, *(double *)v->pval); break; } } @@ -866,7 +877,8 @@ static void varHandler(const iocshVarDef *v, const char *setString) if((*setString != '\0') && (*endp == '\0')) *(int *)v->pval = ltmp; else - printf("Invalid value -- value of %s not changed.\n", v->name); + fprintf(epicsGetStderr(), + "Invalid integer value. Var %s not changed.\n", v->name); break; } case iocshArgDouble: @@ -876,7 +888,8 @@ static void varHandler(const iocshVarDef *v, const char *setString) if((*setString != '\0') && (*endp == '\0')) *(double *)v->pval = dtmp; else - printf("Invalid value -- value of %s not changed.\n", v->name); + fprintf(epicsGetStderr(), + "Invalid double value. Var %s not changed.\n", v->name); break; } } @@ -893,7 +906,7 @@ static void varCallFunc(const iocshArgBuf *args) else { v = (iocshVariable *)registryFind(iocshVarID, args[0].sval); if (v == NULL) { - printf("%s -- no such variable.\n", args[0].sval); + fprintf(epicsGetStderr(), "Var %s not found.\n", args[0].sval); } else { varHandler(v->pVarDef, args[1].sval); @@ -916,7 +929,8 @@ static void iocshCmdCallFunc(const iocshArgBuf *args) */ /* comment */ -static const iocshArg commentArg0 = { "newline-terminated comment",iocshArgArgv}; +static const iocshArg commentArg0 = { "newline-terminated comment", + iocshArgArgv}; static const iocshArg *commentArgs[1] = {&commentArg0}; static const iocshFuncDef commentFuncDef = {"#",1,commentArgs}; static void commentCallFunc(const iocshArgBuf *) diff --git a/src/libCom/iocsh/libComRegister.c b/src/libCom/iocsh/libComRegister.c index 6cd79bb66..4be706dc7 100644 --- a/src/libCom/iocsh/libComRegister.c +++ b/src/libCom/iocsh/libComRegister.c @@ -9,10 +9,10 @@ \*************************************************************************/ #include -#include #define epicsExportSharedSymbols #include "iocsh.h" +#include "epicsStdioRedirect.h" #include "epicsTime.h" #include "epicsThread.h" #include "epicsMutex.h" @@ -60,7 +60,7 @@ static void chdirCallFunc(const iocshArgBuf *args) int status; status = chdir(args[0].sval); if (status) { - printf ("Invalid directory path ignored\n"); + fprintf(stderr, "Invalid directory path, ignored\n"); } } @@ -86,11 +86,11 @@ static void epicsEnvSetCallFunc(const iocshArgBuf *args) char *value = args[1].sval; if (name == NULL) { - printf ("Missing environment variable name argument.\n"); + fprintf(stderr, "Missing environment variable name argument.\n"); return; } if (value == NULL) { - printf ("Missing environment variable value argument.\n"); + fprintf(stderr, "Missing environment variable value argument.\n"); return; } epicsEnvSet (name, value); @@ -231,7 +231,7 @@ static void threadCallFunc(const iocshArgBuf *args) if (*endp) { tid = epicsThreadGetId (cp); if (!tid) { - printf ("\t'%s' is not a known thread name\n", cp); + fprintf(stderr, "\t'%s' is not a known thread name\n", cp); continue; } } @@ -299,7 +299,7 @@ static void epicsThreadResumeCallFunc(const iocshArgBuf *args) if (*endp) { tid = epicsThreadGetId(cp); if (!tid) { - printf("*** argument %d (%s) is not a valid thread name ***\n", i, cp); + fprintf(stderr, "'%s' is not a valid thread name\n", cp); continue; } } @@ -307,13 +307,13 @@ static void epicsThreadResumeCallFunc(const iocshArgBuf *args) tid =(epicsThreadId)ltmp; epicsThreadGetName(tid, nameBuf, sizeof nameBuf); if (nameBuf[0] == '\0') { - printf("*** argument %d (%s) is not a valid thread id ***\n", i, cp); + fprintf(stderr, "'%s' is not a valid thread id\n", cp); continue; } } if (!epicsThreadIsSuspended(tid)) { - printf("*** Thread %s is not suspended ***\n", cp); + fprintf(stderr, "Thread %s is not suspended\n", cp); continue; } epicsThreadResume(tid); diff --git a/src/libCom/osi/epicsGeneralTime.c b/src/libCom/osi/epicsGeneralTime.c index 819220ea7..8ef8a73cc 100644 --- a/src/libCom/osi/epicsGeneralTime.c +++ b/src/libCom/osi/epicsGeneralTime.c @@ -9,7 +9,6 @@ /* Original Authors: David H. Thompson & Sheng Peng (ORNL) */ -#include #include #include @@ -19,6 +18,7 @@ #include "epicsMutex.h" #include "epicsMessageQueue.h" #include "epicsString.h" +#include "epicsStdioRedirect.h" #include "epicsThread.h" #include "epicsTime.h" #include "epicsTimer.h" diff --git a/src/libCom/taskwd/taskwd.c b/src/libCom/taskwd/taskwd.c index c034e1828..f8a061c2c 100644 --- a/src/libCom/taskwd/taskwd.c +++ b/src/libCom/taskwd/taskwd.c @@ -22,7 +22,7 @@ #include "dbDefs.h" #include "epicsEvent.h" #include "epicsExit.h" -#include "epicsStdio.h" +#include "epicsStdioRedirect.h" #include "epicsThread.h" #include "epicsMutex.h" #include "errlog.h" From 22540ac74382622c023e4148856c3d375f8fd5be Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 11 Dec 2013 18:11:51 -0600 Subject: [PATCH 33/38] docs: Release note update. Credit Peter Heesterman with windows build updates. --- documentation/RELEASE_NOTES.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 0ed88c4a4..e4150377a 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -43,6 +43,12 @@ Dirk Zimoch for suggesting this change.

    Both windows-x64-mingw and cygwin-x86_64 build targets are now provided.

    +

    Windows build issues

    + +

    Thanks to Peter Heesterman for suggesting a number of small changes that +clean up build issues on Windows, mostly related to symbol import and export +to/from DLLs.

    +

    CAS: GDD Reference Count Underflow

    Thanks to Bruce Hill a source of an underflow in a GDD reference count in the From 88ae947c84b5125778db04ffbca9b69988e75ce2 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 13 Dec 2013 16:04:01 -0600 Subject: [PATCH 34/38] configure: Refined how/when we pull in /cfg files Only read CONFIG* and RULES* files, and only do so in build dirs, i.e. when T_A is defined. --- configure/CONFIG | 35 +++++--------------------------- configure/CONFIG_FILE_TYPE | 33 +++++++++++++++--------------- configure/RULES_FILE_TYPE | 14 ++++++------- documentation/RELEASE_NOTES.html | 15 +++++++++++++- 4 files changed, 42 insertions(+), 55 deletions(-) diff --git a/configure/CONFIG b/configure/CONFIG index 1b3664bfd..4f20c7d52 100644 --- a/configure/CONFIG +++ b/configure/CONFIG @@ -1,17 +1,13 @@ #************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne +# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne # National Laboratory. # Copyright (c) 2002 The Regents of the University of California, as # Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. +# EPICS BASE is distributed subject to a Software License Agreement found +# in the file LICENSE that is included with this distribution. #************************************************************************* # # $Revision-Id$ -# -# The developer may edit this file. -# assume T_A is the host arch if not specified # # Common build definitions @@ -89,8 +85,6 @@ endif -include $(CONFIG)/os/CONFIG_SITE.Common.$(T_A) -include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) -endif - # Include /cfg/CONFIG* definitions from tops defined in RELEASE* files # ifneq ($(CONFIG),$(TOP)/configure) @@ -103,12 +97,12 @@ endif # Include $(INSTALL_CFG)/CONFIG* definitions # -ifndef T_A TOP_CFG_CONFIGS = $(wildcard $(INSTALL_CFG)/CONFIG*) ifneq ($(TOP_CFG_CONFIGS),) include $(TOP_CFG_CONFIGS) endif -endif + +endif # ifdef T_A # User specific definitions # @@ -119,22 +113,3 @@ ifdef T_A -include $(HOME)/configure/CONFIG_USER.$(EPICS_HOST_ARCH).$(T_A) endif -# All options -# may be overridden here. -# -# EXAMPLES -# -------- -# Build client objects statically ? must be either YES or NO -#STATIC_BUILD=NO -# Host build optimization, must be either YES or NO -#HOST_OPT=YES -# Cross build optimization, must be either YES or NO -#CROSS_OPT=YES -# Generate Verbose Compiler Warnings for host build, must be either YES or NO -#HOST_WARN=YES -# Generate Verbose Compiler Warnings for cross compile builds, must be either YES or NO -#CROSS_WARN=YES -#etc. - -#CROSS_COMPILER_TARGET_ARCHS=vxWorks-68040 - diff --git a/configure/CONFIG_FILE_TYPE b/configure/CONFIG_FILE_TYPE index 3fc6a9d93..0501e1949 100644 --- a/configure/CONFIG_FILE_TYPE +++ b/configure/CONFIG_FILE_TYPE @@ -1,10 +1,10 @@ #************************************************************************* -# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne +# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne # National Laboratory. # Copyright (c) 2002 The Regents of the University of California, as # Operator of Los Alamos National Laboratory. # EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. +# in the file LICENSE that is included with this distribution. #************************************************************************* # $Revision-Id$ # @@ -12,7 +12,7 @@ # # -------------------------------------------------------------- -# Module developers can now define a new type of file, e.g. ABC, +# Module developers can now define a new type of file, e.g. ABC, # so that files of type ABC will be installed into a directory # defined by INSTALL_ABC. This is done by creating a new CONFIG # file, e.g. CONFIG_ABC, with the following lines: @@ -24,8 +24,14 @@ # $(INSTALL_LOCATION). The file type ABC should be target # architecture independent (alh files, medm files, edm files). # -# Optional rules necessary for files of type ABC should be put in -# a RULES_ABC file. +# Files of type ABC are then installed into the INSTALL_ABC +# directory by adding a line like the following to a Makefile. +# +# ABC += +# +# Rules necessary to create files of type ABC should be put in +# a RULES_ABC file. Variables used by those rules should appear +# in a CONFIG_ABC file. # # The module developer installs new CONFIG* or RULES* files # into the directory $(INSTALL_LOCATION)/cfg by including the @@ -33,16 +39,11 @@ # # CFG += CONFIG_ABC RULES_ABC # -# Files of type ABC are installed into INSTALL_ABC directory -# by adding a line like the following to a Makefile. -# -# ABC += -# -# Files in $(INSTALL_LOCATION)/cfg directory are now included by -# the base config files so the definitions and rules are available -# for use by later src directory Makefiles in the same module or -# by other modules with a RELEASE line pointing to the TOP of -# the module with RULES_ABC. +# CONFIG and RULES files in the $(INSTALL_LOCATION)/cfg directory +# are included by the Base config files so their definitions and +# rules are available for use by later src directory Makefiles in +# the same module, or by other modules with a RELEASE line that +# points to the TOP of the module providing these files. FILE_TYPE += ADL INSTALL_ADL = $(INSTALL_LOCATION)/adl @@ -59,6 +60,6 @@ INSTALL_EDL = $(INSTALL_LOCATION)/edl FILE_TYPE += PERL_MODULES INSTALL_PERL_MODULES = $(INSTALL_LOCATION_LIB)/perl -INSTALLS_CFG= $(CFG:%= $(INSTALL_CFG)/%) +INSTALLS_CFG = $(CFG:%= $(INSTALL_CFG)/%) DIRECTORY_TARGETS += $(foreach type, $(FILE_TYPE),$(INSTALL_$(type))) diff --git a/configure/RULES_FILE_TYPE b/configure/RULES_FILE_TYPE index d5aeddf38..b58bf550f 100644 --- a/configure/RULES_FILE_TYPE +++ b/configure/RULES_FILE_TYPE @@ -1,10 +1,10 @@ #************************************************************************* -# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne +# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne # National Laboratory. # Copyright (c) 2002 The Regents of the University of California, as # Operator of Los Alamos National Laboratory. # EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. +# in the file LICENSE that is included with this distribution. #************************************************************************* # $Revision-Id$ # @@ -36,13 +36,11 @@ endif endif #--------------------------------------------- -# Include existing and new $(INSTALL_CFG)/* definitions +# Include our own $(INSTALL_CFG)/RULES* definitions # -TOP_CFG_FILES = $(sort $(wildcard $(INSTALL_CFG)/RULES*) \ - $(wildcard $(INSTALL_CFG)/CONFIG*) \ - $(addprefix $(INSTALL_CFG)/,$(CFG))) -ifneq ($(TOP_CFG_FILES),) - include $(TOP_CFG_FILES) +TOP_CFG_RULES = $(wildcard $(INSTALL_CFG)/RULES*) +ifneq ($(TOP_CFG_RULES),) + include $(TOP_CFG_RULES) endif #--------------------------------------------------------------- diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index e4150377a..2faf69083 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -14,6 +14,19 @@ +

    Inclusion of <top>/cfg/* files refined

    + +

    The way the build system includes files installed in the <top>/cfg/* +directory has been cleaned up. Files whose names begin with CONFIG will now get +included by the CONFIG step, and files whose names begin with RULES will get +included in the RULES step. These files are only ever included when GNUMake is +working in an application build (O.) directory and T_A is defined, so they +cannot be used to create generic build targets at other levels.

    + +

    Files whose names don't start with either CONFIG or RULES are no longer +included automatically, but such files can still be installed into +<top>/cfg by naming them in the CFG variable.

    +

    Fixed iocsh stream redirection for several commands

    A number of iocsh commands did not respond correctly to redirection of their @@ -26,7 +39,7 @@ developers if you discover any. Thanks to Eric Norum for the iocsh changes.

    your C/C++ code is to #include "epicsStdioRedirect.h" instead of stdio.h.

    -

    Fixed crash loading record instance of unknown type

    +

    Fixed crash on loading record instance of unknown type

    Fixed segfault when dbLoadRecords tried to load a record of a type that was not defined in its DBD files.

    From a50c66b6ff4742997430641d4068b4c428a8841d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 16 Dec 2013 12:48:25 -0600 Subject: [PATCH 35/38] libCom/test: Added epicsEnvTest.c VxWorks 6.x can make environment variables private to each thread, which doesn't work too well. A test failure on VxWorks explains how to change the image configuration to fix this. --- documentation/RELEASE_NOTES.html | 9 +++- src/libCom/test/Makefile | 5 ++ src/libCom/test/epicsEnvTest.c | 78 +++++++++++++++++++++++++++ src/libCom/test/epicsRunLibComTests.c | 3 ++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/libCom/test/epicsEnvTest.c diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 2faf69083..301e85543 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -1,5 +1,4 @@ @@ -14,6 +13,14 @@ +

    New test for environment variables

    + +

    A new test program epicsEnvTest has been added to the libCom tests which +checks environment variable APIs. It was written to confirm that threads see +environment variable values that have been set in their parent thread. VxWorks +6.x boot images must be configured with ENV_VAR_USE_HOOKS set to FALSE for the +correct behaviour to occur (a test failure on VxWorks explains this).

    +

    Inclusion of <top>/cfg/* files refined

    The way the build system includes files installed in the <top>/cfg/* diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile index 0d6ab1487..e8e94a3e6 100644 --- a/src/libCom/test/Makefile +++ b/src/libCom/test/Makefile @@ -37,6 +37,11 @@ epicsEllTest_SRCS += epicsEllTest.c testHarness_SRCS += epicsEllTest.c TESTS += epicsEllTest +TESTPROD_HOST += epicsEnvTest +epicsEnvTest_SRCS += epicsEnvTest.c +testHarness_SRCS += epicsEnvTest.c +TESTS += epicsEnvTest + TESTPROD_HOST += epicsErrlogTest epicsErrlogTest_SRCS += epicsErrlogTest.c testHarness_SRCS += epicsErrlogTest.c diff --git a/src/libCom/test/epicsEnvTest.c b/src/libCom/test/epicsEnvTest.c new file mode 100644 index 000000000..bbce4b749 --- /dev/null +++ b/src/libCom/test/epicsEnvTest.c @@ -0,0 +1,78 @@ +/*************************************************************************\ +* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* epicsEnvTest.c */ + +/* Author: Andrew Johnson + * Date: 2013-12-13 + */ + +/* Check environment variable APIs. + * TODO: Add tests for envDefs.h routines. + * + * The thread test is needed on VxWorks 6.x, where the OS can be + * configured to maintain separate, totally independent sets + * of environment variables for each thread. This configuration + * is not supported by EPICS which expects child threads to at + * least inherit the partent thread's environment variables. + */ + +#include +#include + +#include "envDefs.h" +#include "epicsThread.h" +#include "epicsUnitTest.h" +#include "testMain.h" + +#define PARENT "Parent" +#define CHILD "Child" + +static void child(void *arg) +{ + const char *value = getenv(PARENT); + + if (!testOk(value && (strcmp(value, PARENT) == 0), + "Child thread sees parent environment values")) { +#ifdef vxWorks + testDiag("VxWorks image needs ENV_VAR_USE_HOOKS configured as FALSE"); +#else + testDiag("Check OS configuration, environment inheritance needed"); +#endif + } + + epicsEnvSet(CHILD, CHILD); +} + +MAIN(epicsEnvTest) +{ + unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); + const char *value; + + testPlan(3); + + epicsEnvSet(PARENT, PARENT); + + value = getenv(PARENT); + if (!testOk(value && (strcmp(value, PARENT) == 0), + "epicsEnvSet correctly modifies environment")) + testAbort("environment variables not working"); + + epicsThreadCreate("child", 50, stackSize, child, NULL); + epicsThreadSleep(0.1); + + value = getenv(CHILD); + if (value && (strcmp(value, CHILD) == 0)) + testDiag("Child and parent threads share a common environment"); + + value = getenv(PARENT); + testOk(value && (strcmp(value, PARENT) == 0), + "PARENT environment variable not modified"); + + testDone(); + return 0; +} + diff --git a/src/libCom/test/epicsRunLibComTests.c b/src/libCom/test/epicsRunLibComTests.c index 7a6da1e66..e49c10166 100644 --- a/src/libCom/test/epicsRunLibComTests.c +++ b/src/libCom/test/epicsRunLibComTests.c @@ -20,6 +20,7 @@ int epicsThreadTest(void); int epicsTimerTest(void); int epicsAlgorithm(void); int epicsEllTest(void); +int epicsEnvTest(void); int epicsErrlogTest(void); int epicsCalcTest(void); int epicsEventTest(void); @@ -60,6 +61,8 @@ void epicsRunLibComTests(void) runTest(epicsEllTest); + runTest(epicsEnvTest); + runTest(epicsErrlogTest); runTest(epicsCalcTest); From 97636a45e092a531018e481b6ca580e635b20daa Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 16 Dec 2013 14:52:29 -0600 Subject: [PATCH 36/38] libCom: Remove epicsShareAPI from epicsExit APIs Passing epicsExitCallAtExits into atexit() was generating a warning about passing in a __stdcall routine pointer. --- src/libCom/misc/epicsExit.c | 10 +++++----- src/libCom/misc/epicsExit.h | 11 +++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/libCom/misc/epicsExit.c b/src/libCom/misc/epicsExit.c index 5992d4ae8..a3835ae0c 100644 --- a/src/libCom/misc/epicsExit.c +++ b/src/libCom/misc/epicsExit.c @@ -83,7 +83,7 @@ static void epicsExitCallAtExitsPvt ( exitPvt * pep ) } } -epicsShareFunc void epicsShareAPI epicsExitCallAtExits ( void ) +epicsShareFunc void epicsExitCallAtExits ( void ) { exitPvt * pep = 0; epicsThreadOnce ( & exitPvtOnce, exitPvtOnceFunc, 0 ); @@ -99,7 +99,7 @@ epicsShareFunc void epicsShareAPI epicsExitCallAtExits ( void ) } } -epicsShareFunc void epicsShareAPI epicsExitCallAtThreadExits ( void ) +epicsShareFunc void epicsExitCallAtThreadExits ( void ) { exitPvt * pep; epicsThreadOnce ( & exitPvtOnce, exitPvtOnceFunc, 0 ); @@ -126,7 +126,7 @@ static int epicsAtExitPvt ( return status; } -epicsShareFunc int epicsShareAPI epicsAtThreadExit ( +epicsShareFunc int epicsAtThreadExit ( epicsExitFunc func, void *arg ) { exitPvt * pep; @@ -142,7 +142,7 @@ epicsShareFunc int epicsShareAPI epicsAtThreadExit ( return epicsAtExitPvt ( pep, func, arg ); } -epicsShareFunc int epicsShareAPI epicsAtExit( +epicsShareFunc int epicsAtExit( epicsExitFunc func, void *arg ) { int status = -1; @@ -155,7 +155,7 @@ epicsShareFunc int epicsShareAPI epicsAtExit( return status; } -epicsShareFunc void epicsShareAPI epicsExit(int status) +epicsShareFunc void epicsExit(int status) { epicsExitCallAtExits(); epicsThreadSleep(1.0); diff --git a/src/libCom/misc/epicsExit.h b/src/libCom/misc/epicsExit.h index 212467368..78b1bcb00 100644 --- a/src/libCom/misc/epicsExit.h +++ b/src/libCom/misc/epicsExit.h @@ -16,13 +16,12 @@ extern "C" { #endif -epicsShareFunc void epicsShareAPI epicsExit(int status); -epicsShareFunc void epicsShareAPI epicsExitCallAtExits(void); -epicsShareFunc int epicsShareAPI epicsAtExit( - void (*epicsExitFunc)(void *arg),void *arg); +epicsShareFunc void epicsExit(int status); +epicsShareFunc void epicsExitCallAtExits(void); +epicsShareFunc int epicsAtExit(void (*epicsExitFunc)(void *arg),void *arg); -epicsShareFunc void epicsShareAPI epicsExitCallAtThreadExits(void); -epicsShareFunc int epicsShareAPI epicsAtThreadExit( +epicsShareFunc void epicsExitCallAtThreadExits(void); +epicsShareFunc int epicsAtThreadExit( void (*epicsExitFunc)(void *arg),void *arg); From 6a0d5e0e879bef625dae0a2830325c791f5b4559 Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Mon, 16 Dec 2013 15:48:54 -0600 Subject: [PATCH 37/38] Changed EPICS to Release 3.14.12.4 --- documentation/RELEASE_NOTES.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 301e85543..0fc7153d0 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -3,11 +3,11 @@ - EPICS Base R3.14.12.4-rc1 Release Notes + EPICS Base R3.14.12.4 Release Notes -

    EPICS Base Release 3.14.12.4-rc1

    +

    EPICS Base Release 3.14.12.4

    Changes between 3.14.12.3 and 3.14.12.4

    From 30090918754ed694ec3e11bdd268260131f91c70 Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Mon, 16 Dec 2013 15:51:45 -0600 Subject: [PATCH 38/38] Creating R3.14.12.3 --- configure/CONFIG_BASE_VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index 892c6b2e6..432827e23 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -39,10 +39,10 @@ EPICS_PATCH_LEVEL = 4 #EPICS_DEV_SNAPSHOT=-pre2 #EPICS_DEV_SNAPSHOT=-pre2-DEV #EPICS_DEV_SNAPSHOT=-rc1 -EPICS_DEV_SNAPSHOT=-rc1-DEV +#EPICS_DEV_SNAPSHOT=-rc1-DEV #EPICS_DEV_SNAPSHOT=-rc2 #EPICS_DEV_SNAPSHOT=-rc2-DEV -#EPICS_DEV_SNAPSHOT= +EPICS_DEV_SNAPSHOT= # No changes should be needed below here