summaryrefslogtreecommitdiff
path: root/Build/source/utils/vlna/vlna.tex
blob: 1e2660c1bae6dbd9e6796ccbd61f3e4de178c896 (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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
\input cwebmac

\input csmac % Makra pro èe¹tinu
\pageheight=9.5in \fullpageheight=9.8in  \setpage
%\nocon % omit table of contents
\datethis % print date on listing

\def\begitems{\medskip\bgroup\catcode`\*=13 \narrower\narrower}
\def\enditems{\par\egroup\medskip}
{\catcode`\*=13 \gdef*{\par\noindent\llap{$\bullet$\ }\ignorespaces}}



\N{1}{1}PROGRAM VLNA.
Program ète vstupní textový soubor a nahrazuje za specifikovanými
jednopísmennými slovy (napø.~v, k, u) mezery symbolem \uv{\.{\char126}}. To
zabrání pøi následném zpracování \TeX{}em zlomit øádek na nevhodných
místech, která jsou v rozporu s typografickou normou.

Program sestává z tìchto hlavních celkù:
\Y\B\X3:Hlavièkové soubory k naètení\X\6
\X4:Globální deklarace\X\6
\X6:Pomocné funkce\X\6
\X29:Vlnkovací funkce \PB{\\{tie}}\X\6
\X5:Hlavní program\X\par
\fi

\M{2}Definujeme \PB{\.{BANNER}}, co¾ je text, který se objevi pøi startu
programu a obsahuje èíslo verze programu.
Zde je názornì vidìt, ¾e míchání dvou jazykù se nevyhneme. Pøi tisku
textù na terminál nesmíme pøedpokládat, ¾e tam budou èeské fonty.
V~této dokumentaci se setkáme se tøemi jazyky: angliètinou (vìt¹inou
v~kódu programu, cestinou v~/* komentáøích */ a èe¹tinou jinde.
Tu cestinu si vynutil fakt, ¾e DOS-ovská varianta \.{tangle} a
\.{weave} se nesná¹í s~akcentovanými písmeny v~/* komentáøích */.
A~nyní u¾ slíbený (vícejazyèný) \PB{\.{BANNER}}.
\Y\B\4\D$\.{BANNER}$ \5
\.{"This\ is\ program\ vln}\)\.{a,\ version\ 1.5,\ (c)\ }\)\.{1995,\ 2002,\
2009,\ 20}\)\.{10\ Petr\ Olsak\\n"}\par
\fi

\M{3}V programu jsou pou¾ity knihovní funkce, jejích¾ prototypy jsou
definovány ve tøech standardních hlavièkových souborech.
\Y\B\4\X3:Hlavièkové soubory k naètení\X${}\E{}$\6
\8\#\&{include} \.{<stdio.h>}\6
\8\#\&{include} \.{<string.h>}\6
\8\#\&{include} \.{<stdlib.h>}\par
\U1.\fi

\M{4}Definujeme konstanty pro návratový kód. \PB{\.{OK}} pro úspì¹ný bìh,
\PB{\.{WARNING}} pøi výskytu aspoò jedné varovné zprávy, \PB{\.{IO\_ERR}} pro
chybu
v~pøístupu ke vtupním nebo výstupním souborùm, \PB{\.{BAD\_OPTIONS}} pro
syntaktickou chybu na pøíkazové øádce a \PB{\.{BAD\_PROGRAM}} pro pøípad
havárie programu. Ta by nemìla nikdy nastat. Promìnná \PB{\\{status}} bude
obsahovat návratový kód a promìnná \PB{\\{prog\_name}} bude ukazovat na text
nultého parametru pøíkazové øádky.
\Y\B\4\D$\.{OK}$ \5
\T{0}\par
\B\4\D$\.{WARNING}$ \5
\T{1}\par
\B\4\D$\.{IO\_ERR}$ \5
\T{2}\par
\B\4\D$\.{BAD\_OPTIONS}$ \5
\T{3}\par
\B\4\D$\.{BAD\_PROGRAM}$ \5
\T{4}\par
\Y\B\4\X4:Globální deklarace\X${}\E{}$\6
\&{char} ${}{*}\\{prog\_name};{}$\6
\&{int} \\{status};\par
\As7, 8, 17, 18, 19, 23, 28\ETs36.
\U1.\fi

\M{5}Základní rozvr¾ení funkce \PB{\\{main}}.
\Y\B\4\X5:Hlavní program\X${}\E{}$\6
\&{int} \\{main}(\&{int} \\{argc}${},\39{}$\&{char} ${}{*}{*}\\{argv}){}$\1\1\2%
\2\6
${}\{{}$\1\6
\X11:Lokální promìnné funkce \PB{\\{main}}\X;\6
${}\\{prog\_name}\K\\{argv}[\T{0}];{}$\6
${}\\{status}\K\.{OK};{}$\6
\X9:Naètení parametrù pøíkazového øádku\X;\6
\&{if} ${}(\R\\{silent}){}$\1\5
${}\\{fprintf}(\\{stderr},\39\.{BANNER});{}$\2\6
\X24:Inicializace datových struktur\X;\6
\X13:Zpracování souborù\X;\6
\&{return} \\{status};\6
\4${}\}{}$\2\par
\U1.\fi

\N{1}{6}Parametry pøíkazového øádku.
Program ète z~pøíkazového øádku postupnì (nepovinné) parametry,
které zaèínají znakem \uv{\.{-}}. Pak následují jména vstupních a výstupních
souborù.
\begitems
* \.{-f} \dots\ program pracuje jako filtr (viz sekce \PB{$\X13:Zpracování
souborù\X$}). Není-li tento parametr pou¾it, program pracuje v tzv.
standardním re¾imu, kdy jednotlivé soubory jsou vstupní i výstupní.
* \.{-s} \dots\ program nevypí¹e \PB{\.{BANNER}}, ani sumarizaci, ani varování,
pøi nich¾ není program pøedèasnì ukonèen.  V¹echny tyto výpisy
smìøují do \PB{\\{stderr}}, tak¾e pokud program pracuje v re¾imu \uv{filtr},
není nutné tento parametr pou¾ít.
* \.{-r} \dots\ program ma¾e pracovní soubor (soubory), které vytváøí
ve standardním re¾imu (tj. není pou¾it \.{-f}). V reøimu filter nemá
tento parametr vliv.
* \.{-v} \dots\ parametr definuje skupinu písmen, které budou
interpretovány jako neslabièné pøedlo¾ky.
Napø. \.{-v KkSsVvZzOoUuAI}. Pokud není parametr uveden, je pou¾ita
skupina uvedená v tomto pøíkladì.
* \.{-x} \dots\ parametr vymezuje pomocí hexadecimálního zápisu string,
který program vkládá na vyhledaná místa. Implicitnì vkládá vlnku.
Napøíklad \.{-x C2A0} zpùsobí, ¾e program bude vkládat místo vlnky dva byty,
první s kódem \.{C2} a druhý s kódem \.{A0}.
* \.{-m} \dots\ program neprovádí kontrolu math/text módù, tj. vlnkuje i
uvnitø matematického módu \TeX{}u. (Implicite tam nevlnkuje).
* \.{-n} \dots\ prorgram neprovádí kontrolu verbatim módu, tj. vlnkuje i
uvnitø verbatim módu definovaném bì¾nými prostøedími. Imlicite ve
verbatim prostøedí nevlnkuje.
* \.{-l} \dots\ La\TeX{} re¾im. Pøi kontrole text-math-verbatim módù jsou
brány v úvahu dal¹í sekvence, obvyklé v La\TeX{}ových dokumentech.
* \.{-w} \dots\ WEB re¾im. Ohranièení verbatim módu je doplnìno znaky
pou¾ívanými v dokumentech WEB (napø. tento dokument). Dùsledek: program
vlnkuje dokumentaèní èást ka¾dé sekce, ale nikoli kód.
\enditems

Definujeme funkci \PB{\\{printusage}}, která tiskne (pøi chybì) struèný pøehled
mo¾ných parametrù. Nepodaøilo se mi zjistit, jak se ve WEBu napí¹e
kulturnì dlouhý string obsahující \.{\char92n} s formátovacími
po¾adavky. Byl jsem nucen to takto nehezky zapsat.
\Y\B\4\X6:Pomocné funkce\X${}\E{}$\6
\&{static} \&{void} \\{printusage}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"usage:\ vlna\ [opt]\ [}\)\.{filenames]\\n"}%
\.{"\ \ opt\ -f\ :\ \ filter\ }\)\.{mode:\ file1\ file2\ ..}\)\.{.\
file1->file2\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \
file1\ \ \ \ \ \ \ ..}\)\.{.\ file1->stdout\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \
\ \ \ \ \ }\)\.{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ..}\)\.{.\ stdin->stdout%
\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ nofilte}\)\.{r:\ file1\ [file2\ file}\)\.{3\
...]\ all\ are\ in/ou}\)\.{t\\n"}\.{"\ \ \ \ \ \ -s\ :\ \ silent:}\)\.{\ no\
messages\ to\ stde}\)\.{rr\\n"}\.{"\ \ \ \ \ \ -r\ :\ \ rmbacku}\)\.{p:\ if\
nofilter,\ remo}\)\.{ves\ temporary\ files\\}\)\.{n"}\.{"\ \ \ \ \ \ -v\
charset\ :\ }\)\.{\ set\ of\ lettres\ to\ a}\)\.{dd\ tie,\ default:\ KkS}\)%
\.{sVvZzOoUuAI\\n"}\.{"\ \ \ \ \ \ -x\ code\ :\ cod}\)\.{e\ for\ tie\ symbol,\
de}\)\.{fault:\ 7E,\ example\ -}\)\.{x\ C2A0\\n"}\.{"\ \ \ \ \ \ -m\ :\ \
nomath:}\)\.{\ ignores\ math\ modes\\}\)\.{n"}\.{"\ \ \ \ \ \ -n\ :\ \ noverb:}%
\)\.{\ ignores\ verbatim\ mo}\)\.{des\\n"}\.{"\ \ \ \ \ \ -l\ :\ \ LaTeX\ m}\)%
\.{ode\\n"}\.{"\ \ \ \ \ \ -w\ :\ \ web\ mod}\)\.{e\\n"});{}$\6
\4${}\}{}$\2\par
\As10, 12, 20, 21, 22, 25, 26, 39, 41, 44, 45, 47, 48, 50, 52, 54, 55, 56\ETs58.
\U1.\fi

\M{7}Promìnné \PB{\\{isfilter}}, \PB{\\{silent}}, \PB{\\{rmbackup}}, \PB{%
\\{nomath}}, \PB{\\{noverb}},
\PB{\\{latex}}, resp. \PB{\\{web}} øíkají, ¾e je nastaven parametr \.{-f}, %
\.{-s},
\.{-r}, \.{-m}, \.{-n}, \.{-l}, resp. \.{-w}.  Promìnná \PB{\\{charset}}
ukazuje buï na implicitní skupinu znakù \PB{\\{charsetdefault}}, nebo (pøi
pou¾ití parametru \.{-v}) na text uvedený v pøíkazovém øádku.
\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{int} \\{isfilter}${}\K\T{0},{}$ \\{silent}${}\K\T{0},{}$ \\{rmbackup}${}\K%
\T{0},{}$ \\{nomath}${}\K\T{0},{}$ \\{noverb}${}\K\T{0},{}$ \\{web}${}\K%
\T{0},{}$ \\{latex}${}\K\T{0};{}$\6
\&{char} \\{charsetdefault}[\,]${}\K\.{"KkSsVvZzOoUuAI"};{}$\6
\&{char} ${}{*}\\{charset}\K\\{charsetdefault}{}$;\par
\fi

\M{8}String \PB{\\{tiestr}} obsahuje string, kterým se má nahradit vyhledané
místo. Pokud není pou¾it parametr \.{-u}, je tento string jadnoznakový
a obsahuje vlnku. Jinak obsahuje string konvertovaný z parametru \.{-u}.
String má délku \PB{\\{tiestrlen}} bez ohledu na to, zda obsahuje nebo
neobsahuje nulové znaky (C-èková konvence pro stringy není pou¾ita).
\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{unsigned} \&{char} \\{tiestr}[\.{MAXLEN}];\6
\&{int} \\{tiestrlen};\par
\fi

\M{9}\B\X9:Naètení parametrù pøíkazového øádku\X${}\E{}$\6
$\\{tiestr}[\T{0}]\K\.{'\~'};{}$\6
${}\\{tiestrlen}\K\T{1};{}$\6
\&{while} ${}(\\{argc}>\T{1}\W\\{argv}[\T{1}][\T{0}]\E\.{'-'}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{argv}[\T{1}][\T{2}]\I\T{0}){}$\1\5
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS});{}$\2\6
\&{switch} (\\{argv}[\T{1}][\T{1}])\5
${}\{{}$\1\6
\4\&{case} \.{'f'}:\5
${}\\{isfilter}\K\T{1};{}$\6
\&{break};\6
\4\&{case} \.{'s'}:\5
${}\\{silent}\K\T{1};{}$\6
\&{break};\6
\4\&{case} \.{'r'}:\5
${}\\{rmbackup}\K\T{1};{}$\6
\&{break};\6
\4\&{case} \.{'v'}:\6
\&{if} ${}(\\{argc}<\T{2}){}$\1\5
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS});{}$\2\6
${}\\{argv}\PP;{}$\6
${}\\{argc}\MM;{}$\6
${}\\{charset}\K\\{argv}[\T{1}];{}$\6
\&{break};\6
\4\&{case} \.{'x'}:\6
\&{if} ${}(\\{argc}<\T{2}){}$\1\5
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS});{}$\2\6
${}\\{argv}\PP;{}$\6
${}\\{argc}\MM;{}$\6
\\{settiestr}(\\{argv}[\T{1}]);\6
\&{break};\6
\4\&{case} \.{'m'}:\5
${}\\{nomath}\K\T{1};{}$\6
\&{break};\6
\4\&{case} \.{'n'}:\5
${}\\{noverb}\K\T{1};{}$\6
\&{break};\6
\4\&{case} \.{'l'}:\5
${}\\{latex}\K\T{1};{}$\6
\&{break};\6
\4\&{case} \.{'w'}:\5
${}\\{web}\K\T{1};{}$\6
\&{break};\6
\4\&{default}:\5
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS}){}$;\C{ nezn\'am\'y parametr
}\6
\4${}\}{}$\2\6
${}\\{argc}\MM;{}$\6
${}\\{argv}\PP;{}$\6
\4${}\}{}$\2\par
\U5.\fi

\M{10}Vyøe¹íme konverzi kódu zapsaného za parametrem \.{-x} na string \PB{%
\\{tiestr}}.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{unsigned} \&{char} \\{hexnum}(\&{char} \|c)\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\|c\G\.{'0'}\W\|c\Z\.{'9'}){}$\1\5
\&{return} \|c${}-\.{'0'};{}$\2\6
\&{if} ${}(\|c\G\.{'A'}\W\|c\Z\.{'F'}){}$\1\5
\&{return} \|c${}-\.{'A'}+\T{10};{}$\2\6
\&{if} ${}(\|c\G\.{'a'}\W\|c\Z\.{'f'}){}$\1\5
\&{return} \|c${}-\.{'a'}+\T{10};{}$\2\6
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS});{}$\6
\4${}\}{}$\2\7
\&{static} \&{void} \\{settiestr}(\&{char} ${}{*}\|s){}$\1\1\2\2\6
${}\{{}$\1\6
\&{int} \|i${},{}$ \|j;\7
${}\|i\K\\{strlen}(\|s);{}$\6
\&{if} ${}((\|i>\T{2}*\.{MAXLEN})\V\|i\MOD\T{2}\E\T{1}){}$\1\5
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS});{}$\2\6
${}\\{tiestrlen}\K\|i/\T{2};{}$\6
${}\|j\K\T{0};{}$\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{tiestrlen};{}$ ${}\|i\PP){}$\5
${}\{{}$\1\6
${}\\{tiestr}[\|i]\K\\{hexnum}(\|s[\|j\PP])\LL\T{4};{}$\6
${}\\{tiestr}[\|i]\MRL{+{\K}}\\{hexnum}(\|s[\|j\PP]);{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\N{1}{11}Zpracování souborù.  Parametr \PB{\.{MAXLEN}} definuje maximální
mo¾nou
délku jména souboru, který vytvoøíme jako pøechodný, nebo zálohový.
Dále deklarujeme promìnné typu \uv{stream}.
\Y\B\4\D$\.{MAXLEN}$ \5
\T{120}\par
\Y\B\4\X11:Lokální promìnné funkce \PB{\\{main}}\X${}\E{}$\6
\&{FILE} ${}{*}\\{infile},{}$ ${}{*}\\{outfile};{}$\6
\&{char} \\{backup}[\.{MAXLEN}];\6
\&{int} \|j;\par
\U5.\fi

\M{12}Definujeme funkci pro výpis chybového hlá¹ení pøi neúspì¹ném otevøení
souboru.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{ioerr}(\&{char} ${}{*}\|f){}$\1\1\2\2\6
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ cannot\ open\ fil}\)\.{e\ \%s\\n"},\39%
\\{prog\_name},\39\|f);{}$\6
\4${}\}{}$\2\par
\fi

\M{13}Zpùsob zpracování souborù rozli¹íme podle re¾imu daným pøepínaèem \.{-f}.
\Y\B\4\X13:Zpracování souborù\X${}\E{}$\6
\&{if} (\\{isfilter}) \X14:Zpracování v re¾imu filter\X\6
\&{else} \X15:Zpracování v¹ech souborù pøíkazové øádky\X\par
\Q6.
\U5.\fi

\M{14}V re¾imu \PB{$\\{isfilter}\E\T{1}$} je dal¹í zpracování závislé na poètu
souborù v
pøíkazové øádce:
\begitems
* nula souborù -- vstup je \PB{\\{stdin}} a výstup je \PB{\\{stdout}},
* jeden soubor -- je vstupní, výstup je \PB{\\{stdout}},
* dva soubory -- první je vstupní, druhý výstupní,
* více souborù -- program skonèí s chybou.
\enditems
\Y\B\4\X14:Zpracování v re¾imu filter\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\\{argc}>\T{3}){}$\1\5
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS});{}$\2\6
${}\\{infile}\K\\{stdin};{}$\6
${}\\{outfile}\K\\{stdout};{}$\6
\&{if} ${}(\\{argc}\G\T{2}){}$\1\5
${}\\{infile}\K\\{fopen}(\\{argv}[\T{1}],\39\.{"r"});{}$\2\6
\&{if} ${}(\\{infile}\E\NULL){}$\1\5
${}\\{ioerr}(\\{argv}[\T{1}]),\39\\{exit}(\.{IO\_ERR});{}$\2\6
\&{if} ${}(\\{argc}\E\T{3}){}$\1\5
${}\\{outfile}\K\\{fopen}(\\{argv}[\T{2}],\39\.{"wb"});{}$\2\6
\&{if} ${}(\\{outfile}\E\NULL){}$\1\5
${}\\{ioerr}(\\{argv}[\T{2}]),\39\\{exit}(\.{IO\_ERR});{}$\2\6
\&{if} ${}(\\{argc}\G\T{2}){}$\1\5
${}\\{filename}\K\\{argv}[\T{1}];{}$\2\6
\&{else}\1\5
${}\\{filename}\K\NULL;{}$\2\6
${}\\{tie}(\\{infile},\39\\{outfile});{}$\6
\&{if} ${}(\\{outfile}\I\\{stdout}){}$\1\5
\\{fclose}(\\{outfile});\2\6
\&{if} ${}(\\{infile}\I\\{stdin}){}$\1\5
\\{fclose}(\\{infile});\2\6
\4${}\}{}$\2\par
\U13.\fi

\M{15}V~re¾imu \PB{$\\{isfilter}\E\T{0}$} jsou jednotlivé soubory v~pøíkazovém
øádku
interpretovány jako vstupní i výstupní. Více souborù v~pøíkazovém øádku má
stejný efekt, jako opakované volání programu na jednotlivé soubory.
V~\UNIX/u lze tedy napø. napsat \.{\jobname\ *.tex} a program doplní vlnky do
v¹ech souborù s~pøíponou~\.{tex}. Toto neplatí v~DOSu, proto¾e interpretace
masky je v~\UNIX/u starostí shellu a nikoli programu samotného. Ná¹ program
masku nebude interpretovat. Je-li v~tomto re¾imu nulový poèet souborù,
program se ukonèí s~chybou.
\Y\B\4\X15:Zpracování v¹ech souborù pøíkazové øádky\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\\{argc}\E\T{1}){}$\1\5
${}\\{printusage}(\,),\39\\{exit}(\.{BAD\_OPTIONS});{}$\2\6
\&{while} ${}(\\{argc}>\T{1}){}$\5
${}\{{}$\1\6
${}\\{argc}\MM;{}$\6
${}\\{argv}\PP;{}$\6
\X16:Pøejmenuj vstup \PB{\\{argv}[\T{0}]} na \PB{\\{backup}} a otevøi jej jako %
\PB{\\{infile}}\X;\6
\&{if} ${}(\\{infile}\E\NULL){}$\5
${}\{{}$\1\6
\\{ioerr}(\\{argv}[\T{0}]);\6
\&{continue};\6
\4${}\}{}$\2\6
${}\\{outfile}\K\\{fopen}(\\{argv}[\T{0}],\39\.{"wb"});{}$\6
\&{if} ${}(\\{outfile}\E\NULL){}$\5
${}\{{}$\1\6
\\{ioerr}(\\{argv}[\T{0}]);\6
${}\\{rename}(\\{backup},\39\\{argv}[\T{0}]);{}$\6
${}\\{status}\K\.{WARNING};{}$\6
\&{continue};\6
\4${}\}{}$\2\6
${}\\{filename}\K\\{argv}[\T{0}];{}$\6
${}\\{tie}(\\{infile},\39\\{outfile});{}$\6
${}\\{fclose}(\\{outfile}),\39\\{fclose}(\\{infile});{}$\6
\&{if} (\\{rmbackup})\1\5
\\{remove}(\\{backup});\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U13.\fi

\M{16}Pøi \PB{$\\{isfilter}\E\T{0}$} program pøejmenuje ka¾dý  zpracovávaný
soubor tak, ¾e
zmìní poslední písmeno názvu souboru na znak \.{\char126}. Tento
pøejmenovaný soubor bude otevøen jako vstupní a výstupem bude pùvodní
soubor. Vstupní soubor pøi \PB{$\\{rmbackup}\E\T{0}$} zùstane zachován jako
záloha.

Proè vlnku nepøidáváme na konec názvu souboru, ale mìníme ji za poslední
znak souboru? Proto¾e chceme, aby program fungoval i v tak nemo¾ných
systémech, jako je DOS.
\Y\B\4\X16:Pøejmenuj vstup \PB{\\{argv}[\T{0}]} na \PB{\\{backup}} a otevøi jej
jako \PB{\\{infile}}\X${}\E{}$\6
$\\{infile}\K\NULL;{}$\6
${}\|j\K\\{strlen}(\\{argv}[\T{0}])-\T{1};{}$\6
\&{if} ${}(\|j\G\.{MAXLEN}\V\\{argv}[\T{0}][\|j]\E\.{'\~'}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\\{silent}){}$\1\5
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ the\ conflict\ of}\)\.{\ file\ name\ \%s%
\\n"},\39\\{prog\_name},\39\\{argv}[\T{0}]);{}$\2\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{strcpy}(\\{backup},\39\\{argv}[\T{0}]);{}$\6
${}\\{backup}[\|j]\K\.{'\~'};{}$\6
\\{remove}(\\{backup});\6
${}\|j\K\\{rename}(\\{argv}[\T{0}],\39\\{backup});{}$\6
\&{if} ${}(\|j\E\T{0}){}$\1\5
${}\\{infile}\K\\{fopen}(\\{backup},\39\.{"r"});{}$\2\6
\4${}\}{}$\2\par
\U15.\fi

\N{1}{17}Patterny.  Abychom mohli úèelnì definovat chování programu
v~rùzných situacích, zavedeme datovou strukturu \PB{\.{PATTERN}}. Zhruba
øeèeno, budeme sledovat vstup znak po znaku a pokud bude èást vstupu
souhlasit s~definovaným patternem, provedeme námi po¾adovanou
akci. Napøíklad nejèastìj¹í aktivitu, pøidání vlnky uvnitø øádku,
spustíme v~okam¾iku, kdy vstupní text odpovídá patternu \uv{\.{\ (v\
p}}, kde \uv{\.{\ }} znamená jedna nebo více mezer a tabelátorù,
\uv{\.{(}} je nula nebo více otevíracích závorek v¹eho druhu,
\uv{\.{v}} znamená jedno písmeno z~mno¾iny pøedlo¾ek (viz \PB{\\{charset}}) a
\uv{\.{p}} zde znamená libovolné písmeno. Pøíklad zde není zcela pøesný.
Pøesnì jsou v¹echny patterny pro ná¹ program definovány v~závìreèných
sekcích tohoto povídání.

Pattern bude znamenat koneènou sekvenci tzv. pozic patternu (\PB{\.{PATITEM}}).
Cykly uvnitø pozic pro jednoduchost nepøipustíme. Ka¾dá pozice obsahuje
øetìzec znakù, uva¾ovaný pro danou pozici (v~pøíkladu pozice~\uv{\.{\ }} by
obsahovala mezeru a tabelátor, zatímco pozice \.{v} odpovídá \PB{\\{charset}}).
Ka¾dá pozice má svùj pøepínaè (\PB{\\{flag}}), který obsahuje informaci o~tom,
zda shodu testovaného znaku s~nìkterým prvkem v~mno¾inì znakù
budeme pova¾ovat za úspìch èi neúspìch a zda pozice se ve zkoumaném
øetìzci mù¾e vyskytovat právì jednou nebo opakovanì. Jako druhý pøípad
staèí implementovat \uv{nula nebo více} proto¾e \uv{jedna nebo více} lze
popsat pomocí dvou pozic, první \uv{právì jednou} a následující \uv{nula
nebo více}. Jednotlivé pozice jsou zøetìzeny ukazatelem \PB{\\{next}}, poslední
pozice má \PB{$\\{next}\E\NULL$}. Stejnì tak jednotlivé patterny budeme
sestavovat do seznamù a budou rovnì¾ zøetìzeny ukazatelem \PB{\\{next}}.

Pattern kromì øetìzu pozic obsahuje ukazatel na funkci (proceduru) \PB{%
\\{proc}},
která se má vykonat v~pøípadì, ¾e testovaný øetìzec vyhovuje patternu.

\Y\B\4\D$\.{ONE}$ \5
\T{1}\C{ flag: prave jeden vyskyt }\par
\B\4\D$\.{ANY}$ \5
\T{2}\C{ flag: nula nebo vice }\par
\B\4\D$\.{ONE\_NOT}$ \5
${-}{}$\T{1}\C{ flag: prave jednou, znak nesmi byt v mnozine }\par
\B\4\D$\.{ANY\_NOT}$ \5
${-}{}$\T{2}\C{ flag: nula nebo vice, znak nesmi byt v mnozine }\par
\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{typedef} \&{struct} \&{PATITEM} ${}\{{}$\C{ jedna pozice patternu }\1\6
\&{char} ${}{*}\\{str}{}$;\C{ seznam znaku na teto pozici }\6
\&{int} \\{flag};\C{ vyznam seznamu znaku }\6
\&{struct} \&{PATITEM} ${}{*}\\{next}{}$;\C{ nasledujici pozice patternu }\2\6
${}\}{}$ \&{PATITEM};\6
\&{typedef} \&{struct} \&{PATTERN} ${}\{{}$\C{ jeden pattern }\1\6
\&{PATITEM} ${}{*}\\{patt}{}$;\C{ ukazatel na prvni pozici }\7
${}\&{void}({*}\\{proc})(\&{void}){}$;\C{ procedura spustena pri souhlasu
patternu }\7
\&{struct} \&{PATTERN} ${}{*}\\{next}{}$;\C{ nasledujici v seznamu vsech
patternu }\2\6
${}\}{}$ \&{PATTERN};\par
\fi

\M{18}Deklarujeme nìkteré globální promìnné pro práci s~patterny. \PB{\\{lapi}}
je pole
obsahující ukazatele na aktuální pozice v~otevøených patternech. Øíkáme,
¾e \uv{pattern je otevøen}, pokud zkoumaný øetìzec s~ním {\it zaèíná\/}
souhlasit. Pattern se uzavøe, pokud nastane jedna ze dvou mo¾ností:
zkoumaný øetìzec s~mím souhlasí a¾ do konce (v~takovém pøípadì se provede
procedura \PB{\\{proc}}), nebo pøi vy¹etøování dal¹ích znakù ze zkoumaného
øetìzce pøestane øetìzec s~patternem souhlasit.

V~dané chvíli mù¾e být pattern otevøen nìkolikrát. Napø. pattern \.{abac}
je pøi stringu \.{aba} pøi výskytu druhého \.{a} otevøen podruhé. Proto
pole obsahuje ukazatele na právì aktuální pozici patternu a nikoli na
pattern jako takový.

V~poli \PB{\\{lapi}} budou na poèátku samá \PB{$\NULL$} (to se pøi pøekladu
inicializuje
samo) a pøemazání ukazatele na pozici konstantou \PB{$\NULL$} budeme pova¾ovat
za zavøení patternu. Vedle pole \PB{\\{lapi}} soumìrnì udr¾ujeme pole \PB{%
\\{lapt}},
do nìho¾ budeme ukládat ukazatele na odpovídající otevøený pattern. Tuto
informaci pou¾ijeme v~pøípadì, ¾e potøebujeme napø, znát \PB{\\{proc}}
patternu.

\PB{\\{listpatt}} bude ukazovat na zaèátek aktuálního seznamu patternù. Seznamy
budeme mít dva. Jeden se pou¾ije, nacházíme-li se mimo komentáø a druhý
v~pøípadì, ¾e se nacházíme v~prostoru \TeX{}ovského komentáøe (tj. za
procentem). Starty tìchto seznamù patternù jsou \PB{\\{normallist}} a
\PB{\\{commentlist}} a aktivní \PB{\\{listpatt}} má v¾dy jednu z~tìchto dvou
hodnot.

Promìnné \PB{\\{lastpt}} a \PB{\\{lastpi}} pou¾ijeme pro budování øetìzové
struktury
patternù.

Promìnná \PB{\|c} obsahuje právì testovaný znak ze vstupu (který se rovnì¾
pøepí¹e do bufferu \PB{\\{buff}}). Z~bufferu obèas ukládáme data do výstupního
proudu. Dìláme to ale v¾dy jen v~okam¾iku, kdy není otevøen ¾ádný
pattern. Tehdy toti¾ \uv{nehrozí} situace, ¾e by nìjaká procedura vyvolaná
souhlasem patternu po¾adovala v~tomto bufferu nìjaké zmìny se zpìtnou
platností. O~vyprázdnìní bufferu se zaèneme zajímat a¾ v~okam¾iku, kdy je
zaplnìn aspoò na hodnotu \PB{\.{BUFI}}, abychom proceduru pøepisu bufferu do
výstupního proudu neaktivovali zbyteènì èasto.
\Y\B\4\D$\.{MAXPATT}$ \5
\T{200}\C{ maximalni pocet patternu }\par
\B\4\D$\.{MAXBUFF}$ \5
\T{500}\C{ velikost bufferu pro operace }\par
\B\4\D$\.{BUFI}$ \5
\T{300}\C{ velikost stredniho zaplneni }\par
\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{PATITEM} ${}{*}\\{lapi}[\.{MAXPATT}]{}$;\C{ pole ukazatelu na aktualni
pozice }\6
\&{PATTERN} ${}{*}\\{lapt}[\.{MAXPATT}]{}$;\C{ pole odpovidajicich ukazatelu na
patterny }\6
\&{PATTERN} ${}{*}\\{listpatt},{}$ ${}{*}\\{normallist},{}$ ${}{*}%
\\{commentlist},{}$ ${}{*}\\{pt},{}$ ${}{*}\\{lastpt}\K\NULL;{}$\6
\&{PATITEM} ${}{*}\\{lastpi}\K\NULL;{}$\6
\&{char} \|c;\C{ zrovna nacetny znak }\6
\&{char} \\{buff}[\.{MAXBUFF}];\C{ prechodny buffer }\6
\&{int} \\{ind};\C{ aktualni pozice prechodneho bufferu }\par
\fi

\M{19}Dne 30. 4. 2009 jsem pøidal mo¾nost ètení vstupu, který obsahuje nulové
byty.
Takové nuly se pøepisují do výstupu, ale program si jich nev¹ímá pøi
procházení patternù. Tím je mo¾no program pou¾ít na soubory kódované
v UTF16, aèkoli patterny obsahují jen jednobytové ASCII znaky.
Buffer \PB{\\{buff}} mù¾e obsahovat i nulové byty, které je tøeba pøepsat do
výstupu.
Na druhé stranì buffer \PB{\\{buffnz}} obsahuje jen nenulové byty, na které se
nìkdy ptáme pøi pohledu dozadu. Nejdel¹í pohled dozadu je o ètyøi byty.
Udìlám tedy \PB{\\{buffnz}} osmibytový, zaènu jej plnit od \PB{\\{buffnz}}[4]
a kdykoli je buffer zcela zaplnìn, pøesunu horní ètyøi byty na spodní a dále
pokraèuji v plnìní bufferu od pozice \PB{\\{buffnz}}[4].
\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{char} \\{buffnz}[\T{8}];\6
\&{int} \\{inz};\par
\fi

\M{20}Nyní definujeme pomocné funkce \PB{\\{setpattern}}, \PB{\\{setpi}} a \PB{%
\\{normalpattern}}.
Tyto funkce alokují pamì» pomocí standardní funkce \PB{\\{malloc}}. Abychom
mohli
ohlídat pøípadnou chybu pøi alokaci, budeme allokovat pamì» zprostøedkovanì
pomocí funkce \PB{\\{myalloc}}.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} ${}{*}{}$\\{myalloc}(\&{int} \\{size})\1\1\2\2\6
${}\{{}$\1\6
\&{void} ${}{*}\|p;{}$\7
${}\|p\K\\{malloc}(\\{size});{}$\6
\&{if} ${}(\|p\E\NULL){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s,\ no\ memory,\ mall}\)\.{oc\ failed\\n"},%
\39\\{prog\_name});{}$\6
\\{exit}(\.{BAD\_PROGRAM});\6
\4${}\}{}$\2\6
\&{return} \|p;\6
\4${}\}{}$\2\par
\fi

\M{21}Funkce \PB{\\{setpattern}} alokuje pamì»ové místo struktury \PB{%
\&{PATTERN}} a napojí
ji pomocí promìnné \PB{\\{lastpt}} na u¾ alokovaný øetìz patternù.
Vrátí ukazatel na novì alokované místo. Jednotlivé pozice patternu se musí
následovnì alokovat pomocí \PB{\\{setpi}}.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{PATTERN} ${}{*}\\{setpattern}(\&{void}({*}\\{proc})(\&{void})){}$%
\1\1\2\2\6
${}\{{}$\1\6
\&{PATTERN} ${}{*}\\{pp};{}$\7
${}\\{pp}\K\\{myalloc}(\&{sizeof}(\&{PATTERN}));{}$\6
${}\\{pp}\MG\\{proc}\K\\{proc};{}$\6
${}\\{pp}\MG\\{next}\K\NULL;{}$\6
${}\\{pp}\MG\\{patt}\K\NULL;{}$\6
\&{if} ${}(\\{lastpt}\I\NULL){}$\1\5
${}\\{lastpt}\MG\\{next}\K\\{pp};{}$\2\6
${}\\{lastpt}\K\\{pp};{}$\6
${}\\{lastpi}\K\NULL;{}$\6
\&{return} \\{pp};\6
\4${}\}{}$\2\par
\fi

\M{22}Funkce \PB{\\{setpi}} alokuje pamì»ové místo pro jednu pozici patternu.
Provede
zøetìzení tak, aby první pozice øetìzu pozic byla zaznamenána v polo¾ce
\PB{\\{patt}} ve struktuøe \PB{\&{PATTERN}} a dal¹í byly provázány polo¾kou %
\PB{\\{next}} ve
struktuøe \PB{\&{PATITEM}}. Poslední pozice má \PB{$\\{next}\E\NULL$}.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{setpi}(\&{char} ${}{*}\\{str},\39{}$\&{int} \\{flag})\1%
\1\2\2\6
${}\{{}$\1\6
\&{PATITEM} ${}{*}\|p;{}$\7
${}\|p\K\\{myalloc}(\&{sizeof}(\&{PATITEM}));{}$\6
${}\|p\MG\\{str}\K\\{str};{}$\6
${}\|p\MG\\{flag}\K\\{flag};{}$\6
${}\|p\MG\\{next}\K\NULL;{}$\6
\&{if} ${}(\\{lastpi}\E\NULL){}$\1\5
${}\\{lastpt}\MG\\{patt}\K\|p;{}$\2\6
\&{else}\1\5
${}\\{lastpi}\MG\\{next}\K\|p;{}$\2\6
${}\\{lastpi}\K\|p;{}$\6
\4${}\}{}$\2\par
\fi

\M{23}Pøipravme si pùdu pro funkci \PB{\\{normalpattern}}. Tato funkce alokuje
strukturu pro jeden pattern vèetnì pozic patternu na základì vstupního
stringu. Ka¾dá pozice patternu obsahuje v~mno¾inì znakù jediný znak a má
\PB{$\\{flag}\K\.{ONE}$}. Znaky ve vstupním stringu odpovídají po øadì
jednotlivým
pozicím. Vytvoøí se vlastnì jakýsi absolutní pattern, tj. testovaný øetìzec
se musí pøesnì shodovat s~uvedeným stringem. Výjimku tvoøí znak \PB{\.{"."}},
který se interpretuje jako nula nebo více mezer. Chceme-li teèku
vnutit do patternu, napí¹eme dvì teèky za sebou.

Nejdøíve deklarujeme pole v¹ech mo¾ných jednopísmenných stringù.
\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{char} \\{strings}[\T{512}];\6
\&{int} \|i;\par
\fi

\M{24}Inicializujeme toto pole (znak, nula, znak, nula, atd...).
\Y\B\4\X24:Inicializace datových struktur\X${}\E{}$\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\T{256};{}$ ${}\|i\PP){}$\5
${}\{{}$\1\6
${}\\{strings}[\T{2}*\|i]\K{}$(\&{char}) \|i;\6
${}\\{strings}[\T{2}*\|i+\T{1}]\K\T{0};{}$\6
\4${}\}{}$\2\par
\As37, 40, 42, 43, 46, 49, 51, 53\ETs57.
\U5.\fi

\M{25}Definujme funkci \PB{\\{normalpattern}}.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{PATTERN} ${}{*}\\{normalpattern}(\&{void}({*}\\{proc})(\&{void}),%
\39{}$\&{const} \&{char} ${}{*}\\{str}){}$\1\1\2\2\6
${}\{{}$\1\6
\&{PATTERN} ${}{*}\\{pp};{}$\6
\&{int} \|j${}\K\T{0};{}$\7
${}\\{pp}\K\\{setpattern}(\\{proc});{}$\6
\&{while} (\\{str}[\|j])\5
${}\{{}$\1\6
\&{if} ${}(\\{str}[\|j]\E\.{'.'}){}$\5
${}\{{}$\1\6
${}\|j\PP;{}$\6
\&{if} ${}(\\{str}[\|j]\I\.{'.'}){}$\5
${}\{{}$\1\6
${}\\{setpi}(\\{blankscr},\39\.{ANY});{}$\6
\&{continue};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
${}\\{setpi}({\AND}\\{strings}{}$[(\&{unsigned} \&{char}) \\{str}[\|j]${}*%
\T{2}],\39\.{ONE});{}$\6
${}\|j\PP;{}$\6
\4${}\}{}$\2\6
\&{return} \\{pp};\6
\4${}\}{}$\2\par
\fi

\M{26}Funkce \PB{\\{match}}. Definujeme funkci, která na základì hodnoty znaku %
\PB{\|c}
(promìnná \PB{\|c} je definována jako globální), a pozice patternu \PB{\|p}
(parametr
funkce) vrátí informaci o tom, zda znak souhlasí s patternem. Záporná èísla
\PB{\.{FOUND}}, resp. \PB{\.{NOFOUND}} znamenají, ¾e je tøeba uzavøít pattern s
tím, ¾e
vzor odpovídá, resp. neodpovídá patternu. Nezáporné èíslo vrátí v pøípadì,
¾e zkoumaný vstup stále souhlasí s patternem, ale není je¹tì
rozhodnuto. Velikost návratové hodnoty v takovém pøípadì udává, o kolik
pozic je tøeba se posunout v patternu, abychom mìli ukazatel na pozici
patternu v souhlase s novou situací, zpùsobenou znakem \PB{\|c}.

Pokud je \PB{\|c} v mno¾inì znakù pro danou pozici \PB{$\|p\MG\\{str}$}, bude %
\PB{$\|m\E\T{1}$}, jinak
je \PB{$\|m\E{-}\T{1}$}. Pokud tímto èíslem pronásobíme hodnotu \PB{$\|p\MG%
\\{flag}$}, nemusíme
vìtvení podle \PB{$\|p\MG\\{flag}$} programovat dvakrát. Hodnoty \PB{\\{flag}}
jsou toti¾
symetrické podle nuly, napø. \PB{$\.{ANY}\E{-}\.{ANY\_NOT}$}.
\Y\B\4\D$\.{FOUND}$ \5
${-}{}$\T{1}\par
\B\4\D$\.{NOFOUND}$ \5
${-}{}$\T{2}\par
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{int} \\{match}(\&{PATITEM} ${}{*}\|p){}$\1\1\2\2\6
${}\{{}$\1\6
\&{int} \|m;\7
\&{if} ${}(\\{strchr}(\|p\MG\\{str},\39\|c)\I\NULL){}$\1\5
${}\|m\K\T{1}{}$;\C{ Znak nalezen }\2\6
\&{else}\1\5
${}\|m\K{-}\T{1}{}$;\C{ Znak nenalezen }\2\6
\&{switch} ${}(\|m*\|p\MG\\{flag}){}$\5
${}\{{}$\1\6
\4\&{case} \.{ANY}:\5
\&{return} \T{0};\C{ Souhas, neni nutny posun }\6
\4\&{case} \.{ONE}:\6
\&{if} ${}(\|p\MG\\{next}\E\NULL){}$\1\5
\&{return} \.{FOUND};\2\6
\&{return} \T{1};\C{ Souhas, nutny posun o 1 }\6
\4\&{case} \.{ONE\_NOT}:\5
\&{return} \.{NOFOUND};\C{ Nesouhlas }\6
\4\&{case} \.{ANY\_NOT}:\5
\X27:Vra» hodnotu podle následující pozice patternu\X;\6
\4${}\}{}$\2\6
\&{return} \T{0};\C{ Tady bychom nikdy nemeli byt, return pro potlaceni
varovani }\6
\4${}\}{}$\2\par
\fi

\M{27}O kolik pozic je tøeba se posunout a s jakým výsledkem zjistíme
rekurzivním voláním funkce \PB{\\{match}}.
\Y\B\4\X27:Vra» hodnotu podle následující pozice patternu\X${}\E{}$\6
\&{switch} ${}(\|m\K\\{match}(\|p\MG\\{next})){}$\5
${}\{{}$\1\6
\4\&{case} \.{NOFOUND}:\5
\&{return} \.{NOFOUND};\6
\4\&{case} \.{FOUND}:\5
\&{return} \.{FOUND};\6
\4\&{default}:\5
\&{return} \T{1}${}+\|m;{}$\6
\4${}\}{}$\2\par
\U26.\fi

\N{1}{28}Vlnkovací funkce.
Nejprve pøipravíme globální deklarace pro \uv{vlnkovací} funkci \PB{\\{tie}}.
Funkce \PB{\\{tie}} \uv{ovlnkuje} vstupní soubor \PB{\\{infile}} a vytvoøí
soubor
\PB{\\{outfile}}.  Pøi \PB{$\\{silent}\K\T{0}$} tiskne závìreènou zprávu o
zpracování. V této
zprávì se objeví jméno souboru, které se funkce \uv{dozví} prostøednictvím
globální promìnné \PB{\\{filename}}. Promìnná \PB{\\{numline}} poèítá øádky,
promìnná
\PB{\\{numchanges}} sèítá zmìny, tj. poèet doplnìných vlnek.
Promìnná \PB{\\{mode}} nabývý nìkteré z hodnot \PB{\.{TEXTMODE}}, \PB{%
\.{MATHMODE}},
\PB{\.{DISPLAYMODE}} a \PB{\.{VERBMODE}} podle stavu ve èteném textu.
\Y\B\4\D$\.{TEXTMODE}$ \5
\T{0}\par
\B\4\D$\.{MATHMODE}$ \5
\T{1}\par
\B\4\D$\.{DISPLAYMODE}$ \5
\T{2}\par
\B\4\D$\.{VERBMODE}$ \5
\T{3}\par
\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{char} ${}{*}\\{filename}{}$;\C{ jmeno zpracovavaneho souboru }\6
\&{long} \&{int} \\{numline}${},{}$ \\{numchanges};\C{ pro zaverecnou
statistiku }\6
\&{int} \\{mode};\par
\fi

\M{29}Nyní definujeme vlnkovací funkci \PB{\\{tie}}. Ve¹kerá èinnost se opírá o
strukturu patternù. Výhodné je (z dùvodu rychlosti) \uv{natvrdo} zde
implementovat jen pøepínání mezi stavem ètení z oblasti komentáøe
(\PB{$\\{listpatt}\E\\{commentlist}$}) a mimo komentáø (\PB{$\\{listpatt}\E%
\\{normallist}$});
\Y\B\4\X29:Vlnkovací funkce \PB{\\{tie}}\X${}\E{}$\6
\&{static} \&{void} \\{tie}(\&{FILE} ${}{*}\\{input},\39{}$\&{FILE} ${}{*}%
\\{output}){}$\1\1\2\2\6
${}\{{}$\1\6
\&{int} \\{ap};\C{ ap je pocet otevrenych patternu }\6
\&{register} \&{int} \|k${},{}$ \|m${},{}$ \|n;\6
\&{int} \\{ic};\6
\&{PATTERN} ${}{*}\\{pp};{}$\6
\&{PATITEM} ${}{*}\\{pi};{}$\7
\X30:Inicializace promìnných pøi startu funkce \PB{\\{tie}}\X;\6
\&{while} ${}(\R\\{feof}(\\{input})){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{ap}\E\T{0}\W\\{ind}>\.{BUFI}\W\|c\I\.{'\\\\'}){}$\1\5
\X31:Vyprázdni buffer\X;\2\6
\X33:Otevøi nové patterny\X;\C{ 1. 2. 2010: prohozene poradi }\6
\&{if} ${}(\\{ind}\G\.{MAXBUFF}){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"Operating\ buffer\ ov}\)\.{erflow,\ is\
anything\ }\)\.{wrong?\\n"});{}$\6
\\{exit}(\.{BAD\_PROGRAM});\6
\4${}\}{}$\2\6
\&{if} ${}((\\{ic}\K\\{getc}(\\{input}))\E\.{EOF}{}$)\C{ opravil Cejka Rudolf }%
\1\6
\&{break};\2\6
${}\\{buff}[\\{ind}\PP]\K\|c\K\\{ic};{}$\6
\&{if} ${}(\|c\E\T{0}){}$\1\5
\&{continue};\C{ 30. 4. 2009 }\2\6
\&{if} ${}(\\{inz}\G\T{8}){}$\5
${}\{{}$\1\6
\&{for} ${}(\\{inz}\K\T{0};{}$ ${}\\{inz}<\T{4};{}$ ${}\\{inz}\PP){}$\1\5
${}\\{buffnz}[\\{inz}]\K\\{buffnz}[\\{inz}+\T{4}];{}$\2\6
${}\\{inz}\K\T{4};{}$\6
\4${}\}{}$\2\6
${}\\{buffnz}[\\{inz}\PP]\K\|c;{}$\6
\&{if} ${}(\|c\E\.{'\\n'}){}$\1\5
${}\\{numline}\PP,\39\\{listpatt}\K\\{normallist};{}$\2\6
\&{if} ${}(\|c\E\.{'\%'}\W\\{mode}\I\.{VERBMODE}\W\\{buffnz}[\\{inz}-\T{2}]\I%
\.{'\\\\'}){}$\1\5
${}\\{listpatt}\K\\{commentlist};{}$\2\6
\X32:Projdi otevøené patterny\X;\6
\4${}\}{}$\2\6
\X31:Vyprázdni buffer\X;\6
\&{if} ${}(\R\\{web}){}$\1\5
\\{checkmode}(\,);\C{ zaverecna kontrola modu }\2\6
\&{if} ${}(\R\\{silent}){}$\1\5
\X35:Tiskni závìreènou zprávu\X;\2\6
\4${}\}{}$\2\par
\U1.\fi

\M{30}\B\X30:Inicializace promìnných pøi startu funkce \PB{\\{tie}}\X${}\E{}$\6
\&{for} ${}(\|k\K\T{0};{}$ ${}\|k<\.{MAXPATT};{}$ ${}\|k\PP){}$\1\5
${}\\{lapi}[\|k]\K\NULL;{}$\2\6
${}\|c\K\.{'\\n'};{}$\6
${}\\{buff}[\T{0}]\K\T{1};{}$\6
${}\\{mode}\K\\{ap}\K\T{0};{}$\6
${}\\{ind}\K\T{1};{}$\6
\&{for} ${}(\\{inz}\K\T{0};{}$ ${}\\{inz}<\T{4};{}$ ${}\\{inz}\PP){}$\1\5
${}\\{buffnz}[\\{inz}]\K\T{0};{}$\2\6
${}\\{inz}\K\T{4};{}$\6
${}\\{numline}\K\T{1};{}$\6
${}\\{numchanges}\K\T{0};{}$\6
${}\\{mode}\K\.{TEXTMODE}{}$;\par
\A38.
\U29.\fi

\M{31}Pøi manipulaci s bufferem byl pou¾it jeden trik. Ve¹keré naètené znaky
zaèínají a¾ od \PB{\\{buff}[\T{1}]}, zatímco \PB{\\{buff}[\T{0}]} je rovno
nule. Je to proto, ¾e
nìkteré algoritmy se vrací o jeden znak zpìt za svùj pattern, aby zjistily,
zda tam není symbol \uv{\.{\char92}} (napøíklad na výskyt sekvence
\.{\char92\char37} je tøeba reagovat jinak, ne¾ na výskyt obyèejného
procenta). Kdybychm zazaèali od \PB{\\{buff}[\T{0}]}, v nìkterých situacích
bychom se ptali, zda \PB{$\\{buff}[{-}\T{1}]\E\.{'\\\\'}$}, tj. sahali bychom
na neo¹etøené
místo v pamìti. Od 30. 4. 2009 tento problém pominul, proto¾e se ptáme dozadu
pouze
v~\PB{\\{buffnz}}, ale vlastnost døíve implementovanou v \PB{\\{buff}} jsem
ponechal beze zmìny.
\Y\B\4\X31:Vyprázdni buffer\X${}\E{}$\6
${}\{{}$\1\6
${}\\{fwrite}({\AND}\\{buff}[\T{1}],\39\\{ind}-\T{1},\39\T{1},\39%
\\{output});{}$\6
${}\\{ind}\K\T{1};{}$\6
\4${}\}{}$\2\par
\U29.\fi

\M{32}Pøi procházení otevøenými patterny posunujeme v poli \PB{\\{lapi}} pozice
jednotlivých patternù podle pokynù funkce \PB{\\{match}}, pøípadnì pattern
zavøeme
a pøípadnì vyvoláme proceduru patternu.

Nìkteré patterny v poli \PB{\\{lapi}} u¾ mohou být zavøeny, tak¾e je nutno s
tímto
polem pracovat jako s jakýmsi dìravým sýrem.
\Y\B\4\X32:Projdi otevøené patterny\X${}\E{}$\6
$\|n\K\\{ap};{}$\6
${}\|k\K\T{0};{}$\6
\&{while} (\|n)\5
${}\{{}$\1\6
\&{while} ${}(\\{lapi}[\|k]\E\NULL){}$\1\5
${}\|k\PP{}$;\C{ zastav se na prvnim ukazateli na pattern }\2\6
\&{switch} ${}(\|m\K\\{match}(\\{lapi}[\|k])){}$\5
${}\{{}$\1\6
\4\&{case} \.{FOUND}:\5
${}({*}\\{lapt}[\|k]\MG\\{proc})(\,){}$;\C{ Pattern nalezen, spustit proceduru
}\6
\4\&{case} \.{NOFOUND}:\5
${}\\{lapi}[\|k]\K\NULL{}$;\C{ Deaktivace patternu }\6
${}\\{ap}\MM;{}$\6
\&{break};\6
\4\&{default}:\6
\&{while} ${}(\|m\MM){}$\1\5
${}\\{lapi}[\|k]\K\\{lapi}[\|k]\MG\\{next}{}$;\C{ dalsi pozice patternu }\2\6
\4${}\}{}$\2\6
${}\|k\PP;{}$\6
${}\|n\MM;{}$\6
\4${}\}{}$\2\par
\U29.\fi

\M{33}Pøi otevírání nových patternù, které nejsou v tuto chvíli zablokovány,
se hned vypoøádáme s takovými patterny, které nám dávají rovnou odpovìï
typu \PB{\.{FOUND}} nebo \PB{\.{NOFOUND}}. V takových pøípadech ani nezaná¹íme
ukazatel
na pozici do pole \PB{\\{lapi}}.
\Y\B\4\X33:Otevøi nové patterny\X${}\E{}$\6
$\\{pp}\K\\{listpatt};{}$\6
\&{if} (\|c)\1\6
\&{while} ${}(\\{pp}\I\NULL){}$\5
${}\{{}$\1\6
\&{switch} ${}(\|m\K\\{match}(\\{pp}\MG\\{patt})){}$\5
${}\{{}$\1\6
\4\&{case} \.{FOUND}:\5
${}({*}\\{pp}\MG\\{proc})(\,){}$;\C{ spustit proceduru }\6
\4\&{case} \.{NOFOUND}:\5
\&{break};\6
\4\&{default}:\5
\X34:Vytvoø ukazatel na nový pattern a \PB{\&{break}}\X;\6
\4${}\}{}$\2\6
${}\\{pp}\K\\{pp}\MG\\{next};{}$\6
\4${}\}{}$\2\2\par
\U29.\fi

\M{34}Není-li hned známa odpovìï, zda pattern vyhovuje èi nikoli,
pøekontrolujeme nejdøíve, zda u¾ není pattern ve stejné pozici otevøený.
Pak najdeme první \uv{díru} v tabulce \PB{\\{lapi}} a tam uhnízdíme nový
ukazatel
na pozici v patternu.
\Y\B\4\X34:Vytvoø ukazatel na nový pattern a \PB{\&{break}}\X${}\E{}$\6
$\\{pi}\K\\{pp}\MG\\{patt};{}$\6
\&{while} ${}(\|m\MM){}$\1\5
${}\\{pi}\K\\{pi}\MG\\{next};{}$\2\6
${}\|n\K\\{ap};{}$\6
${}\|k\K\T{0};{}$\6
\&{while} (\|n)\5
${}\{{}$\1\6
\&{if} ${}(\\{lapi}[\|k]\E\\{pi}){}$\1\5
\&{break};\2\6
\&{if} ${}(\\{lapi}[\|k\PP]\I\NULL){}$\1\5
${}\|n\MM;{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\R\|n){}$\5
${}\{{}$\1\6
${}\|k\K\T{0};{}$\6
\&{while} ${}(\\{lapi}[\|k]\I\NULL){}$\1\5
${}\|k\PP;{}$\2\6
\&{if} ${}(\|k\G\.{MAXPATT}){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"I\ cannot\ allocate\ p}\)\.{p,\ is\ anything\
wrong}\)\.{?\\n"});{}$\6
\\{exit}(\.{BAD\_PROGRAM});\6
\4${}\}{}$\2\6
${}\\{lapt}[\|k]\K\\{pp};{}$\6
${}\\{lapi}[\|k]\K\\{pi};{}$\6
${}\\{ap}\PP;{}$\6
\4${}\}{}$\2\par
\U33.\fi

\M{35}Poslední vìcí ve funci \PB{\\{tie}} je tisk závìreèné statistiky
zpracování.
\Y\B\4\X35:Tiskni závìreènou zprávu\X${}\E{}$\6
$\\{fprintf}(\\{stderr},\39\.{"\~\~\~\ file:\ \%s\\t\ \ lin}\)\.{es:\ \%ld,\
changes:\ \%l}\)\.{d\\n"},\39\\{filename},\39\\{numline},\39\\{numchanges}){}$;%
\par
\U29.\fi

\N{1}{36}Inicializace patternù.
Po vytvoøení pøedchozího kódu opírajícího se o~patterny máme nyní v~ruce
pomìrnì silný nástroj na definování rùzných èinností programu prostým
vytvoøením patternu a pøíslu¹né jeho procedury. Pokud budeme chtít
v~budoucnu nìjaký rys programu pøidat, pravdìpodobnì to bude snadné.

Nejprve deklarujeme nìkteré èasto pou¾ívané skupiny znakù v~patternech.

\Y\B\4\X4:Globální deklarace\X${}\mathrel+\E{}$\6
\&{char} \\{tblanks}[\,]${}\K\.{"\ \~\\t"};{}$\6
\&{char} \\{blanks}[\,]${}\K\.{"\ \\t"};{}$\6
\&{char} \\{blankscr}[\,]${}\K\.{"\ \\t\\n"};{}$\6
\&{char} \\{tblankscr}[\,]${}\K\.{"\ \~\\t\\n"};{}$\6
\&{char} \\{nochar}[\,]${}\K\.{"\%\~\\n"};{}$\6
\&{char} \\{cr}[\,]${}\K\.{"\\n"};{}$\6
\&{char} \\{prefixes}[\,]${}\K\.{"[(\{\~"};{}$\6
\&{char} \\{dolar}[\,]${}\K\.{"\$"};{}$\6
\&{char} \\{backslash}[\,]${}\K\.{"\\\\"};{}$\6
\&{char} \\{openbrace}[\,]${}\K\.{"\{"};{}$\6
\&{char} \\{letters}[\,]${}\K\.{"abcdefghijklmnopqrs}\)\.{tuvwxyzABCDEFGHIJKLM}%
\)\.{NOPQRSTUVWXYZ"};{}$\6
\&{PATTERN} ${}{*}\\{vlnkalist},{}$ ${}{*}\\{mathlist},{}$ ${}{*}%
\\{parcheck},{}$ ${}{*}\\{verblist}{}$;\par
\fi

\M{37}Zaèneme definicí nejèastìji pou¾ívaného patternu na vlnkování uvnitø
øádku. Pøipomeòme, ¾e opakované volání funkce \PB{\\{setpattern}} vytváøí
internì
seznam patternù, pøièem¾ o~jejich propojení se nemusíme starat. Vyzvedneme
si z~návratového kódu funkce pouze ukazatel na první polo¾ku seznamu
\PB{\\{normallist}}. Stejnì tak opakované volání funkce \PB{\\{setpi}} vytváøí
seznam
pozic pro naposledy deklarovaný pattern.
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
$\\{vlnkalist}\K\\{setpattern}(\\{vlnkain});{}$\6
${}\\{setpi}(\\{tblankscr},\39\.{ONE});{}$\6
${}\\{setpi}(\\{tblanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{prefixes},\39\.{ANY});{}$\6
${}\\{setpi}(\\{charset},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{nochar},\39\.{ONE\_NOT}){}$;\par
\fi

\M{38}\B\X30:Inicializace promìnných pøi startu funkce \PB{\\{tie}}\X${}%
\mathrel+\E{}$\6
$\\{listpatt}\K\\{normallist}\K\\{vlnkalist}{}$;\par
\fi

\M{39}Vlo¾ení vlnky znamená vykonat následující práci: Zapamatovat si znak za
skupinou mezer
(do promìnné \PB{\|p}). Pokud pøed tímto znakem pøedchází nulový byte,
pou¾ijeme ho pozdìji, proto
si jej ulo¾íme do promìnné \PB{\|z}. Dále se posuneme v bufferu vlevo pøes
v¹echny mezery, tabelátory
(pøesnìji \PB{\\{blanks}}) a pøeskakujeme pøitom v¹echny nulové byty. Index %
\PB{\\{ind}} se zastaví
na pøedlo¾ce. Posuneme jej doprava za pøedlo¾ku (++\PB{\\{ind}}) a pokud tam je
nulový byte a první znak
\PB{\\{tiestr}} není nulový, posuneme se a¾ za tento nulový byte. Dále vlo¾íme
string \PB{\\{tiestr}},
neboli vlnku. Nakonec pøipojíme zapamatovaný znak \PB{\|p}, ov¹em pokud pøed
ním byla nula,
vlo¾íme ji je¹tì pøed znak \PB{\|p}.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{vlnkain}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{int} \|i;\6
\&{char} \|p${},{}$ \|z;\7
${}\\{ind}\MM;{}$\6
${}\|p\K\\{buff}[\\{ind}\MM];{}$\6
${}\|z\K\\{buff}[\\{ind}];{}$\6
\&{while} ${}(\R\\{buff}[\\{ind}]\V(\\{strchr}(\\{blanks},\39\\{buff}[\\{ind}])%
\I\NULL)){}$\1\5
${}\\{ind}\MM;{}$\2\6
\&{if} ${}(\R\\{buff}[\PP\\{ind}]\W\\{tiestr}[\T{0}]){}$\1\5
${}\\{ind}\PP;{}$\2\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{tiestrlen};{}$ ${}\|i\PP){}$\1\5
${}\\{buff}[\\{ind}\PP]\K\\{tiestr}[\|i];{}$\2\6
${}\|i\K\\{tiestrlen}{}$;\C{ nulu pred p vlozime, pokud je z==0 a }\6
\&{if} ${}(\R\\{tiestr}[\T{0}]){}$\1\5
${}\|i\MM{}$;\C{ pocet vlozenych znaku z tiestr }\2\6
\&{if} ${}(\R\|z\W(\|i\MOD\T{2})){}$\1\5
${}\\{buff}[\\{ind}\PP]\K\T{0}{}$;\C{ je sudy }\2\6
${}\\{buff}[\\{ind}\PP]\K\|p;{}$\6
${}\\{numchanges}\PP;{}$\6
\4${}\}{}$\2\par
\fi

\M{40}Podobnì pro tvorbu vlnky \uv{pøes øádek} vytvoøíme pattern a kód
procedury.
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
\\{setpattern}(\\{vlnkacr});\6
${}\\{setpi}(\\{tblankscr},\39\.{ONE});{}$\6
${}\\{setpi}(\\{tblanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{prefixes},\39\.{ANY});{}$\6
${}\\{setpi}(\\{charset},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{cr},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{nochar},\39\.{ONE\_NOT}){}$;\par
\fi

\M{41}V proceduøe k tomuto patternu musíme o¹etøit pøípad typu
\uv{\.{a\char126v\char92np}},
kdy nelze prostì pøehodit \uv{\.{\char92n}} za \uv{\.{v}}, proto¾e
bychom roztrhli
mezeru svázanou vlnkou u¾ døíve. Proto musíme vyhledat vhodné místo pro
roztr¾ení øádku, které bude a¾ {\it pøed\/} znakem \uv{\.{a}}. Pøi dùsledném
o¹etøení tohoto fenoménu mù¾eme dokonce narazit na situaci
\uv{\.{\char92n\ v\char126v\char126v\char92np}},  kde nemù¾eme vlo¾it
\uv{\.{\char92n}} pøed první výskyt \uv{\.{v}}, proto¾e bychom dostali
\uv{\.{\char92n\char92n}}, tedy prázdný
øádek. Ten je v \TeX{}u interperetován odli¹nì. V této výjimeèné
situaci pouze zru¹íme stávající (v poøadí druhé) \uv{\.{\char92n}} a
nebudeme vytváøet nové. Na výstupu bude soubor o jeden øádek krat¹í.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{vlnkacr}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{char} \|p${},{}$ \|z;\6
\&{int} \|i${},{}$ \|j;\7
${}\\{ind}\MM;{}$\6
${}\|p\K\\{buff}[\\{ind}\MM];{}$\6
${}\|z\K\\{buff}[\\{ind}];{}$\6
\&{while} ${}(\R\\{buff}[\\{ind}]\V(\\{strchr}(\\{blankscr},\39\\{buff}[%
\\{ind}])\I\NULL)){}$\1\5
${}\\{ind}\MM;{}$\2\6
${}\|i\K\\{ind}{}$;\C{ misto predlozky, kterou chceme vazat }\6
\&{while} ${}(\|i\G\T{0}\W(\\{strchr}(\\{blankscr},\39\\{buff}[\|i])\E%
\NULL)){}$\1\5
${}\|i\MM;{}$\2\6
${}\|j\K\|i;{}$\6
\&{while} ${}(\|i\G\T{0}\W(\R\\{buff}[\\{ind}]\V(\\{strchr}(\\{blanks},\39%
\\{buff}[\|i])\I\NULL))){}$\1\5
${}\|i\MM;{}$\2\6
\&{if} ${}(\|i\G\T{0}\W\\{buff}[\|i]\E\.{'\\n'}){}$\1\5
${}\|j\K{-}\T{1};{}$\2\6
\&{if} ${}(\|j\G\T{0}){}$\1\5
${}\\{buff}[\|j]\K\.{'\\n'};{}$\2\6
\&{else}\1\5
${}\\{numline}\MM;{}$\2\6
\&{if} ${}(\R\\{buff}[\PP\\{ind}]\W\\{tiestr}[\T{0}]){}$\1\5
${}\\{ind}\PP;{}$\2\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{tiestrlen};{}$ ${}\|i\PP){}$\1\5
${}\\{buff}[\\{ind}\PP]\K\\{tiestr}[\|i];{}$\2\6
${}\|i\K\\{tiestrlen};{}$\6
\&{if} ${}(\R\\{tiestr}[\T{0}]){}$\1\5
${}\|i\MM;{}$\2\6
\&{if} ${}(\R\|z\W(\|i\MOD\T{2})){}$\1\5
${}\\{buff}[\\{ind}\PP]\K\T{0};{}$\2\6
${}\\{buff}[\\{ind}\PP]\K\|p;{}$\6
${}\\{numchanges}\PP;{}$\6
\4${}\}{}$\2\par
\fi

\M{42}Nyní vytvoøíme patterny pro pøípady typu \.{\char92uv\char`\{v lese\char`%
\}}.
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
\\{setpattern}(\\{vlnkain});\C{ na radku }\6
${}\\{setpi}(\\{tblankscr},\39\.{ONE});{}$\6
${}\\{setpi}(\\{backslash},\39\.{ONE});{}$\6
${}\\{setpi}(\\{letters},\39\.{ONE});{}$\6
${}\\{setpi}(\\{letters},\39\.{ANY});{}$\6
${}\\{setpi}(\\{openbrace},\39\.{ONE});{}$\6
${}\\{setpi}(\\{prefixes},\39\.{ANY});{}$\6
${}\\{setpi}(\\{charset},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{nochar},\39\.{ONE\_NOT});{}$\6
\\{setpattern}(\\{vlnkacr});\C{ pres radek }\6
${}\\{setpi}(\\{tblankscr},\39\.{ONE});{}$\6
${}\\{setpi}(\\{backslash},\39\.{ONE});{}$\6
${}\\{setpi}(\\{letters},\39\.{ONE});{}$\6
${}\\{setpi}(\\{letters},\39\.{ANY});{}$\6
${}\\{setpi}(\\{openbrace},\39\.{ONE});{}$\6
${}\\{setpi}(\\{prefixes},\39\.{ANY});{}$\6
${}\\{setpi}(\\{charset},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{cr},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{nochar},\39\.{ONE\_NOT}){}$;\par
\fi

\M{43}Vytvoøíme patterny a proceduru pro potlatèení tvorby vlnky u písmen tìsnì
následujících sekvence \.{\char92TeX} a \.{\char92LaTeX}. Tj. nechceme, aby
napø z textu \uv{\.{Vlastnosti~\char92TeX~u~jsou...}} jsme dostali text
s nesprávnì vázaným písmenem
\uv{\.{Vlastnosti~\char92TeX~u\char126jsou...}}.
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
$\\{normalpattern}(\\{tielock},\39\.{"\\\\TeX"});{}$\6
${}\\{setpi}(\\{blankscr},\39\.{ONE});{}$\6
${}\\{normalpattern}(\\{tielock},\39\.{"\\\\LaTeX"});{}$\6
${}\\{setpi}(\\{blankscr},\39\.{ONE}){}$;\par
\fi

\M{44}Procedura \PB{\\{tielock}} obsahuje neèistý trik. Pøi provádìní procedury
je
právì naèten znak z \PB{\\{blankscr}} a je ulo¾en do \PB{\\{buff}}. Testy na
otevírání
nových patternù pro tento znak teprve budou následovat a testují se na
hodnotu promìnné \PB{\|c}. Staèí tedy zmìnit hodnotu \PB{\|c} a vlnkovací
patterny se
neotevøou.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{tielock}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\|c\K\T{1};{}$\6
\4${}\}{}$\2\par
\fi

\M{45}O¹etøíme nyní pøechod do/z matematického re¾imu \TeX{}u. Uvnitø math
módu vlnky nedìláme. Pøi zji¹tìném nesouladu v pøechodech mezi
math-módy spustíme následující proceduru.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{printwarning}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\R\\{silent}){}$\1\5
${}\\{fprintf}(\\{stderr},\39\.{"\~!\~\ warning:\ text/m}\)\.{ath/verb\ mode\
mismat}\)\.{ch,\ \ file:\ \%s,\ \ line}\)\.{:\ \%ld\\n"},\39\\{filename},\39%
\\{numline}-(\|c\E\.{'\\n'}\?\T{1}:\T{0}));{}$\2\6
${}\\{status}\K\.{WARNING};{}$\6
\4${}\}{}$\2\par
\fi

\M{46}Zaèneme patterny pro pøechod do/z matematického re¾imu, ohranièeného
jedním dolarem, nebo v La\TeX{}u pøíslu¹nými sekvencemi.  Sekvence
La\TeX{}u \.{\char92(} a \.{\char92)} nejsou zahrnuty, proto¾e bývají
èasto pøedefinovány k jiným u¾iteènìj¹ím vìcem.
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
\&{if} ${}(\R\\{nomath}){}$\5
${}\{{}$\1\6
${}\\{mathlist}\K\\{setpattern}(\\{onedollar});{}$\6
${}\\{setpi}(\\{dolar},\39\.{ONE});{}$\6
${}\\{setpi}(\\{dolar},\39\.{ONE\_NOT});{}$\6
\&{if} (\\{latex})\5
${}\{{}$\1\6
${}\\{normalpattern}(\\{mathin},\39\.{"\\\\begin.\{math\}"});{}$\6
${}\\{normalpattern}(\\{mathout},\39\.{"\\\\end.\{math\}"});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{47}\B\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{mathin}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{mode}\I\.{TEXTMODE}){}$\1\5
\\{printwarning}(\,);\2\6
${}\\{mode}\K\.{MATHMODE};{}$\6
${}\\{normallist}\K\\{listpatt}\K\\{mathlist};{}$\6
\4${}\}{}$\2\7
\&{static} \&{void} \\{mathout}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{mode}\I\.{MATHMODE}){}$\1\5
\\{printwarning}(\,);\2\6
${}\\{mode}\K\.{TEXTMODE};{}$\6
${}\\{normallist}\K\\{listpatt}\K\\{vlnkalist};{}$\6
\4${}\}{}$\2\par
\fi

\M{48}Pøi programování procedury \PB{\\{onedollar}} nesmíme zapomenout na
výskyt
sekvence \.{\char92\$}. V tom pøípadì akci ignorujeme. Podobnì u sekvence
\.{\$\$} souhlasí ten druhý dolar s na¹ím patternem, ale to u¾ jsme uvnitø
display módu. V takovém pøípadì také nic nedìláme.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{onedollar}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{buffnz}[\\{inz}-\T{3}]\E\.{'\\\\'}\V(\\{buffnz}[\\{inz}-\T{3}]\E%
\.{'\$'}\W\\{buffnz}[\\{inz}-\T{4}]\I\.{'\\\\'})){}$\1\5
\&{return};\2\6
\&{if} ${}(\\{mode}\E\.{DISPLAYMODE}){}$\1\5
\\{printwarning}(\,);\2\6
\&{else}\5
${}\{{}$\1\6
\&{if} ${}(\\{mode}\E\.{TEXTMODE}){}$\1\5
\\{mathin}(\,);\2\6
\&{else}\1\5
\\{mathout}(\,);\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{49}Pokud najdeme prázdný øádek, pøekontrolujeme, zda náhodou nejsme v
math-módu. Pokud ano, vypí¹eme varování a pøejdeme do textového módu.
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
$\\{parcheck}\K\\{setpattern}(\\{checkmode});{}$\6
${}\\{setpi}(\\{cr},\39\.{ONE});{}$\6
${}\\{setpi}(\\{blanks},\39\.{ANY});{}$\6
${}\\{setpi}(\\{cr},\39\.{ONE}){}$;\par
\fi

\M{50}\B\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{checkmode}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{mode}\I\.{TEXTMODE}){}$\5
${}\{{}$\1\6
\\{printwarning}(\,);\6
${}\\{mode}\K\.{TEXTMODE};{}$\6
${}\\{normallist}\K\\{listpatt}\K\\{vlnkalist};{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{51}Nyní o¹etøíme výskyt dvou dolarù, tj. vstup do/z display módu.
Rovnì¾ mysleme na La\TeX{}isty a jejich prostøedí pro display-mód. Proto¾e
je mo¾ná alternativa s hvìzdièkou na konci názvu prostøedí, radìji u¾
uzavírací závorku do patternu nezahrnujeme.

\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
\&{if} ${}(\R\\{nomath}){}$\5
${}\{{}$\1\6
${}\\{normalpattern}(\\{twodollars},\39\.{"\$\$"});{}$\6
\&{if} (\\{latex})\5
${}\{{}$\1\6
${}\\{normalpattern}(\\{displayin},\39\.{"\\\\begin.\{displaymat}\)\.{h"});{}$\6
${}\\{normalpattern}(\\{displayin},\39\.{"\\\\begin.\{equation"});{}$\6
${}\\{normalpattern}(\\{displayout},\39\.{"\\\\end.\{displaymath"});{}$\6
${}\\{normalpattern}(\\{displayout},\39\.{"\\\\end.\{equation"});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{52}\B\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{displayin}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{mode}\I\.{TEXTMODE}){}$\1\5
\\{printwarning}(\,);\2\6
${}\\{mode}\K\.{DISPLAYMODE};{}$\6
${}\\{normallist}\K\\{listpatt}\K\\{parcheck};{}$\6
\4${}\}{}$\2\7
\&{static} \&{void} \\{displayout}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{mode}\I\.{DISPLAYMODE}){}$\1\5
\\{printwarning}(\,);\2\6
${}\\{mode}\K\.{TEXTMODE};{}$\6
${}\\{normallist}\K\\{listpatt}\K\\{vlnkalist};{}$\6
\4${}\}{}$\2\7
\&{static} \&{void} \\{twodollars}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{buffnz}[\\{inz}-\T{3}]\E\.{'\\\\'}){}$\1\5
\&{return};\2\6
\&{if} ${}(\\{mode}\E\.{DISPLAYMODE}){}$\1\5
\\{displayout}(\,);\2\6
\&{else}\1\5
\\{displayin}(\,);\2\6
\4${}\}{}$\2\par
\fi

\M{53}Následuje o¹etøení tzv. verbatim módu. Pro plain i La\TeX{} jsou
nejèastìj¹í
závorky pro verbatim mod tyto (variantu s \.{\char92begtt} pou¾ívám
s oblibou já).
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
\&{if} ${}(\R\\{noverb}){}$\5
${}\{{}$\1\6
${}\\{verblist}\K\\{normalpattern}(\\{verbinchar},\39\.{"\\\\verb"});{}$\6
${}\\{setpi}(\\{blankscr},\39\.{ANY});{}$\6
${}\\{setpi}(\\{blankscr},\39\.{ONE\_NOT});{}$\6
${}\\{normalpattern}(\\{verbin},\39\.{"\\\\begtt"});{}$\6
\&{if} (\\{latex})\1\5
${}\\{normalpattern}(\\{verbin},\39\.{"\\\\begin.\{verbatim"});{}$\2\6
\4${}\}{}$\2\6
\&{if} (\\{web})\5
${}\{{}$\1\6
${}\\{normalpattern}(\\{verbin},\39\.{"@<"});{}$\6
${}\\{normalpattern}(\\{verbin},\39\.{"@d"});{}$\6
\4${}\}{}$\2\6
\&{if} ${}(\R\\{noverb}){}$\5
${}\{{}$\1\6
${}\\{verboutlist}[\T{0}]\K\\{setpattern}(\\{verbout});{}$\6
${}\\{setpi}(\\{verbchar},\39\.{ONE});{}$\6
${}\\{verboutlist}[\T{1}]\K\\{normalpattern}(\\{verbout},\39\.{"%
\\\\endtt"});{}$\6
\&{if} (\\{latex})\1\5
${}\\{verboutlist}[\T{2}]\K\\{normalpattern}(\\{verbout},\39\.{"\\\\end%
\{verbatim"});{}$\2\6
\4${}\}{}$\2\6
\&{if} (\\{web})\5
${}\{{}$\1\6
${}\\{verboutlist}[\T{3}]\K\\{normalpattern}(\\{verbout},\39\.{"@\ "});{}$\6
${}\\{normalpattern}(\\{verbout},\39\.{"@*"});{}$\6
${}\\{normalpattern}(\\{verbout},\39\.{"@>|"});{}$\6
\4${}\}{}$\2\par
\fi

\M{54}Procedura \PB{\\{verbinchar}} se od \uv{spoleèné} procedury \PB{%
\\{verbin}} li¹í v
tom, ¾e zavede do stringu \PB{\\{verbchar}} momentální hodnotu promìnné \PB{%
\|c}.
Proto druhý výskyt této hodnoty verbatim re¾im ukonèí.
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{int} \\{prevmode};\6
\&{PATTERN} ${}{*}\\{prevlist},{}$ ${}{*}\\{verboutlist}[\T{4}];{}$\6
\&{char} \\{verbchar}[\T{2}];\7
\&{static} \&{void} \\{verbinchar}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\\{prevmode}\K\\{mode};{}$\6
${}\\{verbchar}[\T{0}]\K\|c;{}$\6
${}\|c\K\T{1};{}$\6
${}\\{listpatt}\K\\{normallist}\K\\{verboutlist}[\T{0}];{}$\6
${}\\{prevlist}\K\\{listpatt}\MG\\{next};{}$\6
${}\\{listpatt}\MG\\{next}\K\NULL;{}$\6
${}\\{mode}\K\.{VERBMODE};{}$\6
\4${}\}{}$\2\par
\fi

\M{55}Pøi programování \uv{obecné} funkce \PB{\\{verbin}} musíme dbát na to,
aby
zùstal aktivní pouze odpovídající \uv{výstupní} pattern k danému
vstupnímu. Také si zapamatujeme mód, ze kterého jsme do verbatim
oblasti vstoupili, abychom se k nìmu mohli vrátit (napø. uvnitø
math. módu mù¾e být
\.{\char92hbox} a v nìm lokálnì verbatim konstrukce).
\Y\B\4\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{verbin}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{int} \|i;\7
${}\|i\K\T{0};{}$\6
${}\\{prevmode}\K\\{mode};{}$\6
\&{switch} (\|c)\5
${}\{{}$\1\6
\4\&{case} \.{'t'}:\5
${}\|i\K\T{1};{}$\6
\&{break};\6
\4\&{case} \.{'m'}:\5
${}\|i\K\T{2};{}$\6
\&{break};\6
\4\&{case} \.{'<'}:\5
;\6
\4\&{case} \.{'d'}:\5
${}\|i\K\T{3};{}$\6
\&{if} ${}(\\{buffnz}[\\{inz}-\T{3}]\E\.{'@'}){}$\1\5
\&{return};\C{ dvojity @ ignorovat }\2\6
\&{break};\6
\4${}\}{}$\2\6
${}\\{listpatt}\K\\{normallist}\K\\{verboutlist}[\|i];{}$\6
${}\\{prevlist}\K\\{listpatt}\MG\\{next};{}$\6
\&{if} ${}(\|c\I\.{'<'}\W\|c\I\.{'d'}){}$\1\5
${}\\{listpatt}\MG\\{next}\K\NULL;{}$\2\6
${}\\{mode}\K\.{VERBMODE};{}$\6
\4${}\}{}$\2\par
\fi

\M{56}\B\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{verbout}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{mode}\I\.{VERBMODE}){}$\1\5
\&{return};\2\6
\&{if} ${}(\\{web}\W\\{buffnz}[\\{inz}-\T{2}]\E\.{'@'}\W\\{buffnz}[\\{inz}-%
\T{3}]\E\.{'@'}){}$\1\5
\&{return};\2\6
${}\\{mode}\K\\{prevmode};{}$\6
${}\\{normallist}\MG\\{next}\K\\{prevlist};{}$\6
\&{switch} (\\{mode})\5
${}\{{}$\1\6
\4\&{case} \.{DISPLAYMODE}:\5
${}\\{normallist}\K\\{listpatt}\K\\{parcheck};{}$\6
\&{break};\6
\4\&{case} \.{MATHMODE}:\5
${}\\{normallist}\K\\{listpatt}\K\\{mathlist};{}$\6
\&{break};\6
\4\&{case} \.{TEXTMODE}:\5
${}\\{normallist}\K\\{listpatt}\K\\{vlnkalist};{}$\6
\&{break};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{57}Nyní implementujeme vlastnost døíve pou¾ívaného programu vlnka, tj. ¾e
lze jeho èinnost vypnout a opìt zapnout v komentáøích. Vytváøíme druhý
nezávislý seznam patternù a proto nejprve pronulujeme \PB{\\{lastpt}}.
\Y\B\4\X24:Inicializace datových struktur\X${}\mathrel+\E{}$\6
$\\{lastpt}\K\T{0};{}$\6
${}\\{commentlist}\K\\{normalpattern}(\\{tieoff},\39\.{"\%.\~.-"});{}$\6
${}\\{normalpattern}(\\{tieon},\39\.{"\%.\~.+"}){}$;\par
\fi

\M{58}\B\X6:Pomocné funkce\X${}\mathrel+\E{}$\6
\&{static} \&{void} \\{tieoff}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\\{normallist}\K\NULL;{}$\6
\4${}\}{}$\2\7
\&{static} \&{void} \\{tieon}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\\{normallist}\K\\{vlnkalist};{}$\6
\4${}\}{}$\2\par
\fi

\M{59}Dal¹í plánovaná vylep¹ení. Program by mohl èíst definici svého chování
nejen z~pøíkazové øádky, ale v~mnohem kompletnìj¹í podobì, vèetnì
u¾ivatelsky definovaných patternù, z komentáøové oblasti ve èteném souboru.
Parametry zde uvedené by mohly mít vy¹¹í prioritu, ne¾ parametry
z~pøíkazové øádky a mohl by se tøeba roz¹iøovat seznam sekvencí, za nimi¾
písmena nemají být vázana vlnkou (zatím je implemenováno na pevno jen
\.{\char92TeX} a \.{\char92LaTeX}).

\fi

\N{1}{60}Rejstøík.


\fi


\inx
\fin
\con