This is Unofficial EPICS BASE Doxygen Site
stringinRecord.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 
10 /* recStringin.c - Record Support Routines for Stringin records */
11 /*
12  * Author: Janet Anderson
13  * Date: 4/23/91
14  */
15 
16 
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #include "dbDefs.h"
24 #include "epicsPrint.h"
25 #include "alarm.h"
26 #include "callback.h"
27 #include "dbAccess.h"
28 #include "dbEvent.h"
29 #include "dbFldTypes.h"
30 #include "devSup.h"
31 #include "errMdef.h"
32 #include "recSup.h"
33 #include "recGbl.h"
34 #include "special.h"
35 #include "menuYesNo.h"
36 
37 #define GEN_SIZE_OFFSET
38 #include "stringinRecord.h"
39 #undef GEN_SIZE_OFFSET
40 #include "epicsExport.h"
41 
42 /* Create RSET - Record Support Entry Table*/
43 #define report NULL
44 #define initialize NULL
45 static long init_record(struct dbCommon *, int);
46 static long process(struct dbCommon *);
47 static long special(DBADDR *, int);
48 #define get_value NULL
49 #define cvt_dbaddr NULL
50 #define get_array_info NULL
51 #define put_array_info NULL
52 #define get_units NULL
53 #define get_precision NULL
54 #define get_enum_str NULL
55 #define get_enum_strs NULL
56 #define put_enum_str NULL
57 #define get_graphic_double NULL
58 #define get_control_double NULL
59 #define get_alarm_double NULL
60 
62  RSETNUMBER,
63  report,
64  initialize,
66  process,
67  special,
68  get_value,
69  cvt_dbaddr,
72  get_units,
80 };
81 epicsExportAddress(rset,stringinRSET);
82 
83 static void monitor(stringinRecord *);
84 static long readValue(stringinRecord *);
85 
86 
87 static long init_record(struct dbCommon *pcommon, int pass)
88 {
89  struct stringinRecord *prec = (struct stringinRecord *)pcommon;
90  STATIC_ASSERT(sizeof(prec->oval)==sizeof(prec->val));
91  STATIC_ASSERT(sizeof(prec->sval)==sizeof(prec->val));
92  stringindset *pdset = (stringindset *) prec->dset;
93 
94  if (pass == 0) return 0;
95 
96  recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
97  recGblInitConstantLink(&prec->siol, DBF_STRING, prec->sval);
98 
99  if (!pdset) {
100  recGblRecordError(S_dev_noDSET, prec, "stringin: init_record");
101  return S_dev_noDSET;
102  }
103 
104  /* must have read_stringin function defined */
105  if ((pdset->common.number < 5) || (pdset->read_stringin == NULL)) {
106  recGblRecordError(S_dev_missingSup, prec, "stringin: init_record");
107  return S_dev_missingSup;
108  }
109 
110  if (pdset->common.init_record) {
111  long status = pdset->common.init_record(pcommon);
112 
113  if (status)
114  return status;
115  }
116  strncpy(prec->oval, prec->val, sizeof(prec->oval));
117  return 0;
118 }
119 
120 /*
121  */
122 static long process(struct dbCommon *pcommon)
123 {
124  struct stringinRecord *prec = (struct stringinRecord *)pcommon;
125  stringindset *pdset = (stringindset *)(prec->dset);
126  long status;
127  unsigned char pact=prec->pact;
128 
129  if( (pdset==NULL) || (pdset->read_stringin==NULL) ) {
130  prec->pact=TRUE;
131  recGblRecordError(S_dev_missingSup,(void *)prec,"read_stringin");
132  return(S_dev_missingSup);
133  }
134 
135  status=readValue(prec); /* read the new value */
136  /* check if device support set pact */
137  if ( !pact && prec->pact ) return(0);
138 
139  prec->pact = TRUE;
140  recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
141 
142  /* check event list */
143  monitor(prec);
144  /* process the forward scan link record */
145  recGblFwdLink(prec);
146 
147  prec->pact=FALSE;
148  return(status);
149 }
150 
151 static long special(DBADDR *paddr, int after)
152 {
153  stringinRecord *prec = (stringinRecord *)(paddr->precord);
154  int special_type = paddr->special;
155 
156  switch(special_type) {
157  case(SPC_MOD):
158  if (dbGetFieldIndex(paddr) == stringinRecordSIMM) {
159  if (!after)
160  recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
161  else
162  recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
163  return(0);
164  }
165  default:
166  recGblDbaddrError(S_db_badChoice, paddr, "stringin: special");
167  return(S_db_badChoice);
168  }
169 }
170 
171 static void monitor(stringinRecord *prec)
172 {
173  int monitor_mask = recGblResetAlarms(prec);
174 
175  if (strncmp(prec->oval, prec->val, sizeof(prec->val))) {
176  monitor_mask |= DBE_VALUE | DBE_LOG;
177  strncpy(prec->oval, prec->val, sizeof(prec->oval));
178  }
179 
180  if (prec->mpst == stringinPOST_Always)
181  monitor_mask |= DBE_VALUE;
182  if (prec->apst == stringinPOST_Always)
183  monitor_mask |= DBE_LOG;
184 
185  if (monitor_mask)
186  db_post_events(prec, prec->val, monitor_mask);
187 }
188 
189 static long readValue(stringinRecord *prec)
190 {
191  stringindset *pdset = (stringindset *) prec->dset;
192  long status = 0;
193 
194  if (!prec->pact) {
195  status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
196  if (status) return status;
197  }
198 
199  switch (prec->simm) {
200  case menuYesNoNO:
201  status = pdset->read_stringin(prec);
202  break;
203 
204  case menuYesNoYES: {
205  recGblSetSevr(prec, SIMM_ALARM, prec->sims);
206  if (prec->pact || (prec->sdly < 0.)) {
207  status = dbGetLink(&prec->siol, DBR_STRING, prec->sval, 0, 0);
208  if (status == 0) {
209  strncpy(prec->val, prec->sval, sizeof(prec->val));
210  prec->udf = FALSE;
211  }
212  prec->pact = FALSE;
213  } else { /* !prec->pact && delay >= 0. */
214  epicsCallback *pvt = prec->simpvt;
215  if (!pvt) {
216  pvt = calloc(1, sizeof(epicsCallback)); /* very lazy allocation of callback structure */
217  prec->simpvt = pvt;
218  }
219  if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
220  prec->pact = TRUE;
221  }
222  break;
223  }
224 
225  default:
226  recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
227  status = -1;
228  }
229 
230  return status;
231 }
#define RSETNUMBER
Definition: recSup.h:92
#define DBR_STRING
Definition: db_access.h:69
#define FALSE
Definition: dbDefs.h:32
#define initialize
pvd::Status status
epicsExportAddress(rset, stringinRSET)
#define report
#define get_units
#define init_record
#define get_graphic_double
#define S_dev_missingSup
Definition: devSup.h:170
#define get_alarm_double
#define SOFT_ALARM
Definition: alarm.h:106
#define NULL
Definition: catime.c:38
#define get_array_info
rset stringinRSET
Miscellaneous macro definitions.
#define get_enum_str
#define get_precision
#define DBE_VALUE
Definition: caeventmask.h:38
Device support routines.
#define STATIC_ASSERT(expr)
Declare a condition that should be true at compile-time.
Definition: epicsAssert.h:86
#define DBE_LOG
Definition: caeventmask.h:40
#define SIMM_ALARM
Definition: alarm.h:110
#define cvt_dbaddr
#define put_array_info
#define get_enum_strs
#define TRUE
Definition: dbDefs.h:27
#define put_enum_str
if(yy_init)
Definition: scan.c:972
#define get_control_double
Definition: recSup.h:67
#define SPC_MOD
Definition: special.h:33
int prec
Definition: reader.c:29
#define INVALID_ALARM
Definition: alarm.h:53
#define special
Definition: dfanoutRecord.c:50
#define S_dev_noDSET
Definition: devSup.h:169
#define get_value
Exporting IOC objects.