load.ml 1.9 KB

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