generator: Refactor code for Perl bindings.
[libguestfs.git] / tools / virt-df
index 71658f7..d9ef8f9 100755 (executable)
@@ -473,6 +473,7 @@ sub print_title
         printf "%-36s%10s %10s %10s %5s\n",
           $cols[1], $cols[2], $cols[3], $cols[4], $cols[5];
     } else {
+        # Columns don't need special CSV quoting.
         print (join (",", @cols), "\n");
     }
 }
@@ -491,7 +492,11 @@ sub print_cols
 
         printf ("%10s %10s %10s %5s\n", $_[2], $_[3], $_[4], $percent);
     } else {
-        printf ("\"%s\",\"%s\",%d,%d,%d,%.1f%%\n", @_);
+        # Need to quote libvirt domain and filesystem.
+        my $dom = shift;
+        my $fs = shift;
+        print csv_quote($dom), ",", csv_quote($fs), ",";
+        printf ("%d,%d,%d,%.1f%%\n", @_);
     }
 }
 
@@ -509,6 +514,31 @@ sub human_size
     }
 }
 
+# Quote field for CSV without using an external module.
+sub csv_quote
+{
+    local $_ = shift;
+
+    my $needs_quoting = /[ ",\n\0]/;
+    return $_ unless $needs_quoting;
+
+    my $i;
+    my $out = '"';
+    for ($i = 0; $i < length; ++$i) {
+        my $c = substr $_, $i, 1;
+        if ($c eq '"') {
+            $out .= '""';
+        } elsif ($c eq '\0') {
+            $out .= '"0';
+        } else {
+            $out .= $c;
+        }
+    }
+    $out .= '"';
+
+    return $out;
+}
+
 =head1 NOTE ABOUT CSV FORMAT
 
 Comma-separated values (CSV) is a deceptive format.  It I<seems> like
@@ -533,6 +563,13 @@ for Perl or Python's built-in csv library).
 
 Most spreadsheets and databases can import CSV directly.
 
+=head1 SHELL QUOTING
+
+Libvirt guest names can contain arbitrary characters, some of which
+have meaning to the shell such as C<#> and space.  You may need to
+quote or escape these characters on the command line.  See the shell
+manual page L<sh(1)> for details.
+
 =head1 SEE ALSO
 
 L<guestfs(3)>,