Changing directory with perl's TokeParser - html

How can I change the directory TokeParser looks when opening a file for parsing (e.g. adding a directory before $htmlFileName)?
my $p = HTML::TokeParser->new($htmlFileName);

To change the directory in Perl :
chdir($dir);
perldoc said :
chdir EXPR
chdir FILEHANDLE
chdir DIRHANDLE
chdir Changes the working directory to EXPR, if possible. If EXPR is omitted, changes to the directory specified by $ENV{HOME}, if set; if not, changes to the directory specified by
$ENV{LOGDIR}. (Under VMS, the variable $ENV{SYS$LOGIN} is also checked, and used if it is set.) If neither is set, "chdir" does nothing. It returns true on success, false
otherwise. See the example under "die".
On systems that support fchdir(2), you may pass a filehandle or directory handle as the argument. On systems that don't support fchdir(2), passing handles raises an exception.
NOTE
another solution is to put the full path in $htmlFileName

my $p = HTML::TokeParser->new("/foo/bar/$htmlFileName")
or die $!;

Related

How to get value of variable from open file

I am working on TCL script that will open another tcl file and I want to get value of variable from second opened file and use it in the first file.
Two file abc.tcl and xyz.tcl
abc.tcl opens file xyz.tcl and reads value of variable and use it in abc.tcl.
If xyz.tcl sets a global variable, abc.tcl will be able to see it if it used source to load in xyz.tcl.
Here's a simple example. This is xyz.tcl:
set SomeVariable 12345
This is abc.tcl:
source xyz.tcl
puts "The password on my luggage is $SomeVariable"
The source command is really very simple internally. It just reads in the contents of the file (into a string), and then internally evals that string. Yes, this means that you probably shouldn't put source inside a procedure, at least not unless you're sure what the consequences of this are.

PhpStorm navigate to file by string value

I have a variable with file path like:
$file = '/some/file.txt';
or
var file = '/some/file.txt'
To edit file.txt I:
Left click on string.
Do Extend Selection shortcut.
Do Navigate File... shortcut.
Can I do it faster? For example, by clicking on '/some/file.txt' with some modifier key.
Install and use Navigate From Literal plugin -- it works with any strings as it matches files by names.
It's not 100% perfect though .. as it seems to work rather with file names and even though the path in string is pretty unique .. it most likely will show a choice for all files named the same (e.g. file.txt in your case) -- at least this is what I remember when using it.

How to copy multiple files with Tcl file command

From Tcl online manual I see that Tcl's file copy command can take multiple source files as argument:
file copy ?-force? ?--? source ?source ...? targetDir
However, I have the following code:
set flist [list a.txt b.txt]
file copy $flist [file join D:\\ test dest]
And get this error message:
error copying "a.txt b.txt": no such file or directory
How do I properly pass a file list as source argument to the file copy command?
The right way to do this is to use expansion:
file copy {*}$flist {D:\test\dest}
The {*} substitutes the words of the list given by what follows it as separate words; it's precisely right here.
I've also written the destination directory as a brace-quoted literal.
Still on Tcl 8.4 or before? Upgrade! Or use this:
eval file copy $flist [list {D:\test\dest}]
It's quite a lot harder to use eval right than {*}, so really upgrade.
Or even do:
foreach f $flist {
file copy $f {D:\test\dest}
}
Given that IO operations will dominate the performance, you shouldn't notice any speed difference for doing it this way.
The problem is the list is passed as a whole to the command instead of individual elements. Use {*} operator to break the list down to its individual elements.
The short answer is don't use a list the way you have done.
This works in your example:
set flist "a.txt b.txt"
file copy $flist [file join D:\\ test dest]
More correct would be to use the list expansion {*} syntax.

Converting Tcl to C++

I am trying to convert some tcl script into a C++ program. I don't have much experience with tcl and am hoping someone could explain what some of the following things are actually doing in the tcl script:
1) set rtn [true_test_sfm $run_dir]
2) cd [glob $run_dir]
3) set pwd [pwd]
Is the first one just checking if true_test_sfm directory exists in run_dir?
Also, I am programming on a windows machine. Would the system function be the equivalent to exec statements in tcl? And if so how would I print the result of the system function call to stdout?
In Tcl, square brackets indicate "evaluate the code between the square brackets". The result of that evaluation is substituted for the entire square-bracketed expression. So, the first line invokes the function true_test_sfm with a single argument $run_dir; the result of that function call is then assigned to the variable rtn. Unfortunately, true_test_sfm is not a built-in Tcl function, which means it's user-defined, which means there's no way we can tell you what the effect of that function call will be based on the information you've provided here.
glob is a built-in Tcl function which takes a file pattern as an argument and then lists files that match that pattern. For example, if a directory contains files "foo", "bar" and "baz", glob b* would return a list of two files, "bar" and "baz". Therefore the second line is looking for any files that match the pattern given by $run_dir, then using the cd command (another Tcl built-in) to change to the directory found by glob. Probably $run_dir is not actually a file pattern, but an explicit file name (ie, no globbing characters like * or ? in the string), otherwise this code may break unexpectedly. On Windows, some combination of FindFirstFile/FindNextFile in C++ could be used as a substitute for glob in Tcl, and SetCurrentDirectory could substitute for cd.
pwd is another built-in Tcl function which returns the process current working directory as an absolute path. So the last line is querying the current working directory and saving the result in a variable named pwd. Here you could use GetCurrentDirectory as a substitute for pwd.

TCL- script to output a file which contains size of all the files in the directry and subdirectories

Please help me with the script which outputs the file that contains names of the files in subdirectories and its memory in bytes, the arguement to the program is the folder path .output file should be file name in 1st column and its memory in second column
Note:folder contains subfolders...inside subfolders there are files
.I tried this way
set fp [open files_memory.txt w]
set file_names [glob ../design_data/*/*]
foreach file $file_names {
puts $fp "$file [lindex [exec du -sh $file] 0]"
}
close $fp
Result sample:
../design_data/def/ip2.def.gz 170M
../design_data/lef/tsmc13_10_5d.lef 7.1M
But i want only file name to be printed that is ip2.def.gz , tsmc13_10_5d.lef ..etc(not the entirepath) and file memorry should be aligned
TCL
The fileutil package in Tcllib defines the command fileutil::find, which can recursively list the contents of a directory. You can then use foreach to iterate over the list and get the sizes of each of them with file size, before producing the output with puts, perhaps like this:
puts "$filename\t$size"
The $filename is the name of the file, and the $size is how large it is. You will have obtained these values earlier (i.e., in the line or two before!). The \t in the middle is turned into a TAB character. Replace with spaces or a comma or virtually anything else you like; your call.
To get just the last part of the filename, I'd do:
puts $fp "[file tail $file] [file size $file]"
This does stuff with the full information about the file size, not the abbreviated form, so if you really want 4k instead of 4096, keep using that (slow) incantation with exec du. (If the consumer is a program, or a programmer, writing out the size in full is probably better.)
In addition to Donal's suggestion, there are more tools for getting files recursively:
recursive_glob (from the Tclx package) and
for_recursive_glob (also from Tclx)
fileutil::findByPattern (from the fileutil package)
Here is an example of how to use for_recursive_glob:
package require Tclx
for_recursive_glob filename {../design_data} {*} {
puts $filename
}
This suggestion, in combination with Donal's should be enough for you to create a complete solution. Good luck.
Discussion
The for_recursive_glob command takes 4 arguments:
The name of the variable representing the complete path name
A list of directory to search for (e.g. {/dir1 /dir2 /dir3})
A list of patterns to search for (e.g. {*.txt *.c *.cpp})
Finally, the body of the for loop, where you want to do something with the filename.
Based on my experience, for_recursive_glob cannot handle directories that you don't have permission to (i.e. on Mac, Linux, and BSD platforms, I don't know about Windows). In which case, the script will crash unless you catch the exception.
The recursive_glob command is similar, but it returns a list of filenames instead of structuring in a for loop.