summaryrefslogtreecommitdiff
path: root/Build/source/utils/vlna/vlna.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/vlna/vlna.w')
-rw-r--r--Build/source/utils/vlna/vlna.w125
1 files changed, 101 insertions, 24 deletions
diff --git a/Build/source/utils/vlna/vlna.w b/Build/source/utils/vlna/vlna.w
index da84b8711b6..6d1ff5c2536 100644
--- a/Build/source/utils/vlna/vlna.w
+++ b/Build/source/utils/vlna/vlna.w
@@ -32,7 +32,7 @@ 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ý) |BANNER|.
-@d BANNER "This is program vlna, version 1.2, (c) 1995, 2002 Petr Olsak\n"
+@d BANNER "This is program vlna, version 1.5, (c) 1995, 2002, 2009, 2010 Petr Olsak\n"
@ V programu jsou použity knihovní funkce, jejíchž prototypy jsou
definovány ve třech standardních hlavičkových souborech.
@@ -89,6 +89,10 @@ souborů.
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
@@ -101,7 +105,7 @@ souborů.
vlnkuje dokumentační část každé sekce, ale nikoli kód.
\enditems
-Definujeme funkci |printusage|, které tiskne (při chybě) stručný přehled
+Definujeme funkci |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.
@@ -117,6 +121,7 @@ static void printusage (void)
" -s : silent: no messages to stderr\n"
" -r : rmbackup: if nofilter, removes temporary files\n"
" -v charset : set of lettres to add tie, default: KkSsVvZzOoUuAI\n"
+ " -x code : code for tie symbol, default: 7E, example -x C2A0\n"
" -m : nomath: ignores math modes\n"
" -n : noverb: ignores verbatim modes\n"
" -l : LaTeX mode\n"
@@ -133,7 +138,18 @@ int isfilter=0, silent=0, rmbackup=0, nomath=0, noverb=0, web=0, latex=0;
char charsetdefault[]="KkSsVvZzOoUuAI";
char *charset=charsetdefault;
+@ String |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 |tiestrlen| bez ohledu na to, zda obsahuje nebo
+neobsahuje nulové znaky (C-čková konvence pro stringy není použita).
+@<Globální deklarace@>=
+unsigned char tiestr[MAXLEN];
+int tiestrlen;
+
@ @<Načtení parametrů ...@>=
+tiestr[0] = '~';
+tiestrlen = 1;
while (argc>1 && argv[1][0] == '-') {
if (argv[1][2] != 0) printusage (), exit (BAD_OPTIONS);
switch(argv[1][1]) {
@@ -142,6 +158,8 @@ while (argc>1 && argv[1][0] == '-') {
case 'r': rmbackup = 1; break;
case 'v': if (argc<2) printusage (), exit (BAD_OPTIONS);
argv++; argc--; charset = argv[1]; break;
+ case 'x': if (argc<2) printusage (), exit (BAD_OPTIONS);
+ argv++; argc--; settiestr(argv[1]); break;
case 'm': nomath = 1; break;
case 'n': noverb = 1; break;
case 'l': latex = 1; break;
@@ -152,6 +170,26 @@ while (argc>1 && argv[1][0] == '-') {
argc--; argv++;
}
+@ Vyřešíme konverzi kódu zapsaného za parametrem \.{-x} na string |tiestr|.
+@<Pomocné funkce@>=
+unsigned char hexnum(char c) {
+ if (c >= '0' && c <= '9') return c - '0';
+ if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+ if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+ printusage (), exit (BAD_OPTIONS);
+}
+void settiestr(char *s) {
+ int i, j, c;
+ i = strlen(s);
+ if ((i > 2*MAXLEN) || i%2 == 1) printusage (), exit (BAD_OPTIONS);
+ tiestrlen = i/2;
+ j = 0;
+ for (i=0; i<tiestrlen; i++) {
+ tiestr[i] = hexnum(s[j++]) << 4;
+ tiestr[i] += hexnum(s[j++]);
+ }
+}
+
@* Zpracování souborů. Parametr |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}.
@@ -347,6 +385,20 @@ char c; /* zrovna nacetny znak */
char buff[MAXBUFF]; /* prechodny buffer */
int ind; /* aktualni pozice prechodneho bufferu */
+@ 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 |buff| může obsahovat i nulové byty, které je třeba přepsat do výstupu.
+Na druhé straně buffer |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 |buffnz| osmibytový, začnu jej plnit od |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 |buffnz|[4].
+@<Globální deklarace@>=
+char buffnz[8];
+int inz;
+
@ Nyní definujeme pomocné funkce |setpattern|, |setpi| a |normalpattern|.
Tyto funkce alokují paměť pomocí standardní funkce |malloc|. Abychom mohli
ohlídat případnou chybu při alokaci, budeme allokovat paměť zprostředkovaně
@@ -514,8 +566,8 @@ static void tie (FILE *input, FILE *output)
@<Inicializace proměnných při startu funkce |tie|@>;
while (!feof(input)) {
- @<Otevři nové patterny@>;
if (ap == 0 && ind > BUFI && c !='\\') @<Vyprázdni buffer@>;
+ @<Otevři nové patterny@>; /* 1. 2. 2010: prohozene poradi */
if (ind >= MAXBUFF) {
fprintf (stderr, "Operating buffer overflow, is anything wrong?\n");
exit (BAD_PROGRAM);
@@ -523,8 +575,14 @@ static void tie (FILE *input, FILE *output)
if ((ic = getc(input)) == EOF) /* opravil Cejka Rudolf */
break;
buff[ind++] = c = ic;
+ if (c == 0) continue; /* 30. 4. 2009 */
+ if (inz>=8) {
+ for (inz=0; inz<4; inz++) buffnz[inz] = buffnz[inz+4];
+ inz=4;
+ }
+ buffnz[inz++] = c;
if (c == '\n') numline++, listpatt = normallist;
- if (c == '%' && mode!=VERBMODE && buff[ind-2] != '\\') listpatt = commentlist;
+ if (c == '%' && mode!=VERBMODE && buffnz[inz-2] != '\\') listpatt = commentlist;
@<Projdi otevřené patterny@>;
}
@<Vyprázdni buffer@>;
@@ -535,7 +593,9 @@ static void tie (FILE *input, FILE *output)
@ @<Inicializace proměnných při ...@>=
for (k=0; k<MAXPATT; k++) lapi[k] = NULL;
c = '\n';
-buff[0] = mode = ap = 0; ind = 1;
+buff[0] = 1; mode = ap = 0; ind = 1;
+for(inz=0; inz<4; inz++) buffnz[inz] = 0;
+inz = 4;
numline = 1; numchanges = 0;
mode = TEXTMODE;
@@ -546,11 +606,11 @@ 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 |buff[0]|, v některých situacích
bychom se ptali, zda |buff[-1]=='\\'|, tj. sahali bychom na neošetřené
-místo v paměti.
+místo v paměti. Od 30. 4. 2009 tento problém pominul, protože se ptáme dozadu pouze
+v~|buffnz|, ale vlastnost dříve implementovanou v |buff| jsem ponechal beze změny.
@<Vyprázdni buffer@>=
{
- buff[ind] = 0;
- fputs (&buff[1], output);
+ fwrite (&buff[1], ind-1, 1, output);
ind = 1;
}
@@ -579,7 +639,7 @@ typu |FOUND| nebo |NOFOUND|. V takových případech ani nezanášíme ukazatel
na pozici do pole |lapi|.
@<Otevři nové patterny@>=
pp = listpatt;
-while (pp != NULL) {
+if (c) while (pp != NULL) {
switch (m = match (pp->patt)) {
case FOUND: (*pp->proc)(); /* spustit proceduru */
case NOFOUND: break;
@@ -656,15 +716,28 @@ setpi (nochar, ONE_NOT);
@ @<Inicializace proměnných při ...@>=
listpatt = normallist = vlnkalist;
-@ @<Pomocné funkce@>=
+@ Vložení vlnky znamená vykonat následující práci: Zapamatovat si znak za skupinou mezer
+(do proměnné |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é |z|. Dále se posuneme v bufferu vlevo přes všechny mezery, tabelátory
+(přesněji |blanks|) a přeskakujeme přitom všechny nulové byty. Index |ind| se zastaví
+na předložce. Posuneme jej doprava za předložku (++|ind|) a pokud tam je nulový byte a první znak
+|tiestr| není nulový, posuneme se až za tento nulový byte. Dále vložíme string |tiestr|,
+neboli vlnku. Nakonec připojíme zapamatovaný znak |p|, ovšem pokud před ním byla nula,
+vložíme ji ještě před znak |p|.
+@<Pomocné funkce@>=
static void vlnkain(void)
{
- char p;
+ int i;
+ char p, z;
ind--;
p = buff[ind--];
- while (strchr(blanks, buff[ind]) !=NULL) ind--;
- ind++;
- buff[ind++] = '~';
+ z = buff[ind];
+ while (!buff[ind] || (strchr(blanks, buff[ind]) !=NULL)) ind--;
+ if (!buff[++ind] && tiestr[0]) ind++;
+ for (i=0; i<tiestrlen; i++) buff[ind++] = tiestr[i];
+ i = tiestrlen; /* nulu pred p vlozime, pokud je z==0 a */
+ if (!tiestr[0]) i--; /* pocet vlozenych znaku z tiestr */
+ if (!z && (i%2)) buff[ind++] = 0; /* je sudy */
buff[ind++] = p;
numchanges++;
}
@@ -698,20 +771,24 @@ nebudeme vytvářet nové. Na výstupu bude soubor o jeden řádek kratší.
@<Pomocné funkce@>=
static void vlnkacr(void)
{
- char p;
+ char p, z;
int i, j;
ind--;
p = buff[ind--];
- while (strchr(blankscr, buff[ind]) !=NULL) ind--;
+ z = buff[ind];
+ while (!buff[ind] || (strchr(blankscr, buff[ind]) !=NULL)) ind--;
i = ind; /* misto predlozky, kterou chceme vazat */
while (i >= 0 && (strchr(blankscr, buff[i]) == NULL)) i--;
j = i;
- while (i >= 0 && (strchr(blanks, buff[i]) != NULL)) i--;
+ while (i >= 0 && (!buff[ind] || (strchr(blanks, buff[i]) != NULL))) i--;
if (i >= 0 && buff[i] == '\n') j = -1;
if (j >= 0) buff[j] = '\n';
else numline--;
- ind++;
- buff[ind++] = '~';
+ if (!buff[++ind] && tiestr[0]) ind++;
+ for (i=0; i<tiestrlen; i++) buff[ind++] = tiestr[i];
+ i = tiestrlen;
+ if (!tiestr[0]) i--;
+ if (!z && (i%2)) buff[ind++] = 0;
buff[ind++] = p;
numchanges++;
}
@@ -757,7 +834,7 @@ normalpattern (tielock, "\\LaTeX");
setpi (blankscr, ONE);
@ Procedura |tielock| obsahuje nečistý trik. Při provádění procedury je
-právě načten znak z |blankscr| a je uložen do buff. Testy na otevírání
+právě načten znak z |blankscr| a je uložen do |buff|. Testy na otevírání
nových patternů pro tento znak teprve budou následovat a testují se na
hodnotu proměnné |c|. Stačí tedy změnit hodnotu |c| a vlnkovací patterny se
neotevřou.
@@ -816,7 +893,7 @@ display módu. V takovém případě také nic neděláme.
@<Pomocné funkce@>=
static void onedollar (void)
{
- if (buff[ind-3]=='\\' || (buff[ind-3]=='$' && buff[ind-4]!='\\')) return;
+ if (buffnz[inz-3]=='\\' || (buffnz[inz-3]=='$' && buffnz[inz-4]!='\\')) return;
if (mode==DISPLAYMODE) printwarning ();
else {
if (mode==TEXTMODE) mathin();
@@ -871,7 +948,7 @@ static void displayout (void)
}
static void twodollars (void)
{
- if (buff[ind-3]=='\\') return;
+ if (buffnz[inz-3]=='\\') return;
if (mode==DISPLAYMODE) displayout ();
else displayin ();
}
@@ -939,7 +1016,7 @@ static void verbin (void)
case 'm': i = 2; break;
case '<': ;
case 'd': i = 3;
- if (buff[ind-3]=='@@') return; /* dvojity @@ ignorovat */
+ if (buffnz[inz-3]=='@@') return; /* dvojity @@ ignorovat */
break;
}
listpatt = normallist = verboutlist[i];
@@ -952,7 +1029,7 @@ static void verbin (void)
static void verbout (void)
{
if (mode!=VERBMODE) return;
- if (web && buff[ind-2] == '@@' && buff[ind-3] == '@@') return;
+ if (web && buffnz[inz-2] == '@@' && buffnz[inz-3] == '@@') return;
mode = prevmode;
normallist->next = prevlist;
switch (mode) {