LABELS.PAS 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. (* programme comment‚ et expliqu‚ dans le livre *)
  2. (* LE DESASSEMBLEUR 8086 COLIBRI, publi‚ par *)
  3. (* L'INSTITUT PASCAL: *)
  4. (* 26 Rue Lamartine, 75009 PARIS *)
  5. (* Tel: (1) 42.85.10.82 *)
  6. (*$r+*)
  7. program gestion_labels_de_desassemblage;
  8. type string2= string[2];
  9. string4= string[4];
  10. string15= string[15];
  11. string21= string[41];
  12. string64= string[64];
  13. string80= string[80];
  14. string127= string[127];
  15. set_of_char= set of char;
  16. t_type_label= (call_valide_instruction, call_valide,
  17. call_instruction, call,
  18. relatif_instruction, relatif,
  19. utilisateur_code,
  20. utilisateur_donnee,
  21. deja, efface);
  22. t_fiche_label= record
  23. adresse: integer;
  24. type_label: t_type_label;
  25. nom: string15;
  26. end;
  27. t_pointeur_label= ^t_cellule_label;
  28. t_cellule_label= record
  29. adresse: integer;
  30. nom: string15;
  31. type_label: t_type_label;
  32. numero_fiche: integer;
  33. pt_inferieurs, pt_superieurs: t_pointeur_label;
  34. end;
  35. t_pointeur_alphabetique= ^t_cellule_alphabetique;
  36. t_cellule_alphabetique= record
  37. nom: string15;
  38. adresse: integer;
  39. type_label: t_type_label;
  40. numero_fiche: integer;
  41. pt_inferieurs, pt_superieurs: t_pointeur_alphabetique;
  42. end;
  43. var choix, choix1: char;
  44. fichier_label: file of t_fiche_label;
  45. nom_fichier_label: string64;
  46. fiche_label: t_fiche_label;
  47. resultat_entree_sortie: byte;
  48. racine_labels_code, racine_labels_donnees: t_pointeur_label;
  49. racine_alphabetique: t_pointeur_alphabetique;
  50. sommet_tas: ^integer;
  51. sortie: text;
  52. nom_sortie: string64;
  53. procedure stop;
  54. var l_stop: char;
  55. begin
  56. read(kbd, l_stop);
  57. end;
  58. procedure affiche_erreur(p_message: string80);
  59. begin
  60. writeln;
  61. write('erreur: ', p_message);
  62. readln;
  63. end;
  64. function f_octet_hexadecimal(p_octet: byte): string2;
  65. const kt_hexa: array[0..15] of char= '0123456789ABCDEF';
  66. begin
  67. f_octet_hexadecimal:= concat(kt_hexa[p_octet div 16],
  68. kt_hexa[p_octet mod 16]);
  69. end;
  70. function f_entier_hexadecimal(p_entier: integer): string4;
  71. begin
  72. f_entier_hexadecimal:= concat(f_octet_hexadecimal(hi(p_entier)),
  73. f_octet_hexadecimal(lo(p_entier)));
  74. end;
  75. function f_lis_commande(p_ensemble_ok: set_of_char): char;
  76. var l_touche: char;
  77. begin
  78. repeat
  79. read(kbd, l_touche);
  80. l_touche:= upcase(l_touche); write(l_touche);
  81. until l_touche in p_ensemble_ok;
  82. f_lis_commande:= l_touche;
  83. end;
  84. procedure choisis_sortie;
  85. begin
  86. write('nom sortie <a:essai.txt> ? '); readln(nom_sortie);
  87. writeln(sortie); close(sortie);
  88. assign(sortie, nom_sortie);
  89. rewrite(sortie); writeln(sortie);
  90. end;
  91. procedure change_nom_fichier;
  92. begin
  93. write('nom <a:zones.dta> ? '); readln(nom_fichier_label);
  94. end;
  95. function f_fichier_existe(p_nom_fichier_label: string64): boolean;
  96. begin
  97. assign(fichier_label, p_nom_fichier_label);
  98. (*$i-*)
  99. reset(fichier_label);
  100. (*$i+*)
  101. f_fichier_existe:= ioresult= 0;
  102. close(fichier_label);
  103. end;
  104. procedure cree_fichier;
  105. begin
  106. if f_fichier_existe(nom_fichier_label)
  107. then begin
  108. writeln;
  109. write('le fichier existe d‚j…. D‚truire, Quitter ? ');
  110. if f_lis_commande(['D', 'Q'])<> 'D'
  111. then exit;
  112. writeln;
  113. end;
  114. assign(fichier_label, nom_fichier_label);
  115. rewrite(fichier_label);
  116. close(fichier_label);
  117. end;
  118. procedure ouvre_fichier;
  119. begin
  120. assign(fichier_label, nom_fichier_label);
  121. (*$i-*)
  122. reset(fichier_label);
  123. (*$i+*)
  124. resultat_entree_sortie:= ioresult;
  125. if resultat_entree_sortie<> 0
  126. then writeln('le fichier ', nom_fichier_label, ' n''a pas ‚t‚ ouvert');
  127. end;
  128. procedure affiche_fiche(p_numero: integer; p_nom: string15; p_adresse: integer;
  129. p_type_label: t_type_label);
  130. begin
  131. write(sortie, p_numero: 5);
  132. write(sortie, ' ', p_nom, '':16- length(p_nom));
  133. write(sortie, ' $', f_entier_hexadecimal(p_adresse), ' ');
  134. case p_type_label of
  135. call_valide_instruction : write(sortie, 'call valid‚ instruction');
  136. call_valide : write(sortie, 'call valid‚');
  137. call_instruction : write(sortie, 'call instruction');
  138. call : write(sortie, 'call');
  139. relatif_instruction : write(sortie, 'relatif instruction');
  140. relatif : write(sortie, 'relatif');
  141. utilisateur_code : write(sortie, 'utilisateur code');
  142. utilisateur_donnee : write(sortie, 'utilisateur donn‚e');
  143. deja : write(sortie, 'd‚j…');
  144. efface : write(sortie, 'effac‚');
  145. end;
  146. end;
  147. procedure gere_par_numero_de_fiche;
  148. var l_choix: char;
  149. procedure liste_fichier;
  150. var l_numero_fiche: integer;
  151. l_dernier_numero: integer;
  152. begin
  153. ouvre_fichier;
  154. if resultat_entree_sortie<> 0
  155. then exit;
  156. repeat
  157. write('num‚ro d‚but <0> ? '); readln(l_numero_fiche);
  158. until (l_numero_fiche>= 0) and (l_numero_fiche< filesize(fichier_label));
  159. write('num‚ro fin <', filesize(fichier_label)- 1, '> ? '); readln(l_dernier_numero);
  160. seek(fichier_label, l_numero_fiche);
  161. while not eof(fichier_label) and (l_numero_fiche<= l_dernier_numero) do
  162. begin
  163. read(fichier_label, fiche_label);
  164. with fiche_label do
  165. affiche_fiche(l_numero_fiche, nom, adresse, type_label);
  166. writeln(sortie);
  167. l_numero_fiche:= l_numero_fiche+ 1;
  168. end;
  169. close(fichier_label);
  170. end;
  171. procedure ajoute_fichier;
  172. var l_type_label: char;
  173. begin
  174. ouvre_fichier;
  175. if resultat_entree_sortie<> 0
  176. then exit;
  177. seek(fichier_label, filesize(fichier_label));
  178. repeat
  179. writeln;
  180. writeln('ajoute la fiche: ', filepos(fichier_label));
  181. write('nom <TRI> ? '); readln(fiche_label.nom);
  182. write('adresse <$1234> ? '); readln(fiche_label.adresse);
  183. write('type Code, Donn‚e ? ');
  184. l_type_label:= f_lis_commande(['C', 'D']); writeln;
  185. if l_type_label= 'D'
  186. then fiche_label.type_label:= utilisateur_donnee
  187. else fiche_label.type_label:= utilisateur_code;
  188. write(fichier_label, fiche_label);
  189. write('Continuer, Quitter ? ');
  190. read(kbd, choix1); writeln(choix1);
  191. until upcase(choix1)= 'Q';
  192. close(fichier_label);
  193. end;
  194. procedure modifie_fichier;
  195. var l_numero_fiche: integer;
  196. l_type_label: char;
  197. begin
  198. ouvre_fichier;
  199. if resultat_entree_sortie<> 0
  200. then exit;
  201. repeat
  202. writeln;
  203. repeat
  204. write('modifie la fiche num‚ro <0..', filesize(fichier_label)- 1, '> ? ');
  205. readln(l_numero_fiche);
  206. until (l_numero_fiche>= 0) and (l_numero_fiche< filesize(fichier_label));
  207. seek(fichier_label, l_numero_fiche); read(fichier_label, fiche_label);
  208. with fiche_label do
  209. affiche_fiche(l_numero_fiche, nom, adresse, type_label);
  210. writeln;
  211. write('nom <TRI> ? '); readln(fiche_label.nom);
  212. write('adresse <$1234> ? '); readln(fiche_label.adresse);
  213. write('type Code, Donn‚e ? ');
  214. l_type_label:= f_lis_commande(['C', 'D']); writeln;
  215. if l_type_label= 'D'
  216. then fiche_label.type_label:= utilisateur_code
  217. else fiche_label.type_label:= utilisateur_code;
  218. seek(fichier_label, l_numero_fiche); write(fichier_label, fiche_label);
  219. write('Continuer, Quitter ? ');
  220. read(kbd, choix1); writeln(choix1);
  221. until upcase(choix1)= 'Q';
  222. close(fichier_label);
  223. end;
  224. procedure supprime_fiche;
  225. var l_numero_fiche: integer;
  226. begin
  227. ouvre_fichier;
  228. if resultat_entree_sortie<> 0
  229. then exit;
  230. repeat
  231. writeln;
  232. repeat
  233. write('supprimer la fiche num‚ro <0..', filesize(fichier_label)- 1, '> ? ');
  234. readln(l_numero_fiche);
  235. until (l_numero_fiche>= 0) and (l_numero_fiche< filesize(fichier_label));
  236. seek(fichier_label, l_numero_fiche); read(fichier_label, fiche_label);
  237. with fiche_label do
  238. affiche_fiche(l_numero_fiche, nom, adresse, type_label);
  239. write('. Supprime ? '); read(kbd, choix1); writeln(choix1);
  240. if upcase(choix1)= 'S'
  241. then begin
  242. fiche_label.type_label:= efface;
  243. seek(fichier_label, l_numero_fiche);
  244. write(fichier_label, fiche_label);
  245. end;
  246. write('Continuer, Quitter ? ');
  247. read(kbd, choix1); writeln(choix1);
  248. until upcase(choix1)= 'Q';
  249. close(fichier_label);
  250. end;
  251. procedure filtre_plage_labels;
  252. var l_numero_fiche: integer;
  253. l_nouveau_fichier_label: file of t_fiche_label;
  254. l_nouveau_nom: string64;
  255. l_nouveau_numero: integer;
  256. l_minimum, l_maximum: integer;
  257. begin
  258. writeln('place dans nouveau fichier que certaines adresses');
  259. write('r‚‚crit sous le nom <LABELS2.DTA> ? '); readln(l_nouveau_nom);
  260. if f_fichier_existe(l_nouveau_nom)
  261. then begin
  262. writeln;
  263. write('le fichier ', l_nouveau_nom, ' existe d‚j…. D‚truire, Quitter ? ');
  264. if f_lis_commande(['D', 'Q'])<> 'D'
  265. then exit;
  266. writeln;
  267. end;
  268. assign(l_nouveau_fichier_label, l_nouveau_nom);
  269. rewrite(l_nouveau_fichier_label);
  270. l_nouveau_numero:= 0;
  271. ouvre_fichier;
  272. if resultat_entree_sortie<> 0
  273. then exit;
  274. l_numero_fiche:= 0;
  275. writeln(filesize(fichier_label));
  276. write('adresse minimale <$1234> ? '); readln(l_minimum);
  277. write('adresse maximale <$5678> ? '); readln(l_maximum);
  278. while not eof(fichier_label) do
  279. begin
  280. read(fichier_label, fiche_label);
  281. write(l_numero_fiche:4);
  282. with fiche_label do
  283. affiche_fiche(l_numero_fiche, nom, adresse, type_label);
  284. if (fiche_label.adresse- $8000>= l_minimum- $8000)
  285. and (fiche_label.adresse- $8000<= l_maximum- $8000)
  286. then begin
  287. if fiche_label.type_label in [call_valide_instruction..utilisateur_donnee]
  288. then begin
  289. writeln(' ajoute');
  290. write(l_nouveau_fichier_label, fiche_label);
  291. l_nouveau_numero:= l_nouveau_numero+ 1;
  292. end
  293. else writeln(' pas ajout‚');
  294. end
  295. else writeln(' en dehors');
  296. l_numero_fiche:= l_numero_fiche+ 1;
  297. end;
  298. close(l_nouveau_fichier_label);
  299. close(fichier_label);
  300. end;
  301. begin
  302. writeln;
  303. write('Ajoute, Liste, Modifie, Supprime, Filtre, Quitte ? ');
  304. l_choix:= f_lis_commande(['A', 'L', 'M', 'S', 'F', 'Q']); writeln;
  305. case l_choix of
  306. 'A' : ajoute_fichier;
  307. 'F' : filtre_plage_labels;
  308. 'L' : liste_fichier;
  309. 'M' : modifie_fichier;
  310. 'S' : supprime_fiche;
  311. end;
  312. end;
  313. procedure ajoute_un_label(var pv_pointeur: t_pointeur_label;
  314. p_numero_fiche: integer;
  315. p_signale_si_deja: boolean);
  316. procedure ajoute_label(var pv_pointeur: t_pointeur_label);
  317. begin
  318. if pv_pointeur= nil
  319. then begin
  320. new(pv_pointeur);
  321. with pv_pointeur^ do
  322. begin
  323. adresse:= fiche_label.adresse;
  324. numero_fiche:= p_numero_fiche;
  325. nom:= fiche_label.nom;
  326. type_label:= fiche_label.type_label;
  327. pt_inferieurs:= nil; pt_superieurs:= nil;
  328. end;
  329. end
  330. else
  331. if fiche_label.adresse- $8000< pv_pointeur^.adresse- $8000
  332. then ajoute_label(pv_pointeur^.pt_inferieurs)
  333. else
  334. if fiche_label.adresse- $8000> pv_pointeur^.adresse- $8000
  335. then ajoute_label(pv_pointeur^.pt_superieurs)
  336. else
  337. if p_signale_si_deja
  338. and not (fiche_label.type_label in [deja, efface])
  339. then begin
  340. write(pv_pointeur^.numero_fiche,
  341. ' a la mˆme adresse !'); stop;
  342. end;
  343. end;
  344. begin
  345. ajoute_label(pv_pointeur);
  346. end;
  347. procedure construis_index;
  348. const k_signale_si_deja= true;
  349. var l_numero_fiche, l_derniere_fiche: integer;
  350. begin
  351. ouvre_fichier;
  352. if resultat_entree_sortie<> 0
  353. then exit;
  354. l_derniere_fiche:= filesize(fichier_label);
  355. write('num‚ro d‚but <0> ? '); readln(l_numero_fiche);
  356. write('num‚ro fin <', l_derniere_fiche- 1, '> ? '); readln(l_derniere_fiche);
  357. seek(fichier_label, l_numero_fiche);
  358. release(sommet_tas);
  359. racine_labels_code:= nil;
  360. racine_labels_donnees:= nil;
  361. while not eof(fichier_label) and (l_numero_fiche< l_derniere_fiche) do
  362. begin
  363. read(fichier_label, fiche_label);
  364. with fiche_label do
  365. affiche_fiche(l_numero_fiche, nom, adresse, type_label);
  366. if fiche_label.type_label= utilisateur_donnee
  367. then ajoute_un_label(racine_labels_donnees, l_numero_fiche,
  368. k_signale_si_deja)
  369. else
  370. if fiche_label.type_label in [call_valide_instruction..utilisateur_code]
  371. then ajoute_un_label(racine_labels_code, l_numero_fiche,
  372. k_signale_si_deja);
  373. writeln;
  374. l_numero_fiche:= l_numero_fiche+ 1;
  375. end;
  376. close(fichier_label);
  377. end;
  378. procedure liste_index;
  379. var l_type_liste: char;
  380. l_arbre_code_ou_donnees: char;
  381. procedure affiche(p_pointeur: t_pointeur_label);
  382. begin
  383. if p_pointeur<> nil
  384. then begin
  385. affiche(p_pointeur^.pt_inferieurs);
  386. with p_pointeur^ do
  387. case l_type_liste of
  388. 'C' :
  389. affiche_fiche(numero_fiche, nom, adresse, type_label);
  390. 'E' :
  391. if nom<> ''
  392. then begin
  393. write(sortie, nom, '': 16- length(nom));
  394. write(sortie, 'EQU $', f_entier_hexadecimal(adresse));
  395. end;
  396. end;
  397. writeln(sortie);
  398. affiche(p_pointeur^.pt_superieurs);
  399. end;
  400. end;
  401. begin
  402. write('labels de Code ou de Donn‚es ? ');
  403. l_arbre_code_ou_donnees:=f_lis_commande(['C', 'D']); writeln;
  404. write('format Complet ou Equates ? ');
  405. l_type_liste:=f_lis_commande(['C', 'E']); writeln;
  406. if l_arbre_code_ou_donnees= 'C'
  407. then affiche(racine_labels_code)
  408. else affiche(racine_labels_donnees);
  409. end;
  410. procedure ajoute_ou_modifie_labels;
  411. var l_entree: text;
  412. l_nom_entree: string64;
  413. l_arbre_code_ou_donnees: char;
  414. l_ajoute_ou_modifie: char;
  415. l_ligne_entree: string127;
  416. l_erreur_entree: boolean;
  417. procedure entre_type_de_traitement;
  418. var l_confirme: char;
  419. begin
  420. repeat
  421. writeln;
  422. write('nom du fichier d''entr‚e <con:> ou <b:labels.txt> ? ');
  423. readln(l_nom_entree);
  424. write('labels de Code ou de Donn‚es ? ');
  425. l_arbre_code_ou_donnees:=f_lis_commande(['C', 'D']);
  426. writeln;
  427. write('Ajoute ou Modifie des noms ? ');
  428. l_ajoute_ou_modifie:=f_lis_commande(['A', 'M']);
  429. writeln;
  430. writeln;
  431. write('Vous confirmez ce choix: Ok, Modifier ? ');
  432. l_confirme:= f_lis_commande(['O', 'M']); writeln;
  433. until upcase(l_confirme)= 'O';
  434. if (l_nom_entree= 'con:') or (l_nom_entree= 'CON:')
  435. then begin
  436. writeln;
  437. writeln('entre les lignes: le_label EQU $1234 <RETURN>');
  438. writeln('CTRL-Z pour finir ');
  439. end;
  440. end;
  441. procedure traite_la_ligne;
  442. var l_indice: integer;
  443. l_taille_ligne: integer;
  444. l_nom: string127;
  445. l_adresse: integer;
  446. l_pt_courant: t_pointeur_label;
  447. procedure analyse_ligne;
  448. var l_erreur_numerique: boolean;
  449. procedure calcule_adresse;
  450. var l_caractere: char;
  451. begin
  452. l_erreur_numerique:= false;
  453. l_adresse:= 0;
  454. repeat
  455. l_caractere:= upcase(l_ligne_entree[l_indice]);
  456. if l_caractere in ['0'..'9']
  457. then l_adresse:= l_adresse* 16+ ord(l_caractere)- 48
  458. else
  459. if l_caractere in ['A'..'F']
  460. then l_adresse:= l_adresse* 16+ ord(l_caractere)- 55
  461. else
  462. if l_caractere<> ' '
  463. then l_erreur_numerique:= true;
  464. l_indice:= l_indice+ 1;
  465. until l_erreur_numerique or (l_indice> length(l_ligne_entree));
  466. end;
  467. begin
  468. l_taille_ligne:= length(l_ligne_entree);
  469. l_indice:= 1;
  470. if not (l_ligne_entree[l_indice] in ['A'..'Z', 'a'..'z', '_', '‚'..'—', '.'])
  471. then begin
  472. writeln; write('^': l_indice);
  473. affiche_erreur('ne commence pas A..Z, a..z, ‚..—, _ . ');
  474. l_erreur_entree:= true;
  475. exit;
  476. end;
  477. l_indice:= l_indice+ 1;
  478. while (l_indice<= l_taille_ligne)
  479. and (l_ligne_entree[l_indice] in ['0'..'9', 'A'..'B', 'a'..'z',
  480. '_', '‚'..'—']) do
  481. l_indice:= l_indice+ 1;
  482. if (l_indice> l_taille_ligne) or (l_ligne_entree[l_indice]<> ' ')
  483. then begin
  484. writeln; write('^': l_indice);
  485. affiche_erreur('nom label incorrect');
  486. l_erreur_entree:= true;
  487. exit;
  488. end;
  489. move(l_ligne_entree[1], l_nom[1], l_indice- 1);
  490. l_nom[0]:= chr(l_indice- 1);
  491. while (l_indice<= l_taille_ligne)
  492. and (l_ligne_entree[l_indice]= ' ') do
  493. l_indice:= l_indice+ 1;
  494. while (l_indice<= l_taille_ligne)
  495. and (l_ligne_entree[l_indice]<> ' ') do
  496. l_indice:= l_indice+ 1;
  497. while (l_indice<= l_taille_ligne)
  498. and (l_ligne_entree[l_indice]= ' ') do
  499. l_indice:= l_indice+ 1;
  500. if (l_indice> l_taille_ligne) or (l_ligne_entree[l_indice]<> '$')
  501. then begin
  502. writeln; write('^': l_indice);
  503. affiche_erreur('attend ESPACE EQU ESPACE $');
  504. l_erreur_entree:= true;
  505. exit;
  506. end;
  507. l_indice:= l_indice+ 1;
  508. calcule_adresse;
  509. if l_erreur_numerique
  510. then begin
  511. writeln; write('^': l_indice);
  512. affiche_erreur('erreur dans l''adresse');
  513. l_erreur_entree:= true;
  514. end;
  515. end;
  516. procedure ajoute_nom;
  517. const k_pas_signaler_doubles= false;
  518. var l_numero_fiche: integer;
  519. l_confirme: char;
  520. begin
  521. if l_arbre_code_ou_donnees= 'C'
  522. then l_pt_courant:= racine_labels_code
  523. else l_pt_courant:= racine_labels_donnees;
  524. while (l_pt_courant<> nil) and (l_pt_courant^.adresse<> l_adresse) do
  525. if l_adresse< l_pt_courant^.adresse
  526. then l_pt_courant:= l_pt_courant^.pt_inferieurs
  527. else l_pt_courant:= l_pt_courant^.pt_superieurs;
  528. if l_pt_courant= nil
  529. then begin
  530. if l_ajoute_ou_modifie= 'M'
  531. then begin
  532. write('pas trouv‚ l''adresse. ',
  533. 'Ajouter nouveau label, Quitter ? ');
  534. l_confirme:= f_lis_commande(['A', 'Q']); writeln;
  535. if l_confirme= 'Q'
  536. then exit;
  537. end;
  538. fiche_label.adresse:= l_adresse;
  539. if l_arbre_code_ou_donnees= 'C'
  540. then fiche_label.type_label:= utilisateur_code
  541. else fiche_label.type_label:= utilisateur_donnee;
  542. fiche_label.nom:= l_nom;
  543. l_numero_fiche:= filesize(fichier_label);
  544. seek(fichier_label, l_numero_fiche);
  545. write(fichier_label, fiche_label);
  546. if l_arbre_code_ou_donnees= 'C'
  547. then ajoute_un_label(racine_labels_code, l_numero_fiche, k_pas_signaler_doubles)
  548. else ajoute_un_label(racine_labels_donnees, l_numero_fiche, k_pas_signaler_doubles);
  549. end
  550. else begin
  551. if l_pt_courant^.nom<> l_nom
  552. then begin
  553. if l_ajoute_ou_modifie= 'A'
  554. then begin
  555. write(l_pt_courant^.nom, ' -> ', l_nom, ' Ok ajouter, Quitter ? ');
  556. l_confirme:= f_lis_commande(['O', 'Q']); writeln;
  557. if l_confirme= 'Q'
  558. then exit;
  559. end;
  560. fiche_label.adresse:= l_adresse;
  561. fiche_label.nom:= l_nom;
  562. if l_pt_courant^.type_label< utilisateur_code
  563. then fiche_label.type_label:= l_pt_courant^.type_label
  564. else
  565. if l_arbre_code_ou_donnees= 'C'
  566. then fiche_label.type_label:= utilisateur_code
  567. else fiche_label.type_label:= utilisateur_donnee;
  568. seek(fichier_label, l_pt_courant^.numero_fiche);
  569. write(fichier_label, fiche_label);
  570. l_pt_courant^.nom:= l_nom;
  571. end;
  572. end;
  573. end;
  574. begin
  575. l_erreur_entree:= false;
  576. analyse_ligne;
  577. if not l_erreur_entree
  578. then ajoute_nom;
  579. end;
  580. begin
  581. ouvre_fichier;
  582. if resultat_entree_sortie<> 0
  583. then exit;
  584. entre_type_de_traitement;
  585. assign(l_entree, l_nom_entree);
  586. (*$i-*)
  587. reset(l_entree);
  588. (*$i+*)
  589. if ioresult<> 0
  590. then begin
  591. write('erreur ouverture ', l_nom_entree);
  592. close(l_entree);
  593. close(fichier_label);
  594. exit;
  595. end;
  596. while not eof(l_entree) do
  597. begin
  598. readln(l_entree, l_ligne_entree);
  599. write(l_ligne_entree);
  600. if length(l_ligne_entree)> 0
  601. then traite_la_ligne;
  602. writeln;
  603. end;
  604. close(fichier_label);
  605. close(l_entree);
  606. end;
  607. procedure construis_index_alphabetique;
  608. var l_numero_fiche, l_derniere_fiche: integer;
  609. procedure ajoute_label(var pv_pointeur: t_pointeur_alphabetique);
  610. begin
  611. if pv_pointeur= nil
  612. then begin
  613. write('.');
  614. new(pv_pointeur);
  615. with pv_pointeur^ do
  616. begin
  617. nom:= fiche_label.nom;
  618. adresse:= fiche_label.adresse;
  619. type_label:= fiche_label.type_label;
  620. numero_fiche:= l_numero_fiche;
  621. pt_inferieurs:= nil; pt_superieurs:= nil;
  622. end
  623. end
  624. else
  625. if fiche_label.nom< pv_pointeur^.nom
  626. then ajoute_label(pv_pointeur^.pt_inferieurs)
  627. else ajoute_label(pv_pointeur^.pt_superieurs);
  628. end;
  629. begin
  630. ouvre_fichier;
  631. if resultat_entree_sortie<> 0
  632. then exit;
  633. l_derniere_fiche:= filesize(fichier_label);
  634. write('num‚ro d‚but <0> ? '); readln(l_numero_fiche);
  635. write('num‚ro fin <', l_derniere_fiche, '> ? '); readln(l_derniere_fiche);
  636. seek(fichier_label, l_numero_fiche);
  637. release(sommet_tas);
  638. racine_labels_code:= nil;
  639. racine_labels_donnees:= nil;
  640. racine_alphabetique:= nil;
  641. while not eof(fichier_label) and (l_numero_fiche< l_derniere_fiche) do
  642. begin
  643. read(fichier_label, fiche_label);
  644. with fiche_label do
  645. affiche_fiche(l_numero_fiche, nom, adresse, type_label);
  646. ajoute_label(racine_alphabetique);
  647. writeln;
  648. l_numero_fiche:= l_numero_fiche+ 1;
  649. end;
  650. close(fichier_label);
  651. end;
  652. procedure liste_alphabetique;
  653. var l_premiere_fiche: boolean;
  654. l_pointeur_precedent: t_pointeur_alphabetique;
  655. procedure liste_arbre(p_pointeur: t_pointeur_alphabetique);
  656. begin
  657. if p_pointeur<> nil
  658. then begin
  659. liste_arbre(p_pointeur^.pt_inferieurs);
  660. if p_pointeur^.type_label<= utilisateur_donnee
  661. then
  662. with p_pointeur^ do
  663. begin
  664. affiche_fiche(numero_fiche, nom, adresse, type_label);
  665. if l_premiere_fiche
  666. then l_premiere_fiche:= false
  667. else
  668. if (l_pointeur_precedent^.nom= nom)
  669. and (nom<> '')
  670. and (nom[1]= ' ')
  671. and not (
  672. (
  673. (l_pointeur_precedent^.type_label in [call_valide_instruction..utilisateur_code])
  674. and (type_label= utilisateur_donnee)
  675. )
  676. or
  677. (
  678. (l_pointeur_precedent^.type_label= utilisateur_donnee)
  679. and (type_label in [call_valide_instruction..utilisateur_code])
  680. )
  681. )
  682. then begin
  683. write(sortie, ' d‚j… !');
  684. stop;
  685. end;
  686. writeln(sortie);
  687. l_pointeur_precedent:= p_pointeur;
  688. end;
  689. liste_arbre(p_pointeur^.pt_superieurs);
  690. end;
  691. end;
  692. begin
  693. l_premiere_fiche:= false;
  694. liste_arbre(racine_alphabetique);
  695. end;
  696. procedure initialise;
  697. begin
  698. nom_fichier_label:= 'labels.dta';
  699. mark(sommet_tas);
  700. racine_labels_code:= nil;
  701. racine_labels_donnees:= nil;
  702. racine_alphabetique:= nil;
  703. nom_sortie:= 'CON:';
  704. assign(sortie, nom_sortie);
  705. rewrite(sortie);
  706. end;
  707. begin
  708. initialise;
  709. repeat
  710. writeln;
  711. writeln(nom_fichier_label, ', sortie: ', nom_sortie);
  712. writeln('Cr‚e, Nom, Sortie');
  713. writeln('GŠre par num‚ro de fiche');
  714. writeln('Tri index, Liste index, Ajoute ou modifie index‚');
  715. write ('tRi alphab‚tique, listE alphab‚tique, Quitte ? ');
  716. read(kbd, choix); writeln(choix); choix:= upcase(choix);
  717. case choix of
  718. 'A' : ajoute_ou_modifie_labels;
  719. 'C' : cree_fichier;
  720. 'E' : liste_alphabetique;
  721. 'G' : gere_par_numero_de_fiche;
  722. 'L' : liste_index;
  723. 'N' : change_nom_fichier;
  724. 'R' : construis_index_alphabetique;
  725. 'S' : choisis_sortie;
  726. 'T' : construis_index;
  727. end;
  728. until choix= 'Q';
  729. close(sortie);
  730. end.