Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Done Nitpick about %@unique[]'s generated files.

Nov
344
10
I've been fooling around with the @unique[] function, and I've noticed something about the random infix it uses:

1719581360984.png


It's fairly obvious that in both "short" names, a '0' was meant to be there but was chopped off while the number was being treated as a number.

This isn't a high priority thing, but I think it'd be more convenient to ensure the generated file names always have a known length, to ease up processes that may want to use many on-the-fly created files.



This happens in the same manner in all TCC versions I've tested (which I expected, as this probably hasn't been touched in a long time).
 
I don't have access to the code, but I suspect that @UNIQUE is just a wrapper around GetTempFileName(). So we can probably blame Microsoft.
 
Last edited:
I think @Charles Dye is correct. Roll your own using the likes of this. You'll get file name collisions with the expected randomness. I don't know what MS does to avoid that but I reckon whatever it is, it's the reason for the timing quirks.

Code:
v:\> function unique4 `UNI%@format[04,%@convert[10,16,%@random[0,65535]]].tmp`

v:\> echo %@unique4[]
UNI0C78.tmp

It would be interesting to study the collisions when @UNIQUE is used many times. If you use it 65537 times there must be collisions.
 
I remember writing a substitute @UNIQUE once upon a time. My concern was what happens if you have two or more instances of TCC running at the same time. It seemed possible to me that two near-simultaneous calls to @UNIQUE could generate the same nonexistent-at-the-moment filename, especially since GetTempFileName() uses the system clock as its starting value. Probably a silly thing to worry about, but it bothered me at the time.... My solution was to incorporate TCC's PID in the generated filename, so two different instances could never cough up matching filenames.

Also note that GetTempFileName() generates filename in MS-DOS-compatible 8.3 format, which should not be necessary any more. Today there's no reason why temp filenames can't include six or eight or 32 random characters.
 
I wonder what GetTempFileName()'s goal is. The names are meant to be unique; the docs don't mention random. If you use a fixed delay

between calls to @UNIQUE you get a sequence that's obviously not random. Here's what I get with no delays.

Code:
v:\> uniquecollisions.btm
FE52
FE72
FE92
FEB3
FED3
FEF3
FF13
FF34
FF54
FF84

... with 200ms delays

Code:
v:\> uniquecollisions.btm
C16D
C259
C344
C42F
C51B
C606
C6F2
C7DD
C8C8
C9B4

... with 1000ms delays

Code:
v:\> uniquecollisions.btm
915A
9572
997A
9D82
A19A
A5A3
A9AB
ADB3
B1CB
B5D3

I figure whatever the (fixed) delay, the sequence will be approximately arithmetic (modulo 65536) if there are no intervening random delays or some kind of reset. You can see that in @mfarah's output where the increment is approximetely 5033.

For my money, you might as well just step through 0000~FFFF (modulo 65536) using a random starting point and a fixed prime increment. Here's what I get using the increment 19231. I's guaranteed to give 65536 different names in 65536 tries. This (below) is strictly arithmetic but does that matter?

Code:
v:\> do i=1 to 10 (randomffff.btm)
9D01
E820
333F
7E5E
C97D
149C
5FBB
AADA
F5F9
4118

Off-topic, but here's an odd one. I think the "E-0" is being seen as indicating scientific notation.

Code:
v:\> echo %@eval[0xE076-0xCCCD]
5033

v:\> echo %@eval[0xF41E-0xE076]
TCC: Syntax error "0xF41E-0xE076"

v:\> echo %@eval[0xF41E - 0xE076]
5032
 
I wonder what GetTempFileName()'s goal is. The names are meant to be unique; the docs don't mention random.

Careless wording on my part. By 'random characters' I meant the uniquifying part of the filename.

For my money, you might as well just step through 0000~FFFF (modulo 65536) using a random starting point and a fixed prime increment.

I think so too. Here's the relevant bit of mine:

Code:
    rand_s( &Value );
    Value &= 0xffffff;


    do {
        wsprintf( TempName, L"%s-%X-%06X%s", Prefix, Pid, Value, Ext );
        Value = ( Value + 17 ) & 0xffffff;

        wcscpy_s( FullName, MAX_FILENAME_LEN, Path );
        AppendFilename( FullName, TempName, MAX_FILENAME_LEN );

    } while ( QueryIsFileOrDirectory( FullName ) );

Random starting value, adds 17 modulo 2^24. And Microsoft's uses a quasi-random starting value (the system clock) and adds 1 modulo 2^16.
 
For your consideration;
Code:
E:\Utils>repeat 10 (echo %@uuid[3].tmp)
476722AFC4474E66BF0B9F56CAD7B11D.tmp
6E53D6594DE04FB0A682A2FD55451B33.tmp
29A969BA83E149ADA089506FDA22BCAD.tmp
0AC17E3E0CF14EA5A59B1150FE65AB3E.tmp
660316388EBC45228B4BB2E260D6614D.tmp
A1F9C72B75DC461C8CDA54EF679B4051.tmp
6D434B0AD74D43B2B2F060FB68420941.tmp
840AFDAB135C4ED2B449E790264CE714.tmp
BAE7F073F2EA4455A044D3BD4C8EA424.tmp
81A12B60CA0B4420BD08D9C7B26FB6AB.tmp

Joe
 
Careless wording on my part. By 'random characters' I meant the uniquifying part of the filename.

I wasn't referring to your use of "random". Randomness seems to have nothing to do with it; I was off-base there.

I wonder if TCC uses GetTempFileName (it does import it) and if it does, what it passes as uUnique.
 
Back
Top
[FOX] Ultimate Translator
Translate