diff options
author | Ascrod <32915892+Ascrod@users.noreply.github.com> | 2019-04-18 20:35:10 -0400 |
---|---|---|
committer | Ascrod <32915892+Ascrod@users.noreply.github.com> | 2019-04-18 20:35:10 -0400 |
commit | af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec (patch) | |
tree | 4aac6c4383fb9e279fccb13c65a4e44595fd4cf6 /toolkit | |
parent | 40fc72376411587e7bf9985fb9545eca1c9aaa8e (diff) | |
parent | 51722cd4fecb5c8c79a302f2771cad71535df5ea (diff) | |
download | UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar.gz UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar.lz UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar.xz UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.zip |
Merge branch 'master' into default-pref
Diffstat (limited to 'toolkit')
-rw-r--r-- | toolkit/components/passwordmgr/LoginHelper.jsm | 6 | ||||
-rw-r--r-- | toolkit/components/passwordmgr/storage-mozStorage.js | 2 | ||||
-rw-r--r-- | toolkit/identity/FirefoxAccounts.jsm | 313 | ||||
-rw-r--r-- | toolkit/identity/moz.build | 4 | ||||
-rw-r--r-- | toolkit/identity/tests/unit/head_identity.js | 8 | ||||
-rw-r--r-- | toolkit/identity/tests/unit/test_firefox_accounts.js | 270 | ||||
-rw-r--r-- | toolkit/identity/tests/unit/xpcshell.ini | 1 | ||||
-rw-r--r-- | toolkit/modules/AppConstants.jsm | 7 | ||||
-rw-r--r-- | toolkit/modules/moz.build | 3 | ||||
-rw-r--r-- | toolkit/xre/nsAppRunner.cpp | 2 |
10 files changed, 6 insertions, 610 deletions
diff --git a/toolkit/components/passwordmgr/LoginHelper.jsm b/toolkit/components/passwordmgr/LoginHelper.jsm index e0c4d872b..c6cd40915 100644 --- a/toolkit/components/passwordmgr/LoginHelper.jsm +++ b/toolkit/components/passwordmgr/LoginHelper.jsm @@ -202,7 +202,7 @@ this.LoginHelper = { return true; } } catch (ex) { - // newURI will throw for some values e.g. chrome://FirefoxAccounts + // newURI will throw for some values return false; } } @@ -406,7 +406,7 @@ this.LoginHelper = { try { preferredOriginScheme = Services.io.newURI(preferredOrigin, null, null).scheme; } catch (ex) { - // Handle strings that aren't valid URIs e.g. chrome://FirefoxAccounts + // Handle strings that aren't valid URIs } } @@ -457,7 +457,7 @@ this.LoginHelper = { return loginURI.scheme == preferredOriginScheme; } catch (ex) { - // Some URLs aren't valid nsIURI (e.g. chrome://FirefoxAccounts) + // Some URLs aren't valid nsIURI log.debug("dedupeLogins/shouldReplaceExisting: Error comparing schemes:", existingLogin.hostname, login.hostname, "preferredOrigin:", preferredOrigin, ex); diff --git a/toolkit/components/passwordmgr/storage-mozStorage.js b/toolkit/components/passwordmgr/storage-mozStorage.js index 7fc9e57fd..9da244f7a 100644 --- a/toolkit/components/passwordmgr/storage-mozStorage.js +++ b/toolkit/components/passwordmgr/storage-mozStorage.js @@ -471,7 +471,7 @@ LoginManagerStorage_mozStorage.prototype = { params["http" + field] = "http://" + valueURI.hostPort; } } catch (ex) { - // newURI will throw for some values (e.g. chrome://FirefoxAccounts) + // newURI will throw for some values // but those URLs wouldn't support upgrades anyways. } break; diff --git a/toolkit/identity/FirefoxAccounts.jsm b/toolkit/identity/FirefoxAccounts.jsm deleted file mode 100644 index 1d2ed0439..000000000 --- a/toolkit/identity/FirefoxAccounts.jsm +++ /dev/null @@ -1,313 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["FirefoxAccounts"]; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/Log.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/identity/LogUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "objectCopy", - "resource://gre/modules/identity/IdentityUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "makeMessageObject", - "resource://gre/modules/identity/IdentityUtils.jsm"); - -// loglevel preference should be one of: "FATAL", "ERROR", "WARN", "INFO", -// "CONFIG", "DEBUG", "TRACE" or "ALL". We will be logging error messages by -// default. -const PREF_LOG_LEVEL = "identity.fxaccounts.loglevel"; -try { - this.LOG_LEVEL = - Services.prefs.getPrefType(PREF_LOG_LEVEL) == Ci.nsIPrefBranch.PREF_STRING - && Services.prefs.getCharPref(PREF_LOG_LEVEL); -} catch (e) { - this.LOG_LEVEL = Log.Level.Error; -} - -var log = Log.repository.getLogger("Identity.FxAccounts"); -log.level = LOG_LEVEL; -log.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter())); - -log.warn("The FxAccountsManager has been removed."); -var FxAccountsManager = null; -var ONVERIFIED_NOTIFICATION = null; -var ONLOGIN_NOTIFICATION = null; -var ONLOGOUT_NOTIFICATION = null; - -function FxAccountsService() { - Services.obs.addObserver(this, "quit-application-granted", false); - if (ONVERIFIED_NOTIFICATION) { - Services.obs.addObserver(this, ONVERIFIED_NOTIFICATION, false); - Services.obs.addObserver(this, ONLOGIN_NOTIFICATION, false); - Services.obs.addObserver(this, ONLOGOUT_NOTIFICATION, false); - } - - // Maintain interface parity with Identity.jsm and MinimalIdentity.jsm - this.RP = this; - - this._rpFlows = new Map(); - - // Enable us to mock FxAccountsManager service in testing - this.fxAccountsManager = FxAccountsManager; -} - -FxAccountsService.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]), - - observe: function observe(aSubject, aTopic, aData) { - switch (aTopic) { - case null: - // Guard against matching null ON*_NOTIFICATION - break; - case ONVERIFIED_NOTIFICATION: - log.debug("Received " + ONVERIFIED_NOTIFICATION + "; firing request()s"); - for (let [rpId,] of this._rpFlows) { - this.request(rpId); - } - break; - case ONLOGIN_NOTIFICATION: - log.debug("Received " + ONLOGIN_NOTIFICATION + "; doLogin()s fired"); - for (let [rpId,] of this._rpFlows) { - this.request(rpId); - } - break; - case ONLOGOUT_NOTIFICATION: - log.debug("Received " + ONLOGOUT_NOTIFICATION + "; doLogout()s fired"); - for (let [rpId,] of this._rpFlows) { - this.doLogout(rpId); - } - break; - case "quit-application-granted": - Services.obs.removeObserver(this, "quit-application-granted"); - if (ONVERIFIED_NOTIFICATION) { - Services.obs.removeObserver(this, ONVERIFIED_NOTIFICATION); - Services.obs.removeObserver(this, ONLOGIN_NOTIFICATION); - Services.obs.removeObserver(this, ONLOGOUT_NOTIFICATION); - } - break; - } - }, - - cleanupRPRequest: function(aRp) { - aRp.pendingRequest = false; - this._rpFlows.set(aRp.id, aRp); - }, - - /** - * Register a listener for a given windowID as a result of a call to - * navigator.id.watch(). - * - * @param aRPCaller - * (Object) an object that represents the caller document, and - * is expected to have properties: - * - id (unique, e.g. uuid) - * - origin (string) - * - * and a bunch of callbacks - * - doReady() - * - doLogin() - * - doLogout() - * - doError() - * - doCancel() - * - */ - watch: function watch(aRpCaller) { - this._rpFlows.set(aRpCaller.id, aRpCaller); - log.debug("watch: " + aRpCaller.id); - log.debug("Current rp flows: " + this._rpFlows.size); - - // Log the user in, if possible, and then call ready(). - let runnable = { - run: () => { - this.fxAccountsManager.getAssertion(aRpCaller.audience, - aRpCaller.principal, - { silent:true }).then( - data => { - if (data) { - this.doLogin(aRpCaller.id, data); - } else { - this.doLogout(aRpCaller.id); - } - this.doReady(aRpCaller.id); - }, - error => { - log.error("get silent assertion failed: " + JSON.stringify(error)); - this.doError(aRpCaller.id, error); - } - ); - } - }; - Services.tm.currentThread.dispatch(runnable, - Ci.nsIThread.DISPATCH_NORMAL); - }, - - /** - * Delete the flow when the screen is unloaded - */ - unwatch: function(aRpCallerId, aTargetMM) { - log.debug("unwatching: " + aRpCallerId); - this._rpFlows.delete(aRpCallerId); - }, - - /** - * Initiate a login with user interaction as a result of a call to - * navigator.id.request(). - * - * @param aRPId - * (integer) the id of the doc object obtained in .watch() - * - * @param aOptions - * (Object) options including privacyPolicy, termsOfService - */ - request: function request(aRPId, aOptions) { - aOptions = aOptions || {}; - let rp = this._rpFlows.get(aRPId); - if (!rp) { - log.error("request() called before watch()"); - return; - } - - // We check if we already have a pending request for this RP and in that - // case we just bail out. We don't want duplicated onlogin or oncancel - // events. - if (rp.pendingRequest) { - log.debug("request() already called"); - return; - } - - // Otherwise, we set the RP flow with the pending request flag. - rp.pendingRequest = true; - this._rpFlows.set(rp.id, rp); - - let options = makeMessageObject(rp); - objectCopy(aOptions, options); - - log.debug("get assertion for " + rp.audience); - - this.fxAccountsManager.getAssertion(rp.audience, rp.principal, options) - .then( - data => { - log.debug("got assertion for " + rp.audience + ": " + data); - this.doLogin(aRPId, data); - }, - error => { - log.debug("get assertion failed: " + JSON.stringify(error)); - // Cancellation is passed through an error channel; here we reroute. - if ((error.error && (error.error.details == "DIALOG_CLOSED_BY_USER")) || - (error.details == "DIALOG_CLOSED_BY_USER")) { - return this.doCancel(aRPId); - } - this.doError(aRPId, error); - } - ) - .then( - () => { - this.cleanupRPRequest(rp); - } - ) - .catch( - () => { - this.cleanupRPRequest(rp); - } - ); - }, - - /** - * Invoked when a user wishes to logout of a site (for instance, when clicking - * on an in-content logout button). - * - * @param aRpCallerId - * (integer) the id of the doc object obtained in .watch() - * - */ - logout: function logout(aRpCallerId) { - // XXX Bug 945363 - Resolve the SSO story for FXA and implement - // logout accordingly. - // - // For now, it makes no sense to logout from a specific RP in - // Firefox Accounts, so just directly call the logout callback. - if (!this._rpFlows.has(aRpCallerId)) { - log.error("logout() called before watch()"); - return; - } - - // Call logout() on the next tick - let runnable = { - run: () => { - this.fxAccountsManager.signOut().then(() => { - this.doLogout(aRpCallerId); - }); - } - }; - Services.tm.currentThread.dispatch(runnable, - Ci.nsIThread.DISPATCH_NORMAL); - }, - - childProcessShutdown: function childProcessShutdown(messageManager) { - for (let [key,] of this._rpFlows) { - if (this._rpFlows.get(key)._mm === messageManager) { - this._rpFlows.delete(key); - } - } - }, - - doLogin: function doLogin(aRpCallerId, aAssertion) { - let rp = this._rpFlows.get(aRpCallerId); - if (!rp) { - log.warn("doLogin found no rp to go with callerId " + aRpCallerId); - return; - } - - rp.doLogin(aAssertion); - }, - - doLogout: function doLogout(aRpCallerId) { - let rp = this._rpFlows.get(aRpCallerId); - if (!rp) { - log.warn("doLogout found no rp to go with callerId " + aRpCallerId); - return; - } - - rp.doLogout(); - }, - - doReady: function doReady(aRpCallerId) { - let rp = this._rpFlows.get(aRpCallerId); - if (!rp) { - log.warn("doReady found no rp to go with callerId " + aRpCallerId); - return; - } - - rp.doReady(); - }, - - doCancel: function doCancel(aRpCallerId) { - let rp = this._rpFlows.get(aRpCallerId); - if (!rp) { - log.warn("doCancel found no rp to go with callerId " + aRpCallerId); - return; - } - - rp.doCancel(); - }, - - doError: function doError(aRpCallerId, aError) { - let rp = this._rpFlows.get(aRpCallerId); - if (!rp) { - log.warn("doError found no rp to go with callerId " + aRpCallerId); - return; - } - - rp.doError(aError); - } -}; - -this.FirefoxAccounts = new FxAccountsService(); - diff --git a/toolkit/identity/moz.build b/toolkit/identity/moz.build index 4c0dc8190..ba9697bd6 100644 --- a/toolkit/identity/moz.build +++ b/toolkit/identity/moz.build @@ -29,8 +29,4 @@ EXTRA_JS_MODULES.identity += [ 'Sandbox.jsm', ] -EXTRA_PP_JS_MODULES.identity += [ - 'FirefoxAccounts.jsm', -] - FINAL_LIBRARY = 'xul' diff --git a/toolkit/identity/tests/unit/head_identity.js b/toolkit/identity/tests/unit/head_identity.js index a266e7aee..c63261b95 100644 --- a/toolkit/identity/tests/unit/head_identity.js +++ b/toolkit/identity/tests/unit/head_identity.js @@ -239,18 +239,10 @@ try { } catch (noPref) {} Services.prefs.setBoolPref("toolkit.identity.debug", true); -// Switch on firefox accounts -var initialPrefFXAValue = false; -try { - initialPrefFXAValue = Services.prefs.getBoolPref("identity.fxaccounts.enabled"); -} catch (noPref) {} -Services.prefs.setBoolPref("identity.fxaccounts.enabled", true); - // after execution, restore prefs do_register_cleanup(function() { log("restoring prefs to their initial values"); Services.prefs.setBoolPref("toolkit.identity.debug", initialPrefDebugValue); - Services.prefs.setBoolPref("identity.fxaccounts.enabled", initialPrefFXAValue); }); diff --git a/toolkit/identity/tests/unit/test_firefox_accounts.js b/toolkit/identity/tests/unit/test_firefox_accounts.js deleted file mode 100644 index c0c63deb6..000000000 --- a/toolkit/identity/tests/unit/test_firefox_accounts.js +++ /dev/null @@ -1,270 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/DOMIdentity.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "FirefoxAccounts", - "resource://gre/modules/identity/FirefoxAccounts.jsm"); - -// Make the profile dir available; this is necessary so that -// services/fxaccounts/FxAccounts.jsm can read and write its signed-in user -// data. -do_get_profile(); - -function MockFXAManager() { - this.signedInUser = true; -} -MockFXAManager.prototype = { - getAssertion: function(audience) { - let result = this.signedInUser ? TEST_ASSERTION : null; - return Promise.resolve(result); - }, - - signOut: function() { - this.signedInUser = false; - return Promise.resolve(null); - }, - - signIn: function(user) { - this.signedInUser = user; - return Promise.resolve(user); - }, -} - -var originalManager = FirefoxAccounts.fxAccountsManager; -FirefoxAccounts.fxAccountsManager = new MockFXAManager(); -do_register_cleanup(() => { - log("restoring fxaccountsmanager"); - FirefoxAccounts.fxAccountsManager = originalManager; -}); - -function withNobodySignedIn() { - return FirefoxAccounts.fxAccountsManager.signOut(); -} - -function withSomebodySignedIn() { - return FirefoxAccounts.fxAccountsManager.signIn('Pertelote'); -} - -function test_overall() { - do_check_neq(FirefoxAccounts, null); - run_next_test(); -} - -function test_mock() { - do_test_pending(); - - withSomebodySignedIn().then(() => { - FirefoxAccounts.fxAccountsManager.getAssertion().then(assertion => { - do_check_eq(assertion, TEST_ASSERTION); - do_test_finished(); - run_next_test(); - }); - }); -} - -function test_watch_signed_in() { - do_test_pending(); - - let received = []; - - let mockedRP = mock_fxa_rp(null, TEST_URL, function(method, data) { - received.push([method, data]); - - if (method == "ready") { - // confirm that we were signed in and then ready was called - do_check_eq(received.length, 2); - do_check_eq(received[0][0], "login"); - do_check_eq(received[0][1], TEST_ASSERTION); - do_check_eq(received[1][0], "ready"); - do_test_finished(); - run_next_test(); - } - }); - - withSomebodySignedIn().then(() => { - FirefoxAccounts.RP.watch(mockedRP); - }); -} - -function test_watch_signed_out() { - do_test_pending(); - - let received = []; - - let mockedRP = mock_fxa_rp(null, TEST_URL, function(method) { - received.push(method); - - if (method == "ready") { - // confirm that we were signed out and then ready was called - do_check_eq(received.length, 2); - do_check_eq(received[0], "logout"); - do_check_eq(received[1], "ready"); - - do_test_finished(); - run_next_test(); - } - }); - - withNobodySignedIn().then(() => { - FirefoxAccounts.RP.watch(mockedRP); - }); -} - -function test_request() { - do_test_pending(); - - let received = []; - - let mockedRP = mock_fxa_rp(null, TEST_URL, function(method, data) { - received.push([method, data]); - - // On watch(), we are signed out. Then we call request(). - if (received.length === 2) { - do_check_eq(received[0][0], "logout"); - do_check_eq(received[1][0], "ready"); - - // Pretend request() showed ux and the user signed in - withSomebodySignedIn().then(() => { - FirefoxAccounts.RP.request(mockedRP.id); - }); - } - - if (received.length === 3) { - do_check_eq(received[2][0], "login"); - do_check_eq(received[2][1], TEST_ASSERTION); - - do_test_finished(); - run_next_test(); - } - }); - - // First, call watch() with nobody signed in - withNobodySignedIn().then(() => { - FirefoxAccounts.RP.watch(mockedRP); - }); -} - -function test_logout() { - do_test_pending(); - - let received = []; - - let mockedRP = mock_fxa_rp(null, TEST_URL, function(method) { - received.push(method); - - // At first, watch() signs us in automatically. Then we sign out. - if (received.length === 2) { - do_check_eq(received[0], "login"); - do_check_eq(received[1], "ready"); - - FirefoxAccounts.RP.logout(mockedRP.id); - } - - if (received.length === 3) { - do_check_eq(received[2], "logout"); - do_test_finished(); - run_next_test(); - } - }); - - // First, call watch() - withSomebodySignedIn().then(() => { - FirefoxAccounts.RP.watch(mockedRP); - }); -} - -function test_error() { - do_test_pending(); - - let received = []; - - // Mock the fxAccountsManager so that getAssertion rejects its promise and - // triggers our onerror handler. (This is the method that's used internally - // by FirefoxAccounts.RP.request().) - let originalGetAssertion = FirefoxAccounts.fxAccountsManager.getAssertion; - FirefoxAccounts.fxAccountsManager.getAssertion = function(audience) { - return Promise.reject(new Error("barf!")); - }; - - let mockedRP = mock_fxa_rp(null, TEST_URL, function(method, message) { - // We will immediately receive an error, due to watch()'s attempt - // to getAssertion(). - do_check_eq(method, "error"); - do_check_true(/barf/.test(message)); - - // Put things back the way they were - FirefoxAccounts.fxAccountsManager.getAssertion = originalGetAssertion; - - do_test_finished(); - run_next_test(); - }); - - // First, call watch() - withSomebodySignedIn().then(() => { - FirefoxAccounts.RP.watch(mockedRP); - }); -} - -function test_child_process_shutdown() { - do_test_pending(); - let rpCount = FirefoxAccounts.RP._rpFlows.size; - - makeObserver("identity-child-process-shutdown", (aTopic, aSubject, aData) => { - // Last of all, the shutdown observer message will be fired. - // This takes place after the RP has a chance to delete flows - // and clean up. - do_check_eq(FirefoxAccounts.RP._rpFlows.size, rpCount); - do_test_finished(); - run_next_test(); - }); - - let mockedRP = mock_fxa_rp(null, TEST_URL, (method) => { - // We should enter this function for 'ready' and 'child-process-shutdown'. - // After we have a chance to do our thing, the shutdown observer message - // will fire and be caught by the function above. - do_check_eq(FirefoxAccounts.RP._rpFlows.size, rpCount + 1); - switch (method) { - case "ready": - DOMIdentity._childProcessShutdown("my message manager"); - break; - - case "child-process-shutdown": - // We have to call this explicitly because there's no real - // dom window here. - FirefoxAccounts.RP.childProcessShutdown(mockedRP._mm); - break; - - default: - break; - } - }); - - mockedRP._mm = "my message manager"; - withSomebodySignedIn().then(() => { - FirefoxAccounts.RP.watch(mockedRP); - }); - - // fake a dom window context - DOMIdentity.newContext(mockedRP, mockedRP._mm); -} - -var TESTS = [ - test_overall, - test_mock, - test_watch_signed_in, - test_watch_signed_out, - test_request, - test_logout, - test_error, - test_child_process_shutdown, -]; - -TESTS.forEach(add_test); - -function run_test() { - run_next_test(); -} diff --git a/toolkit/identity/tests/unit/xpcshell.ini b/toolkit/identity/tests/unit/xpcshell.ini index 38b37402c..309e4791c 100644 --- a/toolkit/identity/tests/unit/xpcshell.ini +++ b/toolkit/identity/tests/unit/xpcshell.ini @@ -9,7 +9,6 @@ support-files = # Test load modules first so syntax failures are caught early. [test_load_modules.js] [test_minimalidentity.js] -[test_firefox_accounts.js] [test_identity_utils.js] [test_log_utils.js] diff --git a/toolkit/modules/AppConstants.jsm b/toolkit/modules/AppConstants.jsm index 1e2204f7e..ae0eea1c4 100644 --- a/toolkit/modules/AppConstants.jsm +++ b/toolkit/modules/AppConstants.jsm @@ -102,13 +102,6 @@ MOZ_SAFE_BROWSING: false, #endif - MOZ_SERVICES_CLOUDSYNC: -#ifdef MOZ_SERVICES_CLOUDSYNC - true, -#else - false, -#endif - MOZ_UPDATER: #ifdef MOZ_UPDATER true, diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index e0acdb19e..8f66417c1 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -151,8 +151,7 @@ for var in ('ANDROID_PACKAGE_NAME', for var in ('MOZ_TOOLKIT_SEARCH', 'MOZ_SYSTEM_NSS', 'MOZ_UPDATER', - 'MOZ_SWITCHBOARD', - 'MOZ_SERVICES_CLOUDSYNC'): + 'MOZ_SWITCHBOARD'): if CONFIG[var]: DEFINES[var] = True diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 26e432b3c..4ae70fd43 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -2462,7 +2462,7 @@ RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfileDir, if (!file) return false; -#if defined(XP_UNIX) || defined(XP_BEOS) +#if defined(XP_UNIX) #define PLATFORM_FASL_SUFFIX ".mfasl" #elif defined(XP_WIN) #define PLATFORM_FASL_SUFFIX ".mfl" |