Can any one help, whats wrong with the below syntax?

let len = String.length ova in
let slash_pos = Str.search_backward (Str.regexp “/”) ova len in
let n = slash_pos + 1 in
let file_name = Str.string_after ova n in
if (Filename.extension file_name) = “.ova” then
file_name = “”;
let ova = Str.string_before ova slash_pos in

A small tip you can use

```OCaml
some code here
​```

to quote your code.

Concerning your code extract, it looks like you did not paste all the code?

let len = String.length ova in
let slash_pos = Str.search_backward (Str.regexp "/") ova len in
let n = slash_pos + 1 in
let file_name = Str.string_after ova n in
if (Filename.extension file_name) = ".ova" then
file_name = "";
let ova = Str.string_before ova slash_pos in

At least, the last in indicate that the current expression is not finished. Did you mean

let len = String.length ova in
let slash_pos = Str.search_backward (Str.regexp "/") ova len in
let n = slash_pos + 1 in
let file_name = Str.string_after ova n in
if (Filename.extension file_name) = ".ova" then
file_name = "";
let ova = Str.string_before ova slash_pos in
ova

?

yes , i have code further as below

let ova = Str.string_before ova slash_pos in

let top_dir, ova_type =
if is_directory ova then ova, Directory
else (
let tmpdir =
let base_dir = (open_guestfs ())#get_cachedir () in
let t = Mkdtemp.temp_dir ~base_dir “ova.” in
rmdir_on_exit t;
t in

  match detect_file_type ova with
  | `Tar ->
     (* Normal ovas are tar file (not compressed). *)

     (* In newer QEMU we don't have to extract everything.
      * We can access disks inside the tar archive directly.
      *)

…(further more)

Its bit a big file, I had added

let len = String.length ova in
let slash_pos = Str.search_backward (Str.regexp “/”) ova len in
let n = slash_pos + 1 in
let file_name = Str.string_after ova n in
let ova = Str.string_before ova slash_pos in
and file_name at place required it worked fine, but introducing this if condition in bewteen gives me syntax error

if (Filename.extension file_name) = “.ova” then
file_name = “”;

tried many ways, not sure y.

If it is a a big file, you can link it on https://sketch.sh . You should try to give a full self-contained example that reproduce your error. Otherwise, it is bit hard to guess which error you ended up with.

this bit looks wrong

if (Filename.extension file_name) = ".ova" then
file_name = "";

if cond then foo; bla is the same as (if cond then foo); bla
in if cond then foo without an else branch foo must have type unit
file_name = "" compares file_name with the empty string, so it has type bool and thus you have a type (not syntax) error

If you want to conditionally set file_name do let file_name = if ... then "" else file_name in ....

I’m taking file_name from

let file_name = Str.string_after ova n in

so this will return me xyz.ovf but i want to set file_name to " " if it ends with .ova

let file_name = Str.string_after ova n in
if (Filename.extension file_name) = “.ova” then
file_name = “”

else file_name should remain whatever it gets from this
let file_name = Str.string_after ova n

hence i didnt add else part

The problem is that the = sign is not used in ocaml for assignment, but for equality comparison, so in essence, your “then” branch compares file_name to "", and then discards the result, leaving file_name unchanged, which is probably not what you expect.
This is related to the fact that variables introduced by a let-bindings are always immutable, so if you do let file_name = "something" in ... you cannot change the value of file_name. From there, you have two solutions:

  • Introduce another let-binding to shadow the first one, such as
let file_name = Str.string_after ova n in  
let file_name = if (Filename.extension file_name) = ".ova" then "" else file_name in
...

which is the same as

let file_name = Str.string_after ova n in  
let file_name' = if (Filename.extension file_name) = ".ova" then "" else file_name in
...
  • Use a reference to have a mutable string which you can change in some branches and not others:
let file_name = ref (Str.string_after ova n) in (* create a **mutable** string whose contents can be changed *)
if (Filename.extension file_name) = ".ova" then file_name := ""; (* notice the ':=' which is an assignement of some value to a reference *)
...
1 Like

file_name = “”

this is comparison, not assignation

Gaëtan Gilbert

I tried with last code option using reference, but it says : Error: This expression has type string ref
but an expression was expected of type string

Right, so, when you use a reference, such as let file_name = ref (something..) in ..., then file_name has type string ref instead of string. So in order to access the contents of the string, you need to use the ! operator, which has type 'a ref -> 'a. So instead of using file_name, when you need the value, you have to write !file_name.

Thank you very much. that worked.