1+ #include < stdio.h>
2+ #include < stdlib.h>
3+
4+ #define MAX_LABELS 100
5+ #define MAX_LINE_LENGTH 100
6+
7+ struct Label
8+ {
9+ int label;
10+ int is_referenced;
11+ };
12+
13+ // Функция для проверки, является ли символ пробельным
14+ int isspace (int c)
15+ {
16+ return (c == ' ' || c == ' \n ' || c == ' \r ' || c == ' \t ' || c == ' \v ' || c == ' \f ' );
17+ }
18+
19+ // Функция для проверки, является ли символ цифрой
20+ int isdigit (int c)
21+ {
22+ return (c >= ' 0' && c <= ' 9' );
23+ }
24+
25+ // Собственная реализация функции для преобразования строки в число
26+ int my_atoi (const char *str)
27+ {
28+ int result = 0 ;
29+
30+ while (isdigit (*str))
31+ {
32+ result = result * 10 + (*str - ' 0' );
33+ str++;
34+ }
35+
36+ return result;
37+ }
38+
39+ // Функция для извлечения метки из строки
40+ int extract_label (const char *line)
41+ {
42+ while (*line && isspace (*line))
43+ {
44+ line++;
45+ }
46+ if (isdigit (*line))
47+ {
48+ return my_atoi (line);
49+ }
50+
51+ return -1 ;
52+ }
53+
54+ // Функция для поиска метки в массиве меток
55+ int find_label (Label labels[], int num_labels, int label)
56+ {
57+ for (int i = 0 ; i < num_labels; i++)
58+ {
59+ if (labels[i].label == label)
60+ {
61+ return i;
62+ }
63+ }
64+
65+ return -1 ;
66+ }
67+
68+ // Функция для сравнения строки с заданной константой
69+ int compare_with_constant (const char *ptr, const char *constant)
70+ {
71+ while (*constant)
72+ {
73+ if (*ptr != *constant)
74+ {
75+ return 0 ;
76+ }
77+
78+ ptr++;
79+ constant++;
80+ }
81+
82+ return 1 ;
83+ }
84+
85+ // Функция для добавления текста в буфер без использования strcat
86+ void my_strcat (char *dest, const char *src)
87+ {
88+ while (*dest)
89+ {
90+ dest++;
91+ }
92+ while (*src)
93+ {
94+ *dest = *src;
95+ dest++;
96+ src++;
97+ }
98+
99+ *dest = ' \0 ' ;
100+ }
101+
102+ // Функция для добавления ссылки на метку
103+ void add_reference (Label labels[], int num_labels, const char *line)
104+ {
105+ const char *ptr = line;
106+ int found_references = 0 ;
107+ char reference_buffer[MAX_LINE_LENGTH] = " " ;
108+
109+ while (*ptr)
110+ {
111+ if (isdigit (*ptr))
112+ {
113+ const char *prev = ptr - 1 ;
114+
115+ while (prev > line && isspace (*prev))
116+ {
117+ prev--;
118+ }
119+ if (prev > line && (*prev == ' ;' || *prev == ' ' || *prev == ' \n ' ))
120+ {
121+ int label = my_atoi (ptr);
122+ int index = find_label (labels, num_labels, label);
123+
124+ if (index != -1 )
125+ {
126+ labels[index].is_referenced = 1 ;
127+
128+ if (found_references)
129+ {
130+ my_strcat (reference_buffer, " or " );
131+ }
132+
133+ char buffer[10 ];
134+ int len = snprintf (buffer, sizeof (buffer), " %d" , label);
135+
136+ if (len >= 0 && len < sizeof (buffer))
137+ {
138+ buffer[len] = ' \0 ' ;
139+ my_strcat (reference_buffer, buffer);
140+
141+ found_references = 1 ;
142+ }
143+ }
144+ else
145+ {
146+ if (found_references)
147+ {
148+ my_strcat (reference_buffer, " or " );
149+ }
150+
151+ my_strcat (reference_buffer, " non-existing " );
152+
153+ char buffer[10 ];
154+ int len = snprintf (buffer, sizeof (buffer), " %d" , label);
155+
156+ if (len >= 0 && len < sizeof (buffer))
157+ {
158+ buffer[len] = ' \0 ' ;
159+ my_strcat (reference_buffer, buffer);
160+
161+ found_references = 1 ;
162+ }
163+ }
164+ }
165+ while (isdigit (*ptr))
166+ {
167+ ptr++;
168+ }
169+ }
170+ else if (compare_with_constant (ptr, " then" ) || compare_with_constant (ptr, " else" ))
171+ {
172+ ptr += 4 ;
173+
174+ while (*ptr && isspace (*ptr))
175+ {
176+ ptr++;
177+ }
178+ if (isdigit (*ptr))
179+ {
180+ int label = my_atoi (ptr);
181+ int index = find_label (labels, num_labels, label);
182+
183+ if (index != -1 )
184+ {
185+ labels[index].is_referenced = 1 ;
186+
187+ if (found_references)
188+ {
189+ my_strcat (reference_buffer, " or " );
190+ }
191+
192+ char buffer[10 ];
193+ int len = snprintf (buffer, sizeof (buffer), " %d" , label);
194+
195+ if (len >= 0 && len < sizeof (buffer))
196+ {
197+ buffer[len] = ' \0 ' ;
198+ my_strcat (reference_buffer, buffer);
199+
200+ found_references = 1 ;
201+ }
202+ }
203+ else
204+ {
205+ if (found_references)
206+ {
207+ my_strcat (reference_buffer, " or " );
208+ }
209+
210+ my_strcat (reference_buffer, " non-existing " );
211+
212+ char buffer[10 ];
213+ int len = snprintf (buffer, sizeof (buffer), " %d" , label);
214+
215+ if (len >= 0 && len < sizeof (buffer))
216+ {
217+ buffer[len] = ' \0 ' ;
218+ my_strcat (reference_buffer, buffer);
219+
220+ found_references = 1 ;
221+ }
222+ }
223+ while (isdigit (*ptr))
224+ {
225+ ptr++;
226+ }
227+ }
228+ }
229+ else
230+ {
231+ ptr++;
232+ }
233+ }
234+ if (found_references)
235+ {
236+ printf (" Found reference to label: %s\n " , reference_buffer);
237+ }
238+ }
239+
240+ int main (int argc, char *argv[])
241+ {
242+ if (argc != 2 )
243+ {
244+ fprintf (stderr, " Usage: %s <filename>\n " , argv[0 ]);
245+ return 1 ;
246+ }
247+
248+ #pragma warning(push)
249+ #pragma warning(disable : 4996)
250+ FILE *file = fopen (argv[1 ], " r" );
251+ #pragma warning(pop)
252+
253+ if (!file)
254+ {
255+ perror (" Error opening file!" );
256+ return 1 ;
257+ }
258+
259+ int num_labels = 0 ;
260+ Label labels[MAX_LABELS] = {};
261+ char line[MAX_LINE_LENGTH] = {};
262+
263+ // Сбор всех меток
264+ printf (" Collecting labels:\n " );
265+ while (fgets (line, sizeof (line), file))
266+ {
267+ int label = extract_label (line);
268+
269+ if (label != -1 )
270+ {
271+ labels[num_labels].label = label;
272+ labels[num_labels].is_referenced = 0 ;
273+ printf (" Found label: %d\n " , label);
274+ num_labels++;
275+ }
276+ }
277+
278+ // Поиск ссылок на метки
279+ printf (" \n Finding references to labels:\n " );
280+ fseek (file, 0 , SEEK_SET);
281+ while (fgets (line, sizeof (line), file))
282+ {
283+ add_reference (labels, num_labels, line);
284+ }
285+
286+ fclose (file);
287+
288+ // Печать меток, на которые нет ссылок
289+ printf (" \n Labels with no references:\n " );
290+ for (int i = 0 ; i < num_labels; i++)
291+ {
292+ if (!labels[i].is_referenced )
293+ {
294+ printf (" %d\n " , labels[i].label );
295+ }
296+ }
297+ }
0 commit comments