summaryrefslogtreecommitdiff
path: root/Ganlib/src/MSTR.f
blob: 567369bd0a7716d28b38b4c9866146bff23c4481 (plain)
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
*DECK MSTR
      SUBROUTINE MSTR(NENTRY,HENTRY,IENTRY,JENTRY,KENTRY)
*
*-----------------------------------------------------------------------
*
*Purpose:
* Manage user-defined structures.
*
*Copyright:
* Copyright (C) 2002 Ecole Polytechnique de Montreal
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version
*
*Author(s): R. Le Tellier
*
*Parameters: input/output
* NENTRY  number of LCM objects or files used by the operator.
* HENTRY  name of each LCM object or file:
*         HENTRY(1): modification type(VECTOR);
*         HENTRY(2): read-only type(VECTOR).
* IENTRY  type of each LCM object or file:
*         =1 LCM memory object; =2 XSM file; =3 sequential binary file;
*         =4 sequential ascii file.
* JENTRY  access of each LCM object or file:
*         =0 the LCM object or file is created;
*         =1 the LCM object or file is open for modifications;
*         =2 the LCM object or file is open in read-only mode.
* KENTRY  LCM object address or file unit number.
*
*-----------------------------------------------------------------------
*
      USE GANLIB
*----
*  SUBROUTINE ARGUMENTS
*----
      INTEGER     NENTRY                  
      CHARACTER   HENTRY(NENTRY)*12
      INTEGER     IENTRY(NENTRY),JENTRY(NENTRY)
      TYPE(C_PTR) KENTRY(NENTRY)
*----
*  LOCAL VARIABLES
*----
      INTEGER I,ACSTR,TYSTR,ACSTRO,TYSTRO,ACSTR2,TYSTR2
      INTEGER, PARAMETER :: IOUT=6
      INTEGER, PARAMETER :: NSTATE=40
      INTEGER INDIC,NITMA,ISTATE(NSTATE),IPRINT,NBLOCK,ILEN,ITYP,NBDIR
      REAL FLOTT
      DOUBLE PRECISION DFLOTT
      CHARACTER TEXT4*4,NAME*12,PATH*72,DIRS(37)*12,NAME2*12,TEXT12*12
      LOGICAL ROOT
      TYPE(C_PTR) IPSTR,IPSTRO,IPSTR2
      CHARACTER(LEN=12), ALLOCATABLE, DIMENSION(:) :: BLNAM
      INTEGER, ALLOCATABLE, DIMENSION(:) :: BLTYP,BLLEN
*----
*  PARAMETER VALIDATION
*----
      IF(NENTRY.LT.1)
     1  CALL XABORT('MSTR: AT LEAST ONE PARAMETER EXPECTED.')
      DO I=1,NENTRY
         IF(IENTRY(I).GT.2) 
     1     CALL XABORT('MSTR: LINKED LIST OR XSM EXPECTED.')
      ENDDO
*----
*  CREATE STATE-VECTOR/SIGNATURE FOR STRUCTURES IN CREATION MODE
*  VERIFY IF IT EXISTS FOR STRUCTURES IN MODIFICATION MODE
*----
      DO I=1,NENTRY
         ACSTR=JENTRY(I)
         IPSTR=KENTRY(I)
         IF (ACSTR.EQ.0) THEN
*        THE STRUCTURE IS CREATED:
*        ASSIGN IT A DEFAULT SIGNATURE AND A STATE-VECTOR
            NAME='VECTOR'
            CALL LCMPTC(IPSTR,'SIGNATURE',12,NAME)
            ISTATE(:NSTATE)=0
            CALL LCMPUT(IPSTR,'STATE-VECTOR',NSTATE,1,ISTATE)
         ELSEIF (ACSTR.EQ.1) THEN
            CALL LCMLEN(IPSTR,'SIGNATURE',ILEN,ITYP)
            IF ((ILEN.NE.3).OR.(ITYP.NE.3))
     1         CALL XABORT('MSTR: INVALID SIGNATURE FOR '//HENTRY(I)
     2                                                  //'.')
            CALL LCMLEN(IPSTR,'STATE-VECTOR',ILEN,ITYP)
            IF ((ILEN.NE.40).OR.(ITYP.NE.1))
     1          CALL XABORT('MSTR: INVALID STATE-VECTOR FOR '//HENTRY(I)
     2                                                      //'.')
         ENDIF
      ENDDO
*---
* PROCESS USER'S INPUT 
*---
      IPRINT=0
      ACSTR=JENTRY(1)
      TYSTR=IENTRY(1)
      IPSTR=KENTRY(1)
      ACSTR2=ACSTR
      TYSTR2=TYSTR
      IPSTR2=IPSTR
 50   CALL REDGET(INDIC,NITMA,FLOTT,TEXT4,DFLOTT)
      IF(INDIC.EQ.10) GO TO 60
      IF(INDIC.NE.3) CALL XABORT('MSTR: CHARACTER DATA EXPECTED(1).')
      IF(TEXT4.EQ.'EDIT') THEN
*     MODULE EDITION LEVEL
         CALL REDGET(INDIC,IPRINT,FLOTT,TEXT4,DFLOTT)
         IF(INDIC.NE.1) CALL XABORT('MSTR: INTEGER DATA EXPECTED(1).')
      ELSEIF(TEXT4.EQ.'TYPE') THEN
*     USER DEFINED TYPE FOR THE STRUCTURE
         CALL REDGET(INDIC,NITMA,FLOTT,PATH,DFLOTT)
         IF(INDIC.NE.3) 
     1   CALL XABORT('MSTR: CHARACTER DATA EXPECTED(2).')
         CALL MSTANP(NENTRY,IENTRY,JENTRY,KENTRY,PATH,IPSTR,
     1               ACSTR,TYSTR,NBDIR,DIRS,ROOT)
         IF (NBDIR.NE.1) CALL XABORT('MSTR: INVALID TYPE ENTRY.')
         CALL LCMPTC(IPSTR,'SIGNATURE',12,DIRS(1))
      ELSEIF((TEXT4.EQ.'PUT').OR.
     1       (TEXT4.EQ.'GET').OR.
     2       (TEXT4.EQ.'CP')) THEN
*     PUT, GET OR CP ACTION
         CALL REDGET(INDIC,NELEM,FLOTT,TEXT12,DFLOTT)
*        NUMBER OF ELEMENTS
         IF(INDIC.NE.1) CALL XABORT('MSTR: INTEGER DATA EXPECTED(2).')
         IBEG=1
         IEND=NELEM
         IINC=1
         CALL REDGET(INDIC,NITMA,FLOTT,PATH,DFLOTT)
         IF(INDIC.EQ.1) THEN
*        STARTING INDEX
            IBEG=NITMA
            CALL REDGET(INDIC,NITMA,FLOTT,PATH,DFLOTT)
            IF(INDIC.EQ.1) THEN
*           INCREMENT
               IINC=NITMA
            ELSE
               GOTO 10
            ENDIF
            CALL REDGET(INDIC,NITMA,FLOTT,PATH,DFLOTT)
         ENDIF
 10      CONTINUE
         IEND=IBEG+(NELEM-1)*IINC
         IF (INDIC.NE.3)
     1        CALL XABORT('MSTR: CHARACTER DATA EXPECTED(3).')
         IPSTRO=IPSTR
         ACSTRO=ACSTR
         TYSTRO=TYSTR
*        ANALYSE USER'S PATH
         CALL MSTANP(NENTRY,IENTRY,JENTRY,KENTRY,PATH,IPSTR,
     1        ACSTR,TYSTR,NBDIR,DIRS,ROOT)
*        GO TO REQUESTED DIRECTORY         
         IF (NBDIR.GT.1) THEN
            CALL MSTMOV(IPSTR,ACSTR,IPRINT,NBDIR-1,DIRS,ROOT)
         ENDIF
         NAME=DIRS(NBDIR)
         IF (TEXT4.EQ.'PUT') THEN
*        CREATING OR UPDATING DATA IN A BLOCK
            IF (ACSTR.EQ.2)
     1      CALL XABORT('MSTR: PUT NOT PERMITTED IN READ-ONLY MODE')
            CALL LCMGET(IPSTR,'STATE-VECTOR',ISTATE)
            NBLOCK=ISTATE(40)
            ALLOCATE(BLNAM(NBLOCK+1),BLTYP(NBLOCK+1),BLLEN(NBLOCK+1))
            IF (NBLOCK.GT.0) THEN
               CALL LCMGTC(IPSTR,'REC-NAMES',12,NBLOCK+1,BLNAM)
               CALL LCMGET(IPSTR,'REC-TYPES',BLTYP)
               CALL LCMGET(IPSTR,'REC-LENGTHS',BLLEN)
            ENDIF
            CALL MSTPUT(IPSTR,IPRINT,IBEG,IEND,IINC,NAME,NBLOCK,BLNAM,
     1           BLTYP,BLLEN)
            DEALLOCATE(BLLEN,BLTYP,BLNAM)
         ELSEIF(TEXT4.EQ.'GET') THEN
*        RETRIEVING DATA FROM A BLOCK
            CALL MSTGET(IPSTR,IPRINT,IBEG,IEND,IINC,NAME)
         ELSEIF(TEXT4.EQ.'CP') THEN
*        COPYING A BLOCK FROM ONE PLACE TO ANOTHER
            CALL REDGET(INDIC,NITMA,FLOTT,PATH,DFLOTT)
            IF (INDIC.NE.3)
     1        CALL XABORT('MSTR: CHARACTER DATA EXPECTED(4).')
*           ANALYSE USER'S PATH
            CALL MSTANP(NENTRY,IENTRY,JENTRY,KENTRY,PATH,IPSTR2,
     1           ACSTR2,TYSTR2,NBDIR,DIRS,ROOT)    
            IF (ACSTR2.EQ.2)
     1           CALL XABORT('MSTR: CP NOT PERMITTED IN READ-ONLY MODE')
*           GO TO REQUESTED DIRECTORY         
            IF (NBDIR.GT.1) THEN
               CALL MSTMOV(IPSTR2,ACSTR2,IPRINT,NBDIR-1,DIRS,ROOT)
            ENDIF
            NAME2=DIRS(NBDIR)
            CALL LCMGET(IPSTR2,'STATE-VECTOR',ISTATE)
            NBLOCK=ISTATE(40)
            ALLOCATE(BLNAM(NBLOCK+1),BLTYP(NBLOCK+1),BLLEN(NBLOCK+1))
            IF (NBLOCK.GT.0) THEN
               CALL LCMGTC(IPSTR2,'REC-NAMES',12,NBLOCK+1,BLNAM)
               CALL LCMGET(IPSTR2,'REC-TYPES',BLTYP)
               CALL LCMGET(IPSTR2,'REC-LENGTHS',BLLEN)
            ENDIF
            CALL MSTCPB(IPSTR,IPSTR2,IPRINT,IBEG,IEND,IINC,NAME,NAME2,
     1           NBLOCK,BLNAM,BLTYP,BLLEN)
            DEALLOCATE(BLLEN,BLTYP,BLNAM)
         ENDIF
         IPSTR=IPSTRO
         ACSTR=ACSTRO
         TYSTR=TYSTRO
      ELSEIF(TEXT4.EQ.'CD') THEN
*     CHANGING DIRECTORY
         CALL REDGET(INDIC,NITMA,FLOTT,PATH,DFLOTT)
         IF(INDIC.NE.3) 
     1   CALL XABORT('MSTR: CHARACTER DATA EXPECTED(5).')
*        ANALYSE USER'S PATH
         CALL MSTANP(NENTRY,IENTRY,JENTRY,KENTRY,PATH,IPSTR,
     1        ACSTR,TYSTR,NBDIR,DIRS,ROOT)
*        GO TO REQUESTED DIRECTORY   
         CALL MSTMOV(IPSTR,ACSTR,IPRINT,NBDIR,DIRS,ROOT)
      ELSEIF(TEXT4.EQ.';') THEN
         GOTO 60
      ELSE
         CALL XABORT('MSTR: '//TEXT4//' IS AN INVALID KEY WORD.')
      ENDIF
      GOTO 50
*
 60   CONTINUE
*
      RETURN
      END