General cleanup.
[gedcom-parse.git] / multilex.c
1 /* $Id$ */
2 /* $Name$ */
3
4 #include "gedcom.h"
5 #include "multilex.h"
6 #include "encoding.h"
7
8 int line_no = 1;
9
10 typedef int (*lex_func)(void);
11 lex_func lf;
12
13 int lexer_init(ENCODING enc, FILE* f)
14 {
15   if (enc == ONE_BYTE) {
16     gedcom_1byte_in = f;
17     lf = &gedcom_1byte_lex;
18     set_encoding_width(enc);
19     return open_conv_to_internal("ASCII");
20   }
21   else if (enc == TWO_BYTE_HILO) {
22     gedcom_hilo_in = f;
23     lf = &gedcom_hilo_lex;
24     set_encoding_width(enc);
25     return open_conv_to_internal("UNICODE");
26   }
27   else if (enc == TWO_BYTE_LOHI) {
28     gedcom_lohi_in = f;
29     lf = &gedcom_lohi_lex;
30     set_encoding_width(enc);
31     return open_conv_to_internal("UNICODE");
32   }
33   else {
34     return 0;
35   }
36 }
37
38 void lexer_close()
39 {
40   close_conv_to_internal();
41 }
42
43 int gedcom_lex()
44 {
45   return (*lf)();
46 }
47
48 int determine_encoding(FILE* f)
49 {
50   char first[2];
51
52   fread(first, 1, 2, f);
53   if ((first[0] == '0') && (first[1] == ' ')) {
54     gedcom_message("One-byte encoding");
55     fseek(f, 0, 0);
56     return ONE_BYTE;
57   }
58   else if ((first[0] == '\0') && (first[1] == '0'))
59   {
60     gedcom_message("Two-byte encoding, high-low");
61     fseek(f, 0, 0);
62     return TWO_BYTE_HILO;
63   }
64   else if ((first[0] == '\xFE') && (first[1] == '\xFF'))
65   {
66     gedcom_message("Two-byte encoding, high-low, with BOM");
67     return TWO_BYTE_HILO;
68   }
69   else if ((first[0] == '0') && (first[1] == '\0'))
70   {
71     gedcom_message("Two-byte encoding, low-high");
72     fseek(f, 0, 0);
73     return TWO_BYTE_LOHI;
74   }
75   else if ((first[0] == '\xFF') && (first[1] == '\xFE'))
76   {
77     gedcom_message("Two-byte encoding, low-high, with BOM");
78     return TWO_BYTE_LOHI;
79   }
80   else {
81     gedcom_message("Unknown encoding, falling back to one-byte");
82     fseek(f, 0, 0);
83     return ONE_BYTE;
84   }
85 }
86
87 int gedcom_parse_file(char* file_name)
88 {
89   ENCODING enc;
90   int result = 1;
91   FILE* file = fopen (file_name, "r");
92   if (!file) {
93     gedcom_error("Could not open file '%s'\n", file_name);
94     return 1;
95   }
96
97   init_encodings();
98   enc = determine_encoding(file);
99   
100   if (lexer_init(enc, file)) {
101     result = gedcom_parse();
102   }
103   lexer_close();
104   
105   return result;
106 }
107