load.ml 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. open Types
  2. open Util
  3. (* Unix command to call for C preprocessor:
  4. * -nostdinc : Don't include from C stdlib
  5. * -C : Don't remove comments
  6. * -traditional-cpp : Don't remove excessive whitespaces, so that error
  7. * messages preserve correct character locations
  8. * -I : Add working dir and executable dir to include dirs *)
  9. let cpp_cmd = "cpp -nostdinc -C -traditional-cpp \
  10. -I" ^ Sys.getcwd () ^ " \
  11. -I" ^ (Filename.dirname Sys.executable_name)
  12. let input_all ic =
  13. let n = in_channel_length ic in
  14. let buf = String.create n in
  15. really_input ic buf 0 n;
  16. close_in ic;
  17. buf
  18. let input_buffered ic chunksize =
  19. let rec read_all buf bufsize pos =
  20. match input ic buf pos (bufsize - pos) with
  21. | 0 -> (close_in ic; buf)
  22. | nread when nread = bufsize - pos ->
  23. let bufsize = bufsize + chunksize in
  24. let pos = pos + nread in
  25. read_all (buf ^ String.create chunksize) bufsize pos
  26. | nread ->
  27. read_all buf bufsize (pos + nread)
  28. in
  29. read_all (String.create chunksize) chunksize 0
  30. let phase = function
  31. | Empty ->
  32. let display_name =
  33. match Globals.args.infile with
  34. | Some filename -> filename
  35. | None -> "<stdin>"
  36. in
  37. let bufsize = 512 in
  38. if Globals.args.cpp then
  39. let cpp_out =
  40. match Globals.args.infile with
  41. | Some filename ->
  42. Unix.open_process_in (cpp_cmd ^ " " ^ filename)
  43. | None ->
  44. let content = input_buffered stdin bufsize in
  45. let cpp_out, cpp_in = Unix.open_process cpp_cmd in
  46. output_string cpp_in content;
  47. close_out cpp_in;
  48. cpp_out
  49. in
  50. log_line 2 "Run C preprocessor";
  51. (* Read preprocessed code from cpp's stdout *)
  52. let preprocessed = input_buffered cpp_out bufsize in
  53. FileContent (display_name, preprocessed)
  54. else
  55. let content =
  56. match Globals.args.infile with
  57. | Some filename -> input_all (open_in filename)
  58. | None -> input_buffered stdin bufsize
  59. in
  60. FileContent (display_name, content)
  61. | _ -> raise InvalidInput