doc.pl 9.1 KB
Newer Older
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/perl

use strict;

=pod

PSIDOC label

PSIDOCCOPY label

=cut

13
my ($file, $doc_root, $out_dir) = @ARGV;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
14
15
16
17
my $find = "find ../src -iname \"*.h\" -or -iname \"*.cpp\"";
defined($file) or die "USAGE: $find | $0 file\n";
my %labels;

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
18
loadFiles(\%labels, $file);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
19

20
21
22
23
my @lines;
loadLines(\@lines);

loadLabels(\%labels, \@lines);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
24
25
26

recursiveExpand(\%labels);

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
27
replaceLabels($file, \%labels);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
28

29
30
31
32
33
34
35
36
37
38
printLabels(\%labels);

sub printLabels
{
	my ($labels) = @_;
	foreach my $key (keys %$labels) {
		print "$key\n";
	}
}

39
sub loadLines
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
40
{
41
	my ($lines) = @_;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
42
43
44
	while (<STDIN>) {
		chomp;
		my $f = $_;
45
		loadLinesThisFile($lines, $f);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
46
47
48
	}
}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
49
50
sub loadFiles
{
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
51
	my ($a, $f) = @_;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
52
	my %labels = %$a;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
53

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
54
	open(FILE, "<", $f) or die "$0: Cannot open $f : $!\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
55
56

	while (<FILE>) {
57
58
59
60
61
	    if (/\\ptexReadFile\{([^\}]+)\}/) {
		        my $file = $1;
			if ($doc_root != "") {
			    $file = $doc_root . "/" . $file;
			}
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
62
			my $ret = open(FILE2, "<", $file);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
63
64
65
66
67
			if (!$ret) {
				close(FILE);
				die "$0: ERROR: Cannot read $file, line $_\n";
			}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
68
			my $isMdFile = ($file=~/\.md$/);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
69
70
			my $buffer = "";
			while (<FILE2>) {
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
				if ($isMdFile) {
					s/^# +(.*)/\\chapter\{$1\}/;
					s/^## +(.*)/\\section\{$1\}/;
					s/^### +(.*)\n$/\\subsection\{$1\}/;
					s/\\\@/\@/g;
					s/<b>/\{\\bf /;
					s/<\/b>/\}/;

					s/<pre>/\\begin\{verbatim\}\n/;
					s/<\/pre>/\\end\{verbatim\}\n/;
					s/<code>/\{\\tt /g;
					s/<\/code>/\}/g;
				}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
				$buffer .= $_;
			}

			close(FILE2);

			my $label = getLabelForFile($file);
			my @temp = ($buffer);
			$labels{"$label"} = \@temp;
			next;
		}
	}

	close(FILE);
	%$a = %labels;
}

101
sub loadLinesThisFile
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
102
{
103
	my ($lines, $f) = @_;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
104

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
105
	open(FILE, "<", $f) or die "$0: Cannot open $f : $!\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
106
	while (<FILE>) {
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
		chomp;
		push @$lines, $_;
	}

	close(FILE);
}

sub loadLabels
{
	my ($a, $lines) = @_;
	my %labels = %$a;
	my $label = "!DISABLED";
	my $additional = "";
	my $buffer = "";
	my $nlines = scalar(@$lines);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
122
123
	my $inCodeBlock = 0;
	my $codeBuffer = "";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
124
	my $modifyLater = 1;
125
	my $hasContinue = 0;
126
127
128

	for (my $i = 0; $i < $nlines; ++$i) {
		$_ = $lines->[$i];
129
130
131
132
133
		if (/\/\* *PSIDOC_RESUME */) {
			$hasContinue = 0;
			next;
		}

134
135
136
		if (/\/\* *PSIDOC +(.+$)/) {
			my $rest = $1;
			chomp($rest);
137
			checkThatItDoesNotHaveContinue($hasContinue, "PSIDOC $rest");
138
			($label, $additional) = procPsidocName($rest);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
139
			$modifyLater = 1;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
140

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
141
142
			my $txt = $labels{"$label"};
			if (defined($txt)) {
143
				die "$0: ERROR: Label $label is duplicate\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
144
145
146
147
148
			}

			next;
		}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
149
150
151
		if (/\/\* PSIDOC_CODE_START +(.+$)/) {
			my $rest = $1;
            chomp($rest);
152
			checkThatItDoesNotHaveContinue($hasContinue, "PSIDOC_CODE_START $rest");
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
153
154
155
156
157
158
159
			$rest =~ s/\*\/ *$//;
			if ($inCodeBlock) {
				die "$0: Nested code blocks not allowed\n";
			}

			($label, $additional) = procPsidocName($rest);
			$label =~ s/ //g;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
160
			$modifyLater = ($additional eq "nocapture") ? 0 : 1;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
161

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
162
163
164
165
166
			my $txt = $labels{"$label"};
			if (defined($txt)) {
				die "$0: ERROR: Label $label is duplicate\n";
			}

167
			print STDERR "Opening $label\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
168
169
170
171
172
			$inCodeBlock = 1;
			next;
		}

		if (/\/\* PSIDOC_CODE_END \*\//) {
173
			print STDERR "Closing $label\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
174
175
176
177
			if (!$inCodeBlock) {
				die "$0: Closing code block while none is open\n";
			}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
178
			$labels{"$label"} = [$codeBuffer];
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
179
180
181
182
183
			$codeBuffer = "";
			$inCodeBlock = 0;
			next;
		}

184
		if (/\*\//) {
185
			next if ($hasContinue);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
186
			if ($label ne "!DISABLED" and $modifyLater) {
187
188
				my $inlabel = $label."::";
				$buffer =~ s/PSIDOCCOPY \$/PSIDOCCOPY ${inlabel}/g;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
189
190
				my @temp = ($buffer);
				$labels{"$label"} = \@temp;
191
192
193
194
195
196
				my $proto = captureFirstProtoBelow($i + 1, \@lines);
				if ($proto) {
					my @temp = ($proto);
					my $name = $inlabel."FirstProtoBelow";
					$labels{"$name"} = \@temp;
				}
197
198

				my $debug = 0;
199
200
201
202
				my $hashMark = captureFirstFunctionBelow($i + 1, \@lines, $debug);
				foreach my $key (%$hashMark) {
					my $func = $hashMark->{"$key"};
					next unless ($func);
203
204
					my @temp = ($func);
					my $name = $inlabel."FirstFunctionBelow";
205
					$name .= "::$key" unless ($key eq " ");
206
207
					$labels{"$name"} = \@temp;
				}
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
208
209
210
			}

			$buffer = "";
211
			print STDERR "Changing $label to !DISABLED\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
212
			$label = "!DISABLED";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
213
			$modifyLater = 1;
214
			$additional = "";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
215
216
217
		} elsif ($inCodeBlock) {
			$codeBuffer .= $_."\n";
			next;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
218
219
		}

220
221
222
223
224
		if (/^[ \t]*PSIDOC_CONTINUE *$/) {
			$hasContinue = 1;
			next;
		}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
225
		if ($label ne "!DISABLED") {
226
			$buffer .= $_."\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
227
228
229
		}
	}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
230
231
232
233
	if ($inCodeBlock) {
		die "$0: Code block was not closed for label $label\n";
	}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
234
	my $n = scalar(%labels);
235
	print STDERR "$0: $n labels found\n";
236

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
237
238
239
	%$a = %labels;
}

240
241
242
243
244
245
246
sub checkThatItDoesNotHaveContinue
{
	my ($hasContinue, $txt) = @_;
	return if ($hasContinue == 0);
	die "$0: Cannot use $txt when has continue\n";
}

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
sub procPsidocName
{
	my ($nameLike) = @_;
	my @temp = split/[ \t]/,$nameLike;
	my $n = scalar(@temp);
	die "$0: procPsidocName empty\n" if ($n == 0);
	return $nameLike if ($n == 1);
	die "$0: procPsidocName more than one additional\n" if ($n > 2);
	return @temp;
}

sub captureFirstProtoBelow
{
	my ($ind, $lines) = @_;
	my $nlines = scalar(@$lines);
	my $buffer = "";
	for (my $i = $ind; $i < $nlines; ++$i) {
		$_ = $lines->[$i];
		last if (/\/\*/);
		next if (/^ *\/\//);
		$buffer .= $_."\n";
		last if (/\;/);
	}

	return $buffer if ($buffer eq "");

	$buffer =~ s/\t/  /g;
	$buffer = "\\begin{lstlisting}\n$buffer\n";
	$buffer .= "\\end{lstlisting}\n";

	return $buffer;
}

280
281
282
283
284
285
sub captureFirstFunctionBelow
{
	my ($ind, $lines, $debug) = @_;
	my $nlines = scalar(@$lines);
	my $buffer = "";
	my $level = 0;
286
287
288
	my $markName = "";
	my $markContent = "";
	my %markHash;
289
290
	for (my $i = $ind; $i < $nlines; ++$i) {
		my $line = $lines->[$i];
291
292
293
294
295
296
297
298
299
300
301
302
303
		if ($line =~ /^[ \t]*\/\/ *PSIDOCMARK\_BEGIN +(.+$)/) {
			die "$0: PSIDOCMARK_BEGIN $1 cannot be nested\n" if ($markName ne "");
			$markName = $1;
			next;
		}

		if ($line =~ /^[ \t]*\/\/ *PSIDOCMARK\_END/) {
			die "$0: PSIDOCMARK_END found but no mark open\n" if ($markName eq "");
			$markHash{"$markName"} = dressCode($markContent);
			$markName = $markContent = "";
			next;
		}

304
305
306
		last if ($line =~ /\/\*/);
		next if ($line =~ /^ *\/\//);
		$buffer .= "$line\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
307

308
		$markContent .= "$line\n" if ($markName ne "");
309
310
311
312
313
314
315
316
		my $plus = () = $line =~ /\{/g;
		my $minus = () = $line =~ /\}/g;
		$level += $plus;
		$level -= $minus;
		print "$line **$level**\n" if ($debug);
		last if ($line =~ /\}[^\{\}]*$/ and $level == 0);
	}

317
318
	die "$0: PSIDOCMARK_BEGIN $1 was never ended\n" if ($markName ne "");

319
	$buffer = "" unless ($level == 0);
320
321
	$markHash{" "} = $buffer;
	return \%markHash if ($buffer eq "");
322

323
324
325
	$markHash{" "} = dressCode($buffer);
	return \%markHash;
}
326

327
328
329
330
331
332
333
sub dressCode
{
	my ($code) = @_;
	$code =~ s/\t/  /g;
	$code = "\\begin{lstlisting}\n$code\n";
	$code .= "\\end{lstlisting}\n";
	return $code;
334
335
}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
336
337
sub replaceLabels
{
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
338
	my ($file, $a) = @_;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
339
	my $fout = $file;
340
341
342
343
	if ($out_dir != "") {
	    $fout =~ s/.*\///; #chop the beginning of the path
	    $fout =  $out_dir . "/" . $fout;
	}
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
344
345
346
	$fout=~s/\.ptex$/\.tex/;
	die "$0: $file must have extension .ptex\n" if ($file eq $fout);

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
347
348
	open(FOUT, ">", "$fout") or die "$0: Cannot write to $fout : $!\n";
	open(FILE, "<", $file) or die "$0: Cannot open $file : $!\n";
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
349
350
351
352
353
354
	while (<FILE>) {
		next if (/^[ \t]*%/);
		if (/\\ptexPaste\{([^\}]+)\}/) {
			my $label = $1;
			next if ($label eq "#1");
			my $txt = getTextFromLabel($label,$a);
355
356
357
358
			if (!defined($txt)) {
				$txt = labelNotFound($label);
			}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
359
360
361
362
363
			print FOUT $txt;
			next;
		}

		if (/\\ptexReadFile\{([^\}]+)\}/) {
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
364
365
366
			my $file=$1;
			my $label = getLabelForFile($file);
			my $txt = getTextFromLabel($label,$a);
367
368
369
370
			if (!defined($txt)) {
				$txt = labelNotFound($label,$file);
			}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
371
			print FOUT $txt;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
			next;
		}

		print FOUT;
	}


	close(FILE);
	close(FOUT);

	print STDERR "$0: File $fout written\n";
}

sub recursiveExpand
{
	my ($a) = @_;
	my %labels = %$a;

	my $recurse = 0;
	foreach my $key (keys %labels) {
		my $ptr = $labels{"$key"};
		defined($ptr) or die "$0: Label $key has error\n";
		scalar(@$ptr) > 0 or die "$0: Label $key has error\n";
		my $txt = $ptr->[0];
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
396
		next unless ($txt=~/PSIDOCCOPY/);
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
397
398
399
400
		my $txt2 = expandIfNeeded($txt,$a);
		$recurse = 1 if ($txt2=~/PSIDOCCOPY/);
		my @buffer = ($txt2);
		$ptr = \@buffer;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
401
		$labels{"$key"}=$ptr;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
402
403
	}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
404
	%$a = %labels;
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

	recursiveExpand($a) if ($recurse);
}

sub expandIfNeeded
{
	my ($txt,$a) = @_;
	my %labels = %$a;
	my @temp = split/\n/,$txt;

	my $n = scalar(@temp);
	my $buffer = "";
	for (my $i = 0; $i < $n; ++$i) {
		$_ = $temp[$i];
		if (/PSIDOCCOPY +([^ ]+)/) {
			my $label = $1;
			chomp($label) if ($label=~/\n$/);
			my $txt = getTextFromLabel($label,$a);
423
			if (!defined($txt)) {
424
425
				die "$0: ERROR: line $_, $label not found\n";
				$txt = labelNotFound($label);
426
427
			}

Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
			$buffer .= $txt;
			next;
		}

		$buffer .= $_."\n";
	}

	return $buffer;
}

sub getTextFromLabel
{
	my ($label,$a)=@_;
	my %labels = %$a;
	my $ptr = $labels{"$label"};
	my $txt;
	if (!defined($ptr) || scalar(@$ptr) < 1) {
		print STDERR "$0: ERROR: Label $label not found\n";
		return $txt;
	}

	return $ptr->[0];
}
Alvarez, Gonzalo's avatar
Alvarez, Gonzalo committed
451
452
453
454
455
456
457
458
459

sub getLabelForFile
{
	my ($file) = @_;

	$file=~s/\./DOT/g;
	$file=~s/\//SLASH/g;
	return "FILE$file";
}
460
461
462
463
464
465
466
467

sub labelNotFound
{
	my ($label,$file) = @_;
	my $str = (defined($file)) ? " in $file " : "";
	return "{\\bf\\textcolor{red}{ERROR: Label not found$str}}\n";
}