30 #include "osiFileName.h" 33 #define DBFLDTYPES_GBLSOURCE 34 #define SPECIAL_GBLSOURCE 36 #define epicsExportSharedSymbols 37 #include "dbChannel.h" 50 static char *pNullString =
"";
51 #define messagesize 276 52 #define RPCL_LEN INFIX_TO_POSTFIX_SIZE(80) 60 static char *ppstring[5]={
" NPP",
" PP",
" CA",
" CP",
" CPP"};
61 static char *msstring[4]={
" NMS",
" MS",
" MSI",
" MSS"};
83 static void dbMsgPrint(
DBENTRY *pdbentry,
const char *fmt, ...)
85 static long dbAddOnePath (
DBBASE *pdbbase,
const char *path,
unsigned length);
88 static FILE *openOutstream(
const char *filename)
92 stream = fopen(filename,
"w");
94 fprintf(
stderr,
"error opening %s %s\n",filename,strerror(errno));
100 static void finishOutstream(FILE *stream)
105 if(fclose(stream)) fprintf(
stderr,
"fclose error %s\n",strerror(errno));
113 switch(plink->
type) {
131 epicsPrintf(
"dbFreeLink called but link type %d unknown\n", plink->
type);
133 if(parm && (parm != pNullString)) free((
void *)parm);
137 memset(&plink->
value, 0,
sizeof(
union value));
147 if(!ppathList)
return;
151 free((
void *)pdbPathNode);
153 free((
void *)ppathList);
159 static void zeroDbentry(
DBENTRY *pdbentry)
169 static char *getpMessage(
DBENTRY *pdbentry)
183 void dbMsgCpy(
DBENTRY *pdbentry,
const char *msg)
185 getpMessage(pdbentry);
191 void dbMsgNCpy(
DBENTRY *pdbentry,
const char *msg,
size_t len)
193 getpMessage(pdbentry);
197 strncpy(pdbentry->
message, msg, len);
202 void dbMsgPrint(
DBENTRY *pdbentry,
const char *fmt, ...)
205 getpMessage(pdbentry);
211 static void ulongToHexString(
epicsUInt32 source,
char *pdest)
213 static const char hex_digit_to_ascii[16] =
"0123456789abcdef";
222 *pdest++ =
'0'; *pdest++ =
'x';
224 for (i=0; val!=0; i++) {
226 digit[
i] = hex_digit_to_ascii[val - temp*16];
229 for (j=i-1; j>=0; j--) {
236 static void realToString(
double value,
char *preturn,
int isdouble)
238 static const double delta[2] = {1e-6, 1e-15};
239 static const int precision[2] = {6, 14};
244 char *ptstr = &tstr[0];
250 strcpy(preturn,
"0");
255 if (absvalue < (
double)INT_MAX) {
257 double diff =
value - intval;
259 if (diff < 0) diff = -diff;
260 if (diff < absvalue * delta[isdouble]) {
272 logval = (int)log10(
value);
273 if (logval > 6 || logval < -2) {
277 prec = precision[isdouble];
278 nout = sprintf(ptstr,
"%.*e", prec,
value);
279 loce = strchr(ptstr,
'e');
283 strcpy(preturn, ptstr);
289 prec = precision[isdouble] - logval;
290 if ( prec < 0) prec = 0;
291 sprintf(ptstr,
"%.*f", prec,
value);
295 end = strlen(ptstr) - 1;
298 if (tstr[end] ==
'.') {end--;
break;}
299 if (tstr[end] ==
'0') {end--;
continue;}
300 if (!round && end < precision[isdouble])
break;
301 if (!round && tstr[end] <
'8')
break;
302 if (tstr[end-1] ==
'.') {
303 if (round) end = end-2;
306 if (tstr[end-1] !=
'9')
break;
312 if (tstr[end] <
'9') {tstr[end]++;
break;}
313 if (end == 0) { *preturn++ =
'1'; tstr[end] =
'0';
break;}
317 strcpy(preturn, &tstr[0]);
319 if (!(strchr(preturn,
'.'))) strcat(preturn,
".0");
320 strcat(preturn,
"e");
321 strcat(preturn, loce);
325 static void floatToString(
float value,
char *preturn)
327 realToString((
double)
value, preturn, 0);
330 static void doubleToString(
double value,
char *preturn)
332 realToString(
value, preturn, 1);
345 if(!precordType)
return(
NULL);
346 if(!pflddes)
return(
NULL);
351 return(pdbDeviceMenu);
353 free((
void *)pdbDeviceMenu);
357 if(nChoice <= 0)
return(
NULL);
359 pdbDeviceMenu->
nChoice = nChoice;
368 pflddes->
ftPvt = pdbDeviceMenu;
369 return(pdbDeviceMenu);
375 void dbCatString(
char **
string,
int *stringLength,
char *src,
char *separator)
378 || ((strlen(*
string)+strlen(src)+2) > (
size_t)*stringLength)) {
383 if(*
string) size += strlen(*
string);
386 newString =
dbCalloc(size,
sizeof(
char));
388 strcpy(newString,*
string);
389 free((
void *)(*
string));
393 if(*stringLength>0) {
394 strcat(*
string,separator);
395 *stringLength += (int) strlen(separator);
398 *stringLength += (int) strlen(src);
439 chFilterPlugin *pfilt;
440 chFilterPlugin *pfiltNext;
463 while(pdbRecordType) {
464 for(i=0; i<pdbRecordType->
no_fields; i++) {
466 free((
void *)pdbFldDes->
prompt);
467 free((
void *)pdbFldDes->
name);
468 free((
void *)pdbFldDes->
extra);
469 free((
void *)pdbFldDes->
initial);
475 free((
void *)pdbDeviceMenu);
478 free((
void *)pdbFldDes);
484 free((
void *)pdevSup->
name);
485 free((
void *)pdevSup->
choice);
486 free((
void *)pdevSup);
487 pdevSup = pdevSupNext;
493 free((
void *)ptext->
text);
502 free((
void *)pAttribute->
name);
505 pAttribute = pAttributeNext;
510 free((
void *)pdbRecordType->
name);
511 free((
void *)pdbRecordType->
link_ind);
515 free((
void *)pdbRecordType);
516 pdbRecordType = pdbRecordTypeNext;
523 for(i=0; i< pdbMenu->
nChoice; i++) {
529 free((
void *)pdbMenu ->name);
530 free((
void *)pdbMenu);
531 pdbMenu = pdbMenuNext;
537 free((
void *)pdrvSup->
name);
538 free((
void *)pdrvSup);
539 pdrvSup = pdrvSupNext;
543 free(plinkSup->
name);
550 free((
void *)ptext->
text);
558 free((
void *)ptext->
text);
566 free((
void *)pvar->
name);
567 free((
void *)pvar->
type);
576 free(pbrkTable->
name);
578 free((
void *)pbrkTable);
579 pbrkTable = pbrkTableNext;
583 pfiltNext = (chFilterPlugin *)
ellNext(&pfilt->node);
584 free((
char*)pfilt->name);
585 if(pfilt->fif->priv_free)
586 (*pfilt->fif->priv_free)(pfilt->puser);
595 free(pguiGroup->
name);
596 free((
void *)pguiGroup);
597 pguiGroup = pguiGroupNext;
602 free((
void *)pdbbase);
612 memset(pdbentry,
'\0',
sizeof(
DBENTRY));
622 free((
void *)pdbentry->
message);
628 memset((
char *)pdbentry,
'\0',
sizeof(
DBENTRY));
635 free((
void *)pdbentry->
message);
659 if(!pdbbase)
return(-1);
661 if(!path || strlen(path)==0)
return(
dbAddPath(pdbbase,
"."));
670 unsigned expectingPath;
671 unsigned sawMissingPath;
673 if(!pdbbase)
return(-1);
678 pdbbase->
pathPvt = (
void *)ppathList;
680 if (!path)
return(0);
686 expectingPath =
FALSE;
687 sawMissingPath =
FALSE;
692 if (isspace((
int)*path)) {
698 sawMissingPath =
TRUE;
704 expectingPath =
TRUE;
706 plast = strlen (path) + path - 1;
707 expectingPath =
FALSE;
710 while (isspace((
int)*plast)) {
719 len = (plast - path) + 1;
720 if (dbAddOnePath (pdbbase, path, (
unsigned) len))
return (-1);
731 if (expectingPath||sawMissingPath) {
732 return dbAddOnePath (pdbbase,
".", 1);
737 static long dbAddOnePath (
DBBASE *pdbbase,
const char *path,
unsigned length)
742 if(!pdbbase)
return(-1);
747 strncpy(pdbPathNode->
directory, path, length);
757 if (!pdbbase)
return NULL;
760 if (pdbGuiGroup->
key == key)
return pdbGuiGroup->
name;
769 if (!pdbbase)
return 0;
780 const char *precordTypename,
int level)
785 stream = openOutstream(filename);
786 if(!stream)
return -1;
788 finishOutstream(stream);
793 DBBASE *pdbbase,FILE *fp,
const char *precordTypename,
int level)
802 if (precordTypename) {
803 if (*precordTypename == 0 || *precordTypename ==
'*')
807 if(!precordTypename) {
817 fprintf(
stderr,
"dbWriteRecordFP: No record description for %s\n",
831 fprintf(fp,
"grecord(%s,\"%s\") {\n",
834 fprintf(fp,
"record(%s,\"%s\") {\n",
842 fprintf(fp,
"\tfield(%s,\"\")\n",
845 fprintf(fp,
"\tfield(%s,\"",
859 fprintf(fp,
"\tinfo(\"%s\",\"",
862 fprintf(fp,
"\")\n");
874 fprintf(fp,
"alias(\"%s\",\"%s\")\n",
878 if(precordTypename)
break;
886 DBBASE *ppdbbase,
const char *filename,
const char *menuName)
891 stream = openOutstream(filename);
893 finishOutstream(stream);
904 fprintf(
stderr,
"pdbbase not specified\n");
908 if (*menuName == 0 || *menuName ==
'*')
914 gotMatch = (strcmp(menuName,pdbMenu->
name)==0) ?
TRUE :
FALSE;
919 fprintf(fp,
"menu(%s) {\n",pdbMenu->
name);
920 for(i=0; i<pdbMenu->
nChoice; i++) {
921 fprintf(fp,
"\tchoice(%s,\"%s\")\n",pdbMenu->
papChoiceName[i],
933 DBBASE *pdbbase,
const char *filename,
const char *recordTypeName)
938 stream = openOutstream(filename);
940 finishOutstream(stream);
945 DBBASE *pdbbase,FILE *fp,
const char *recordTypeName)
953 fprintf(
stderr,
"pdbbase not specified\n");
956 if (recordTypeName) {
957 if (*recordTypeName == 0 || *recordTypeName ==
'*')
964 gotMatch = (strcmp(recordTypeName,pdbRecordType->
name)==0)
969 if(!gotMatch)
continue;
970 fprintf(fp,
"recordtype(%s) {\n",pdbRecordType->
name);
971 for(i=0; i<pdbRecordType->
no_fields; i++) {
975 fprintf(fp,
"\tfield(%s,%s) {\n",pdbFldDes->
name,
978 fprintf(fp,
"\t\tprompt(\"%s\")\n",pdbFldDes->
prompt);
980 fprintf(fp,
"\t\tinitial(\"%s\")\n",pdbFldDes->
initial);
982 fprintf(fp,
"\t\tpromptgroup(\"%s\")\n",
987 fprintf(fp,
"\t\tspecial(%d)\n",pdbFldDes->
special);
990 fprintf(fp,
"\t\tspecial(%s)\n",
997 fprintf(fp,
"\t\textra(\"%s\")\n",pdbFldDes->
extra);
1000 fprintf(fp,
"\t\tmenu(%s)\n",
1003 fprintf(
stderr,
"\t\t menu: NOT FOUND\n");
1006 fprintf(fp,
"\t\tsize(%d)\n",
1010 if(pdbFldDes->
prop) fprintf(fp,
"\t\tprop(YES)\n");
1011 if(pdbFldDes->
base) fprintf(fp,
"\t\tbase(HEX)\n");
1013 fprintf(fp,
"\t\tinterest(%d)\n",pdbFldDes->
interest);
1014 if(!pdbFldDes->
as_level) fprintf(fp,
"\t\tasl(ASL0)\n");
1015 fprintf(fp,
"\t}\n");
1018 if(recordTypeName)
break;
1028 stream = openOutstream(filename);
1030 finishOutstream(stream);
1040 fprintf(
stderr,
"dbWriteDeviceFP: pdbbase not specified\n");
1052 if(j>=LINK_NTYPES) {
1053 fprintf(fp,
"link_type not valid\n");
1056 fprintf(fp,
"device(%s,%s,%s,\"%s\")\n",
1057 pdbRecordType->
name,
1070 stream = openOutstream(filename);
1072 finishOutstream(stream);
1081 fprintf(
stderr,
"pdbbase not specified\n");
1086 fprintf(fp,
"driver(%s)\n",pdrvSup->
name);
1096 fprintf(
stderr,
"pdbbase not specified\n");
1101 fprintf(fp,
"link(%s,%s)\n", plinkSup->
name, plinkSup->
jlif_name);
1111 fprintf(
stderr,
"pdbbase not specified\n");
1116 fprintf(fp,
"registrar(%s)\n",ptext->
text);
1126 fprintf(
stderr,
"pdbbase not specified\n");
1131 fprintf(fp,
"function(%s)\n",ptext->
text);
1141 fprintf(
stderr,
"pdbbase not specified\n");
1146 fprintf(fp,
"variable(%s,%s)\n",pvar->
name,pvar->
type);
1156 stream = openOutstream(filename);
1158 finishOutstream(stream);
1169 fprintf(
stderr,
"pdbbase not specified\n");
1175 fprintf(fp,
"breaktable(%s) {\n",pbrkTable->
name);
1177 for(i=0; i < pbrkTable->
number; i++) {
1178 fprintf(fp,
"\t%e, %e\n",pbrkInt->
raw,pbrkInt->
eng);
1191 zeroDbentry(pdbentry);
1202 zeroDbentry(pdbentry);
1213 zeroDbentry(pdbentry);
1234 int createNew =
TRUE;
1242 compare = strcmp(pattribute->
name,name);
1246 if(compare>=0)
break;
1261 pattribute->
name =
dbCalloc(strlen(name)+1,
sizeof(
char));
1262 strcpy(pattribute->
name,name);
1264 pdbFldDes->
name = pattribute->
name;
1280 const char *
pname = *ppname;
1287 while (pattribute) {
1288 size_t nameLen = strlen(pattribute->
name);
1289 int compare = strncmp(pattribute->
name, pname, nameLen);
1292 int ch = pname[nameLen];
1294 if (ch !=
'_' && !isalnum(ch)) {
1298 *ppname = &pname[nameLen];
1301 if (strlen(pname) > nameLen) {
1305 if (compare >= 0)
break;
1328 short indfield = pdbentry->
indfield;
1339 pflddes = precordType->
papFldDes[indfield];
1367 for(indfield=0; indfield<precordType->
no_fields; indfield++) {
1368 pflddes = precordType->
papFldDes[indfield];
1380 if(!pflddes)
return(
NULL);
1381 return(pflddes->
name);
1388 if(!pflddes)
return(-1);
1396 if(!pflddes)
return(
NULL);
1404 if(!pflddes)
return(
NULL);
1405 return(&pflddes->
prompt[0]);
1412 if(!pflddes)
return(0);
1428 if(!pdbFldDes || (strcmp(pdbFldDes->
name,
"NAME")!=0))
1432 zeroDbentry(pdbentry);
1434 zeroDbentry(pdbentry);
1436 preclist = &precordType->
recList;
1441 if((status =
dbAllocRecord(pdbentry,precordName)))
return(status);
1447 if(!ppvd) {
errMessage(-1,
"Logic Err: Could not add to PVD");
return(-1);}
1467 while (pAliasNode) {
1470 pAliasNode->
precord == precord &&
1474 pAliasNode = pAliasNodeNext;
1492 preclist = &precordType->
recList;
1503 if (status)
return status;
1519 while(pdbRecordType) {
1521 while(pdbRecordNode) {
1525 pdbRecordNode = pdbRecordNodeNext;
1536 const char *
pname = *ppname;
1541 zeroDbentry(pdbentry);
1542 pfn = strchr(pname,
'.');
1544 lenName = (size_t) (pfn - pname);
1546 lenName = strlen(pname);
1549 ppvdNode =
dbPvdFind(pdbbase, pname, lenName);
1555 *ppname = pname + lenName;
1563 if (status)
return status;
1574 zeroDbentry(pdbentry);
1600 if(!precordType)
return(0);
1608 if(!precordType)
return(0);
1617 if(!pdbRecordType)
return NULL;
1618 if(!precnode)
return NULL;
1644 if(!precnode)
return 0;
1684 errMessage(-1,
"dbCreateAlias: Add to PVD failed");
1704 if(!precnode)
return 0;
1720 if(!pdbFldDes || (strcmp(pdbFldDes->
name,
"NAME")!=0))
1732 if(status)
return(status);
1736 if((status =
dbCreateRecord(&dbentry,newRecordName)))
return(status);
1742 if((status =
dbPutString(&dbentry,pvalue)))
return(status);
1755 if (status)
return (status);
1766 const char *
pname = *ppname;
1767 short top, bottom, test;
1768 char **papsortFldName;
1780 if ((ch = *pname) &&
1781 (ch ==
'_' || isalpha(ch))) {
1782 while ((ch = pname[++nameLen]))
1783 if (!(ch ==
'_' || isalnum(ch)))
break;
1794 *ppname = &pname[nameLen];
1801 test = (top + bottom) / 2;
1803 int compare = strncmp(papsortFldName[test], pname, nameLen);
1805 compare = (int) (strlen(papsortFldName[test]) - nameLen);
1812 pdbentry->
indfield = sortFldInd[test];
1813 *ppname = &pname[nameLen];
1815 }
else if (compare > 0) {
1817 if (top < bottom)
break;
1818 test = (top + bottom) / 2;
1821 if (top < bottom)
break;
1822 test = (top + bottom) / 2;
1835 if (status)
return status;
1838 if (ch == 0 || isspace(ch))
return 0;
1848 void *pfield = pdbentry->
pfield;
1852 dbMsgCpy(pdbentry,
"fldDes not found");
1861 dbMsgCpy(pdbentry,
"Field not allocated (NULL)");
1872 dbMsgNCpy(pdbentry, (
char *)pfield, pflddes->
size);
1890 plink = (
DBLINK *)pfield;
1891 switch(plink->
type) {
1895 }
else if (plink->
text) {
1896 dbMsgCpy(pdbentry, plink->
text);
1898 dbMsgCpy(pdbentry,
"");
1905 dbMsgCpy(pdbentry,
"");
1912 dbMsgPrint(pdbentry,
"%s%s",
1928 dbMsgPrint(pdbentry,
"%s%s%s%s",
1936 dbMsgPrint(pdbentry,
"#C%d S%d @%s",
1941 dbMsgPrint(pdbentry,
"#B%d C%d N%d A%d F%d @%s",
1947 dbMsgPrint(pdbentry,
"#R%d M%d D%d E%d",
1954 dbMsgPrint(pdbentry,
"#L%d A%d C%d S%d @%s",
1960 dbMsgPrint(pdbentry,
"#L%d A%d @%s",
1965 dbMsgPrint(pdbentry,
"#L%u N%u P%u S%u @%s",
1971 dbMsgPrint(pdbentry,
"#L%u B%u G%u @%s",
1980 dbMsgPrint(pdbentry,
"#V%d C%d S%d @%s",
1984 dbMsgPrint(pdbentry,
"#V%d S%d @%s",
1995 switch(plink->
type) {
1999 }
else if (plink->
text) {
2000 dbMsgCpy(pdbentry, plink->
text);
2002 dbMsgCpy(pdbentry,
"");
2009 dbMsgCpy(pdbentry,
"");
2024 dbMsgPrint(pdbentry,
"%s%s",
2026 ppind ? ppstring[ppind] :
"");
2043 void *pfield = pdbentry->
pfield;
2045 unsigned char cvttype;
2050 message = getpMessage(pdbentry);
2051 cvttype = pflddes->
base;
2057 ulongToHexString(*(
char *) pfield, message);
2063 ulongToHexString(*(
epicsUInt8 *) pfield, message);
2069 ulongToHexString(*(
epicsInt16 *) pfield, message);
2076 ulongToHexString(*(
epicsUInt16 *) pfield, message);
2082 ulongToHexString(*(
epicsInt32 *) pfield, message);
2088 ulongToHexString(*(
epicsUInt32 *) pfield, message);
2115 dbMsgCpy(pdbentry,
"Field not found");
2119 if (!pdbMenu || choice_ind < 0 || choice_ind >= pdbMenu->
nChoice)
2122 dbMsgCpy(pdbentry, pchoice);
2132 dbMsgCpy(pdbentry,
"Field not found");
2139 if (choice_ind<0 || choice_ind>=pdbDeviceMenu->
nChoice)
2141 pchoice = pdbDeviceMenu->
papChoice[choice_ind];
2142 dbMsgCpy(pdbentry, pchoice);
2177 switch (plink->
type) {
2202 }
else if(
dbCanSetLink(plink, &link_info, devsup)!=0) {
2203 errlogPrintf(
"Error: %s.%s: can't initialize link type %d with \"%s\" (type %d)\n",
2206 }
else if(
dbSetLink(plink, &link_info, devsup)) {
2207 errlogPrintf(
"Error: %s.%s: failed to initialize link type %d with \"%s\" (type %d)\n",
2219 dbJLinkFree(pinfo->
jlink);
2232 memset(pinfo, 0,
sizeof(*pinfo));
2235 while (*str && isspace((
int)*str)) str++;
2239 while (len > 0 && isspace((
int)str[len-1])) len--;
2241 pstr = malloc(len + 1);
2251 memcpy(pstr, str+1, --len);
2257 memcpy(pstr, str, len);
2261 if (*str ==
'{' && str[len-1] ==
'}') {
2262 if (dbJLinkParse(str, len, ftype, &pinfo->
jlink))
2273 char *parm = strchr(pstr,
'@');
2277 len -= (parm - pstr);
2281 ret = sscanf(pinfo->
target,
"# %c%d %c%d %c%d %c%d %c%d %c",
2293 if (ret<0 || ret>10 || ret%2==1)
goto fail;
2314 memmove(pinfo->
target, parm, len + 1);
2333 if (pstr[0] ==
'[' && pstr[len-1] ==
']' &&
2334 (strchr(pstr,
',') || strchr(pstr,
'"'))) {
2340 pstr = strchr(pstr,
' ');
2350 if (strstr(pstr,
"NPP")) pinfo->
modifiers = 0;
2380 if (pinfo->
ltype == expected_type)
2383 switch (pinfo->
ltype) {
2430 switch(pinfo->
ltype) {
2482 if(strcmp(pinfo->
hwid,
"VCS")==0) {
2487 }
else if(strcmp(pinfo->
hwid,
"VS")==0) {
2492 cantProceed(
"dbSetLinkHW: logic error, unknown VXI_IO variant");
2498 cantProceed(
"dbSetLinkHW: logic error, unhandled link type");
2514 switch (pinfo->
ltype) {
2517 dbSetLinkConst(plink, pinfo);
2521 dbSetLinkPV(plink, pinfo);
2525 dbSetLinkJSON(plink, pinfo);
2528 errlogMessage(
"Warning: dbSetLink: forgot to test with dbCanSetLink() or logic error");
2532 else if (expected_type == pinfo->
ltype) {
2534 dbSetLinkHW(plink, pinfo);
2548 void *pfield = pdbentry->
pfield;
2551 int stringHasMacro=
FALSE;
2555 stringHasMacro = strstr(pstring,
"$(") || strstr(pstring,
"${");
2556 if(!macroIsOk && stringHasMacro) {
2565 strncpy((
char *)pfield, pstring, pflddes->
size-1);
2566 ((
char *)pfield)[pflddes->
size-1] = 0;
2572 if (
postfix(pstring,rpcl,&err)) {
2617 status =
dbSetLink(plink, &link_info, devsup);
2626 if (!status && strcmp(pflddes->
name,
"VAL") == 0) {
2641 char *message = getpMessage(pdbentry);
2657 strcpy(message,
"fldDes not found");
2661 if (strstr(pstring,
"$(") || strstr(pstring,
"${"))
2667 size_t length = strlen(pstring);
2669 if (length >= pflddes->
size) {
2670 sprintf(message,
"String too long, max %d characters",
2679 status =
postfix(pstring, rpcl, &err);
2681 sprintf(message,
"%s in CALC expression '%s'",
2745 if (strcmp(pchoice, pstring) == 0) {
2750 strcpy(message,
"Not a valid menu choice");
2758 if (!pdbDeviceMenu || pdbDeviceMenu->
nChoice == 0)
2761 for (i = 0; i < pdbDeviceMenu->
nChoice; i++) {
2762 const char *pchoice = pdbDeviceMenu->
papChoice[
i];
2767 if (strcmp(pchoice, pstring) == 0) {
2772 strcpy(message,
"Not a valid device type");
2781 strcpy(message,
"Not a valid field type");
2791 strcpy(message,
"Not a valid integer");
2795 strcpy(message,
"Internal error (badBase)");
2799 strcpy(message,
"Number too large for field type");
2803 strcpy(message,
"Number too small for field type");
2807 strcpy(message,
"Extraneous characters after number");
2811 strcpy(message,
"Unknown numeric conversion error");
2857 if (status)
return status;
2862 if (!pattern || !*pattern)
return 0;
2877 if (!strcmp(pinfo->
name, name)) {
2904 if (!pinfo)
return (
NULL);
2905 return (pinfo->
name);
2911 if (!pinfo)
return (
NULL);
2920 newstring = realloc(pinfo->
string,1+strlen(
string));
2922 strcpy(newstring,
string);
2923 pinfo->
string = newstring;
2938 if (!pinfo)
return (
NULL);
2961 pinfo->
name = calloc(1,1+strlen(name));
2966 strcpy(pinfo->
name, name);
2967 pinfo->
string = calloc(1,1+strlen(
string));
2973 strcpy(pinfo->
string,
string);
2984 if(!pgph)
return(
NULL);
2997 return "BAD_DBF_TYPE";
3017 if(!pgph)
return(
NULL);
3025 if(!pflddes)
return(
NULL);
3030 if(!pdbMenu)
return(
NULL);
3037 if(!pdbDeviceMenu)
return(
NULL);
3049 if(!pflddes)
return(-1);
3054 if(!pdbMenu)
return(0);
3061 if(!pdbDeviceMenu)
return(0);
3062 return(pdbDeviceMenu->
nChoice);
3074 if(!pflddes)
return(
NULL);
3079 if(!pdbMenu)
return(
NULL);
3080 if(index<0 || index>=pdbMenu->
nChoice)
return(
NULL);
3087 if(!pdbDeviceMenu)
return(
NULL);
3088 if(index<0 || index>=pdbDeviceMenu->
nChoice)
return(
NULL);
3089 return(pdbDeviceMenu->
papChoice[index]);
3102 char **papChoice =
NULL;
3104 if(!pflddes)
return(-1);
3109 if(!pdbMenu)
return(-1);
3118 if(!pdbDeviceMenu)
return(-1);
3120 nChoice = pdbDeviceMenu->
nChoice;
3126 if(nChoice<=0 || !papChoice)
return(-1);
3127 for(ind=0; ind<nChoice; ind++) {
3128 if(strcmp(choice,papChoice[ind])==0)
return(ind);
3135 if (!pgph)
return NULL;
3144 char *rtnval =
NULL;
3160 if (!pgph)
return NULL;
3169 return((
int)precordType->
no_links);
3180 if (index < 0 || index >= precordType->
no_links)
3195 fprintf(
stderr,
"pdbbase not specified\n");
3200 printf(
"no path defined\n");
3203 while(pdbPathNode) {
3213 dbBase *pdbbase,
const char *precordTypename,
int level)
3216 fprintf(
stderr,
"pdbbase not specified\n");
3225 fprintf(
stderr,
"pdbbase not specified\n");
3239 fprintf(
stderr,
"pdbbase not specified\n");
3244 if(recordTypeName) {
3245 gotMatch = (strcmp(recordTypeName,pdbRecordType->
name)==0)
3250 if(!gotMatch)
continue;
3251 printf(
"name(%s) no_fields(%hd) no_prompt(%hd) no_links(%hd)\n",
3254 printf(
"index name\tsortind sortname\n");
3255 for(i=0; i<pdbRecordType->
no_fields; i++) {
3257 printf(
"%5d %s\t%7d %s\n",
3262 for(i=0; i<pdbRecordType->
no_links; i++)
3267 printf(
"rset * %p rec_size %d\n",
3269 if(recordTypeName)
break;
3274 DBBASE *pdbbase,
const char *recordTypeName,
const char *fname)
3283 fprintf(
stderr,
"pdbbase not specified\n");
3288 if(recordTypeName) {
3289 gotMatch = (strcmp(recordTypeName,pdbRecordType->
name)==0)
3294 if(!gotMatch)
continue;
3295 printf(
"recordtype(%s) \n",pdbRecordType->
name);
3296 for(i=0; i<pdbRecordType->
no_fields; i++) {
3300 if(fname && strcmp(fname,pdbFldDes->
name)!=0)
continue;
3302 printf(
"\t prompt: %s\n",
3317 printf(
"\t field_type: %s\n",
3325 printf(
"\t promptgroup: %s\n",
3330 printf(
"\t initial: %s\n",
3333 if(pdbFldDes->
ftPvt)
3334 printf(
"\t\t menu: %s\n",
3337 printf(
"\t\t menu: NOT FOUND\n");
3348 printf(
"Attribute: name %s value %s\n",
3352 if(recordTypeName)
break;
3362 if (recordTypeName) {
3363 if (*recordTypeName == 0 || *recordTypeName ==
'*')
3367 fprintf(
stderr,
"pdbbase not specified\n");
3372 if(recordTypeName) {
3373 gotMatch = (strcmp(recordTypeName,pdbRecordType->
name)==0)
3378 if(!gotMatch)
continue;
3379 printf(
"recordtype(%s)\n",pdbRecordType->
name);
3386 if (pdevSup->
pdset) {
3387 static const char *names[] = {
3391 " - get_ioint_info()" 3396 printf(
"\t number: %d\n", n);
3397 for (i = 0; i < n; ++
i, ++pfunc) {
3398 const char *name = (i <
NELEMENTS(names)) ? names[i] :
"";
3400 printf(
"\t func %d: %p%s\n", i, (
void *)*pfunc, name);
3404 if (pdevSup->
pdsxt) {
3405 printf(
"\t add_record: %p\n",
3407 printf(
"\t del_record: %p\n",
3411 if(recordTypeName)
break;
3418 fprintf(
stderr,
"pdbbase not specified\n");
3427 fprintf(
stderr,
"pdbbase not specified\n");
3436 fprintf(
stderr,
"pdbbase not specified\n");
3445 fprintf(
stderr,
"pdbbase not specified\n");
3454 fprintf(
stderr,
"pdbbase not specified\n");
3467 fprintf(
stderr,
"pdbbase not specified\n");
3472 if (name && strcmp(name,pbrkTable->
name)!=0)
continue;
3473 printf(
"breaktable(%s) {\n",pbrkTable->
name);
3475 for(ind=0; ind < pbrkTable->
number; ind++) {
3476 printf(
"\traw=%f slope=%e eng=%f\n",
3504 DBENTRY dbentry, *pdbentry = &dbentry;
3506 FILE *stream = report ? report :
stdout;
3509 fprintf(
stderr,
"dbReportDeviceConfig: pdbbase not specified\n");
3522 for (ilink=0; ilink<nlinks; ilink++) {
3533 plink = pdbentry->
pfield;
3534 linkType = plink->
type;
3541 linkType = linfo.
ltype;
3542 if (linkType && bus[linkType])
3551 if (!linkType || !bus[linkType])
3565 if (strcmp(
dbGetString(pdbentry),
"LINEAR") != 0) {
3569 strcpy(cvtValue,
"cvt(");
3575 strcat(cvtValue,
",");
3578 strcat(cvtValue,
")");
3581 fprintf(stream,
"%-8s %-20s %-20s %-20s %-s\n",
3582 bus[linkType], linkValue, dtypValue,
3591 finishOutstream(stream);
char * dbGetStringNum(DBENTRY *pdbentry)
long dbWriteDriver(DBBASE *pdbbase, const char *filename)
dbDeviceMenu * dbGetDeviceMenu(DBENTRY *pdbentry)
long dbFirstField(DBENTRY *pdbentry, int dctonly)
long dbCreateAlias(DBENTRY *pdbentry, const char *alias)
long dbPath(DBBASE *pdbbase, const char *path)
void dbDumpLink(DBBASE *pdbbase)
char * dbVerify(DBENTRY *pdbentry, const char *pstring)
void dbInitEntry(dbBase *pdbbase, DBENTRY *pdbentry)
const char * dbGetInfoName(DBENTRY *pdbentry)
long dbFirstRecordType(DBENTRY *pdbentry)
long dbWriteBreaktable(DBBASE *pdbbase, const char *filename)
LIBCOM_API const char * calcErrorStr(short error)
Convert an error code to a string.
#define S_dbLib_recNotFound
long dbNextInfo(DBENTRY *pdbentry)
long dbNextMatchingInfo(DBENTRY *pdbentry, const char *pattern)
#define assert(exp)
Declare that a condition should be true.
int dbGetNRecords(DBENTRY *pdbentry)
#define ellCount(PLIST)
Report the number of nodes in a list.
PVDENTRY * dbPvdAdd(dbBase *pdbbase, dbRecordType *precordType, dbRecordNode *precnode)
long dbPutRecordAttribute(DBENTRY *pdbentry, const char *name, const char *value)
DBENTRY * dbCopyEntry(DBENTRY *pdbentry)
int dbFindFieldType(const char *type)
An EPICS-specific replacement for ANSI C's assert.
struct dbCommon * precord
long dbPutInfoString(DBENTRY *pdbentry, const char *string)
dbRecordType * precordType
#define S_stdlib_underflow
STATIC_ASSERT(messagesize >=21)
#define OSI_PATH_LIST_SEPARATOR
LIBCOM_API int epicsParseInt64(const char *str, epicsInt64 *to, int base, char **units)
LIBCOM_API int epicsStdCall LIBCOM_API int epicsStdCall epicsVsnprintf(char *str, size_t size, const char *format, va_list ap)
int dbIsVisibleRecord(DBENTRY *pdbentry)
ELLNODE * ellNth(ELLLIST *pList, int nodeNum)
Find the Nth node in a list.
void dbFreeEntry(DBENTRY *pdbentry)
long dbFindFieldPart(DBENTRY *pdbentry, const char **ppname)
#define cvtShortToString(val, str)
long dbWriteLinkFP(DBBASE *pdbbase, FILE *fp)
unsigned short epicsUInt16
linkSup * dbFindLinkSup(dbBase *pdbbase, const char *name)
The API for the EPICS Calculation Engine.
DBENTRY * dbAllocEntry(dbBase *pdbbase)
int epicsStrGlobMatch(const char *str, const char *pattern)
long dbGetLinkField(DBENTRY *pdbentry, int index)
long dbFindRecordType(DBENTRY *pdbentry, const char *recordType)
char value[MAX_STRING_SIZE]
#define S_dbLib_flddesNotFound
LIBCOM_API int epicsParseInt8(const char *str, epicsInt8 *to, int base, char **units)
#define S_stdlib_noConversion
void dbDumpPath(DBBASE *pdbbase)
const char * dbGetInfo(DBENTRY *pdbentry, const char *name)
void dbFinishEntry(DBENTRY *pdbentry)
pvd::StructureConstPtr type
int dbGetMenuIndexFromString(DBENTRY *pdbentry, const char *choice)
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
#define S_dbLib_recExists
void dbPvdFreeMem(dbBase *pdbbase)
void dbCatString(char **string, int *stringLength, char *src, char *separator)
void dbFreePath(DBBASE *pdbbase)
#define errMessage(S, PM)
long dbWriteDriverFP(DBBASE *pdbbase, FILE *fp)
long dbWriteFunctionFP(DBBASE *pdbbase, FILE *fp)
brkTable * dbFindBrkTable(dbBase *pdbbase, const char *name)
long dbInvisibleRecord(DBENTRY *pdbentry)
void dbDumpRecord(dbBase *pdbbase, const char *precordTypename, int level)
void dbPvdDelete(dbBase *pdbbase, dbRecordNode *precnode)
long dbNextRecordType(DBENTRY *pdbentry)
void * dbGetInfoPointer(DBENTRY *pdbentry)
void dbDumpBreaktable(DBBASE *pdbbase, const char *name)
long dbFindRecord(DBENTRY *pdbentry, const char *pname)
Miscellaneous macro definitions.
void dbDumpDevice(DBBASE *pdbbase, const char *recordTypeName)
A library to manage storage that is allocated and quickly freed.
size_t cvtUInt64ToHexString(epicsUInt64 val, char *pdest)
long dbNextRecord(DBENTRY *pdbentry)
LIBCOM_API int epicsParseUInt8(const char *str, epicsUInt8 *to, int base, char **units)
#define S_stdlib_extraneous
long dbWriteBreaktableFP(DBBASE *pdbbase, FILE *fp)
unsigned long long epicsUInt64
long dbFindRecordPart(DBENTRY *pdbentry, const char **ppname)
long dbPutInfoPointer(DBENTRY *pdbentry, void *pointer)
LIBCOM_API void epicsStdCall gphDelete(struct gphPvt *pvt, const char *name, void *pvtid)
void dbFreeLinkInfo(dbLinkInfo *pinfo)
LIBCOM_API void epicsStdCall gphInitPvt(struct gphPvt **ppvt, int tableSize)
dbBase * dbAllocBase(void)
int dbGetNRecordTypes(DBENTRY *pdbentry)
char * dbRecordName(DBENTRY *pdbentry)
void dbDumpField(DBBASE *pdbbase, const char *recordTypeName, const char *fname)
long dbWriteRecordType(DBBASE *pdbbase, const char *filename, const char *recordTypeName)
long dbCopyRecord(DBENTRY *pdbentry, const char *newRecordName, int overWriteOK)
A doubly-linked list library.
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
LIBCOM_API GPHENTRY *epicsStdCall gphFind(struct gphPvt *pvt, const char *name, void *pvtid)
#define ellNext(PNODE)
Find the next node in list.
struct dbRecordType * pdbRecordType
#define EPICS_PRINTF_STYLE(f, a)
size_t cvtInt64ToHexString(epicsInt64 val, char *pdest)
#define cvtUshortToString(val, str)
long dbWriteRecord(DBBASE *ppdbbase, const char *filename, const char *precordTypename, int level)
maplinkType pamaplinkType[LINK_NTYPES]
#define cvtLongToString(val, str)
int dbGetNMenuChoices(DBENTRY *pdbentry)
struct macro_link macro_link
long dbGetAttributePart(DBENTRY *pdbentry, const char **ppname)
unsigned int process_passive
struct dbRecordNode * aliasedRecnode
long(* add_record)(struct dbCommon *precord)
size_t cvtInt64ToString(epicsInt64 val, char *pdest)
const char * dbGetInfoString(DBENTRY *pdbentry)
long dbNextField(DBENTRY *pdbentry, int dctonly)
char * dbGetMenuStringFromIndex(DBENTRY *pdbentry, int index)
long dbFindInfo(DBENTRY *pdbentry, const char *name)
int dbIsAlias(DBENTRY *pdbentry)
#define cvtUcharToString(val, str)
void dbmfFree(void *mem)
Free the memory allocated by dbmfMalloc.
LIBCOM_API int epicsParseUInt64(const char *str, epicsUInt64 *to, int base, char **units)
LIBCOM_API int epicsParseDouble(const char *str, double *to, char **units)
void dbDumpMenu(dbBase *pdbbase, const char *menuName)
char ** dbGetMenuChoices(DBENTRY *pdbentry)
int dbFollowAlias(DBENTRY *pdbentry)
int epicsStrPrintEscaped(FILE *fp, const char *s, size_t len)
PVDENTRY * dbPvdFind(dbBase *pdbbase, const char *name, size_t lenName)
long dbDeleteRecord(DBENTRY *pdbentry)
int dbFoundField(DBENTRY *pdbentry)
char * dbGetFieldName(DBENTRY *pdbentry)
long dbCreateRecord(DBENTRY *pdbentry, const char *precordName)
char * dbGetRecordName(DBENTRY *pdbentry)
long dbPutStringNum(DBENTRY *pdbentry, const char *pstring)
LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
A calloc() that never returns NULL.
#define S_stdlib_overflow
LIBCOM_API void epicsStdCall gphFreeMem(struct gphPvt *pvt)
char * dbGetPromptGroupNameFromKey(DBBASE *pdbbase, const short key)
int errlogPrintf(const char *pFormat,...)
#define S_dbLib_infoNotFound
void dbFreeBase(dbBase *pdbbase)
long dbWriteVariableFP(DBBASE *pdbbase, FILE *fp)
size_t cvtUInt64ToString(epicsUInt64 val, char *pdest)
#define epicsParseFloat32(str, to, units)
void dbDumpVariable(DBBASE *pdbbase)
long dbFirstInfo(DBENTRY *pdbentry)
#define cvtCharToString(val, str)
char * epicsStrDup(const char *s)
int dbGetNFields(DBENTRY *pdbentry, int dctonly)
int dbGetNLinks(DBENTRY *pdbentry)
void dbDumpRegistrar(DBBASE *pdbbase)
long dbFreeRecord(DBENTRY *pdbentry)
char * dbGetPrompt(DBENTRY *pdbentry)
mapspcType pamapspcType[]
void dbCopyEntryContents(DBENTRY *pfrom, DBENTRY *pto)
epicsShareExtern mapdbfType pamapdbfType[]
int errlogMessage(const char *message)
LIBCOM_API int epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units)
long dbAllocRecord(DBENTRY *pdbentry, const char *precordName)
long(* del_record)(struct dbCommon *precord)
long dbWriteMenu(DBBASE *ppdbbase, const char *filename, const char *menuName)
struct ELLNODE * previous
Pointer to previous node in list.
long dbDeleteAliases(DBENTRY *pdbentry)
char * dbGetDefault(DBENTRY *pdbentry)
short dbGetPromptGroupKeyFromName(DBBASE *pdbbase, const char *name)
void dbReportDeviceConfig(dbBase *pdbbase, FILE *report)
long dbGetFieldAddress(DBENTRY *pdbentry)
char * dbGetString(DBENTRY *pdbentry)
#define dbCalloc(nobj, size)
LIBCOM_API int epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units)
long dbWriteRegistrarFP(DBBASE *pdbbase, FILE *fp)
LIBCOM_API int epicsParseInt16(const char *str, epicsInt16 *to, int base, char **units)
long dbWriteRecordFP(DBBASE *pdbbase, FILE *fp, const char *precordTypename, int level)
#define ellInit(PLIST)
Initialize a list type.
void dbDumpDriver(DBBASE *pdbbase)
void dbFreeLinkContents(struct link *plink)
void ellInsert(ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode)
Inserts a node into a list immediately after a specific node.
LIBCOM_API void cantProceed(const char *msg,...)
dbRecordType * precordType
long dbFirstRecord(DBENTRY *pdbentry)
int dbGetPromptGroup(DBENTRY *pdbentry)
long dbFreeRecords(DBBASE *pdbbase)
const char * dbGetFieldTypeString(int dbfType)
drvSup * dbFindDriver(dbBase *pdbbase, const char *name)
#define DBRN_FLAGS_HASALIAS
long dbFindField(DBENTRY *pdbentry, const char *pname)
char * dbGetRelatedField(DBENTRY *psave)
long dbWriteDevice(DBBASE *pdbbase, const char *filename)
long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
void dbPvdInitPvt(dbBase *pdbbase)
Routines for code that can't continue or return after an error.
LIBCOM_API int epicsParseUInt16(const char *str, epicsUInt16 *to, int base, char **units)
long dbPutString(DBENTRY *pdbentry, const char *pstring)
long dbVisibleRecord(DBENTRY *pdbentry)
long dbAddPath(DBBASE *pdbbase, const char *path)
LIBCOM_API long postfix(const char *psrc, char *pout, short *perror)
Compile an infix expression into postfix byte-code.
dbMenu * dbFindMenu(dbBase *pdbbase, const char *name)
int dbIsMacroOk(DBENTRY *pdbentry)
#define S_dbLib_fieldNotFound
int dbGetFieldDbfType(DBENTRY *pdbentry)
long dbDeleteInfo(DBENTRY *pdbentry)
#define S_dbLib_nameLength
long dbWriteRecordTypeFP(DBBASE *pdbbase, FILE *fp, const char *recordTypeName)
long dbWriteMenuFP(DBBASE *pdbbase, FILE *fp, const char *menuName)
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
long dbWriteDeviceFP(DBBASE *pdbbase, FILE *fp)
#define DBRN_FLAGS_VISIBLE
long dbPutInfo(DBENTRY *pdbentry, const char *name, const char *string)
void * dbmfMalloc(size_t size)
Allocate memory.
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
void dbDumpFunction(DBBASE *pdbbase)
#define cvtUlongToString(val, str)
void dbDumpRecordType(DBBASE *pdbbase, const char *recordTypeName)
#define S_dbLib_recordTypeNotFound
#define epicsParseFloat64(str, to, units)
char * dbGetRecordTypeName(DBENTRY *pdbentry)
long dbGetRecordAttribute(DBENTRY *pdbentry, const char *pname)
#define DBRN_FLAGS_ISALIAS
long dbCanSetLink(DBLINK *plink, dbLinkInfo *pinfo, devSup *devsup)
#define DBLINK_FLAG_TSELisTIME
long dbSetLink(DBLINK *plink, dbLinkInfo *pinfo, devSup *devsup)
int dbGetNAliases(DBENTRY *pdbentry)
epicsShareFunc int dbIsDefaultValue(DBENTRY *pdbentry)
#define ellFirst(PLIST)
Find the first node in list.