From d19187a0729217cdd2f3e2aa6b06079290d933c9 Mon Sep 17 00:00:00 2001 From: John Whitington Date: Tue, 1 Dec 2020 17:40:50 +0000 Subject: [PATCH] Posix implementation of non-Unix date getter --- cpdf.ml | 18 ++++---- cpdfmanual.pdf | Bin 240202 -> 240204 bytes cpdfmanual.tex | 4 +- cpdfstrftime.ml | 108 ++++++++++++++++++++++++++++++++++++++++------- cpdfstrftime.mli | 19 ++++++++- cpdftime.c | 62 --------------------------- 6 files changed, 120 insertions(+), 91 deletions(-) delete mode 100644 cpdftime.c diff --git a/cpdf.ml b/cpdf.ml index 457051f..ca0cdb1 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -3703,15 +3703,15 @@ let make_xmp_date_from_components d = Printf.sprintf "%02i" d.offset_minutes in Cpdfstrftime.strftime - ~time:{Unix.tm_sec = d.second; - Unix.tm_min = d.minute; - Unix.tm_hour = d.hour; - Unix.tm_mday = d.day; - Unix.tm_mon = d.month - 1; - Unix.tm_year = d.year - 1900; - Unix.tm_wday = 0; - Unix.tm_yday = 0; - Unix.tm_isdst = false} + ~time:{Cpdfstrftime._tm_sec = d.second; + Cpdfstrftime._tm_min = d.minute; + Cpdfstrftime._tm_hour = d.hour; + Cpdfstrftime._tm_mday = d.day; + Cpdfstrftime._tm_mon = d.month - 1; + Cpdfstrftime._tm_year = d.year - 1900; + Cpdfstrftime._tm_wday = 0; + Cpdfstrftime._tm_yday = 0; + Cpdfstrftime._tm_isdst = false} "%Y-%m-%dT%H:%M:%S" ^ tzd diff --git a/cpdfmanual.pdf b/cpdfmanual.pdf index cc62eb332296992ddc4779b0038994ee5bc1e9c6..092571192a5f92d4fa3a79753f121658c2e932f5 100644 GIT binary patch delta 3231 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
OM&> zxeAzKgFkPaUbGVV4%1(m9LOw!k(Cbe%|~Ne5WztP7odk=d$S!P5J9moEUt1vKnqTk zM1~x+G$0#TR(@gGw3Q*0Jhw8n5~}2e0q}sz7yk%IPTd zbK@8(=xNBZ(Z4U{kw0hJa3{W#DlgTnTQ "Sunday" | 1 -> "Monday" | 2 -> "Tuesday" | 3 -> "Wednesday" | 4 -> "Thursday" | 5 -> "Friday" | 6 -> "Saturday" @@ -12,7 +34,7 @@ let strf_a t = String.sub (strf_A t) 0 3 let strf_B t = - match t.Unix.tm_mon with + match t._tm_mon with | 0 -> "January" | 1 -> "February" | 2 -> "March" | 3 -> "April" | 4 -> "May" | 5 -> "June" | 6 -> "July" | 7 -> "August" | 8 -> "September" | 9 -> "October" | 10 -> "November" @@ -22,56 +44,56 @@ let strf_b t = String.sub (strf_B t) 0 3 let strf_d t = - let s = string_of_int t.Unix.tm_mday in + let s = string_of_int t._tm_mday in if String.length s = 1 then "0" ^ s else s let strf_e t = - let s = string_of_int t.Unix.tm_mday in + let s = string_of_int t._tm_mday in if String.length s = 1 then " " ^ s else s let strf_H t = - let s = string_of_int t.Unix.tm_hour in + let s = string_of_int t._tm_hour in if String.length s = 1 then "0" ^ s else s let strf_I t = - let s = string_of_int (t.Unix.tm_hour mod 12) in + let s = string_of_int (t._tm_hour mod 12) in if String.length s = 1 then "0" ^ s else s let strf_j t = - let s = string_of_int t.Unix.tm_yday in + let s = string_of_int t._tm_yday in match String.length s with | 1 -> "00" ^ s | 2 -> "0" ^ s | _ -> s let strf_m t = - let s = string_of_int (t.Unix.tm_mon + 1) in + let s = string_of_int (t._tm_mon + 1) in if String.length s = 1 then "0" ^ s else s let strf_M t = - let s = string_of_int t.Unix.tm_min in + let s = string_of_int t._tm_min in if String.length s = 1 then "0" ^ s else s let strf_p t = - if t.Unix.tm_hour >= 12 then "p.m" else "a.m" + if t._tm_hour >= 12 then "p.m" else "a.m" let strf_S t = - let s = string_of_int t.Unix.tm_sec in + let s = string_of_int t._tm_sec in if String.length s = 1 then "0" ^ s else s let strf_T t = strf_H t ^ ":" ^ strf_M t ^ ":" ^ strf_S t let strf_u t = - match t.Unix.tm_wday with + match t._tm_wday with | 0 -> "7" | n -> string_of_int (n + 1) let strf_w t = - string_of_int t.Unix.tm_wday + string_of_int t._tm_wday let strf_Y t = - string_of_int (t.Unix.tm_year + 1900) + string_of_int (t._tm_year + 1900) let strf_percent _ = "%" @@ -82,9 +104,64 @@ let strftime_pairs = "%p", strf_p; "%S", strf_S; "%T", strf_T; "%u", strf_u; "%w", strf_w; "%Y", strf_Y; "%%", strf_percent] +(* On Posix, call out to 'date'. On Windows, read %DATE% and %TIME% with 'cmd + * /C echo %TIME%'. On failure, exception escapes to caller. *) +let contents_of_file filename = + let ch = open_in_bin filename in + let s = really_input_string ch (in_channel_length ch) in + close_in ch; + s + +let return_date () = + match Sys.os_type with + "Unix" -> + (* Call the POSIX 'date' program, redirected to a temp file, and parse. *) + let tempfile = Filename.temp_file "cpdf" "strftime" in + let command = Filename.quote_command "date" ~stdout:tempfile ["+%S-%M-%H-%d-%m-%Y-%w-%j"] in + let outcode = Sys.command command in + if outcode > 0 then raise (Failure "Date command returned non-zero exit code") else + let r = contents_of_file tempfile in + let get_int o l = int_of_string (String.sub r o l) in + Sys.remove tempfile; + {_tm_sec = get_int 0 2; + _tm_min = get_int 3 2; + _tm_hour = get_int 6 2; + _tm_mday = get_int 9 2; + _tm_mon = get_int 12 2 - 1; + _tm_year = get_int 15 4 - 1900; + _tm_wday = get_int 20 1; + _tm_yday = get_int 22 3 - 1; + _tm_isdst = false} + | _ -> + (* Run 'cmd /C echo %TIME%' and 'cmd /C echo %DATE%' *) + {_tm_sec = 0; + _tm_min = 0; + _tm_hour = 0; + _tm_mday = 1; + _tm_mon = 0; + _tm_year = 0; + _tm_wday = 0; + _tm_yday = 0; + _tm_isdst = false} + +let current_time () = + (*t_of_unix (Unix.localtime (Unix.gettimeofday ()))*) + try return_date () with + e -> + Printf.eprintf "Failed to retrieve time due to %s\n" (Printexc.to_string e); + {_tm_sec = 0; + _tm_min = 0; + _tm_hour = 0; + _tm_mday = 1; + _tm_mon = 0; + _tm_year = 0; + _tm_wday = 0; + _tm_yday = 0; + _tm_isdst = false} + let strftime ?time text = let time = - match time with None -> Unix.localtime (Unix.gettimeofday ()) | Some t -> t + match time with None -> current_time () | Some t -> t in let text = ref text in iter @@ -92,4 +169,3 @@ let strftime ?time text = text := string_replace_all search (replace_fun time) !text) strftime_pairs; !text - diff --git a/cpdfstrftime.mli b/cpdfstrftime.mli index aa6c86e..09dfd36 100644 --- a/cpdfstrftime.mli +++ b/cpdfstrftime.mli @@ -1,4 +1,19 @@ (** C-style strftime *) -(** This supports the following format specifiers: %a %A %b %B %s %e %H %I %j %m %M %p %S %T %u %w %Y %% *) -val strftime : ?time:Unix.tm -> string -> string +(** Supports the following format specifiers: + %a %A %b %B %s %e %H %I %j %m %M %p %S %T %u %w %Y %% *) + +(** Our version of Unix's tm, so Unix not required *) +type t = + {_tm_sec : int; + _tm_min : int; + _tm_hour : int; + _tm_mday : int; + _tm_mon : int; + _tm_year : int; + _tm_wday : int; + _tm_yday : int; + _tm_isdst : bool} + +(** If time omitted, the current time is used. *) +val strftime : ?time:t -> string -> string diff --git a/cpdftime.c b/cpdftime.c deleted file mode 100644 index e2adf0b..0000000 --- a/cpdftime.c +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************/ -/* */ -/* OCaml */ -/* */ -/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ -/* */ -/* Copyright 1996 Institut National de Recherche en Informatique et */ -/* en Automatique. */ -/* */ -/* All rights reserved. This file is distributed under the terms of */ -/* the GNU Lesser General Public License version 2.1, with the */ -/* special exception on linking described in the file LICENSE. */ -/* */ -/**************************************************************************/ - -/* This is not presently used. We need to bring in the win32unix implementation - * too and have the correct one chosen. Also need to copy across the OCaml - * interface to these functions */ - -#include -#include -#include -#include -#include - -double cpdf_unix_gettimeofday_unboxed(value unit) -{ - struct timeval tp; - gettimeofday(&tp, NULL); - return ((double) tp.tv_sec + (double) tp.tv_usec / 1e6); -} - -CAMLprim value cpdf_unix_gettimeofday(value unit) -{ - return caml_copy_double(cpdf_unix_gettimeofday_unboxed(unit)); -} - -static value cpdf_alloc_tm(struct tm *tm) -{ - value res; - res = caml_alloc_small(9, 0); - Field(res,0) = Val_int(tm->tm_sec); - Field(res,1) = Val_int(tm->tm_min); - Field(res,2) = Val_int(tm->tm_hour); - Field(res,3) = Val_int(tm->tm_mday); - Field(res,4) = Val_int(tm->tm_mon); - Field(res,5) = Val_int(tm->tm_year); - Field(res,6) = Val_int(tm->tm_wday); - Field(res,7) = Val_int(tm->tm_yday); - Field(res,8) = tm->tm_isdst ? Val_true : Val_false; - return res; -} - -CAMLprim value cpdf_unix_localtime(value t) -{ - time_t clock; - struct tm * tm; - clock = (time_t) Double_val(t); - tm = localtime(&clock); - return cpdf_alloc_tm(tm); -} -