-
Notifications
You must be signed in to change notification settings - Fork 1
/
datPrmry.c
181 lines (153 loc) · 6.3 KB
/
datPrmry.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include "cnf.h" /* F77 <-> C string handling functions */
#include "ems.h" /* EMS error reporting routines */
#include "ems_par.h" /* EMS public constants */
#include "hds1.h" /* Global definitions for HDS */
#include "rec.h" /* Public rec_ definitions */
#include "dat1.h" /* Internal dat_ definitions */
#include "dat_err.h" /* DAT__ error code definitions */
#include "hds.h"
#define TRUE 1
#define FALSE 0
/* F77_INTEGER_FUNCTION(dat_prmry)( LOGICAL(SET),
* CHARACTER(LOC),
* LOGICAL(PRMRY),
* INTEGER(STATUS)
* TRAIL(LOC) )
*/
int
datPrmry(int set,
HDSLoc **locator,
int *prmry,
int *status)
{
/*
*+
* Name:
* DAT_PRMRY
* Purpose:
* Set or enquire primary/secondary locator status.
* Language:
* ANSI C
* Invocation:
* CALL DAT_PRMRY( SET, LOC, PRMRY, STATUS )
* Description:
* The routine may be used to promote a locator to become a
* "primary" locator, to demote it to become a "secondary" locator,
* or to enquire about the primary/secondary status of a locator.
* It allows control over the duration for which an HDS container
* file remains open; each file remains open only so long as there
* is at least one primary locator associated with it.
* Arguments:
* SET = LOGICAL (Given)
* If a .TRUE. value is given for this argument, then the routine
* will perform a "set" operation to set the primary/secondary
* status of a locator. Otherwise it will perform an "enquire"
* operation to return the value of this status without changing
* it.
* LOC = CHARACTER * ( * ) (Given and Returned)
* The locator whose primary/secondary status is to be set or
* enquired.
* PRMRY = LOGICAL (Given and Returned)
* If SET is .TRUE., then this is an input argument and specifies
* the new value to be set (.TRUE. for a primary locator, .FALSE.
* for a secondary locator). If SET is .FALSE., then this is an
* output argument and will return a value indicating whether or
* not a primary locator was supplied.
* STATUS = INTEGER (Given and Returned)
* The global status.
* Notes:
* - The value of the LOC argument will not normally be changed.
* However, if it is the last primary locator associated with a
* container file, and is being demoted from a primary to a
* secondary locator, then the container file will be left without
* an associated primary locator. In this case, the locator supplied
* will be annulled (along with any other secondary locators
* associated with the same file), a value of DAT__NOLOC will be
* returned, and the file will be closed.
* - The DAT__NOLOC constant is defined in the include file
* DAT_PAR.
* Copyright:
* Copyright (C) 1992 Science & Engineering Research Council
* Authors:
* RFWS: R.F. Warren-Smith (STARLINK, RAL)
* BKM: B.K. McIlwrath (STARLINK, RAL)
* {enter_new_authors_here}
* History:
* 24-SEP-1992 (RFWS):
* Original version.
* 23-APR-2002 (BKM):
* Convert to C interface.
* 15-NOV-2005 (TIMJ):
* Use HDSLoc API
* {enter_changes_here}
* Bugs:
* {note_any_bugs_here}
*-
*/
/* Local Variables: */
int refcnt; /* Container file reference count */
struct LCP *lcp; /* Pointer to LCP */
/*. */
/* Check the inherited global status. */
if ( !_ok( *status) ) return *status;
hds_gl_status = *status;
/* Import the locator. */
dat1_import_loc( *locator, &lcp );
if ( _ok( hds_gl_status ) )
{
/* If the locator attribute is being enquired, then return its value. */
if ( !set )
{
*prmry = lcp->primary ? TRUE : FALSE;
}
/* Otherwise, if a secondary locator is being promoted to a primary */
/* locator, then flag it as such and increment the reference count for its */
/* container file. */
else if ( !lcp->primary && *prmry )
{
lcp->primary = 1;
rec_refcnt( &lcp->data.han, 1, &refcnt, &hds_gl_status );
}
/* Otherwise, if a primary locator is being demoted to a secondary locator, */
/* then obtain the current reference count for its container file. */
else if ( lcp->primary && !( *prmry ) )
{
rec_refcnt( &lcp->data.han, 0, &refcnt, &hds_gl_status );
if ( _ok( hds_gl_status ) )
{
/* If the reference count is more than one (so there is at least one other */
/* primary locator still associated with it), then demote the locator and */
/* decrement the reference count. */
if ( refcnt > 1 )
{
lcp->primary = 0;
rec_refcnt( &lcp->data.han, -1, &refcnt, &hds_gl_status );
}
/* Otherwise, annul the LCP, causing the locator supplied and all other */
/* locators associated with the same container file to become invalid, and */
/* the container file itself to be closed. */
else
{
dat1_annul_lcp( &lcp );
/* Nullify the locator value. */
dat1_free_hdsloc(locator );
}
}
}
}
/* If an error occurred, then report appropriate contextual information. */
if ( !_ok( hds_gl_status ) )
{
emsSetnc( "DOING", set ? "setting" : "enquiring",
EMS__SZTOK );
emsRep( "DAT_PRMRY_ERR",
"DAT_PRMRY: Error ^DOING primary locator status.",
&hds_gl_status );
}
/* Return the current global status value. */
*status = hds_gl_status;
return *status;
}