885ec30d0291b1f494bc2df2feb182cc5d4cbf4f
[platform/upstream/libxkbcommon.git] / src / xkbcomp / parseutils.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "parseutils.h"
28 #include "path.h"
29
30 ParseCommon *
31 AppendStmt(ParseCommon * to, ParseCommon * append)
32 {
33     ParseCommon *start = to;
34
35     if (append == NULL)
36         return to;
37     while ((to != NULL) && (to->next != NULL))
38     {
39         to = to->next;
40     }
41     if (to)
42     {
43         to->next = append;
44         return start;
45     }
46     return append;
47 }
48
49 ExprDef *
50 ExprCreate(unsigned op, unsigned type)
51 {
52     ExprDef *expr;
53     expr = uTypedAlloc(ExprDef);
54     if (expr)
55     {
56         expr->common.stmtType = StmtExpr;
57         expr->common.next = NULL;
58         expr->op = op;
59         expr->type = type;
60     }
61     else
62     {
63         FATAL("Couldn't allocate expression in parser\n");
64         /* NOTREACHED */
65     }
66     return expr;
67 }
68
69 ExprDef *
70 ExprCreateUnary(unsigned op, unsigned type, ExprDef * child)
71 {
72     ExprDef *expr;
73     expr = uTypedAlloc(ExprDef);
74     if (expr)
75     {
76         expr->common.stmtType = StmtExpr;
77         expr->common.next = NULL;
78         expr->op = op;
79         expr->type = type;
80         expr->value.child = child;
81     }
82     else
83     {
84         FATAL("Couldn't allocate expression in parser\n");
85         /* NOTREACHED */
86     }
87     return expr;
88 }
89
90 ExprDef *
91 ExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
92 {
93     ExprDef *expr;
94     expr = uTypedAlloc(ExprDef);
95     if (expr)
96     {
97         expr->common.stmtType = StmtExpr;
98         expr->common.next = NULL;
99         expr->op = op;
100         if ((op == OpAssign) || (left->type == TypeUnknown))
101             expr->type = right->type;
102         else if ((left->type == right->type) || (right->type == TypeUnknown))
103             expr->type = left->type;
104         else
105             expr->type = TypeUnknown;
106         expr->value.binary.left = left;
107         expr->value.binary.right = right;
108     }
109     else
110     {
111         FATAL("Couldn't allocate expression in parser\n");
112         /* NOTREACHED */
113     }
114     return expr;
115 }
116
117 KeycodeDef *
118 KeycodeCreate(const char *name, unsigned long value)
119 {
120     KeycodeDef *def;
121
122     def = uTypedAlloc(KeycodeDef);
123     if (def)
124     {
125         def->common.stmtType = StmtKeycodeDef;
126         def->common.next = NULL;
127         strncpy(def->name, name, XkbKeyNameLength);
128         def->name[XkbKeyNameLength] = '\0';
129         def->value = value;
130     }
131     else
132     {
133         FATAL("Couldn't allocate key name definition in parser\n");
134         /* NOTREACHED */
135     }
136     return def;
137 }
138
139 KeyAliasDef *
140 KeyAliasCreate(const char *alias, const char *real)
141 {
142     KeyAliasDef *def;
143
144     def = uTypedAlloc(KeyAliasDef);
145     if (def)
146     {
147         def->common.stmtType = StmtKeyAliasDef;
148         def->common.next = NULL;
149         strncpy(def->alias, alias, XkbKeyNameLength);
150         def->alias[XkbKeyNameLength] = '\0';
151         strncpy(def->real, real, XkbKeyNameLength);
152         def->real[XkbKeyNameLength] = '\0';
153     }
154     else
155     {
156         FATAL("Couldn't allocate key alias definition in parser\n");
157         /* NOTREACHED */
158     }
159     return def;
160 }
161
162 VModDef *
163 VModCreate(xkb_atom_t name, ExprDef * value)
164 {
165     VModDef *def;
166     def = uTypedAlloc(VModDef);
167     if (def)
168     {
169         def->common.stmtType = StmtVModDef;
170         def->common.next = NULL;
171         def->name = name;
172         def->value = value;
173     }
174     else
175     {
176         FATAL("Couldn't allocate variable definition in parser\n");
177         /* NOTREACHED */
178     }
179     return def;
180 }
181
182 VarDef *
183 VarCreate(ExprDef * name, ExprDef * value)
184 {
185     VarDef *def;
186     def = uTypedAlloc(VarDef);
187     if (def)
188     {
189         def->common.stmtType = StmtVarDef;
190         def->common.next = NULL;
191         def->name = name;
192         def->value = value;
193     }
194     else
195     {
196         FATAL("Couldn't allocate variable definition in parser\n");
197         /* NOTREACHED */
198     }
199     return def;
200 }
201
202 VarDef *
203 BoolVarCreate(xkb_atom_t nameToken, unsigned set)
204 {
205     ExprDef *name, *value;
206
207     name = ExprCreate(ExprIdent, TypeUnknown);
208     name->value.str = nameToken;
209     value = ExprCreate(ExprValue, TypeBoolean);
210     value->value.uval = set;
211     return VarCreate(name, value);
212 }
213
214 InterpDef *
215 InterpCreate(char *sym, ExprDef * match)
216 {
217     InterpDef *def;
218
219     def = uTypedAlloc(InterpDef);
220     if (def)
221     {
222         def->common.stmtType = StmtInterpDef;
223         def->common.next = NULL;
224         def->sym = sym;
225         def->match = match;
226     }
227     else
228     {
229         FATAL("Couldn't allocate interp definition in parser\n");
230         /* NOTREACHED */
231     }
232     return def;
233 }
234
235 KeyTypeDef *
236 KeyTypeCreate(xkb_atom_t name, VarDef * body)
237 {
238     KeyTypeDef *def;
239
240     def = uTypedAlloc(KeyTypeDef);
241     if (def)
242     {
243         def->common.stmtType = StmtKeyTypeDef;
244         def->common.next = NULL;
245         def->merge = MergeDefault;
246         def->name = name;
247         def->body = body;
248     }
249     else
250     {
251         FATAL("Couldn't allocate key type definition in parser\n");
252         /* NOTREACHED */
253     }
254     return def;
255 }
256
257 SymbolsDef *
258 SymbolsCreate(const char *keyName, ExprDef *symbols)
259 {
260     SymbolsDef *def;
261
262     def = uTypedAlloc(SymbolsDef);
263     if (def)
264     {
265         def->common.stmtType = StmtSymbolsDef;
266         def->common.next = NULL;
267         def->merge = MergeDefault;
268         memset(def->keyName, 0, 5);
269         strncpy(def->keyName, keyName, 4);
270         def->symbols = symbols;
271     }
272     else
273     {
274         FATAL("Couldn't allocate symbols definition in parser\n");
275         /* NOTREACHED */
276     }
277     return def;
278 }
279
280 GroupCompatDef *
281 GroupCompatCreate(int group, ExprDef * val)
282 {
283     GroupCompatDef *def;
284
285     def = uTypedAlloc(GroupCompatDef);
286     if (def)
287     {
288         def->common.stmtType = StmtGroupCompatDef;
289         def->common.next = NULL;
290         def->merge = MergeDefault;
291         def->group = group;
292         def->def = val;
293     }
294     else
295     {
296         FATAL("Couldn't allocate group compat definition in parser\n");
297         /* NOTREACHED */
298     }
299     return def;
300 }
301
302 ModMapDef *
303 ModMapCreate(uint32_t modifier, ExprDef * keys)
304 {
305     ModMapDef *def;
306
307     def = uTypedAlloc(ModMapDef);
308     if (def)
309     {
310         def->common.stmtType = StmtModMapDef;
311         def->common.next = NULL;
312         def->merge = MergeDefault;
313         def->modifier = modifier;
314         def->keys = keys;
315     }
316     else
317     {
318         FATAL("Couldn't allocate mod mask definition in parser\n");
319         /* NOTREACHED */
320     }
321     return def;
322 }
323
324 IndicatorMapDef *
325 IndicatorMapCreate(xkb_atom_t name, VarDef * body)
326 {
327     IndicatorMapDef *def;
328
329     def = uTypedAlloc(IndicatorMapDef);
330     if (def)
331     {
332         def->common.stmtType = StmtIndicatorMapDef;
333         def->common.next = NULL;
334         def->merge = MergeDefault;
335         def->name = name;
336         def->body = body;
337     }
338     else
339     {
340         FATAL("Couldn't allocate indicator map definition in parser\n");
341         /* NOTREACHED */
342     }
343     return def;
344 }
345
346 IndicatorNameDef *
347 IndicatorNameCreate(int ndx, ExprDef * name, bool virtual)
348 {
349     IndicatorNameDef *def;
350
351     def = uTypedAlloc(IndicatorNameDef);
352     if (def)
353     {
354         def->common.stmtType = StmtIndicatorNameDef;
355         def->common.next = NULL;
356         def->merge = MergeDefault;
357         def->ndx = ndx;
358         def->name = name;
359         def->virtual = virtual;
360     }
361     else
362     {
363         FATAL("Couldn't allocate indicator index definition in parser\n");
364         /* NOTREACHED */
365     }
366     return def;
367 }
368
369 ExprDef *
370 ActionCreate(xkb_atom_t name, ExprDef * args)
371 {
372     ExprDef *act;
373
374     act = uTypedAlloc(ExprDef);
375     if (act)
376     {
377         act->common.stmtType = StmtExpr;
378         act->common.next = NULL;
379         act->op = ExprActionDecl;
380         act->value.action.name = name;
381         act->value.action.args = args;
382         return act;
383     }
384     FATAL("Couldn't allocate ActionDef in parser\n");
385     return NULL;
386 }
387
388 static bool
389 ResizeKeysymList(ExprDef *list, unsigned int extra)
390 {
391     int i;
392
393     if (list->value.list.nSyms + extra > list->value.list.szSyms)
394     {
395         list->value.list.szSyms *= 2;
396         list->value.list.szSyms += extra;
397         if (list->value.list.szSyms == 1)
398             list->value.list.szSyms = 4;
399         list->value.list.syms = uTypedRecalloc(list->value.list.syms,
400                                                list->value.list.nSyms,
401                                                list->value.list.szSyms,
402                                                char *);
403         if (list->value.list.syms == NULL)
404         {
405             FATAL("Couldn't resize list of symbols for append\n");
406             return false;
407         }
408     }
409     if (list->value.list.nLevels >= list->value.list.szLevels)
410     {
411         list->value.list.szLevels *= 2;
412         if (list->value.list.szLevels == 0)
413             list->value.list.szLevels = 4;
414         list->value.list.symsMapIndex =
415             uTypedRecalloc(list->value.list.symsMapIndex,
416                            list->value.list.nLevels,
417                            list->value.list.szLevels,
418                            int);
419         if (list->value.list.symsMapIndex == NULL)
420         {
421             FATAL("Couldn't resize keysym index map for append\n");
422             return false;
423         }
424         list->value.list.symsNumEntries =
425             uTypedRecalloc(list->value.list.symsNumEntries,
426                            list->value.list.nLevels,
427                            list->value.list.szLevels,
428                            unsigned int);
429         if (list->value.list.symsNumEntries == NULL)
430         {
431             FATAL("Couldn't resize num keysym entries for append\n");
432             return false;
433         }
434         for (i = list->value.list.nLevels; i < list->value.list.szLevels; i++)
435             list->value.list.symsMapIndex[i] = -1;
436     }
437
438     return true;
439 }
440
441 ExprDef *
442 CreateKeysymList(char *sym)
443 {
444     ExprDef *def;
445
446     def = ExprCreate(ExprKeysymList, TypeSymbols);
447     if (!def)
448     {
449         FATAL("Couldn't allocate expression for keysym list in parser\n");
450         return NULL;
451     }
452
453     def->value.list.nSyms = 0;
454     def->value.list.szSyms = 0;
455     def->value.list.nLevels = 0;
456     def->value.list.szLevels = 0;
457     def->value.list.syms = NULL;
458     def->value.list.symsMapIndex = NULL;
459     def->value.list.symsNumEntries = NULL;
460
461     if (!ResizeKeysymList(def, 1))
462     {
463         FreeStmt(&def->common);
464         return NULL;
465     }
466
467     def->value.list.syms[0] = sym;
468     def->value.list.symsMapIndex[0] = 0;
469     def->value.list.symsNumEntries[0] = 1;
470     def->value.list.nLevels = 1;
471     def->value.list.nSyms = 1;
472
473     return def;
474 }
475
476 ExprDef *
477 CreateMultiKeysymList(ExprDef *list)
478 {
479     int i;
480
481     for (i = 1; i < list->value.list.szLevels; i++)
482     {
483         list->value.list.symsMapIndex[i] = -1;
484         list->value.list.symsNumEntries[i] = 0;
485     }
486     list->value.list.symsMapIndex[0] = 0;
487     list->value.list.symsNumEntries[0] = list->value.list.nLevels;
488     list->value.list.nLevels = 1;
489
490     return list;
491 }
492
493 ExprDef *
494 AppendKeysymList(ExprDef * list, char *sym)
495 {
496     if (!ResizeKeysymList(list, 1))
497         return NULL;
498
499     list->value.list.symsMapIndex[list->value.list.nLevels] =
500         list->value.list.nSyms;
501     list->value.list.symsNumEntries[list->value.list.nLevels] = 1;
502     list->value.list.syms[list->value.list.nSyms++] = sym;
503     list->value.list.nLevels++;
504     return list;
505 }
506
507 ExprDef *
508 AppendMultiKeysymList(ExprDef * list, ExprDef * append)
509 {
510     int i;
511
512     if (!ResizeKeysymList(list, append->value.list.nSyms))
513         return NULL;
514
515     list->value.list.symsMapIndex[list->value.list.nLevels] =
516         list->value.list.nSyms;
517     list->value.list.symsNumEntries[list->value.list.nLevels] =
518         append->value.list.nSyms;
519     for (i = 0; i < append->value.list.nSyms; i++) {
520         list->value.list.syms[list->value.list.nSyms++] =
521             append->value.list.syms[i];
522         append->value.list.syms[i] = NULL;
523     }
524     list->value.list.nLevels++;
525
526     FreeStmt(&append->common);
527
528     return list;
529 }
530
531 int
532 LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
533 {
534     xkb_keysym_t sym;
535
536     if ((!str) || (strcasecmp(str, "any") == 0) ||
537         (strcasecmp(str, "nosymbol") == 0))
538     {
539         *sym_rtrn = XKB_KEY_NoSymbol;
540         return 1;
541     }
542     else if ((strcasecmp(str, "none") == 0) ||
543              (strcasecmp(str, "voidsymbol") == 0))
544     {
545         *sym_rtrn = XKB_KEY_VoidSymbol;
546         return 1;
547     }
548     sym = xkb_keysym_from_name(str);
549     if (sym != XKB_KEY_NoSymbol)
550     {
551         *sym_rtrn = sym;
552         return 1;
553     }
554     return 0;
555 }
556
557 static void
558 FreeInclude(IncludeStmt *incl);
559
560 IncludeStmt *
561 IncludeCreate(char *str, unsigned merge)
562 {
563     IncludeStmt *incl, *first;
564     char *file, *map, *stmt, *tmp, *extra_data;
565     char nextop;
566     bool haveSelf;
567
568     haveSelf = false;
569     incl = first = NULL;
570     file = map = NULL;
571     tmp = str;
572     stmt = uDupString(str);
573     while ((tmp) && (*tmp))
574     {
575         if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
576         {
577             if ((file == NULL) && (map == NULL))
578             {
579                 if (haveSelf)
580                     goto BAIL;
581                 haveSelf = true;
582             }
583             if (first == NULL)
584                 first = incl = uTypedAlloc(IncludeStmt);
585             else
586             {
587                 incl->next = uTypedAlloc(IncludeStmt);
588                 incl = incl->next;
589             }
590             if (incl)
591             {
592                 incl->common.stmtType = StmtInclude;
593                 incl->common.next = NULL;
594                 incl->merge = merge;
595                 incl->stmt = NULL;
596                 incl->file = file;
597                 incl->map = map;
598                 incl->modifier = extra_data;
599                 incl->path = NULL;
600                 incl->next = NULL;
601             }
602             else
603             {
604                 WSGO("Allocation failure in IncludeCreate\n");
605                 ACTION("Using only part of the include\n");
606                 break;
607             }
608             if (nextop == '|')
609                 merge = MergeAugment;
610             else
611                 merge = MergeOverride;
612         }
613         else
614         {
615             goto BAIL;
616         }
617     }
618     if (first)
619         first->stmt = stmt;
620     else
621         free(stmt);
622     return first;
623
624 BAIL:
625     ERROR("Illegal include statement \"%s\"\n", stmt);
626     ACTION("Ignored\n");
627     FreeInclude(first);
628     free(stmt);
629     return NULL;
630 }
631
632 void
633 CheckDefaultMap(XkbFile * maps, const char *fileName)
634 {
635     XkbFile *dflt, *tmp;
636
637     dflt = NULL;
638     for (tmp = maps, dflt = NULL; tmp != NULL;
639          tmp = (XkbFile *) tmp->common.next)
640     {
641         if (tmp->flags & XkbLC_Default)
642         {
643             if (dflt == NULL)
644                 dflt = tmp;
645             else
646             {
647                 if (warningLevel > 2)
648                 {
649                     WARN("Multiple default components in %s\n",
650                           (fileName ? fileName : "(unknown)"));
651                     ACTION("Using %s, ignoring %s\n",
652                             (dflt->name ? dflt->name : "(first)"),
653                             (tmp->name ? tmp->name : "(subsequent)"));
654                 }
655                 tmp->flags &= (~XkbLC_Default);
656             }
657         }
658     }
659 }
660
661 /*
662  * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
663  * wildcards.
664  */
665 static const unsigned char componentSpecLegal[] = {
666     0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
667     0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
668     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669     0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
670 };
671
672 static void
673 EnsureSafeMapName(char *name)
674 {
675     if (!name)
676         return;
677
678     while (*name!='\0') {
679         if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
680             *name= '_';
681         name++;
682     }
683 }
684
685 XkbFile *
686 CreateXKBFile(struct xkb_context *ctx, int type, char *name,
687               ParseCommon *defs, unsigned flags)
688 {
689     XkbFile *file;
690
691     file = uTypedAlloc(XkbFile);
692     if (file)
693     {
694         EnsureSafeMapName(name);
695         memset(file, 0, sizeof(XkbFile));
696         file->type = type;
697         file->topName = uDupString(name);
698         file->name = name;
699         file->defs = defs;
700         file->id = xkb_context_take_file_id(ctx);
701         file->flags = flags;
702     }
703     return file;
704 }
705
706 unsigned
707 StmtSetMerge(ParseCommon * stmt, unsigned merge, struct YYLTYPE *loc, void *scanner)
708 {
709     if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
710     {
711         yyerror(loc, scanner, "illegal use of 'alternate' merge mode");
712         merge = MergeDefault;
713     }
714     return merge;
715 }
716
717 static void
718 FreeExpr(ExprDef *expr)
719 {
720     int i;
721
722     if (!expr)
723         return;
724
725     switch (expr->op)
726     {
727     case ExprActionList:
728     case OpNegate:
729     case OpUnaryPlus:
730     case OpNot:
731     case OpInvert:
732         FreeStmt(&expr->value.child->common);
733         break;
734     case OpDivide:
735     case OpAdd:
736     case OpSubtract:
737     case OpMultiply:
738     case OpAssign:
739         FreeStmt(&expr->value.binary.left->common);
740         FreeStmt(&expr->value.binary.right->common);
741         break;
742     case ExprActionDecl:
743         FreeStmt(&expr->value.action.args->common);
744         break;
745     case ExprArrayRef:
746         FreeStmt(&expr->value.array.entry->common);
747         break;
748     case ExprKeysymList:
749         for (i = 0; i < expr->value.list.nSyms; i++)
750             free(expr->value.list.syms[i]);
751         free(expr->value.list.syms);
752         free(expr->value.list.symsMapIndex);
753         free(expr->value.list.symsNumEntries);
754         break;
755     default:
756         break;
757     }
758 }
759
760 static void
761 FreeInclude(IncludeStmt *incl)
762 {
763     IncludeStmt *next;
764
765     while (incl)
766     {
767         next = incl->next;
768
769         free(incl->file);
770         free(incl->map);
771         free(incl->modifier);
772         free(incl->path);
773         free(incl->stmt);
774
775         free(incl);
776         incl = next;
777     }
778 }
779
780 void
781 FreeStmt(ParseCommon *stmt)
782 {
783     ParseCommon *next;
784     YYSTYPE u;
785
786     while (stmt)
787     {
788         next = stmt->next;
789         u.any = stmt;
790
791         switch (stmt->stmtType)
792         {
793         case StmtInclude:
794             FreeInclude((IncludeStmt *)stmt);
795             /* stmt is already free'd here. */
796             stmt = NULL;
797             break;
798         case StmtExpr:
799             FreeExpr(u.expr);
800             break;
801         case StmtVarDef:
802             FreeStmt(&u.var->name->common);
803             FreeStmt(&u.var->value->common);
804             break;
805         case StmtKeyTypeDef:
806             FreeStmt(&u.keyType->body->common);
807             break;
808         case StmtInterpDef:
809             free(u.interp->sym);
810             FreeStmt(&u.interp->match->common);
811             FreeStmt(&u.interp->def->common);
812             break;
813         case StmtVModDef:
814             FreeStmt(&u.vmod->value->common);
815             break;
816         case StmtSymbolsDef:
817             FreeStmt(&u.syms->symbols->common);
818             break;
819         case StmtModMapDef:
820             FreeStmt(&u.modMask->keys->common);
821             break;
822         case StmtGroupCompatDef:
823             FreeStmt(&u.groupCompat->def->common);
824             break;
825         case StmtIndicatorMapDef:
826             FreeStmt(&u.ledMap->body->common);
827             break;
828         case StmtIndicatorNameDef:
829             FreeStmt(&u.ledName->name->common);
830             break;
831         default:
832             break;
833         }
834
835         free(stmt);
836         stmt = next;
837     }
838 }
839
840 void
841 FreeXKBFile(XkbFile *file)
842 {
843     XkbFile *next;
844
845     while (file)
846     {
847         next = (XkbFile *)file->common.next;
848
849         switch (file->type)
850         {
851         case XkmKeymapFile:
852             FreeXKBFile((XkbFile *)file->defs);
853             break;
854         case XkmTypesIndex:
855         case XkmCompatMapIndex:
856         case XkmSymbolsIndex:
857         case XkmKeyNamesIndex:
858         case XkmGeometryIndex:
859             FreeStmt(file->defs);
860             break;
861         }
862
863         free(file->name);
864         free(file->topName);
865         free(file);
866         file = next;
867     }
868 }