Ticket Change Details
Overview

Artifact ID: 4eaaa9b664fe5ca116577e81a6bd17bf4344f219
Ticket: bd6188edd4290bfdcff4a8ef9355f5280496eda5
dir2c: Output data as character array and not as string
User & Date: anonymous on 2020-04-20 16:03:24
Changes

  1. Change comment to:
    Dear Roy,

    thank you for great tcl2c.tcl and its framework.
    I am learning each day and digging miself through the mechanisms.
    Sorry to be a novice.
    And sorry to use Microsoft compilers.

    The compiler MS-VC2015 (VC9) has a string constant size limit of 65535 characters.
    A possibility to avoid this limit is to use an array of characters, which have a limit of size_z = 0x7CFFFFFF.

    The patch below changes dir2c.tcl to output each file within one character array named  cvfs_data_$idx as follows:

    <verbatim>
    /* Data of boot.tcl */
    static unsigned char cvfs_data_2[] = {
        0x70, 0x72, 0x6f, 0x63, 0x20, 0x74, 0x63, 0x6c, 0x49, 0x6e, 0x69, 0x74, 0x20, 0x7b, 0x7d, 0x20,
    ...
    static struct cvfs_data cvfs_tcl_data[] = {
    ...
        {
            /* name  */ "boot.tcl",
            /* index */ 2,
            /* type  */ CVFS_FILETYPE_FILE,
            /* size  */ 2887,
            /* data  */ cvfs_data_2,
            /* free  */ 0,
        },
    </verbatim>

    The patch allows to use this for all files or files larger than the character length limit.

    I may miss another disadvantage of this method. I suppose, it only avoids the implicite trailing zero byte.

    Thank you,
    Harald

    Patch:
    <verbatim>
    --- C:/Users/oehhar/AppData/Local/Temp/dir2c.tcl-revBASE.svn001.tmp.tcl    Fri Apr 17 17:29:24 2020
    +++ C:/oehhar/elmicron/projekte/el1005_scanlink_dll/source/c-vfs/dir2c.tcl    Mon Apr 20 17:30:25 2020
    @@ -66,26 +66,44 @@
     proc stringify {data} {
         set ret "\""
         for {set idx 0} {$idx < [string length $data]} {incr idx} {
             binary scan [string index $data $idx] H* char
     
             append ret "\\x${char}"
     
    -        if {($idx % 20) == 0 && $idx != 0} {
    +        if {(($idx+1) % 20) == 0} {
                 append ret "\"\n\""
             }
         }
     
         set ret [string trim $ret "\n\""]
     
         set ret "\"$ret\""
     
         return $ret
     }
     
    +# Convert data to a character array
    +proc character_array {data} {
    +    set ret "\{\n\t"
    +    for {set idx 0} {$idx < [string length $data]} {incr idx} {
    +        binary scan [string index $data $idx] H* char
    +        append ret "0x${char}, "
    +
    +        if {(($idx+1) % 16) == 0 } {
    +            append ret "\n\t"
    +        }
    +    }
    +    set ret [string trimright $ret "\n, \t"]
    +
    +    append ret "\n\}"
    +
    +    return $ret
    +}
    +
     # Encrypt the data
     proc random_byte {} {
         set value [expr {int(256 * rand())}]
     
         return $value
     }
     
    @@ -303,64 +321,80 @@
     
         return(0);
     }
     
     #  endif /* !LOADED_CVFS_COMMON */}
     puts ""
     
    -puts "static struct cvfs_data ${code_tag}_data\[\] = {"
    -puts "\t{"
    -puts "\t\t/* Index 0 cannot be used because we use the value 0 to represent failure */"
    -puts "\t\t/* name  */ NULL,"
    -puts "\t\t/* index */ 0,"
    -puts "\t\t/* type  */ 0,"
    -puts "\t\t/* size  */ 0,"
    -puts "\t\t/* data  */ NULL,"
    -puts "\t\t/* free  */ 0,"
    -puts "\t},"
    +# C struct data output buffer (must be delayed after definition of file data)
    +set struct_data ""
    +
     for {set idx 1} {$idx < [llength $files]} {incr idx} {
         set file [lindex $files $idx]
         set shortfile [shorten_file $startdir $file]
     
         unset -nocomplain finfo type
         file stat $file finfo
     
         switch -- $finfo(type) {
             "file" {
                 set size $finfo(size)
     
                 set fd [open $file]
                 fconfigure $fd -translation binary
    -            set data [read $fd]
    +            set data_in [read $fd]
                 close $fd
     
                 if {$obsfucate} {
                     set type "CVFS_FILETYPE_ENCRYPTED_FILE"
    -                set data "(unsigned char *) [stringify [encrypt $data $obsfucation_key]]"
    +                set data_in [encrypt $data $obsfucation_key]
                 } else {
                     set type "CVFS_FILETYPE_FILE"
    -                set data "(unsigned char *) [stringify $data]"
                 }
    +            # Microsoft VC9 compiler has a string limit of 65535 bytes
    +            # so put all larger files into an array which has a higher
    +            # string limit
    +            #if {$size <= 65535} {
    +            #    set data "(unsigned char *) [stringify $data_in]"
    +            #} else {
    +                puts "/* Data of $shortfile */"
    +                set variable_name cvfs_data_$idx
    +                set data $variable_name
    +                puts "static unsigned char ${variable_name}\[\] =\
    +                        [character_array $data_in];"
    +            #}
             }
             "directory" {
                 set type "CVFS_FILETYPE_DIR"
                 set data "NULL"
                 set size 0
             }
         }
     
    -    puts "\t{"
    -    puts "\t\t/* name  */ \"$shortfile\","
    -    puts "\t\t/* index */ $idx,"
    -    puts "\t\t/* type  */ $type,"
    -    puts "\t\t/* size  */ $size,"
    -    puts "\t\t/* data  */ $data,"
    -    puts "\t\t/* free  */ 0,"
    -    puts "\t},"
    +    append struct_data "\t{\n"\
    +            "\t\t/* name  */ \"$shortfile\",\n"\
    +            "\t\t/* index */ $idx,\n"\
    +            "\t\t/* type  */ $type,\n"\
    +            "\t\t/* size  */ $size,\n"\
    +            "\t\t/* data  */ $data,\n"\
    +            "\t\t/* free  */ 0,\n"\
    +            "\t},\n"
     }
    +puts ""
    +puts "static struct cvfs_data ${code_tag}_data\[\] = {"
    +puts "\t{"
    +puts "\t\t/* Index 0 cannot be used because we use the value 0 to represent failure */"
    +puts "\t\t/* name  */ NULL,"
    +puts "\t\t/* index */ 0,"
    +puts "\t\t/* type  */ 0,"
    +puts "\t\t/* size  */ 0,"
    +puts "\t\t/* data  */ NULL,"
    +puts "\t\t/* free  */ 0,"
    +puts "\t},"
    +puts -nonewline $struct_data
     puts "};"
     puts ""
     
     puts "static unsigned long ${code_tag}_lookup_index(const char *path) {"
     puts "\tswitch (cvfs_hash((unsigned char *) path)) {"
     
     for {set idx 1} {$idx < [llength $files]} {incr idx} {

    </verbatim>
  2. Change foundin to "trunk"
  3. Change login to "anonymous"
  4. Change private_contact to "0f366eb3e9e2fcab52b8ebacd197db9047186a5f"
  5. Change severity to "Minor"
  6. Change status to "Open"
  7. Change title to:

    dir2c: Output data as character array and not as string

  8. Change type to "Feature Request"