~ubuntu-branches/ubuntu/hardy/pxp/hardy

« back to all changes in this revision

Viewing changes to src/pxp-engine/pxp_lexing.mlp

  • Committer: Bazaar Package Importer
  • Author(s): Stefano Zacchiroli
  • Date: 2005-03-29 11:06:39 UTC
  • mfrom: (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050329110639-5p39hz1d4aq3r2ec
Tags: 1.1.95-6
* Rebuilt against ocaml 3.08.3
* No longer built with wlex support (since wlex is no longer supported
  upstream and corresponding package has been removed from the debian
  archive)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
(* $Id: pxp_lexing.mlp,v 1.4 2002/03/15 16:14:40 gerd Exp $
 
1
(* $Id: pxp_lexing.mlp 662 2004-05-25 20:57:28Z gerd $
2
2
 * ----------------------------------------------------------------------
3
3
 * PXP: The polymorphic XML parser for Objective Caml.
4
4
 * Copyright by Gerd Stolpmann. See LICENSE for details.
5
5
 *)
6
6
 
7
 
(* This is a version of lexing.ml (from stdlib) that can cope with large
8
 
 * tokens.
9
 
 *)
10
 
 
11
 
(* In recent CVS versions of O'Caml the record component lex_buffer_len
12
 
 * has been renamed to lex_buffer_end. 
13
 
 *)
14
 
 
15
7
open Lexing
16
8
 
17
9
type lexbuf = Lexing.lexbuf
18
10
 
19
 
let lex_refill read_fun aux_buffer lexbuf =
20
 
  let read =
21
 
    read_fun aux_buffer (String.length aux_buffer) in
22
 
  let n =
23
 
    if read > 0
24
 
    then read
25
 
    else (lexbuf.lex_eof_reached <- true; 0) in
26
 
  (* Is there enough space at the end of the buffer? *)
27
 
  let space = String.length lexbuf.lex_buffer - lexbuf.LEX_BUFFER_LEN in
28
 
  if space < n then begin
29
 
    (* No *)
30
 
    (* First try to remove the first lex_start_pos bytes of the buffer *)
31
 
    let s = lexbuf.lex_start_pos in
32
 
    let space' = space - s in
33
 
    let efflen = lexbuf.LEX_BUFFER_LEN - s in
34
 
    if space' >= n then begin
35
 
      (* There is enough space at the beginning of the buffer *)
36
 
      String.(*unsafe_*)blit lexbuf.lex_buffer s lexbuf.lex_buffer 0 efflen;
37
 
    end
38
 
    else begin
39
 
      (* Allocate a bigger buffer *)
40
 
      let oldlen = String.length lexbuf.lex_buffer in
41
 
      let newlen = max (oldlen * 2) (n + efflen) in
42
 
      let newlen = 
43
 
        if newlen > Sys.max_string_length && n+efflen <= Sys.max_string_length
44
 
        then Sys.max_string_length
45
 
        else newlen in
46
 
      let newbuf = String.create newlen in
47
 
      String.(*unsafe_*)blit lexbuf.lex_buffer s newbuf 0 efflen;
48
 
      lexbuf.lex_buffer <- newbuf;
49
 
    end;
50
 
    (* Anyway, the first s bytes have been removed. Update the positions. *)
51
 
    lexbuf.lex_abs_pos <- lexbuf.lex_abs_pos + s;
52
 
    lexbuf.lex_curr_pos <- lexbuf.lex_curr_pos - s;
53
 
    lexbuf.lex_start_pos <- 0;
54
 
    lexbuf.lex_last_pos <- lexbuf.lex_last_pos - s;
55
 
    lexbuf.LEX_BUFFER_LEN <- efflen;
56
 
  end;
57
 
  (* There is now enough space at the end of the buffer *)
58
 
  String.unsafe_blit aux_buffer 0
59
 
                     lexbuf.lex_buffer lexbuf.LEX_BUFFER_LEN
60
 
                     n;
61
 
  lexbuf.LEX_BUFFER_LEN <- lexbuf.LEX_BUFFER_LEN + n
62
 
 
63
 
let from_function f =
64
 
  { refill_buff = lex_refill f (String.create 512);
65
 
    lex_buffer = String.create 1024;
66
 
    LEX_BUFFER_LEN = 0;
67
 
    lex_abs_pos = 0;
68
 
    lex_start_pos = 0;
69
 
    lex_curr_pos = 0;
70
 
    lex_last_pos = 0;
71
 
    lex_last_action = 0;
72
 
    lex_eof_reached = false }
73
 
 
74
 
let from_channel ic =
75
 
  from_function (fun buf n -> input ic buf 0 n)
76
 
 
77
 
let from_string s =
78
 
  { refill_buff = (fun lexbuf -> lexbuf.lex_eof_reached <- true);
79
 
    lex_buffer = s ^ "";
80
 
    LEX_BUFFER_LEN = String.length s;
81
 
    lex_abs_pos = 0;
82
 
    lex_start_pos = 0;
83
 
    lex_curr_pos = 0;
84
 
    lex_last_pos = 0;
85
 
    lex_last_action = 0;
86
 
    lex_eof_reached = true }
 
11
(* We are now again using the functions from Lexing. They are ok since
 
12
 * O'Caml 3.05. In O'Caml 3.04 and earlier versions, the Lexing module
 
13
 * had serious performance problems for very large tokens.
 
14
 *
 
15
 * Note that the type of lexbuf has changed between O'Caml 3.06 and 3.07.
 
16
 * (New components lex_mem, lex_start_p, lex_curr_p.)
 
17
 *)
 
18
 
 
19
let from_function = Lexing.from_function
 
20
 
 
21
let from_channel = Lexing.from_channel
 
22
 
 
23
let from_string = Lexing.from_string
87
24
 
88
25
let lexeme = Lexing.lexeme
89
26
let lexeme_char = Lexing.lexeme_char
90
27
let lexeme_start = Lexing.lexeme_start
91
28
let lexeme_end = Lexing.lexeme_end
92
29
 
 
30
let lexeme_len lexbuf = 
 
31
  lexbuf.lex_curr_pos - lexbuf.lex_start_pos
 
32
 
93
33
let from_string_inplace s =
94
34
  (* avoids copying s *)
95
 
  { refill_buff = (fun lexbuf -> lexbuf.lex_eof_reached <- true);
96
 
    lex_buffer = s;   (* instead of s ^ "" *)
97
 
    LEX_BUFFER_LEN = String.length s;
98
 
    lex_abs_pos = 0;
99
 
    lex_start_pos = 0;
100
 
    lex_curr_pos = 0;
101
 
    lex_last_pos = 0;
102
 
    lex_last_action = 0;
103
 
    lex_eof_reached = true }
 
35
  let lb = from_string "" in
 
36
  { lb with
 
37
      lex_buffer = s;
 
38
      lex_buffer_len = String.length s
 
39
  }
104
40
;;
105
41
 
106
42
let from_another_string_inplace lexbuf s =
107
43
  (* uses lexbuf again for another string (avoids memory allocation) *)
108
44
  lexbuf.lex_buffer <- s;
109
 
  lexbuf.LEX_BUFFER_LEN <- String.length s;
 
45
  lexbuf.lex_buffer_len <- String.length s;
110
46
  lexbuf.lex_abs_pos <- 0;
111
47
  lexbuf.lex_start_pos <- 0;
112
48
  lexbuf.lex_curr_pos <- 0;
113
49
  lexbuf.lex_last_pos <- 0;
114
50
  lexbuf.lex_last_action <- 0;
115
 
  lexbuf.lex_eof_reached <- true
 
51
  lexbuf.lex_eof_reached <- true;
 
52
IFDEF LEXBUF_307
 
53
  let zero_pos = {
 
54
    pos_fname = "";
 
55
    pos_lnum = 1;
 
56
    pos_bol = 0;
 
57
    pos_cnum = 0;
 
58
  } in
 
59
  lexbuf.lex_mem <- [| |];
 
60
  lexbuf.lex_start_p <- zero_pos;
 
61
  lexbuf.lex_curr_p <- zero_pos
 
62
ENDIF
116
63
;;
117
64
 
118
65
 
119
66
let sub_lexeme lexbuf k l =
120
67
  (* = String.sub (Lexing.lexeme lexbuf) k l *)
 
68
  (* In recent versions of O'Caml (3.06+X), there are already definitions 
 
69
   * of sub_lexeme. These have the same effect, but don't protect against
 
70
   * improper usage.
 
71
   *)
121
72
  let lexeme_len = lexbuf.lex_curr_pos - lexbuf.lex_start_pos in
122
73
  if (k < 0 || k > lexeme_len || l < 0 || k+l > lexeme_len) then
123
74
    invalid_arg "sub_lexeme";
127
78
  s
128
79
;;
129
80
 
130
 
(* ======================================================================
131
 
 * History:
132
 
 * 
133
 
 * $Log: pxp_lexing.mlp,v $
134
 
 * Revision 1.4  2002/03/15 16:14:40  gerd
135
 
 *      Fixed the max_string_length bug.
136
 
 *
137
 
 * Revision 1.3  2002/03/13 22:45:42  gerd
138
 
 *      Improved Pxp_lexing.
139
 
 *
140
 
 * Revision 1.2  2002/03/13 22:26:08  gerd
141
 
 *      Added some functions from Pxp_lexer_types.
142
 
 *
143
 
 * Revision 1.1  2002/02/20 00:24:54  gerd
144
 
 *      Initial revision.
145
 
 *
146
 
 * 
147
 
 *)