2415 |
2416 |
2416 |aStream fileName newFileName savFilename needRename |
2417 |aStream fileName newFileName savFilename needRename |
2417 mySourceFileName sameFile s mySourceFileID anySourceRef| |
2418 mySourceFileName sameFile s mySourceFileID anySourceRef| |
2418 |
2419 |
2419 self isLoaded ifFalse:[ |
2420 self isLoaded ifFalse:[ |
2420 ^ FileOutErrorSignal |
2421 ^ FileOutErrorSignal |
2421 raiseRequestWith:self |
2422 raiseRequestWith:self |
2422 errorString:' - will not fileOut unloaded class: ', self name |
2423 errorString:' - will not fileOut unloaded class: ', self name |
2423 ]. |
2424 ]. |
2424 |
2425 |
2425 fileName := fileNameString asFilename. |
2426 fileName := fileNameString asFilename. |
2426 |
2427 |
2427 " |
2428 " |
2428 if file exists, copy the existing to a .sav-file, |
2429 if file exists, copy the existing to a .sav-file, |
2429 create the new file as XXX.new-file, |
2430 create the new file as XXX.new-file, |
2430 and, if that worked rename afterwards ... |
2431 and, if that worked rename afterwards ... |
2431 " |
2432 " |
2432 (fileName exists) ifTrue:[ |
2433 (fileName exists) ifTrue:[ |
2433 sameFile := false. |
2434 sameFile := false. |
2434 |
2435 |
2435 "/ check carefully - maybe, my source does not really come from that |
2436 "/ check carefully - maybe, my source does not really come from that |
2436 "/ file (i.e. all of my methods have their source as string) |
2437 "/ file (i.e. all of my methods have their source as string) |
2437 |
2438 |
2438 anySourceRef := false. |
2439 anySourceRef := false. |
2439 self instAndClassMethodsDo:[:m | |
2440 self instAndClassMethodsDo:[:m | |
2440 m sourcePosition notNil ifTrue:[ |
2441 m sourcePosition notNil ifTrue:[ |
2441 anySourceRef := true |
2442 anySourceRef := true |
2442 ] |
2443 ] |
2443 ]. |
2444 ]. |
2444 |
2445 |
2445 anySourceRef ifTrue:[ |
2446 anySourceRef ifTrue:[ |
2446 s := self sourceStream. |
2447 s := self sourceStream. |
2447 s notNil ifTrue:[ |
2448 s notNil ifTrue:[ |
2448 OperatingSystem isUNIXlike ifTrue:[ |
2449 OperatingSystem isUNIXlike ifTrue:[ |
2449 mySourceFileID := s pathName asFilename info id. |
2450 mySourceFileID := s pathName asFilename info id. |
2450 sameFile := (fileName info id) == mySourceFileID. |
2451 sameFile := (fileName info id) == mySourceFileID. |
2451 ] ifFalse:[ |
2452 ] ifFalse:[ |
2452 mySourceFileID := s pathName asFilename asAbsoluteFilename. |
2453 mySourceFileID := s pathName asFilename asAbsoluteFilename. |
2453 sameFile := (fileName asFilename asAbsoluteFilename) = mySourceFileID. |
2454 sameFile := (fileName asFilename asAbsoluteFilename) = mySourceFileID. |
2454 ]. |
2455 ]. |
2455 s close. |
2456 s close. |
2456 ] ifFalse:[ |
2457 ] ifFalse:[ |
2457 classFilename notNil ifTrue:[ |
2458 classFilename notNil ifTrue:[ |
2458 " |
2459 " |
2459 check for overwriting my current source file |
2460 check for overwriting my current source file |
2460 this is not allowed, since it would clobber my methods source |
2461 this is not allowed, since it would clobber my methods source |
2461 file ... you have to save it to some other place. |
2462 file ... you have to save it to some other place. |
2462 This happens if you ask for a fileOut into the source-directory |
2463 This happens if you ask for a fileOut into the source-directory |
2463 (from which my methods get their source) |
2464 (from which my methods get their source) |
2464 " |
2465 " |
2465 mySourceFileName := Smalltalk getSourceFileName:classFilename. |
2466 mySourceFileName := Smalltalk getSourceFileName:classFilename. |
2466 sameFile := (fileNameString = mySourceFileName). |
2467 sameFile := (fileNameString = mySourceFileName). |
2467 sameFile ifFalse:[ |
2468 sameFile ifFalse:[ |
2468 mySourceFileName notNil ifTrue:[ |
2469 mySourceFileName notNil ifTrue:[ |
2469 OperatingSystem isUNIXlike ifTrue:[ |
2470 OperatingSystem isUNIXlike ifTrue:[ |
2470 sameFile := (fileName info id) == (mySourceFileName asFilename info id) |
2471 sameFile := (fileName info id) == (mySourceFileName asFilename info id) |
2471 ] |
2472 ] |
2472 ] |
2473 ] |
2473 ]. |
2474 ]. |
2474 ] |
2475 ] |
2475 ]. |
2476 ]. |
2476 ]. |
2477 ]. |
2477 |
2478 |
2478 sameFile ifTrue:[ |
2479 sameFile ifTrue:[ |
2479 ^ FileOutErrorSignal |
2480 ^ FileOutErrorSignal |
2480 raiseRequestWith:fileNameString |
2481 raiseRequestWith:fileNameString |
2481 errorString:(' - may not overwrite sourcefile:', fileNameString) |
2482 errorString:(' - may not overwrite sourcefile: %1\try again after loading sources in the browser' withCRs bindWith:fileNameString) |
2482 ]. |
2483 ]. |
2483 |
2484 |
2484 savFilename := Filename newTemporary. |
2485 savFilename := Filename newTemporary. |
2485 fileName copyTo:savFilename. |
2486 fileName copyTo:savFilename. |
2486 newFileName := fileName withSuffix:'new'. |
2487 newFileName := fileName withSuffix:'new'. |
2487 needRename := true |
2488 needRename := true |
2488 ] ifFalse:[ |
2489 ] ifFalse:[ |
2489 "/ another possible trap: if my sourceFileName is |
2490 "/ another possible trap: if my sourceFileName is |
2490 "/ the same as the written one AND the new files directory |
2491 "/ the same as the written one AND the new files directory |
2491 "/ is along the sourcePath, we also need a temporary file |
2492 "/ is along the sourcePath, we also need a temporary file |
2492 "/ first, to avoid accessing the newly written file. |
2493 "/ first, to avoid accessing the newly written file. |
2493 |
2494 |
2494 anySourceRef := false. |
2495 anySourceRef := false. |
2495 self instAndClassMethodsDo:[:m | |
2496 self instAndClassMethodsDo:[:m | |
2496 |mSrc| |
2497 |mSrc| |
2497 |
2498 |
2498 (mSrc := m sourceFilename) notNil ifTrue:[ |
2499 (mSrc := m sourceFilename) notNil ifTrue:[ |
2499 mSrc asFilename baseName = fileName baseName ifTrue:[ |
2500 mSrc asFilename baseName = fileName baseName ifTrue:[ |
2500 anySourceRef := true |
2501 anySourceRef := true |
2501 ] |
2502 ] |
2502 ] |
2503 ] |
2503 ]. |
2504 ]. |
2504 anySourceRef ifTrue:[ |
2505 anySourceRef ifTrue:[ |
2505 newFileName := fileName withSuffix:'new'. |
2506 newFileName := fileName withSuffix:'new'. |
2506 needRename := true |
2507 needRename := true |
2507 ] ifFalse:[ |
2508 ] ifFalse:[ |
2508 newFileName := fileName. |
2509 newFileName := fileName. |
2509 needRename := false |
2510 needRename := false |
2510 ] |
2511 ] |
2511 ]. |
2512 ]. |
2512 [ |
2513 [ |
2513 aStream := newFileName writeStream. |
2514 aStream := newFileName writeStream. |
2514 ] on:FileStream openErrorSignal do:[:ex| |
2515 ] on:FileStream openErrorSignal do:[:ex| |
2515 savFilename notNil ifTrue:[ |
2516 savFilename notNil ifTrue:[ |
2516 savFilename delete |
2517 savFilename delete |
2517 ]. |
2518 ]. |
2518 ^ FileOutErrorSignal |
2519 ^ FileOutErrorSignal |
2519 raiseRequestWith:newFileName name |
2520 raiseRequestWith:newFileName name |
2520 errorString:(' - cannot create file:', newFileName name) |
2521 errorString:(' - cannot create file:', newFileName name) |
2521 ]. |
2522 ]. |
2522 self fileOutOn:aStream. |
2523 self fileOutOn:aStream. |
2523 aStream close. |
2524 aStream close. |
2524 |
2525 |
2525 " |
2526 " |
2526 finally, replace the old-file |
2527 finally, replace the old-file |
2527 be careful, if the old one is a symbolic link; in this case, |
2528 be careful, if the old one is a symbolic link; in this case, |
2528 we have to do a copy ... |
2529 we have to do a copy ... |
2529 " |
2530 " |
2530 needRename ifTrue:[ |
2531 needRename ifTrue:[ |
2531 newFileName copyTo:fileName. |
2532 newFileName copyTo:fileName. |
2532 newFileName delete |
2533 newFileName delete |
2533 ]. |
2534 ]. |
2534 savFilename notNil ifTrue:[ |
2535 savFilename notNil ifTrue:[ |
2535 savFilename delete |
2536 savFilename delete |
2536 ]. |
2537 ]. |
2537 |
2538 |
2538 " |
2539 " |
2539 add a change record; that way, administration is much easier, |
2540 add a change record; that way, administration is much easier, |
2540 since we can see in that changeBrowser, which changes have |
2541 since we can see in that changeBrowser, which changes have |