Import inicial después del "/var incident". :(
[z.facultad/75.41/tabla.git] / tabla.pas
1 unit TABLA;\r
2 \r
3 {\r
4       IMPLEMENTACION : TABLA\r
5       ALMACENAMIENTO : LISTA DOBLE CON CURSORES\r
6 \r
7 }\r
8 \r
9 interface\r
10 \r
11 { usa las funciones generales de TDAs }\r
12 uses\r
13       GRAL, LDC, PILA_C;\r
14 \r
15 { tipos propios de la tabla }\r
16 type\r
17    T_TABLA = record\r
18                   datos: LDC_LDC;\r
19                   ordenada: boolean;\r
20                   end;\r
21 \r
22    T_MOVIM = ( T_MOVIM_primero, T_MOVIM_ultimo, T_MOVIM_siguiente, T_MOVIM_anterior );\r
23 \r
24 \r
25 { ========= }\r
26 { INTERFASE }\r
27 \r
28 PROCEDURE T_TABLA_Crear( VAR t: T_TABLA );\r
29 {  PRE : T nunca fue creada.\r
30    POST: T creada y vacía.}\r
31 FUNCTION  T_TABLA_Vacia( t: T_TABLA): BOOLEAN;\r
32 {  PRE : T creada.\r
33    POST: Si T tiene elementos, entonces es FALSE, sino es TRUE.}\r
34 FUNCTION  T_TABLA_Llena( t: T_TABLA): BOOLEAN;\r
35 {  PRE : T creada.\r
36    POST: Si T tiene lugar para insertar nuevos elementos, entonces es FALSE, sino es TRUE.}\r
37 FUNCTION  T_TABLA_Ordenada( t: T_TABLA): BOOLEAN;\r
38 {  PRE : T no vacía.\r
39    POST: Si T está ordenada, entonces es verdadero, sino es falso.}\r
40 PROCEDURE T_TABLA_Elem_Cte( t: T_TABLA; VAR r: T_REGISTRO);\r
41 {  PRE : T no vacía.\r
42    POST: R contiene el registro corriente.}\r
43 PROCEDURE T_TABLA_Mover_Cte( VAR t: T_TABLA; m: T_MOVIM; VAR error: BOOLEAN );\r
44 {  PRE : T no vacía.\r
45    POST:\r
46      Si M = primero, el nuevo corriente es el primer registro y error es falso.\r
47      Si M = ultimo, el nuevo corriente es el último registro y error es falso.\r
48      Si M = siguiente, el nuevo corriente es el siguiente registro del actual corriente y error es falso.\r
49                        Si el corriente era el ultimo registro, entonces error es verdadero y el corriente sigue siendo el\r
50                        ultimo registro.\r
51      Si M = anterior, el nuevo corriente es el anterior registro del actual corriente y error es falso. Si el corriente era\r
52                       el primer registro, entonces error es verdadero y el corriente sigue siendo el primer registro.}\r
53 PROCEDURE T_TABLA_Insertar( VAR t: T_TABLA; m: T_MOVIM; r: T_REGISTRO );\r
54 {  PRE : T no llena.\r
55    POST:\r
56      Si M = primero, R se agregó, es el primer registro y el nuevo corriente.\r
57      Si M = ultimo, R se agregó, es el último registro y el nuevo corriente.\r
58      Si M = siguiente, R se agregó, es el siguiente registro del corriente, y es el nuevo corriente \r
59      Si M = anterior, R se agregó, es el anterior registro del corriente, y es el nuevo corriente.}\r
60 Procedure T_TABLA_Insertar_Ord( var t: T_TABLA ; var r: T_REGISTRO);\r
61 {  PRE : T no llena y ordenada.\r
62    POST: El regitro r se insertó en la tabla t de tal manera que esta continúa ordenada y r es el nuevo corriente.\r
63          Si ya existía un registro con la misma clave que r, se inserta después que este.}\r
64 PROCEDURE T_TABLA_Limpiar( VAR t: T_TABLA );\r
65 {  PRE : T creada.\r
66    POST:  T vacía.}\r
67 PROCEDURE T_TABLA_Borrar_Cte( VAR t: T_TABLA );\r
68 {  PRE : T no vacía.\r
69    POST:  Se elimino el registro corriente.  El nuevo registro corriente es el siguiente del borrado,\r
70           si el borrado era el ultimo, entonces el nuevo corriente es el primero.}\r
71 PROCEDURE T_TABLA_Modif_Cte( VAR t: T_TABLA; r: T_REGISTRO);\r
72 {  PRE : T no vacía.\r
73    POST:  El contenido del actual corriente fue actualizado con R.  Si T estaba ordenada y no se modificaron los datos\r
74           de la clave del corriente, entonces T sigue ordenada. Si T estaba ordenada y se modificaron los datos de la clave\r
75           del corriente, entonces si la nueva clave rompe el orden de T, T no está más ordenada.}\r
76 PROCEDURE T_TABLA_Ordenar( VAR t: T_TABLA );\r
77 {  PRE : T no vacía.\r
78    POST: T se encuentra ordenada por la clave de sus registros.}\r
79 PROCEDURE T_TABLA_Buscar_Clave( VAR t: T_TABLA; c: T_CLAVE; var error: boolean );\r
80 {  PRE : T no vacía y ordenada.\r
81    POST: Si C es una clave que existe en T, entonces el nuevo corriente es el registro con clave C y error es falso,\r
82          si no error es verdadero y el corriente es el elemento más cercano al buscado cuya clave es mayor que c.}\r
83 PROCEDURE T_TABLA_Buscar_Por_Rango( VAR t: T_TABLA; desde, hasta: T_CLAVE; var p: T_PILAC; var error: boolean );\r
84 {  PRE : T no vacía y ordenada. El valor de la clave desde es menor que el valor de la clave hasta. La pila p está vacía.\r
85    POST: Tengo todos los registros cuyas claves se encuetran entre los valores desde y hasta almacendados en la pila p,\r
86          si encuontró como mínimo una clave. El valor de error es false.\r
87          Si no encontró ninguna clave, entonces p sigue vacía y error es true.}\r
88 \r
89 implementation\r
90 \r
91 PROCEDURE T_TABLA_Crear( VAR t: T_TABLA );\r
92  begin\r
93    LDC_Inicializar( t.datos );\r
94    t.ordenada := true;\r
95  end;\r
96 \r
97 FUNCTION  T_TABLA_Vacia( t: T_TABLA): BOOLEAN;\r
98  begin\r
99    T_TABLA_Vacia := LDC_vacio( t.datos );\r
100  end;\r
101 \r
102 FUNCTION  T_TABLA_Llena( t: T_TABLA): BOOLEAN;\r
103  begin\r
104    T_TABLA_Llena := LDC_lleno( t.datos );\r
105  end;\r
106 \r
107 FUNCTION  T_TABLA_Ordenada( t: T_TABLA): BOOLEAN;\r
108  begin\r
109    T_TABLA_Ordenada := t.ordenada;\r
110  end;\r
111 \r
112 PROCEDURE T_TABLA_Elem_Cte( t: T_TABLA; VAR r: T_REGISTRO);\r
113  begin\r
114    LDC_elem_cte( t.datos, r );\r
115  end;\r
116 \r
117 PROCEDURE T_TABLA_Mover_Cte( VAR t: T_TABLA; m: T_MOVIM; VAR error: BOOLEAN );\r
118  var mov: LDC_movimiento;\r
119  begin\r
120    error := false;\r
121    if ( m <> T_MOVIM_ultimo ) then begin\r
122       case m of\r
123          T_MOVIM_primero:\r
124             mov := LDC_primero;\r
125          T_MOVIM_siguiente:\r
126             mov := LDC_siguiente;\r
127          T_MOVIM_anterior:\r
128             mov := LDC_anterior;\r
129          end;\r
130       LDC_mover_cte( t.datos, mov, error );\r
131       end\r
132    else begin\r
133       while ( not error ) do\r
134          LDC_mover_cte( t.datos, LDC_siguiente, error );\r
135       error := false;\r
136       end;\r
137  end;\r
138 \r
139 PROCEDURE T_TABLA_Insertar( VAR t: T_TABLA; m: T_MOVIM; r: T_REGISTRO );\r
140  var mov  : LDC_movimiento;\r
141      error: boolean;\r
142  begin\r
143    if ( m <> T_MOVIM_ultimo ) then begin\r
144       case m of\r
145          T_MOVIM_primero:\r
146             mov := LDC_primero;\r
147          T_MOVIM_siguiente:\r
148             mov := LDC_siguiente;\r
149          T_MOVIM_anterior:\r
150             mov := LDC_anterior;\r
151          end;\r
152       LDC_insertar( t.datos, mov, r );\r
153       end\r
154    else begin\r
155       if ( not T_TABLA_Vacia( t ) ) then\r
156          T_TABLA_Mover_Cte( t, T_MOVIM_ultimo, error);\r
157       LDC_insertar( t.datos, LDC_siguiente, r );\r
158       end;\r
159    t.ordenada := false;\r
160  end;\r
161 \r
162 PROCEDURE T_TABLA_Insertar_Ord( var t: T_TABLA ; var r: T_REGISTRO);\r
163  var\r
164    err: boolean;\r
165    reg: T_REGISTRO;\r
166 \r
167  begin\r
168    T_TABLA_Buscar_Clave( t, r.dni, err ); {me queda el corriente en el posterior mas cercano}\r
169    T_TABLA_Elem_Cte( t, reg );\r
170    if  ( reg.dni > r.dni ) then\r
171      T_TABLA_Insertar( t, T_MOVIM_anterior, r )\r
172    else\r
173      T_TABLA_Insertar( t, T_MOVIM_siguiente, r );\r
174    t.ordenada:= true\r
175  end;\r
176 \r
177 PROCEDURE T_TABLA_Limpiar( VAR t: T_TABLA );\r
178  begin\r
179    LDC_vaciar( t.datos );\r
180    t.ordenada := true;\r
181  end;\r
182 \r
183 PROCEDURE T_TABLA_Borrar_Cte( VAR t: T_TABLA );\r
184  begin\r
185    LDC_borrar_cte( t.datos );\r
186  end;\r
187 \r
188 PROCEDURE T_TABLA_Modif_Cte( VAR t: T_TABLA; r: T_REGISTRO);\r
189  var\r
190    tmp: T_REGISTRO;\r
191  begin\r
192    T_TABLA_Elem_Cte( t, tmp );\r
193    if ( r.dni <> tmp.dni ) then\r
194       t.ordenada := false;\r
195    LDC_modif_cte( t.datos, r );\r
196  end;\r
197 \r
198 PROCEDURE T_TABLA_Ordenar( VAR t: T_TABLA );\r
199  var\r
200    tmp: T_TABLA;\r
201    r: T_REGISTRO;\r
202    err: boolean;\r
203    actual: T_CLAVE;\r
204 \r
205  begin\r
206    T_TABLA_Elem_Cte( t, r );\r
207    actual := r.dni;\r
208    err := false;\r
209    T_TABLA_Crear( tmp );\r
210    LDC_copiar( t.datos, tmp.datos );\r
211    T_TABLA_Limpiar( t );\r
212    T_TABLA_Elem_cte( tmp, r );\r
213    T_TABLA_Insertar( t, T_MOVIM_primero, r );\r
214    T_TABLA_Mover_Cte( tmp, T_MOVIM_siguiente, err );\r
215    while ( not err ) do begin\r
216        T_TABLA_Elem_cte(tmp, r);\r
217        T_TABLA_Insertar_Ord(t, r);\r
218        T_TABLA_Mover_Cte( tmp, T_MOVIM_siguiente, err );\r
219       end;\r
220    T_TABLA_Buscar_Clave( t, actual, err );\r
221    t.ordenada:= true;\r
222  end;\r
223 \r
224 PROCEDURE T_TABLA_Buscar_Clave( VAR t: T_TABLA; c: T_CLAVE; var error: boolean );\r
225  var\r
226    r: T_REGISTRO;\r
227 \r
228  begin\r
229    error:= false;\r
230    T_TABLA_Mover_Cte( t, T_MOVIM_primero, error );\r
231    T_TABLA_Elem_Cte( t, r );\r
232    while ( ( r.dni < c ) and not error ) do begin\r
233       T_TABLA_Mover_Cte( t, T_MOVIM_siguiente, error );\r
234       T_TABLA_Elem_Cte( t, r );\r
235       end;\r
236    if ( r.dni <> c ) then\r
237       error := true;\r
238  end;\r
239 \r
240 PROCEDURE T_TABLA_Buscar_Por_Rango( VAR t: T_TABLA; desde, hasta: T_CLAVE; var p: T_PILAC; var error: boolean );\r
241  var\r
242    err: boolean;\r
243    r: T_REGISTRO;\r
244 \r
245  begin\r
246     error:= true;\r
247     T_TABLA_Buscar_Clave( t, desde, err );\r
248     T_TABLA_Elem_Cte( t, r );\r
249     if ( r.DNI <= hasta ) then begin\r
250        PILAC_poner( p, r );\r
251        T_TABLA_Mover_Cte( t, T_MOVIM_siguiente, err );\r
252        T_TABLA_Elem_Cte( t, r );\r
253        while ( ( r.DNI <= hasta ) and not err ) do begin\r
254           PILAC_poner( p, r );\r
255           T_TABLA_Mover_Cte( t, T_MOVIM_siguiente, err );\r
256           T_TABLA_Elem_Cte( t, r );\r
257           end;\r
258        error := false;\r
259        end;\r
260  end;\r
261 \r
262 end.