forked from MEGA65/mega65-user-guide
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex_basic_programmes.c
164 lines (138 loc) · 3.55 KB
/
index_basic_programmes.c
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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#define MAX_COMMANDS 1024
char *commands[MAX_COMMANDS];
int cmd_count=0;
int cmd_used[MAX_COMMANDS];
void reset_cmd_usage(void)
{
fprintf(stderr,"RESETCMDS\n");
for(int i=0;i<cmd_count;i++) cmd_used[i]=0;
}
void mark_cmd_used(char *s)
{
for(int i=0;i<cmd_count;i++)
if (!strcmp(s,commands[i])) {
fprintf(stderr," CMD #%d used '%s'\n",i,commands[i]);
cmd_used[i]++;
}
}
void parse_basic_text(char *s)
{
int quote_mode=0;
char token[8192];
int tlen=0;
for(int i=0;s[i];i++) {
if (s[i]=='\"') { quote_mode^=1; tlen=0; }
if (!quote_mode) {
if (isalnum(s[i])) token[tlen++]=s[i];
else {
token[tlen]=0;
if (tlen) {
if (isalpha(token[0])) {
mark_cmd_used(token);
}
// Stop scanning after a REM statement
if (!strcmp(token,"REM")) break;
}
tlen=0;
}
}
}
if (tlen) {
token[tlen]=0;
if (isalpha(token[0])) {
mark_cmd_used(token);
}
}
}
int main(int argc,char **argv)
{
FILE *f=fopen(argv[1],"r");
if (!f) {
fprintf(stderr,"ERROR: Could not read '%s'\n",argv[1]);
exit(-1);
}
int in_code=0;
int code_font=0;
char line[8192];
/*
Pass 1: Find list of BASIC 10 commands
*/
line[0]=0; fgets(line,8192,f);
while(line[0]) {
if (!strncmp("\\index{BASIC 65 Commands!",line,strlen("\\index{BASIC 65 Commands!"))) {
char command[8192];
strcpy(command,&line[strlen("\\index{BASIC 65 Commands!")]);
for(int i=0;command[i];i++) {
if (!isalnum(command[i])) { command[i]=0; break; }
}
int i=0;
for(i=0;i<cmd_count;i++) {
if (!strcmp(command,commands[i])) break;
}
if (i==cmd_count) {
if (isalpha(command[0])) commands[cmd_count++]=strdup(command);
}
}
line[0]=0; fgets(line,8192,f);
}
fclose(f);
fprintf(stderr,"Found %d BASIC keywords.\n",cmd_count);
for(int i=0;i<cmd_count;i++)
fprintf(stderr," %s\n",commands[i]);
/*
Pass 2: Find example programs, and note which commands should be indexed following each example programme.
*/
f=fopen(argv[1],"r");
if (!f) {
fprintf(stderr,"ERROR: Could not read '%s'\n",argv[1]);
exit(-1);
}
in_code=0;
code_font=0;
reset_cmd_usage();
line[0]=0; fgets(line,8192,f);
while(line[0]) {
if (!strncmp("\\verbatimfont{\\codefont}",line,strlen("\\verbatimfont{\\codefont}"))) {
fprintf(stdout,"%s",line);
code_font=1;
} else if (!strncmp("\\begin{verbatim}",line,strlen("\\begin{verbatim}"))) {
fprintf(stdout,"%s",line);
if (code_font==1) {
fprintf(stderr,"BEGIN\n");
reset_cmd_usage();
in_code=1;
}
} else if (!strncmp("\\end{verbatim}",line,strlen("\\end{verbatim}"))) {
fprintf(stdout,"%s",line);
fprintf(stderr,"OUTPUT INDEX\n");
in_code=0;
// Skip any existing index entries
line[0]=0; fgets(line,8192,f);
while (!strncmp("\\index{BASIC 65 Commands!",line,strlen("\\index{BASIC 65 Commands!"))) {
line[0]=0; fgets(line,8192,f);
}
// Dump index list
for(int i=0;i<cmd_count;i++) {
if (cmd_used[i]) {
fprintf(stderr," '%s'\n",commands[i]);
fprintf(stdout,"\\index{BASIC 65 Commands!%s!Examples}\n",commands[i]);
}
}
fprintf(stdout,"%s",line);
} else {
fprintf(stdout,"%s",line);
code_font=0;
if (in_code) {
// Parse example programme to look for known keywords
parse_basic_text(line);
}
}
line[0]=0; fgets(line,8192,f);
}
}