Split off libgedcom.so.
[gedcom-parse.git] / multilex.c
1 /*  This program is free software; you can redistribute it and/or modify  *
2  *  it under the terms of the GNU General Public License as published by  *
3  *  the Free Software Foundation; either version 2 of the License, or     *
4  *  (at your option) any later version.                                   *
5
6  (C) 2001 by The Genes Development Team
7  Original author: Peter Verthez (Peter.Verthez@advalvas.be)
8 */
9
10 /* $Id$ */
11 /* $Name$ */
12
13 #include "gedcom.h"
14 #include "multilex.h"
15 #include "encoding.h"
16
17 int line_no;
18
19 typedef int (*lex_func)(void);
20 lex_func lf;
21
22 int lexer_init(ENCODING enc, FILE* f)
23 {
24   if (enc == ONE_BYTE) {
25     gedcom_1byte_in = f;
26     lf = &gedcom_1byte_lex;
27     set_encoding_width(enc);
28     return open_conv_to_internal("ASCII");
29   }
30   else if (enc == TWO_BYTE_HILO) {
31     gedcom_hilo_in = f;
32     lf = &gedcom_hilo_lex;
33     set_encoding_width(enc);
34     return open_conv_to_internal("UNICODE");
35   }
36   else if (enc == TWO_BYTE_LOHI) {
37     gedcom_lohi_in = f;
38     lf = &gedcom_lohi_lex;
39     set_encoding_width(enc);
40     return open_conv_to_internal("UNICODE");
41   }
42   else {
43     return 0;
44   }
45 }
46
47 void lexer_close()
48 {
49   close_conv_to_internal();
50 }
51
52 int gedcom_lex()
53 {
54   return (*lf)();
55 }
56
57 int determine_encoding(FILE* f)
58 {
59   char first[2];
60
61   fread(first, 1, 2, f);
62   if ((first[0] == '0') && (first[1] == ' ')) {
63     gedcom_message("One-byte encoding");
64     fseek(f, 0, 0);
65     return ONE_BYTE;
66   }
67   else if ((first[0] == '\0') && (first[1] == '0'))
68   {
69     gedcom_message("Two-byte encoding, high-low");
70     fseek(f, 0, 0);
71     return TWO_BYTE_HILO;
72   }
73   else if ((first[0] == '\xFE') && (first[1] == '\xFF'))
74   {
75     gedcom_message("Two-byte encoding, high-low, with BOM");
76     return TWO_BYTE_HILO;
77   }
78   else if ((first[0] == '0') && (first[1] == '\0'))
79   {
80     gedcom_message("Two-byte encoding, low-high");
81     fseek(f, 0, 0);
82     return TWO_BYTE_LOHI;
83   }
84   else if ((first[0] == '\xFF') && (first[1] == '\xFE'))
85   {
86     gedcom_message("Two-byte encoding, low-high, with BOM");
87     return TWO_BYTE_LOHI;
88   }
89   else {
90     gedcom_message("Unknown encoding, falling back to one-byte");
91     fseek(f, 0, 0);
92     return ONE_BYTE;
93   }
94 }
95
96 int gedcom_parse_file(char* file_name)
97 {
98   ENCODING enc;
99   int result = 1;
100   FILE* file = fopen (file_name, "r");
101   line_no = 1;
102   if (!file) {
103     gedcom_error("Could not open file '%s'\n", file_name);
104     return 1;
105   }
106
107   init_encodings();
108   enc = determine_encoding(file);
109   
110   if (lexer_init(enc, file)) {
111     result = gedcom_parse();
112   }
113   lexer_close();
114   fclose(file);
115   
116   return result;
117 }
118